Class lw.Menu

Object
|
+--lw.Menu

class
lw.Menu

The lw.Menu object provides GUI menus ("popup menu", "pull down menu").
There are several steps in the life-time of a menu:

Step 1 is the definition of the menu:
With lw.Menu, the menu is defined as a JavaScript object.
In many cases, menus are defined only once ("statically"),
and will then be used (displayed) many times without modification.
But dynamic creation of the menu structure is not uncommon,
up to letting the user define a "private" menu and keep it as a preference.
There are special provisions that support this smoothly.

Here, a variable holding the main menu is defined.
The main menu contains only links to other menus, and separator lines.
It might be used as a context menu ("on mouse right click").
Next the "font" menu is defined. It contains Action elements and Toggle elements only,
but it might contain Link elements to further submenus as well.

The following functions are used for defining a menu:

makeMenu() assembles and returns the JS menu object.
The arguments to this function are the return values of the other makeXXX functions
and define the menu elements.

makeLink() defines a link element in a menu.
On mouseover, it appends the specified submenu aside the calling menu.
The calling menu will be kept, and the submenu will be closed on mouseout.

makeAction() defines an action element in a menu.
The specified action routine is evaluated when the user clicks the menu line,
and the whole menu (tree) is removed.

makeToggle() defines a toggle element in a menu.
The toggle element is a special form of the general action element,
having one of the two states "on" or "off".
It displays a checkbox symbol, whose checked state is updated dynamically
before each display by evaluating the bean or init routine.
On mouse click, the state is inverted,
the specified bean or action routine is evaluated,
and then the whole menu (tree) is removed.

makeRadio() defines a list of radio elements in a menu.
The radio elements are a generalized form of the toggle element,
having an integer selecting the checked state of one of the elements.
Each radio element displays a radio symbol, whose checked state is updated dynamically
before each display by evaluating the bean or init routine.
On mouse click, the state is inverted,
the specified bean or action routine is evaluated,
and then the whole menu (tree) is removed.

Here, the same menu ("file") will be used either as a submenu to "main",
or as a stand alone menu (when clicking the anchor node).

Step 3 happens automatically while preparing the menu for display:
The show() method updates the state of all Toggle elements
by evaluating the return values of the specified bean getter function (or the init expression).

Step 4 depends on the user's interaction:

A mouseover on a Link element shows the specified menu as a submenu.
While preparing the submenu, more init call-backs for Toggle elements
contained in the submenu may happen.

A mouseout on a submenu removes the submenu.
Parent menus, however, are kept while their child menus are still active.

A mouse click on an Action element or a Toggle element results in a
callback to the specified action or bean setter routine.
After return, the whole menu tree will be closed.

Just as with inline coded HTML event routines,
the callback functions (or expressions)
must be specified as a Strings containing a JavaScript expression.
At run-time, they will be avaluated in the global window context
and have access to the current calling context:

the current Menu: lw.Menu.action.menu,

the index to retrieve the current element from the menu object: lw.Menu.action.ix,

and the originating DOM node: lw.Menu.action.node(lw.Menu.action.node === null indicates a call in the init phase).

Please note that the lw.Menu API definition is based largely on Strings.

Using Strings containing names of variables that hold an object,
instead of using the objects themself may look surprising:
"Why specify the name of a variable instead of it's contents?"
"And why specifiy a JavaScript expressions as source code
instead of just supplying the expression, or the function call, or the function?".

Among others, this form of the API was chosen
to facilitate dynamic modification and serialization of the whole menu structure, if required.
You can, for example, let the user define or modify it's own menu structure
Before terminating the program,
you can serialize the menu(s) to a String, e.g. by calling lw.Persist or lw.JSON,
and save it in a Cookie or on a server.
On the next program start, you can access and deserialize it, and use it immediatelly.
So it is easy to include the menu in the "users preferences" supported by your program.

CLASSNAME

evalAction

Stub: Eval the specified action/bean (JavaScript source).
In "exec mode", this is identical to lw.Menu.eval;
in "design mode", may be redirected to showing the JS string.

hideMac

<static> Object hideMac

if true: does not record actions in lwh.mac (if any).
(must suppress recording while in GUIs)

HOVER

<static> <final> {CSS_Color} HOVER

The CSS :hover background-color.
Set for the menu anchor,
TO DO: and for all DIV and LI elements in the menu.
TO DO: Should read from CSS rule "#lwMenuLine a:hover".
Tried to set className instead, but not so easy...

makeMenu

<static> Object_Menu makeMenu(<Object_MenuElement> elements)

Returns a new Menu structure containing the specified elements.
This function has a variable number of arguments,
where all arguments are the return values of
one of the lw.Menu.make functions.
There are three ways to show a Menu defined in this way on the screen:

Call lw.Menu.show(menu, null, event) in a mouse onclick routine
(such as MS IE oncontextmenu).
This will show the Menu under the current mouse position.

