Menu Bars, Menus, and Menu Items
Any reasonably modern user-interface offers various methods of accomplishing the same goals, such as keyboard commands, tool bar and form buttons, and menus. Some user-interface design guides go so far as to say that any functionality that is reachable via a tool bar button or a form button, should always provide a menu item to accomplish the same thing. Part of the reason for this is that many users may not be inclined to use a mouse, or under certain circumstances the user may not have a mouse available. Also, providing menus and menu items allows the user to look around in a (hopefully) well-sorted and logically devised set of various groups of functionality. It is an easy way to get to know a product if the menus provide a clear overview of what can be done with the program.
The wxWidgets-based menu support that is part of SIMPOL offers the usual menu capabilities: menus, sub-menus, and menu items that can also be either checkable or one of a group of options. An example menu program is show below:
function main() wxwindow w wxmenubar mb wxmenu filemenu, printmenu integer iErrnum string sResult iErrnum = 0 w =@ wxwindow.new(0, 0, 640, 480, captiontext="Main test \ window", error=iErrnum) if w =@= .nul sResult = "Error number: " + .tostr(iErrnum, 10) + \ " opening main window{d}{a}" else w.onvisibilitychange.function =@ quit mb =@ wxmenubar.new() filemenu =@ wxmenu.new() mb.insert(filemenu, "&File", name="filemenu") filemenu.insert("", "&New", enabled=.false, name="new") filemenu.insert("separator") printmenu =@ wxmenu.new() printmenu.insert("radio", "&Laser Printer", checked=.true, \ name="laserprinter") printmenu.insert("radio", "&Inkjet Printer", \ name="inkjetprinter") printmenu.insert("radio", "La&bel Printer", \ name="labelprinter") filemenu.insert("submenu", "&Printer", submenu=printmenu, \ name="printmenu") filemenu.insert("checkable", "Print Second &Copy", \ checked=.true, name="secondcopy") filemenu.insert("separator") filemenu.insert("", "E&xit{9}Ctrl+Q", name="exit") filemenu!exit.onselect.function =@ quit mb.setwindow(w) wxprocess(.inf) end if end function sResult function quit(type(*) me) wxbreak() end function
The program above demonstrates most of the capabilities of the menu support in SIMPOL. A
menubar (like all other SIMPOL GUI objects) exists indepently of its representation in a
window. A menubar can be assigned to a window and then be replaced by another. Looking at
the preceding program, we first create a menu bar and then an empty menu that we insert into
the menu bar. It is not necessary to do it this way, we could just as easily have filled the
menu first and then inserted it into the menu bar. Next we insert a menu item that is
set to disabled from the start. Following this, a separator is inserted and then a printer
menu is created that contains three radio items, only one of which can be selected and we
pre-select the first one. The printer menu is then inserted into the file menu as a sub menu.
This is then followed by a checkable item, entitled "Print Second Copy". Next we add another
separator and the item to exit the program. This item is also given a keyboard accelerator
(by adding a tab character and the desired accelerator combination). In closing the
quit()
function is assigned to the onselect event of the exit item.
Finally the menu bar is set into the window and the program then waits for events. A picture
of the menu can be seen below:
The trickiest part of working with menus may be learning how to correctly address the various
parts. The containership model of the menus is as follows: wxmenubar contains
objects of type wxmenubarentry. That contains objects of type wxmenu.
The wxmenu objects contain objects of type wxmenuitem, which can
themselves contain objects of type wxmenu. So, assuming that there is a variable
called mb
and the menu bar from the program above, to access the
labelprinter
item, the following code would be used:
mb!filemenu.menu!printmenu.submenu!labelprinter
The member operator (!) is used to access the wxmenubarentry that contains a
reference to the filemenu
menu object. The member operator is again used
to access the wxmenuitem represented by the printmenu
object,
and then accesses the labelprinter
item of the sub menu by using the
member operator on the submenu property of the printmenu
menu item.
Creating menus by hand can be quite boring, but until there is a menu editor available, the
menu editor provided by the older Superbase product (including the downloadable demo) can be
used, together with the conversion utility provided for converting Superbase menu programs
to SIMPOL source code. The menu conversion utility is in the
utilities
directory and the program is called:
ngmengen.sbp
.