6.2 Basic Menu Facilities

The Menu pattern defined in Lidskjalv describes the facilities of any type of menu in Lidskjalv. Menu is a subpattern of interfaceObject. The menu handling is fully supported by Lidskjalv in the sense that the application programmer specifies the title and format of the menu (including layout of individual menu items, submenus, etc.) and specifies the actions, associated with the individual menu items. The menu is inserted in the menubar and Lidskjalv handles all events associated with menus (e.g. when some menu item is selected, the proper actions are executed).

Menus may be enabled or disabled. A disabled menu is visible in the menu bar but its title is dimmed and it is impossible to pull the menu down from the menu bar.

If theMenu be an instance of Menu, initialization of theMenu may be done by further binding the open virtual procedure pattern attribute of Menu. In this further binding, the individual items in the menu are defined. The individual items are instances of the menuItem pattern (described below).

The menu may be used as a pull-down menu by inserting it in the menubar, e.g. by THIS(Menu)[]->MenuBar.append, or theMenu[]->MenuBar.append. The menu may also be used as a pop-up menu by invoking (i,p,wi[])-> THIS(menu).popUp or (i, p, wi[])->theMenu.popUp. This will show the menu at position p with the menu element number i selected. wi is a reference to the window item in which the menu should pop-up. Finally, the menu may be used as a hierarchical menu. The menu can be inserted as a submenu of an item of another menu by THIS(Menu)[]->anotherMenuItem.subMenu or theMenu[]-> anotherMenuItem.subMenu. The menu will then be a submenu of anotherMenuItem.

6.2.1 Menu Item Facilities

Each individual item in a menu is described by the menuItem pattern, defined locally to the Menu pattern in Guienv. Most facilities of menuItem deals with describing the format of the menu item. Name makes it possible to specify the name of the item. Key makes it possible to control the keyboard equivalent, and finally, SubMenu makes it possible to control the submenu of this item. Checked is used to control whether or not this menu item should be checked (a toggle menu item). The position of the item in the menu is examined by position.

Items in menus may be enabled (e.g. it is possible to select this menu item) or disable (e.g. the menu item cannot be selected and the menu item is dimmed in the menu). Enabling and disabling of menu items are controlled by the virtual procedure pattern onStatus. The application programmer must further bind onStatus in menu items in order to specify dynamic changes in the selectability of menu items.

When a menu item is selected, some actions must be executed. This is specified using the virtual event pattern onSelect. The application programmer must further bind onSelect in order to specify the actions to be executed as the result of this menu item being selected.

Menu items are initialized in two steps. The title of the menu item is first specified by giving a text string as the name operation of MenuItem. This is usually done in the open virtual in the menu item. Then the menu item is appended to the menu.

The menu items are numbered from the top of the menu, starting with 1, and menu separators are numbered too. Menu separators are specified by using the separator pattern, e.g.

&separator[]->sep[]; sep.open; sep[]->animalMenu.append

Let us look at a small example:

Program 5: menus.bet