Add a onclick="lw.Menu.show(menu, this)" event handler
(or any other event handler)
to a HTML node (such as your main menu bar, or your tool bar).
This will show the Menu beneath the originating anchor node.

Add a Menu.makeLink() element to any of your menus.
This will show the (sub-) Menu on the side over the originating menu anchor node.

Notes:

If you make a (sub) Menu object
that is to be linked to from a (higher level) menu,
then the JavaScript variable holding the sub menu
must be accessible in the global window context
while the menu is used (displayed).

For ease of use,
all menu objects should be accessible globally all the time.

Modifications (including deletion and new creation)
of any Menu object and any Menu element is legal,
while it is currently not in use (not displayed).

If requried, serialization of all menu objects is supported,
e.g. using the lw.JSON or the lw.Persist functions.

makeRadio

Returns a list of new radio elements for use in a Menu.
The radio elements are a generalized form of the toggle element:

There is an integer "checked selector" associated with the list of radio elements

The selector is managed by an integer "bean" getter/setter function:
if called without arguments, the bean function returns the currently selected radio element;
else it sets the current state according to the supplied integer argument.
Example: You define a function debugLevel() that returns the current debug level,
wheras debugLevel(val) sets the current debug level to the specified integer value.

Generalized beans are supported as well:
The bean function may have additional "leading" arguments;
only the last argument determines the state.

Special case: Instead of one bean getter/setter function,
you may specify separate action and init routines (or expressions)
that set respectively return the current state.

The number of radio elements is determined
by the number of entries in the text Array.

Each radio element has a unique integer value, starting with 0.

Before displaying the radio elements,
the bean getter (or the init function) is evaluated;
it's integer return value selects the checked state of one radio element.

The radio elements will be displayed with the specified text,
and show the current checked state ("on", "off").

On mouse click, the bean setter (or the action) will be evaluated
in the global window context.

Just as with inline coded HTML event routines,
these functions (or expressions)
must be specified as a Strings containing a JavaScript expression.
If required, these functions have access to the current calling context:

the current Menu: lw.Menu.action.menu,

the index to retrieve the current element from the menu object: lw.Menu.action.ix,

and the originating DOM node: lw.Menu.action.node(lw.Menu.action.node === null indicates a call in the init phase).

Parameters:

text - required: the Array of display texts for the radio elements

action - required: the bean function (or the action function) to be evaluated on mouse click.

init - optional: the init function to be evaluated before displaying the elements; if missing, or null: the bean or action function will be called instead.

disabled - optional: if true, the element is not available for user input.

makeSelect

Returns a select element with options list for use in a Menu.
Works similar to the radio element.
Note: The first string (index 0) is used as descriptive text for the select element.

Parameters:

text - required: the Array of display texts for the radio elements. The first string (index 0) is used as descriptive text for the select element; the remaining strings will be used as option texts for the select elements. This allows for a "static" initialization of the options. If the second element (index 1) is of type function, however, this function will be called at init time with the descriptive string (index 0) as parameter. The function, now, must build and return an array of Strings dynamically, that is used instead of the static option text strings.

action - required: the bean function (or the action function) to be evaluated on mouse click.

init - optional: the init function to be evaluated before displaying the elements; if missing or null: the bean or action function will be called instead.

disabled - optional: if true, the element is not available for user input.

makeToggle

Returns a new toggle element for use in a Menu.
The toggle element is a special form of the general action element:

There is a boolean state "on" or "off" associated with the toggle

The state is managed by a boolean "bean" getter/setter function:
if called without arguments, the bean function returns the current state;
else it sets the current state according to the supplied boolean argument.
Example: You define a function blink() that returns the current blink state,
wheras blink(true) or blink(false) sets the current blink state.

Generalized beans are supported as well:
The bean function may have additional "leading" arguments;
only the last argument determines the state.
Example: You define a function display('aNodeID')
that returns the current style.display state of the specified DOM node (here: aNodeID),
wheras display('aNodeID', true) or display('aNodeID', false) sets it.

Special case: Instead of one bean getter/setter function,
you may specify separate action and init routines (or expressions)
that set respectively return the current state.

Before displaying the toggle element,
the bean getter (or the init function) is evaluated;
it's return value true/false determines the displayed state of the toggle.

The toggle element will be displayed with the specified text,
and shows the current state of the toggle ("on", "off").

On mouse click, the bean setter (or the action) will be evaluated
in the global window context.

Just as with inline coded HTML event routines,
these functions (or expressions)
must be specified as a Strings containing a JavaScript expression.
If required, these functions have access to the current calling context:

the current Menu: lw.Menu.action.menu,

the index to retrieve the current element from the menu object: lw.Menu.action.ix,

and the originating DOM node: lw.Menu.action.node(lw.Menu.action.node === null indicates a call in the init phase).

Parameters:

text - required: the display text.

action - required: the action function to be evaluated on mouse click.

init - optional: the init function to be evaluated before displaying the element; if missing, or null: the bean or action function will be called instead.

disabled - optional: if true, the element is not available for user input.