Adds a menu and toolbar from annotated functions. It uses the top-level annotations from this module, so it is better to put the commands in a separate struct instad of in your window subclass, to avoid potential conflicts with method names (if you do hit one though, you can use @(.icon(...)) instead of plain @icon(...) to disambiguate, though).
The only required annotation on a function is @menu("Label") to make it appear, but there are several optional ones I'd recommend considering, including @toolbar("group name"), @icon(), @accelerator("keyboard shortcut string"), and @hotkey('char').
You can also use @separator to put a separating line in the menu before the function.
Functions may have zero or one argument. If they have an argument, an automatic dialog box (see: dialog) will be created to request the data from the user before calling your function. Some types have special treatment, like FileName, will invoke the file dialog, assuming open or save based on the name of your function.
Let's look at a complete example:
1 importarsd.minigui;
2 3 voidmain() {
4 autowindow = newMainWindow();
5 6 // we can add widgets before or after setting the menu, either way is fine.7 // i'll do it before here so the local variables are available to the commands.8 9 autotextEdit = newTextEdit(window);
10 11 // Remember, in D, you can define structs inside of functions12 // and those structs can access the function's local variables.13 //14 // Of course, you might also want to do this separately, and if you15 // do, make sure you keep a reference to the window as a struct data16 // member so you can refer to it in cases like this Exit function.17 structCommands {
18 // the & in the string indicates that the next letter is the hotkey19 // to access it from the keyboard (so here, alt+f will open the20 // file menu)21 @menu("&File") {
22 @accelerator("Ctrl+N")
23 @hotkey('n')
24 @icon(GenericIcons.New) // add an icon to the action25 @toolbar("File") // adds it to a toolbar.26 // The toolbar name is never visible to the user, but is used to group icons.27 voidNew() {
28 previousFileReferenced = null;
29 textEdit.content = "";
30 }
31 32 @icon(GenericIcons.Open)
33 @toolbar("File")
34 @hotkey('s')
35 @accelerator("Ctrl+O")
36 voidOpen(FileName!() filename) {
37 importstd.file;
38 textEdit.content = std.file.readText(filename);
39 }
40 41 @icon(GenericIcons.Save)
42 @toolbar("File")
43 @accelerator("Ctrl+S")
44 @hotkey('s')
45 voidSave() {
46 // these are still functions, so of course you can47 // still call them yourself too48 Save_As(previousFileReferenced);
49 }
50 51 // underscores translate to spaces in the visible name52 @hotkey('a')
53 voidSave_As(FileName!() filename) {
54 importstd.file;
55 std.file.write(previousFileReferenced, textEdit.content);
56 }
57 58 // you can put the annotations before or after the function name+args and it works the same way59 @separator60 voidExit() @accelerator("Alt+F4") @hotkey('x') {
61 window.close();
62 }
63 }
64 65 @menu("&Edit") {
66 // not putting accelerators here because the text edit widget67 // does it locally, so no need to duplicate it globally.68 69 @icon(GenericIcons.Undo)
70 voidUndo() @toolbar("Undo") {
71 textEdit.undo();
72 }
73 74 @separator75 76 @icon(GenericIcons.Cut)
77 voidCut() @toolbar("Edit") {
78 textEdit.cut();
79 }
80 @icon(GenericIcons.Copy)
81 voidCopy() @toolbar("Edit") {
82 textEdit.copy();
83 }
84 @icon(GenericIcons.Paste)
85 voidPaste() @toolbar("Edit") {
86 textEdit.paste();
87 }
88 89 @separator90 voidSelect_All() {
91 textEdit.selectAll();
92 }
93 }
94 95 @menu("Help") {
96 voidAbout() @accelerator("F1") {
97 window.messageBox("A minigui sample program.");
98 }
99 100 // @label changes the name in the menu from what is in the code101 @label("In Menu Name")
102 voidotherNameInCode() {}
103 }
104 }
105 106 // declare the object that holds the commands, and set107 // and members you want from it108 Commandscommands;
109 110 // and now tell minigui to do its magic and create the ui for it!111 window.setMenuAndToolbarFromAnnotatedCode(commands);
112 113 // then, loop the window normally;114 window.loop();
115 116 // important to note that the `commands` variable must live through the window's whole life cycle,117 // or you can have crashes. If you declare the variable and loop in different functions, make sure118 // you do `new Commands` so the garbage collector can take over management of it for you.119 }
Note that you can call this function multiple times and it will add the items in order to the given items.
Adds a menu and toolbar from annotated functions. It uses the top-level annotations from this module, so it is better to put the commands in a separate struct instad of in your window subclass, to avoid potential conflicts with method names (if you do hit one though, you can use @(.icon(...)) instead of plain @icon(...) to disambiguate, though).
The only required annotation on a function is @menu("Label") to make it appear, but there are several optional ones I'd recommend considering, including @toolbar("group name"), @icon(), @accelerator("keyboard shortcut string"), and @hotkey('char').
You can also use @separator to put a separating line in the menu before the function.
Functions may have zero or one argument. If they have an argument, an automatic dialog box (see: dialog) will be created to request the data from the user before calling your function. Some types have special treatment, like FileName, will invoke the file dialog, assuming open or save based on the name of your function.
Let's look at a complete example:
Note that you can call this function multiple times and it will add the items in order to the given items.