首页 > 代码库 > tkD--来自TCL/TK之D语言跨平台GUI库

tkD--来自TCL/TK之D语言跨平台GUI库

D越来越有玩头了~~

感觉一下代码的流畅:

  1 module main;  2   3 /**  4  * Imports.  5  */  6 import std.algorithm;  7 import std.array;  8 import std.datetime;  9 import std.file; 10 import tkd.tkdapplication; 11  12 /** 13  * Sample application. 14  */ 15 class Application : TkdApplication 16 { 17     /** 18      * Widgets we need access to on the class level. 19      */ 20     private Entry _entry; 21     private ProgressBar _progressBar; 22     private Canvas _canvas; 23     private Entry _fontEntry; 24     private Entry _colorEntry; 25     private Entry _directoryEntry; 26     private Entry _openFileEntry; 27     private Entry _saveFileEntry; 28     private Entry _messageEntry; 29  30     /** 31      * Open the font dialog. 32      * 33      * Params: 34      *     args = The callback args. 35      */ 36     private void openFontDialog(CommandArgs args) 37     { 38         auto dialog = new FontDialog("Choose a font") 39             .setCommand(delegate(CommandArgs args){ 40                 this._fontEntry.setValue(args.dialog.font); 41             }) 42             .show(); 43     } 44  45     /** 46      * Open the color dialog. 47      * 48      * Params: 49      *     args = The callback args. 50      */ 51     private void openColorDialog(CommandArgs args) 52     { 53         auto dialog = new ColorDialog("Choose a color") 54             .setInitialColor(Color.beige) 55             .show(); 56         this._colorEntry.setValue(dialog.getResult()); 57     } 58  59     /** 60      * Open the directory dialog. 61      * 62      * Params: 63      *     args = The callback args. 64      */ 65     private void openDirectoryDialog(CommandArgs args) 66     { 67         auto dialog = new DirectoryDialog("Choose a directory") 68             .setDirectoryMustExist(true) 69             .show(); 70         this._directoryEntry.setValue(dialog.getResult()); 71     } 72  73     /** 74      * Open the open file dialog. 75      * 76      * Params: 77      *     args = The callback args. 78      */ 79     private void openOpenFileDialog(CommandArgs args) 80     { 81         auto dialog = new OpenFileDialog() 82             .setMultiSelection(true) 83             .setDefaultExtension(".dmo") 84             .addFileType("{{All files} {*}}") 85             .addFileType("{{D language files} {.d .di}}") 86             .addFileType("{{HTML files} {.htm .html}}") 87             .addFileType("{{Text files} {.txt}}") 88             .setInitialDirectory("~") 89             .setInitialFile("file-to-open.dmo") 90             .show(); 91         this._openFileEntry.setValue(dialog.getResults().join(" ")); 92     } 93  94     /** 95      * Open the save file dialog. 96      * 97      * Params: 98      *     args = The callback args. 99      */100     private void openSaveFileDialog(CommandArgs args)101     {102         auto dialog = new SaveFileDialog()103             .setConfirmOverwrite(true)104             .setDefaultExtension(".dmo")105             .addFileType("{{All files} {*}}")106             .addFileType("{{D language files} {.d .di}}")107             .addFileType("{{HTML files} {.htm .html}}")108             .addFileType("{{Text files} {.txt}}")109             .setInitialDirectory("~")110             .setInitialFile("file-to-save.dmo")111             .show();112         this._saveFileEntry.setValue(dialog.getResult());113     }114 115     /**116      * Open the message dialog.117      *118      * Params:119      *     args = The callback args.120      */121     private void openMessageDialog(CommandArgs args)122     {123         auto dialog = new MessageDialog()124             .setMessage("Lorem ipsum dolor sit amet.")125             .setDetailMessage("Nunc at aliquam arcu. Sed eget tellus ligula.\nSed egestas est et tempus cursus.")126             .setType(MessageDialogType.okcancel)127             .show();128         this._messageEntry.setValue(dialog.getResult());129     }130 131     /**132      * Mark a point in the canvas to drag from.133      *134      * Params:135      *     args = The callback args.136      */137     private void mark(CommandArgs args)138     {139         this._canvas.setScanMark(args.event.x, args.event.y);140     }141 142     /**143      * Drag the canvas to reposition the contents.144      *145      * Params:146      *     args = The callback args.147      */148     private void drag(CommandArgs args)149     {150         this._canvas.scanDragTo(args.event.x, args.event.y);151     }152 153     /**154      * Show the about box.155      */156     private void showAbout(CommandArgs args)157     {158         auto dialog = new MessageDialog("About")159             .setMessage("Tkd Showcase")160             .setDetailMessage("An showcase Tkd application demonstrating menus, widgets and dialogs.\n\nThe possiblities are endless.")161             .show();162     }163 164     /**165      * Create the menu.166      */167     private void createMenu()168     {169         auto menuBar = new MenuBar(this.mainWindow);170 171         auto fileMenu = new Menu(menuBar, "File", 0)172             .addEntry(new EmbeddedPng!("cancel.png"), "Quit", &this.exitApplication, ImagePosition.left, "Ctrl-Q");173 174         auto helpMenu = new Menu(menuBar, "Help", 0)175             .addEntry(new EmbeddedPng!("help.png"), "About...", &this.showAbout, ImagePosition.left, "F1");176     }177 178     /**179      * Create the widget pane for the note book.180      *181      * Returns:182      *     The widget pane.183      */184     private Frame createWidgetPane()185     {186         auto widgetPane = new Frame();187 188         auto entryLabelFrame = new LabelFrame(widgetPane, "Text Entry")189             .pack(10, 0, GeometrySide.top, GeometryFill.both, AnchorPosition.center, true);190             auto entry1 = new Text(entryLabelFrame)191                 .setWidth(0)192                 .setHeight(3)193                 .appendText("Nullam sapien lectus, aliquet sit amet quam et, sagittis porttitor dolor.")194                 .pack(5, 0, GeometrySide.bottom, GeometryFill.both, AnchorPosition.northWest, true);195             this._entry = new Entry(entryLabelFrame)196                 .pack(5, 0, GeometrySide.left, GeometryFill.x, AnchorPosition.northWest, true);197             auto entry3 = new SpinBox(entryLabelFrame)198                 .setData(["foo", "bar", "baz", "qux"])199                 .setWrap(true)200                 .setWidth(5)201                 .pack(5, 0, GeometrySide.left);202             auto entry4 = new ComboBox(entryLabelFrame)203                 .setData(["Option 1", "Option 2", "Option 3"])204                 .setValue("Option 1")205                 .pack(5, 0, GeometrySide.left, GeometryFill.x, AnchorPosition.northWest, true);206 207         auto rangeLabelFrame = new LabelFrame(widgetPane, "Progress & Scale")208             .pack(10, 0, GeometrySide.bottom, GeometryFill.both, AnchorPosition.center);209             this._progressBar = new ProgressBar(rangeLabelFrame)210                 .setMaxValue(10)211                 .setValue(4)212                 .pack(5, 0, GeometrySide.top, GeometryFill.x, AnchorPosition.center, true);213             auto scale = new Scale(rangeLabelFrame)214                 .setFromValue(10)215                 .setToValue(0)216                 .setCommand(delegate(CommandArgs args){217                     auto scale = cast(Scale)args.element;218                     this._progressBar.setValue(scale.getValue());219                 })220                 .setValue(4)221                 .pack(5, 0, GeometrySide.top, GeometryFill.x, AnchorPosition.center, true);222 223         auto buttonLabelFrame = new LabelFrame(widgetPane, "Buttons")224             .pack(10, 0, GeometrySide.left, GeometryFill.both, AnchorPosition.center, true);225             auto button1 = new Button(buttonLabelFrame, "Text button")226                 .pack(5);227             auto button2 = new Button(buttonLabelFrame, new EmbeddedPng!("thumbnail.png"), "Image button", ImagePosition.left)228                 .pack(5);229             auto buttonMenu = new Menu()230                 .addEntry("Option 1", delegate(CommandArgs args){})231                 .addEntry("Option 2", delegate(CommandArgs args){})232                 .addEntry("Option 3", delegate(CommandArgs args){});233             auto button3 = new MenuButton(buttonLabelFrame, "Menu button", buttonMenu)234                 .pack(5);235 236         auto checkBoxLabelFrame = new LabelFrame(widgetPane, "Check buttons")237             .pack(10, 0, GeometrySide.left, GeometryFill.both, AnchorPosition.center, true);238             auto checkButton1 = new CheckButton(checkBoxLabelFrame, "Option 1")239                 .check()240                 .pack(5);241             auto checkButton2 = new CheckButton(checkBoxLabelFrame, "Option 2")242                 .pack(5);243             auto checkButton3 = new CheckButton(checkBoxLabelFrame, "Option 3")244                 .pack(5);245 246         auto radioLabelFrame = new LabelFrame(widgetPane, "Radio buttons")247             .pack(10, 0, GeometrySide.left, GeometryFill.both, AnchorPosition.center, true);248             auto radioButton1 = new RadioButton(radioLabelFrame, "Option 1")249                 .setSelectedValue("1")250                 .select()251                 .pack(5);252             auto radioButton2 = new RadioButton(radioLabelFrame, "Option 2")253                 .setSelectedValue("2")254                 .pack(5);255             auto radioButton3 = new RadioButton(radioLabelFrame, "Option 3")256                 .setSelectedValue("3")257                 .pack(5);258 259         return widgetPane;260     }261 262     /**263      * Create the paned pane for the note book.264      *265      * Returns:266      *     The paned pane.267      */268     private Frame createPanedPane()269     {270         auto panedPane = new Frame();271 272             auto panedWindow = new PanedWindow(panedPane);273 274                 auto rows = new TreeViewRow(["Computer"], true, ["computer"]);275                 rows.children ~= new TreeViewRow(["Documents"], true, ["folder"]);276                     rows.children[0].children ~= new TreeViewRow(["Important notes.txt"], true, ["file"]);277                     rows.children[0].children ~= new TreeViewRow(["The D Programming Language.pdf"], true, ["pdf"]);278                 rows.children ~= new TreeViewRow(["Pictures"], true, ["folder"]);279                     rows.children[1].children ~= new TreeViewRow(["Gary and Tessa.jpg"], true, ["image"]);280                 rows.children ~= new TreeViewRow(["Videos"], true, ["folder"]);281                     rows.children[2].children ~= new TreeViewRow(["Carlito‘s Way (1993).mpg"], true, ["video"]);282                     rows.children[2].children ~= new TreeViewRow(["Aliens (1986).mpg"], true, ["video"]);283 284                 auto tree1 = new TreeView(panedWindow)285                     .setHeading("Directory listing")286                     .setTag("computer", new EmbeddedPng!("computer.png"))287                     .setTag("folder", new EmbeddedPng!("folder.png"))288                     .setTag("file", new EmbeddedPng!("page.png"))289                     .setTag("pdf", new EmbeddedPng!("page_white_acrobat.png"))290                     .setTag("video", new EmbeddedPng!("film.png"))291                     .setTag("image", new EmbeddedPng!("images.png"))292                     .addRow(rows);293 294                 auto tree2 = new TreeView(panedWindow)295                     .setHeading("Film")296                     .setWidth(250)297                     .addColumn(new TreeViewColumn("Year").setWidth(20))298                     .addColumn(new TreeViewColumn("IMDB ranking").setWidth(50))299                     .addRow(new TreeViewRow(["The Shawshank Redemption", "1994", "1"]))300                     .addRow(new TreeViewRow(["The Godfather", "1972", "2"]))301                     .addRow(new TreeViewRow(["The Godfather: Part II", "1974", "3"]))302                     .addRow(new TreeViewRow(["The Dark Knight", "2008", "4"]))303                     .addRow(new TreeViewRow(["Pulp Fiction", "1994", "5"]))304                     .addRow(new TreeViewRow(["The Good, the Bad and the Ugly", "1966", "6"]))305                     .addRow(new TreeViewRow(["Schindler‘s List", "1993", "7"]))306                     .addRow(new TreeViewRow(["Angry Men", "1957", "8"]))307                     .addRow(new TreeViewRow(["The Lord of the Rings: The Return of the King", "2003", "9"]))308                     .addRow(new TreeViewRow(["Fight Club", "1999", "10"]));309 310         panedWindow311             .addPane(tree1).setPaneWeight(0, 1)312             .addPane(tree2).setPaneWeight(1, 1)313             .pack(10, 0, GeometrySide.top, GeometryFill.both, AnchorPosition.center, true);314 315         return panedPane;316     }317 318     /**319      * Create the canvas pane for the note book.320      *321      * Returns:322      *     The canvas pane.323      */324     private Frame createCanvasPane()325     {326         auto canvasPane = new Frame();327 328             auto container = new Frame(canvasPane)329                 .pack(10, 0, GeometrySide.top, GeometryFill.both, AnchorPosition.center, true);330 331             container.configureGeometryColumn(0, 1);332             container.configureGeometryRow(0, 1);333 334                 this._canvas = new Canvas(container, Color.bisque)335                     .setCursor(Cursor.hand1)336                     .setScrollRegion(-300, -250, 610, 500)337                     .addItem(new CanvasRectangle([10, 10, 200, 100]).addTag("tagged"))338                     .addItem(new CanvasArc([10, 110, 110, 210], CanvasArcStyle.pie, Color.paleGreen))339                     .addItem(new CanvasImage([210, 10], new EmbeddedPng!("thumbnail.png")))340                     .addItem(new CanvasImage([260, 10], new EmbeddedGif!("thumbnail.gif")))341                     .addItem(new CanvasLine([120, 110, 200, 110, 200, 160]).setArrowPosition(CanvasLineArrow.last))342                     .addItem(new CanvasOval([10, 170, 200, 245], Color.rosyBrown3))343                     .addItem(new CanvasPolygon([220, 80, 320, 80, 300, 120, 240, 120], Color.mediumPurple))344                     .addItem(new CanvasText([30, 192], "Tkd Canvas", Color.white).setFont("{Times New Roman} 22 bold"))345                     .addItem(new CanvasWidget([220, 140], new Button("Embedded\nWidget", new EmbeddedPng!("error.png"))).setWidth(100).setHeight(100))346                     .addTagConfig(new CanvasTagConfig("tagged").setFillColor(Color.salmon))347                     .setXView(0.25)348                     .setYView(0.24)349                     .bind("<ButtonPress-1>", &this.mark)350                     .bind("<B1-Motion>", &this.drag);351 352                 auto xscroll = new XScrollBar(container)353                     .attachWidget(this._canvas)354                     .grid(0, 1, 0, 0, 1, 1, "esw");355 356                 auto yscroll = new YScrollBar(container)357                     .attachWidget(this._canvas)358                     .grid(1, 0, 0, 0, 1, 1, "nes");359 360                 this._canvas361                     .attachXScrollBar(xscroll)362                     .attachYScrollBar(yscroll)363                     .grid(0, 0, 0, 0, 1, 1, "nesw");364 365         return canvasPane;366     }367 368     /**369      * Create the dialog pane for the note book.370      *371      * Returns:372      *     The dialog pane.373      */374     private Frame createDialogPane()375     {376         auto dialogPane = new Frame();377 378             auto modalLabelFrame = new LabelFrame(dialogPane, "Modal")379                 .configureGeometryColumn(1, 1)380                 .pack(10, 0, GeometrySide.top, GeometryFill.both, AnchorPosition.center, true);381 382                 auto colorButton = new Button(modalLabelFrame, new EmbeddedPng!("color_swatch.png"), "Color", ImagePosition.left)383                     .setCommand(&this.openColorDialog)384                     .grid(0, 0, 10);385 386                 this._colorEntry = new Entry(modalLabelFrame)387                     .grid(1, 0, 10, 0, 1, 1, "ew");388 389                 auto directoryButton = new Button(modalLabelFrame, new EmbeddedPng!("chart_organisation.png"), "Directory", ImagePosition.left)390                     .setCommand(&this.openDirectoryDialog)391                     .grid(0, 1, 10);392 393                 this._directoryEntry = new Entry(modalLabelFrame)394                     .setWidth(40)395                     .grid(1, 1, 10, 0, 1, 1, "ew");396 397                 auto fileOpenButton = new Button(modalLabelFrame, new EmbeddedPng!("folder_page.png"), "Open File", ImagePosition.left)398                     .setCommand(&this.openOpenFileDialog)399                     .grid(0, 2, 10);400 401                 this._openFileEntry = new Entry(modalLabelFrame)402                     .setWidth(40)403                     .grid(1, 2, 10, 0, 1, 1, "ew");404 405                 auto fileSaveButton = new Button(modalLabelFrame, new EmbeddedPng!("disk.png"), "Save File", ImagePosition.left)406                     .setCommand(&this.openSaveFileDialog)407                     .grid(0, 3, 10);408 409                 this._saveFileEntry = new Entry(modalLabelFrame)410                     .setWidth(40)411                     .grid(1, 3, 10, 0, 1, 1, "ew");412 413                 auto messageButton = new Button(modalLabelFrame, new EmbeddedPng!("comment.png"), "Message", ImagePosition.left)414                     .setCommand(&this.openMessageDialog)415                     .grid(0, 4, 10);416 417                 this._messageEntry = new Entry(modalLabelFrame)418                     .setWidth(40)419                     .grid(1, 4, 10, 0, 1, 1, "ew");420 421             auto nonModalLabelFrame = new LabelFrame(dialogPane, "Non Modal")422                 .configureGeometryColumn(1, 1)423                 .pack(10, 0, GeometrySide.top, GeometryFill.both, AnchorPosition.center, true);424 425                 auto fontButton = new Button(nonModalLabelFrame, new EmbeddedPng!("style.png"), "Font", ImagePosition.left)426                     .setCommand(&this.openFontDialog)427                     .grid(0, 0, 10);428 429                 this._fontEntry = new Entry(nonModalLabelFrame)430                     .setWidth(40)431                     .grid(1, 0, 10, 0, 1, 1, "ew");432 433         return dialogPane;434     }435 436     /**437      * Set up the key bindings for the application.438      */439     private void setUpKeyBindings()440     {441         this.mainWindow.bind("<F1>", &this.showAbout);442         this.mainWindow.bind("<Control-q>", &this.exitApplication);443     }444 445     /**446      * Initialise the user interface.447      */448     override protected void initInterface()449     {450         this.mainWindow.setTitle("Tkd Showcase");451         this.mainWindow.setMinSize(550, 560);452         this.mainWindow.setDefaultIcon([new EmbeddedPng!("tkicon.png")]);453 454         this.mainWindow.setProtocolCommand(WindowProtocol.deleteWindow, delegate(CommandArgs args){455             this.showAbout(args);456             this.exitApplication(args);457         });458 459         this.mainWindow.setIdleCommand(delegate(CommandArgs args){460             this._entry.setValue(Clock.currTime().toLocalTime().toSimpleString().findSplitBefore(".")[0]);461             this.mainWindow.setIdleCommand(args.callback, 1000);462         });463 464         this.createMenu();465 466         auto noteBook   = new NoteBook();467         auto widgetPane = this.createWidgetPane();468         auto panedPane  = this.createPanedPane();469         auto canvasPane = this.createCanvasPane();470         auto dialogPane = this.createDialogPane();471 472         noteBook473             .addTab("Widgets", widgetPane).setTabImage(0, new EmbeddedPng!("layout_content.png"), ImagePosition.left)474             .addTab("Panes", panedPane).setTabImage(1, new EmbeddedPng!("application_tile_horizontal.png"), ImagePosition.left)475             .addTab("Canvas", canvasPane).setTabImage(2, new EmbeddedPng!("shape_ungroup.png"), ImagePosition.left)476             .addTab("Dialogs", dialogPane).setTabImage(3, new EmbeddedPng!("application_double.png"), ImagePosition.left)477             .pack(10, 0, GeometrySide.top, GeometryFill.both, AnchorPosition.center, true);478 479         auto exitButton = new Button("Exit")480             .setCommand(&this.exitApplication)481             .pack(5);482 483         auto sizeGrip = new SizeGrip(this.mainWindow)484             .pack(0, 0, GeometrySide.bottom, GeometryFill.none, AnchorPosition.southEast);485 486         this.setUpKeyBindings();487     }488 489     /**490      * Exit the application.491      *492      * Params:493      *     args = The command arguments.494      */495     private void exitApplication(CommandArgs args)496     {497         this.exit();498     }499 500 }501 502 /**503  * Main entry point.504  *505  * Params:506  *     args = An array of command line arguments passed to this program.507  */508 void main(string[] args)509 {510     auto app = new Application();511     app.run();512 }