Understanding menus
Toolkit menus are composed of primary and submenu columns, which are either maintained as windows in a window library file (if you define them with a script file) or are generated at runtime (if you define them with the MB_ subroutines).
The menu column name, entry names, column and entry text, and shortcut associations (key sequences that automatically select particular menu entries) are stored with the menu column. If you define them in a script, this information won’t be hard-coded into your program, so it can be modified easily at any time.
The menu processing utilities in Toolkit enable you to load, remove, and delete columns; enable and disable menu entries and sets of entries (menu lists); and process a menu directly.
This topic includes the following sections:
- General appearance of menus
- Making a menu selection
- Processing menus
- Runtime generation of menu columns
- Customizing the way environments place and remove columns
General appearance of menus
Primary menus and submenus appear either as standard drop-down menus or pop-up menus. Pop-up menus can appear at any location on the screen (see %M_POPUP for information). Standard drop-down menus drop down from the menu bar.
For standard drop-down menus, a single menu bar is present on the screen when a menu is not being processed. This menu bar contains the headings for each column in the menu. When the menu is processed, the menu bar is highlighted, and the user can drop down a column and select an entry from the column.
Selections in a column are aligned on the left side, aligned on the right side, or centered within the column. And drop-down primary menu columns are either left-justified, right-justified, or centered beneath the header for that column
If an entry in a menu column is associated with a submenu column, a right arrow (g) is displayed as the column’s shortcut. (You can modify the character used to indicate a submenu. It is shortcut function 99 on your key map.) The user can select that entry and drop down a submenu column. Any entry in a primary menu or submenu can have a submenu column associated with it. Descending into submenu columns gives the screen a “cascading” menu appearance.
Menu columns and entries
A menu column can be global (available for deletion from any display level) or local (only the display level that created the column can delete it). Global columns are loaded to the left side of the menu bar, while local columns are loaded to the right of the global columns. See Understanding environments for more information about global and local and Customizing the way environments place and remove columns for information on setting an option that changes the way local menu columns are placed and removed.
If a column entry has a shortcut, the display consists of two parts: the text of the entry and the shortcut. Shortcuts are displayed in a “column” to the right of the longest text entry. The text of a menu’s shortcut can be retrieved with M_KEYTXT.
You can link one or more column entries into a list of entries. This allows you to enable or disable multiple menu entries at once. (See .LIST for more information on the window building command.)
Display renditions
Five rendition states are associated with a menu:
- Enabled
- Disabled
- Selected
- Column quick-select
- Entry quick-select
When a menu is being processed, all accessible column headers and entries are displayed in the enabled rendition. The column headers and entries that you cannot access are displayed in the disabled rendition. When the menu is not being processed, the menu bar is displayed in the disabled rendition.
As you move among the columns and the entries within the columns, the currently accessed column or entry is displayed in the selected rendition.
By default, an enabled item appears in bold and reverse type, a disabled item appears in reverse type, and a selected item appears in bold type. All are color palette 2 by default.
If you want to change any of the menu renditions, use the U_REND subroutine, the U_EDITREND subroutine, or the “Renditions” function in Proto. (The Synergy UI Toolkit Control Panel also has a “Renditions” function that you can use. See Customizing the look of your application.)
Disabled selections
You can disable (and re-enable) entries, lists of entries, and even entire columns within a given menu. When you do so, the disabled entries or columns have a different display rendition (attribute and color) and cannot be selected.
The subroutines used to disable and enable menu items are M_ENABLE and M_DISABLE.
On Windows, disabled menu entries can be highlighted, but the user will not be able to select them.
Making a menu selection
The user has three ways to make a menu selection: arrow keys, quick-select characters, and shortcuts. (The first two options only work when the menu bar is enabled or being processed.) A menu selection can also be simulated using the %M_SIGNAL function.
To initiate menu processing during terminal input, the user must press a special “process-menu” key. When this occurs, the menu is activated, the first column or the column set by the M_DEFCOL subroutine is automatically dropped down (unless you specified an input string on the M_PROCESS subroutine), and the user can select an entry. As distributed, the process-menu key for UNIX and OpenVMS is ctrl+p; for Windows it is the alt key. (On Windows, the user can also use the mouse.) You can modify this key by supplying an EFKEY_METHOD subroutine.
The menu bar is disabled when an entry is selected or if the user presses the process-menu key a second time, without making a selection.
On UNIX and OpenVMS, you can remove the menu bar from the display screen using the U_BAR subroutine. If you call U_BAR, the menu bar will only be placed when the process-menu key is pressed, and it will be removed again when an entry is selected.
Selection by arrow keys
The most common way to make a menu selection is to use the arrow keys. Once the menu bar is enabled, the left and right arrow keys enable the user to move through the menu, between the various menu columns. When a column is selected (which means that the “cursor” passes over it), the possible selections for that column are dropped down in a vertical list of entries below the heading. The first entry in the column is automatically selected. The user can either press Enter to enter this selection or use the up and down arrow keys to select a different entry within the column.
The arrow keys can be used in any combination, and they will wrap around within the menu and columns. Wrapping means that when the user is on the last entry in a column and presses the down arrow key, the next entry highlighted will be the top one. Likewise, if you are viewing the rightmost menu column and you press the right arrow key, it will wrap to the leftmost menu column. Once the user has chosen an entry with the arrow keys, the user must press the Enter key to enter the selection.
If the user selects an entry that has a submenu associated with it, the possible selections for that submenu column are dropped down in a vertical list of entries that are adjacent to the parent menu entry. The first entry in the submenu column is automatically selected. The user can press the up and down arrow keys to move among the entries of a submenu column just as in a primary menu column. After descending into submenu columns, the user can press either the right or left arrow key to go to the previous menu. The user can also press the process-menu key to go to the primary menu column. (See the previous section for information on the process-menu keys available in various environments.) After returning to the parent (primary) column, the submenu column is removed from the screen.
Selection by quick-select characters
Each menu column and menu entry is associated with a quick-select character. A quick-select character is a single character that will access that entry while the menu is being processed. Usually it is related to the name or text of the entry (for example, the first letter or number of the entry). Quick-select characters are not case sensitive.
When a primary menu or submenu column is dropped down, the user can type the quick-select character to not only highlight the menu entry but also select it. If the quick-select character is not unique in the column, it simply highlights it.
If the menu bar is enabled (being processed), but no column is currently dropped down, the user can drop down a menu by typing the column’s quick-select character.
Quick-select character associations are made in your menu column scripts or with the MB_ENTRY subroutine.
On UNIX and OpenVMS, if a user presses an invalid quick-select character, a beep is generated.
Re-using quick-select characters
The quick-select character for a menu entry need not be unique.
If a character is duplicated within the entries of a column, the system accesses the next entry that matches, going from top to bottom and wrapping to the top after reaching the bottom.
Applying renditions to quick-select characters
The quick-select characters have their own renditions, which can be modified using U_REND, U_EDITREND, or the “Renditions” function in Proto.
There is one rendition for column quick-select characters and another for entry quick-select characters. Both are set to reverse, bold, underline and color 10 by default.
On Windows, quick-select characters are always designated by an underscore (“_”).
Adopting conventions
Although the quick-select character has no real constraints, we recommend that you adopt some conventions regarding the character and its associated text. For example, you can
- require that the quick-select character be contained within the text, and then uppercase that character (for example, “o” for “Option,” “x” for “neXt,” and so forth).
- label your entries with numbers or letters and use those labels as quick-select characters (for example, “1. Calculate,” “E - Exit”).
- flag the quick-select character by applying the same rendition (such as underlining) to it.
- always use the first character of the text as the quick-select character.
Regardless of the method you choose, it is important that your convention be logical, easy to use, and consistent across all of your applications.
For consistency with other Synergy applications, we specifically recommend that you
- use the default rendition (underline, color 10).
- make sure the quick-select character is contained in the entry or header text.
- select quick-select characters that are unique among entries in a column or among headers of placed columns.
Following these conventions for quick-select characters will help ensure that all of your Synergy applications look the same.
A shortcut is a key or key sequence that automatically accesses a particular menu entry. You can use a shortcut even when the menu is not being processed.
To associate a shortcut such as a control character, function key, or arrow key with a given option, you must make an entry for that option in the current menu and assign the desired key to that entry in the menu column script.
The display codes ^, v, <, and > represent the up, down, left, and right arrow keys, respectively, in the menu entry. Arrow keys are disabled as shortcuts during menu processing and are temporarily redefined for movement within the menu.
When the user presses a shortcut, the associated menu entry is immediately selected. Pressing a shortcut is exactly equivalent to pressing the process-menu key, selecting the corresponding column, selecting the corresponding entry, and pressing the Enter key.
The following constraints apply to shortcuts:
- Shortcuts can be used in primary menus only.
- Duplicate shortcuts are allowed, but if more than one column has the same shortcut, the entry in the rightmost column gets processed when the shortcut is pressed.
- On Windows, some keys and key combinations are privatized for lists. That is, they are reserved for the list and cannot be assigned as menu shortcuts without calling L_RETURNKEY and setting their return states to true. See Appendix C: Keyboard Navigation for Lists on Windows and L_RETURNKEY for information.
- ctrl+m is not valid as a shortcut because it is a carriage return. We recommend that you also do not define any other control characters that already have a function on the system as shortcuts (for example, ctrl+s is a screen hold on many systems). Refer to Window Scripts for more information about building menu columns.
On Windows, the page up, page down, home, end, and arrow keys are privatized for lists. That is, they are available for functions internal to the list, but aren’t available as menu shortcuts unless you call the L_RETURNKEY subroutine and set their return states.
Simulating a menu entry or canceling a signaled menu entry
%M_SIGNAL enables you to either signal a menu entry programmatically or cancel a menu entry that’s been signaled programmatically or by the user. Note the following:
- If you want to invoke a menu entry from a method subroutine, we recommend using the D_SIGNAL operation for %M_SIGNAL—especially on Windows, where method subroutines are direct callbacks.
- If you signal a menu entry from a callback routine and process the menu entry in the same callback routine, use the D_REMOVE operation for %M_SIGNAL to cancel the menu entry after you’ve processed it. If you don’t, the menu entry will be resignaled when processing returns to the calling routine.
- We don’t recommend using %M_SIGNAL to signal a menu entry from a list load method. Because of the way Toolkit synchronizes menu entry signaling, Toolkit may not execute the menu entry.
For more information, see %M_SIGNAL.
Processing menus
Before processing a menu column, you must load it from the window library with M_LDCOL or create it with the MB_xxx subroutines. If you want to have a default menu entry or have this new column be the one that is dropped down when the menu is processed, call M_DEFCOL.
To process a pop-up menu, use %M_POPUP. For standard drop-down menus, you can explicitly process the menu by calling M_PROCESS. However, you will find that you rarely need to do this because menu processing happens implicitly during input. Either way, the following global variables enable your application to determine whether a menu entry was selected, what the selection was, and if there is any user text associated with the selection.
These variables are defined in the tools.def file.
Check this variable… |
To determine… |
---|---|
g_select |
Was a menu entry selected? |
g_entnam |
If g_select is true, which menu entry was selected? |
g_entuser |
If g_select is true, what user text is associated with the menu entry? |
Additional menu support subroutines include M_COLUMN, which places, removes, or deletes a column; M_RESET, which disables the menu bar; M_SCINFO, which returns menu and shortcut entry information; M_TEXT, which modifies and retrieves menu entry text; and M_USER, which retrieves the user text string associated with a particular menu entry.
Runtime generation of menu columns
If your application needs to generate a menu column at runtime, use the MB_xxx subroutines. (MB stands for “menu build”.) They provide an alternative to defining your menu columns in script files.
We recommend that you use these subroutines only when you cannot determine the contents of the menu until runtime. Loading columns from window libraries is faster and more modular than generating columns at runtime.
There is an almost one-to-one correspondence between the MB_xxx subroutines and the window script commands that build a column: MB_COLUMN provides essentially the same functionality as the .COLUMN window building command, MB_ENTRY provides the same functionality as the .ENTRY window building command, and so forth. (The only functionality difference is that you cannot specify user text with the MB_xxx subroutines.)
These subroutines are also called in the same order as the column window building commands. For example:
xcall mb_column xcall mb_entry . . . xcall mb_end
Each routine has a control argument, which is the data area required by the menu build subroutines. Control must be an alpha field and may have to vary in size, depending on how many menu entries you put in your column.
If you run out of space in the control argument, you will get the following fatal error: “Overflow of column build control array.” This error indicates that you must increase the data area of the control argument.
Customizing the way environments place and remove columns
The default behavior for each environment’s handling of columns is controlled by the g_plc_col_args flag, which is defined in the distributed tkctl.def file. In UNIX and OpenVMS environments, U_START sets g_plc_col_args to true which tells the subroutine to place and remove the columns as needed. In Windows environments, U_START sets this flag to false which tells the subroutine to ignore any passed column arguments typically needed for input. In any environment, you can alter the value of g_plc_col_args after U_START is called. (Altering g_plc_col_args is not advisable in UNIX or OpenVMS environments because columns containing functions must be placed to make those functions available to the user.)