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:
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
end

Menu

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

Feedback