ORIGIN '~beta/guienv/guienv'
--- program: descriptor ---
guienv
(# menuWindow: @window
     (# menubarType::
          (# animalMenu: @menu
               (# iCat: @menuItem
                    (# eventhandler::
                         (# onSelect:: (# do 'Cat chosen'->putline  #) #);
                       open:: (# do 'Cat'->name #)
                    #);
                  iBear: @menuItem
                    (# eventhandler::
                         (# onSelect:: (# do 'Bear chosen'->putline #)#);
                       open:: (# do 'Bear'->name #)
                    #);
                  iEagle: @menuItem 
                    (# eventhandler::
                         (# onSelect:: (# do 'Eagle chosen'->putline #);
                            onStatus:: (# do false->value #) 
                         #);
                       open:: (# do 'Eagle'->name #)
                    #);
                  open:: 
                    (# sep: ^menuItem
                    do 'Animals'->name;
                       iCat.open; iBear.open; iEagle.open;
                       iCat[]->animalMenu.append;
                       iBear[]->animalMenu.append;
                       &separator[]->sep[]; sep.open; sep[]->animalMenu.append;
                       iEagle[]->animalMenu.append
                    #)
               #);
             open:: (# do animalMenu.open; animalMenu[]->append #)
          #);
        eventhandler::
          (# onAboutToClose:: (# do terminate #) #);
        open:: (# do 'menus'->title #)
     #)
do menuWindow.open
#)

animalMenu is a menu with three items and one separator. The title of animalMenu is Animals and the three menu items have the titles Cat, Bear, and Eagle:

Program 6: screendumps (Windows NT)

[6kb 131x126 GIF]   [4kb 114x126 GIF]

When either Cat or Bear is selected, the title of the item will be printed. The Eagle item is disabled (shown dimmed) and cannot be selected.

6.2.2 Static and Dynamic Menu Items

Menu items are either constantly associated with the same actions during the entire execution of the program as described above (i.e. static menu items), or they may be associated with different actions during the execution of the program (i.e. dynamic menu items). For that reason, Lidskjalv contains two different menu item patterns: menuItem and dynamicMenuItem. MenuItem (described above) describes the static menu items and dynamicMenuItem (a subpattern of menuItem) describes the dynamic menu items. Since static menu items were the subject of the previous section, we will here concentrate on the additional properties of dynamicMenuItems.

DynamicMenuItem is a subpattern of menuItem, and the dynamics of dynamic menu items is controlled by attaching and detaching so-called menuActions to the menu item during the execution of the program. MenuAction is a pattern defined in the menu pattern and defines two attributes: noStatus and onSelect with the same purpose as the onStatus and onSelect attributes of a static menu item. That is, by specializing the onSelect attribute, the actions of the menuAction are specified, and the noStatus attribute controls whether the menuAction is enabled or not.

DynamicMenuItem defines only two new attributes: attach and detach. Attach takes a menuAction as enter parameter and attaches it to the menu item. The result hereof is that then the noStatus attribute of the menu item is invoked, the onStatus attribute of the attached action is invoked instead, and invocation of the onSelect attribute of the menu item will result in invocation of the onSelect attribute of the attached action. The attached action is in this way becoming the behavior of the dynamic menu item. By changing the action associated with a dynamic menu item during the execution of the program, different behaviors may be associated with one particular dynamic menu item. If the dynamic menu item executes a detach, the action is detached and the menu item becomes disabled.

E.g.:

Program 7: rulerMenu.bet

ORIGIN '~beta/guienv/guienv'
--- program: descriptor ---
guienv
(# rulerWindow: @window
     (# menubarType::
          (# rulerMenu: @menu
               (# iHideRuler: @dynamicMenuItem
                    (# open:: (# do 'Hide ruler'->name #) #);
                  iShowRuler: @dynamicMenuItem
                    (# open:: (# do 'Show ruler'->name #) #);
                  hideRuler: @menuAction 
                    (# onSelect:: 
                         (# 
                         do 'Hiding...'->puttext;
                            iHideRuler.detach;
                            showRuler[]->iShowRuler.attach
                         #)
                    #);
                  showRuler: @menuAction 
                    (# onSelect:: 
                         (# do 'Showing...'->puttext;
                            iShowRuler.detach;
                            hideRuler[]->iHideRuler.attach
                         #)
                   #);
                  open:: 
                    (# 
                    do 'Rulers'->name;
                       iHideRuler.open; iHideRuler[]->rulerMenu.append;
                       hideRuler[]->iHideRuler.attach;
                       iShowRuler.open; iShowRuler[]->rulerMenu.append;
                    #)
               #);
             open:: (# do rulerMenu.open; rulerMenu[]->append #)
          #);
        eventhandler::
          (# onAboutToClose:: (# do terminate #) #);
        open:: (# do 'rulerMenu'->title #)
     #)
do rulerWindow.open
#)

Program 8: screendumps
(Windows 95)

[5kb 134x159 GIF]   [7kb 138x159 GIF]


Lidskjalv: User Interface Framework - Tutorial
© 1995-2004 Mjølner Informatics
[Modified: Friday October 27th 2000 at 14:56]