Rich UI Menu
A Rich UI menu widget defines a menu, which is displayed as a single,
top-level entry such as File. The menu has subordinate menu
items that each can provide additional options. To create a menu bar,
you can declare a box widget that contains a series of menus, as shown
in the following example:
menuBar Box{ font = "Arial", children = [
fileMenu,
otherMenu,
helpMenu ]};You are likely to place the menu bar in a larger box, which includes
the overall web page. Here is partial code from a later example:
handler MyHandler type RUIhandler{initialUI =[ui], onConstructionFunction = start}
ui Box{columns = 1, margin = 12, background = "#eeeeee",
children =[ menubar,
new Box{ borderStyle = "solid", borderColor = "orange", borderTopWidth = 25,
padding = 11, children =[changeTextBox]}
]};
The basic idea is that you specify an array of menu items for each
menu, and each menu item references (at most) two functions:
- The item-type function sets up relationships at run time and is invoked when the menu item is being readied for display
- The item-action function responds to the user who selects the menu item. However, in some cases when you declare a menu item, you do not reference the item-action function.
For example, here is the array of items for the file menu, followed
by the file menu declaration:
fileMenuItems menuItem[] =[
new MenuItem{item = "Clear", itemType = MenuBehaviors.simpleText, itemAction = menuAction},
new MenuItem{item = "Type", itemType = MenuBehaviors.simpleText, itemAction = menuAction}];
fileMenu Menu{menubehaviors ::= MenuBehaviors.BasicMenu, title = "File",
options = fileMenuItems, onMenuOpen = closeMenu};Supported properties and functions are described in Widget properties and functions.
Use of this widget requires the following statements:
import com.ibm.egl.rui.widgets.Menu;
import com.ibm.egl.rui.widgets.MenuBehaviors;
import com.ibm.egl.rui.widgets.MenuItem;Please note that you must declare a set of menu items before declaring the menu in which the items are displayed. We explain menu development with this ordering in mind.
MenuItem
The fields for type MenuItem (a
Record part) reference the item-type and item-action functions. We
describe the MenuItem fields before describing the function
characteristics. Here are the fields:
- id
- An optional value to associate the menu item with a CSS entry.
- item
- A value passed to the item-type function. Rich UI provides a few
functions and you can code your own; but assuming you use the existing
choices, the value of the item property is one of the following
values:
- A string to display as a submenu item. Only in this case do you specify an item-action function in the menu-item declaration.
- A widget to display as a submenu item.
- An array that is composed of (a) a submenu title and (b) an array
that references a set of subordinate submenu items. The following
fragment shows this alternative and is from a later example:
new MenuItem{item =["Special", [myTimeItem, myReadOnlyItem]], itemType= MenuBehaviors.subMenu }];
- itemType
- A reference to the item-type function. Rich UI provides three functions that allow for the options described in relation to the item property:
- The function simpleText is appropriate if item is a string to display
- The function widgetItem is appropriate if item is widget
- The function subMenu is appropriate if item is an array of string and subordinate submenu items
All those functions are available in the Rich UI library MenuBehaviors.
- itemAction
- A reference to the item-action function. Specify this value only if the value of the field item is a string.
The item-type function has the characteristics
defined in the following Delegate part:
Delegate
MenuItemType(newItem any in, itemAction MenuItemSelection, parentMenu Menu in)
returns (any)
end
- newItem
- The item you specify when declaring the menu item.
- itemAction
- A reference to the item-action function, as is always required
in the item-type function.
In general, a Delegate part named MenuItemSelection describes the item-action function, as noted later.
- parentMenu
- The menu that contains the menu item.
Here is the Delegate part named MenuItemSelection,
which describes the item-action function:
Delegate MenuItemSelection(parentMenu Menu, item any in) end- parentMenu
- The menu that contains the menu item.
- item
- The menu item.
The item-action function (in outline) might
be as follows:
function menuAction(parentMenu Menu, item any in)
if(parentMenu == fileMenu)
case(item as string)
when("Clear")
;
otherwise
;
end
else
if(parentMenu == helpMenu)
;
else
;
end
end
endMenu
The fields for type Menu are as follows:
- menuBehaviors
- A reference to a function that is invoked during creation or re-display
of the menu, so that styles and functionality are applied to the menu.
The reference is added to the menuBehaviors array by use of
the append syntax (
::=). You can have repeated entries (the syntax is as shown in the example), and when a user selects a menu, the referenced functions run in array-element order. In our example, the menuBehaviors property references the function basicMenu, which is available in the Rich UI library MenuBehaviors. You can use the function basicMenu directly or can use it as a basis for your own function.A Delegate part named MenuBehavior describes the characteristics of the function being referenced. We describe the Delegate part later.
In the menu declaration, list the behaviors property before the other properties.
- title
- The string to display.
- options
- An array of menu items.
- onMenuOpen
- A reference to a function that runs when the user selects the
menu. The function has no return value and has a single parameter
of type Menu and qualifier IN. Here is an example, which ensures that
the user's selection of one menu shuts any other open menu:
function closeMenu(keepOpen Menu IN) if(keepOpen != fileMenu) fileMenu.hideOptions(false); end if(keepOpen != otherMenu) otherMenu.hideOptions(false); end if(keepOpen != helpMenu) helpMenu.hideOptions(false); end end
Here is the Delegate part named MenuBehavior,
which describes each function invoked in response to a menu selection
at run time:
Delegate
MenuBehavior(menu Menu in, titleBar TextLabel, optionsBox Box, options MenuItem[])
end- menu
- The menu.
- titleBar
- A text label that contains the menu title you assigned.
- optionsBox
- A box that contains a child for every item in the menu. The function basicMenu assigns
rules for highlighting those children in response to mouse movements
at run time:
for (index int from 1 to optionsbox.children.getSize() by 1) widget Widget = optionsBox.children[index]; widget.onMouseOver ::= highlight; widget.onMouseOut ::= removemenuhighlight; end - options
- An array of the menu items.
The function layouts() resets
widget behaviors, as described in the following rules:
- When declaring a menu, ensure that you list the menuBehaviors property first.
- If, when writing statements in functions, you change the value of the menuBehaviors property, invoke the menu-specific function layouts() to reset the widget.
Example
You can bring the following example into your workspace to see the relationships described earlier.
package myPkg;
import com.ibm.egl.rui.widgets.Box;
import com.ibm.egl.rui.widgets.CheckBox;
import com.ibm.egl.rui.widgets.HTML;
import com.ibm.egl.rui.widgets.Menu;
import com.ibm.egl.rui.widgets.MenuBehaviors;
import com.ibm.egl.rui.widgets.MenuItem;
import com.ibm.egl.rui.widgets.TextField;
import egl.ui.rui.Event;
handler MyHandler type RUIhandler{initialUI =[ui], onConstructionFunction = start}
{}
ui Box{columns = 1, margin = 12, background = "#eeeeee",
children = [
menubar,
new Box{
borderWidth = 2, borderStyle = "solid", borderColor = "orange",
borderTopWidth = 50, padding = 11,
children =[changeTextBox]}]};
menuBar Box{font = "Arial", children =[fileMenu, otherMenu, helpMenu]};
changeTextBox TextField{text="here"};
readonlyCheck CheckBox{Text = "Read Only", onChange::= setReadOnly};
myTimeItem menuItem{
item = "Time?",
itemType = MenuBehaviors.simpleText,
itemAction = tellTime };
myReadOnlyItem MenuItem {
item = readOnlyCheck,
itemType = MenuBehaviors.widgetItem };
fileMenuItems menuItem[] =[
new MenuItem{item = "Clear",
itemType = MenuBehaviors.simpleText, itemAction = menuAction},
new MenuItem{item = "Type",
itemType = MenuBehaviors.simpleText,
itemAction = menuAction} ];
otherMenuItems menuItem[] =[
new MenuItem{item =["Special", [myTimeItem, myReadOnlyItem]],
itemType= MenuBehaviors.subMenu }];
helpItems menuItem[] =[new MenuItem{item = "About",
itemType = MenuBehaviors.simpleText,
itemAction = showHelp} ];
fileMenu Menu{menubehaviors ::= MenuBehaviors.BasicMenu, title = "File",
options = fileMenuItems, onMenuOpen = closeMenu};
helpMenu Menu{menubehaviors ::= MenuBehaviors.BasicMenu, title = "Help",
options = helpItems, onMenuOpen = closeMenu};
otherMenu Menu{menubehaviors ::= MenuBehaviors.BasicMenu, title = "Other",
options = otherMenuItems, onMenuOpen = closeMenu};
helpArea HTML{onClick ::= hideHelp, position = "absolute", x = 70, y = 60,
backgroundColor = "lightyellow", width = 400, padding = 11,
borderWidth = 3, borderStyle = "solid", height = 50,
text = "Helpful detail is here. <p>Click this box to continue working.</p>"};
function start()
end
function tellTime(parentMenu Menu, item any in)
changeTextBox.text = dateTimeLib.currentTime();
end
function menuAction(parentMenu Menu, item any in)
if(parentMenu == fileMenu)
case(item as string)
when("Clear")
changeTextBox.text = "";
otherwise
changeTextBox.select();
end
else
if(parentMenu == helpMenu)
;
else
; // parentMenu == widgetMenu
end
end
end
function setReadOnly(e Event in)
changeTextBox.readOnly = !(changeTextBox.readOnly);
end
function closeMenu(keepOpen Menu in)
if(keepOpen != fileMenu)
fileMenu.hideOptions(false);
end
if(keepOpen != otherMenu)
otherMenu.hideOptions(false);
end
if(keepOpen != helpMenu)
helpMenu.hideOptions(false);
end
end
function showHelp(parentMenu Menu, item any in)
document.body.appendChild(helparea);
end
function hideHelp(e Event in)
document.body.removeChild(helparea);
end
end