Menus and control panels

FELIX contains a variety of menu bars, pulldowns, and control panels that interact with you to simplify data analysis and processing. These components are unique because you can easily modify the graphical interface. In fact, the interface simply consists of a set of FELIX macros that use specific commands to build and display graphical menus. Within FELIX, you can therefore customize the program's interface to meet the needs of your laboratory by simply editing the macros provided or by writing your own.

The menu commands

Before developing your own menus, you first need to become familiar with the commands for menu interaction. The menu components can be divided into two separate categories. First, the menus themselves contain items that, when selected, execute commands in macros. Menu-type items can be displayed as horizontal menu bars, vertical pulldowns, or icons. Menu items are selected by moving the cursor onto the desired item and clicking the left mouse button. The second category of menu components is the control panel. Menu components are described in detail in this section.

Changing the menubar interface

When FELIX starts, it looks for a file called root.mot to display items on the menu bar and pulldowns. The .mot file(s) must be present in one of the current menu directories (defined by the symbol motpfx). The syntax for a .mot file is:

     mode item_name mnemonic accelerator accelerator_text call_
back call_back_data filename


mode can have different values depending on the what type of menu is being defined. A list of modes follows.


The menubar mode is for the items displayed on the menu bar itself. Here is an example of the use of the menubar mode:

     menubar File F NULL NULL NULL NULL file.mot

where File is the name of the item that appears on the menu bar; F is the hot key that is used for the command (which is underlined on the menu bar); and file.mot is the name of the file that contains the items listed under the File pulldown.


The popup mode is used when an item in the menu bar has a cascading menu attached to it. The following is an example for the use of this mode:

     popup "Plottype" t NULL NULL "view Plottype" NULL plot-

where "Plottype" is the text that appears on the pulldown or cascading menu; t is the hot key; "view Plottype" is text that is given for this menu and is just for your reference (it is not used); and plottype.mot is the name of the file that contains the items to appear on the cascading menu.


The separator mode draws a line to separate groups of related commands commands in a pulldown or cascading menu; for example:

     separator separator NULL NULL NULL NULL NULL NULL

where "separator" is the text for the separator name. This can be any text you desire.


The toggle mode places a toggle into a pulldown or cascading menu; for example:

     toggle "Draw Peaks" D Ctrl<Key>k Ctrl+k "ex drawpeaks" NULL 

where "Draw Peaks" is the label for the toggle that appears on the menu; D is the hot key; Ctrl<Key>k is the accelerator that is bound to this menu item; Ctrl+k is the text that appears next to the text for the menu item; "ex drawpeaks" is the call-back macro that is called when this menu item is selected or when its accelerator or hot key is pressed; and pksdrw is the name of the symbol that is updated when the state of the toggle is changed.


The item mode is used when you want to execute the call-back without any cascading menus; for example:

     item "Plot" P Ctrl<Key>p Ctrl+p "ex plot" NULL NULL

where "Plot" is the text that appears on the menu; P is the hot key for this menu item; Ctrl<Key>p is the accelerator; Ctrl+p is the text that appears next to the label; and "ex plot" is the call-back that is called when this menu item is selected.


The keypad mode is used to define actions that are performed when you press the keypad keys; for example:

     keypad NULL NULL NULL NULL "exm keypad" NULL NULL

where "exm keypad" is the command that is called when you press the keypad buttons.


The mouser mode is used to define the popup that appears when the right mouse button is pressed; for example:

     mouser NULL NULL NULL NULL NULL NULL mouser.mot

where mouser.mot defines the menu items that comprise the right-mouse menu.


The mousem mode is used to define the action performed when you press the middle mouse button; for example:

     mousem NULL NULL NULL NULL "exm cursorval 4" NULL NULL

where "exm cursorval 4" is the call-back that is called when you press the middle mouse button when the cursor is inside a frame.

Changing the iconbar interface

The file used to display icons on the icon bar is icons.mot. The icon file(s) must be present in one of the current menu directories (defined by the symbols icopfx). The following is the syntax for the icons.mot file:

     mode filename call_back ballon_help_text param1 param2 
param3 param4

where mode can be one of the following.


The icon mode is used to display the icons in the icon bar; for example:

     icon zoom20.icon "ex limits 1" "Zoom" NULL NULL NULL NULL

where zoom20.icon is the file that contains the bitmap graphic for the icon; "ex limits 1" is the call-back macro that gets called when you select this icon; and "Zoom" is the balloon help text that appears when the cursor is placed above this icon.


The separator mode is used to separate the icons; for example:

     separator separator NULL NULL NULL NULL NULL NULL

Parameters 1-4 are currently not in use.


The option mode is used to place a popup on the icon bar; for example:

     option plottyp.mnu "ex plottype 0" "plottype" plottyp NULL 

where plottype.mnu is the menu file that contains the text to display on the popup menu; "ex plottype 0" is the call-back that is called when this popup is activated; "plottype" is reserved for balloon help but is not currently displayed; plottyp is the symbol that is changed when you select a different item on the popup.

Control panels

There are many applications in NMR processing where you need to enter information such as filenames and various processing parameters. For defining this information from within a graphical environment, you can create customized control panels from ASCII text files. Cntrol panels are separate windows that can be placed anywhere on the screen. Also, control panels open at the most recent coordinates where a control panel was placed.

To open a control panel, issue the following command statement with appropriate arguments:

     mnu p menu x_origin y_origin

The mnu p keywords in the statement tells FELIX to read a menu file containing a control-panel definition. The menu argument is the name of a menu file that must be present in one of the current menu directories (defined by mnupfx, mnupf1, and other symbols). By convention, menu files use the .mnu extension. The x_origin and y_origin define the position of the upper left corner of the box in character units (with Motif graphics these numbers are ignored, although they have to be supplied). A character unit is defined as the maximum space that a character needs to be written correctly. The letter "a" is one character unit wide and one character unit high. For example, the command line:

     mnu p xopen 20 4

opens a control panel and places it on the screen. A full list of the file, and the control panel it creates, is shown below. Most of the files that define control panels begin with the letter "x". This is not mandatory, but is simply a convention to help organize the directory containing the menu files.

The ASCII file xopen.mnu looks like this:

23 40
*h 1 1 14 `OPEN FILE'
*o 2 2 40 5 5 &mytype&ftype &newpfx&ftype newfil(
*c 3 19 5 `File Type'
*p 12 19 16 7 `Matrix (*.mat)' `Felix Data (*.dat)'
`DBA (*.dba)' `Insight II Molecule (.car)' `PDB Molecule (.pdb)' `Other Data (Bruker, Varian, JEOL, FFW)
(*)' `Macro (*.mac)' ftype
*c 3 20 5 `Dimension' (de:ftype.eq.1)
*p 12 20 8 2 `1D' `ND' datdim (de:ftype.eq.1)
*c 20 20 5 `Access' (de:ftype.eq.0)
*c 20 21 5 `Storage' (de:ftype.eq.0)
*p 27 20 10 2 `Read Only' `Write' macces
*p 27 21 10 2 `Disk' `Memory' matmem (de:ftype.eq.0)
*x 2 22 40 5

This file creates the following control panel:

Within the file that defines a control panel are two different classifications of commands. The first group of commands provides the graphical information needed to design the control panel. They define the size of the control panel, the text for the control panel header (*h), the text for user prompting (*c), and coordinates for displaying highlighted boxes (*x). These commands are for output only. The second group of commands found in control-panel files are for setting symbol values based on input from the user. These commands create entry boxes ("fields") (*f), toggles (*t), switches (*s), list boxes (*l), buttons (*b), combo boxes (*p), file-select tools (*o), and list boxes (*v) with multiple items on a line (so-called variable lists).

Output commands

The *h command in the control-panel file specifies the header text. The format of this command is:

     *h x_origin y_origin number_of_characters `header text'

The header text must be enclosed in single quotes. By default, the header is left-justified within the control panel and thus the parameters x-origin and y-origin are ignored. Header text may contain characters or use symbol substitution for customizing the header.

The *c command in a control-panel file is used to place text. Text in control panels is most commonly used for labeling the required input for entry boxes. (The command that defines an entry box is not coupled to the text that labels it.) The format of a character string command within a control-panel file is:

     *c x_origin y_origin number_of_characters descriptor_text

Using the *c command, character strings can be placed throughout the control panel. Character strings are limited to 64 characters and must be enclosed in single quotes.

To enhance the appearance of control panels, you may uses highlighted rectangles. These rectangles are often used to group related switches or entry boxes. Within a control panel definition, these rectangles are defined as:

     *x x_origin y_origin width height

The x_origin and y_origin parameters define the bottom left corner of the highlighted rectangle. The width and height parameters define the rectangle size in character units.

A variation of the highlighted rectangle is when an extra symbol or text string is found on the line:

     *x x_origin y_origin text

This means to place the text on the left top line of the highlighted box.

For control panels needing extra user notification, you can make the computer beep. This is commonly used for control panels that warn of errors or request confirmation of potentially dangerous actions such as file deletion. The command for generating a beep within control panels is simply:


Input commands

The second class of commands found within control panels defines information to be input to the program. These commands include functions for entering and updating symbol values, setting the value of the reserved symbol button, and choosing between switches and toggles.

To generate an entry box for data input, the *f command is placed within the control-panel file. This has the format:

     *f x_origin y_origin length type symbol

Again, the x_origin and y_origin values are used to place the box using character units. The length defines the length of the box in character units. The type defines what the entry box expects. A c means a character must be input into the entry box, an i means an integer, and an r means a real number. The symbol can be either a reserved symbol name or a user symbol name. In either case, the current value of the symbol is displayed in the box. If that symbol has not yet been defined, then a new user symbol is created and is defined to have the value 0 or blank, depending on whether the field is numeric or character. The symbol does not contain the & used for substitution because we want the symbol name, not its value. Note that the box itself contains no prompting information. Hints to the user must be indicated separately using *c commands as discussed above.

Symbol values can also be updated from within list boxes. A list box is an object that appears within control panels that lets the user select and scroll through values from a displayed list. To display a list box the *l command is placed within the control-panel file. This command has the format:

     *l x_origin y_origin width height list_file select symbol

The x_origin and y_origin values are used to define the lower left corner of the list box in character units. The width and height define the width and height of the list box in character units. The list_file is the name of the ASCII (text) file whose contents are to appear in the list box. select is the name of the symbol that defines which line is selected from the list. The value of select is 1 if the first line in the list is selected, 2 if the second line is selected, and so on. The symbol is the name of the symbol whose value is updated to reflect the selected line. For example, if the selected value was test.mac, symbol will be test.mac after the "test.mac" line is selected from the list box. From list boxes, you therefore have two means of getting output: select defines the number of the line in the list box that was selected, and symbol represents its actual alphanumeric value. When exiting from a list box, either of these values can be used to make a later decision.

List boxes are especially useful for selecting files or matrices to be read and displayed. The text file named by list_file may be of virtually any form or origin. In many places in the menu interface, FELIX shows a list box of filenames. To do this, FELIX issues a UNIX command to obtain a directory listing and store it in a file, then shows the contents of that file in the list box. You could just as easily build a file using the opn, put, and cls commands.

Switches are used within control panels for setting the values of symbols that integer numbers. Switches take the form of radio buttons (sets of small circles) that can be placed anywhere within the control panel. FELIX is currently limited to the placement of four radio buttons per switch command. By convention, a radio-button option is selected when its circle is highlighted. The command for building switches in control panels takes the format:

     *s x_origin_1 y_origin_1 spacing # item1 ... itemN symbol

The # parameter defines the number of radio buttons. The origins define the coordinate positions of the radio buttons. symbol defines the symbol for the switch value. If you select the first radio button, the symbol is 0. Selecting the second radio button sets the symbol to one, and so on. The spacing parameter sets the vertical distance between the radio buttons. From an application point of view, symbol values set with switches are used within macros for defining branching points or parameter values. If that symbol has not yet been defined, then a new user symbol is created and defined to have a zero value. When the control panel is first drawn, the radio button corresponding to the current value of the symbol is highlighted. Only one radio button per switch can be highlighted. When another radio button is selected, the previous one loses the highlight and the new one becomes highlighted. The contents of item1 ... itemN are the text prompts for the radio buttons.

Toggles operate much like switches, but they can be only on or off, and take up less space within the control panel. The command for making toggles in control panels takes the format:

     *t x_origin y_origin length # text_1 text_2 symbol

The origins are used to place the toggle using character units. The length is the width of the toggle in character units. Since the actual toggle does not contain any text, text_1 and text_2 can be blank. The # defines the number of toggle options, which is usually 2, since toggles can be only on or off. The symbol is the reserved or user symbol used for storing the current value of the toggle. From an applications point of view, symbol values set with toggles are used within macros for defining branch points. In addition, toggles have applications for telling the user the current state of yes-or-no symbols. For example, the value for the drwbox symbol is either 0 or 1, depending on whether you want a box around your spectrum to be drawn. When the control panel is first drawn, the toggle value corresponding to the current value of symbol is displayed. As for entry boxes, there is no text prompt outside the toggle. The *c command is often used to put text near the toggle to supply appropriate information.

Buttons are similar to toggles and switches, in that they change symbol values. Buttons differ, however, in that they all change the reserved symbol called button and then exit a control panel. (A control panel that doesn't contain a button cannot be exited!) The command for placing a button within a control panel is:

     *b x_origin y_origin length text value

The origins are used to place the button. The length defines the length of the button. The text is the button text, and the value defines the value of the button reserved symbol when that button is selected. Buttons are usually used for branching within macro routines. The most common use of buttons is the OK/Cancel choice presented on many control panels. By convention, buttons that have text = CANCEL always set the value argument to zero, and buttons with text = OK always sey the value argument to one. In addition, the text in the Cancel button is red. To enable shortcuts, FELIX treats two keys on the keyboard as if they were control-panel buttons. When a control panel is displayed, pressing <Esc> exits the control panel and sets button to zero; likewise, pressing <Enter> exits the control panel and sets button to one.

Pulldowns (combo boxes) are very similar to toggles, except that selecting a pulldown shows all valid choices at once, whereas a toggle shows only one choice at a time. Clicking a pulldown with the cursor, opens a vertical list of all choices. Pulldowns are preferred over toggles when the set of choices is not obvious. For example, a yes-or-no choice is ideal for toggles, and a Points/PPM/Hertz/None choice is better suited for a pulldown. The command syntax is:

     *p x_origin y_origin length # text_1 ... text_N symbol

Some special tools are available, which take advantage of the Motif widget set and which also make it easier for you to create your own menus. The file-open tool is such a widget:

     *o x_origin y_origin width height #_lines extension dir 

x_origin and y_origin set the position of this tool in the control panel. The width and height set the width and height of the tool. #_lines sets the number of files to display inside the list box contained within the file-open tool. extension sets the default type of files to be searched for in the directory. dir is the directory to be searched, and filename is the name of the file that is returned when you select a file from the list. An example of specifying such a tool is in the xmatopen.mnu menu file:

     *o 2 2 40 5 5 &mytype &newpfx newfil

where &mytpe is *.mat and &newpfx is the directory where the matrix files are to be looked for.

Control-panel dependencies and special behaviors

Input box dependencies

The selectability of any entry box in a control panel can be made dependent on the value of another symbol. By default, an entry box is always selectable. however, you can define a dependency for the box, so that it is selectable and editable only when some symbol value meets a specific criterion. For example, the entry box for the name of an annotation file can be made dependent on the symbol that controls the drawing of annotations, so that the user can change the annotation filename only when annotation-drawing is turned on.

An example helps to illustrate the usage and syntax. The following two lines come from the macro that specifies the 1D PLOT GENERAL PARAMETERS control panel. They control automatic drawing of annotations in the current plot:

     *t 20 9 12 2 `No' `Yes' pltann 

*f 20 10 12 c annfil (de:pltann.eq.1)

The first line defines a yes-or-no toggle to control the symbol pltann, the reserved symbol for drawing annotations on plots. The second line defines an entry box where the user can enter the name of the annotation file into the symbol annfil. The last portion of the second line contains the dependency formula, which states that this box is selectable only when pltann is 1.

Another example from the same control-panel macro controls the selectability of the entry box for the 1D peak entity:

     *f 20 6 12 c picent (

This dependency states that the 1D peak entity name is selectable only when drwpks is greater than zero.

The formal syntax for specifying entry-box dependency is as follows: The parentheses and the leading de: are required and define this parameter to be a dependency descriptor. The rest of the descriptor must be of the form symbol.relation.value -- this specifies the name of one symbol, one of the arithmetic relations (for example, eq, ne, lt, gt, le, or ge), and one numeric value. The entry box is selectable only when the stated relation is true. An entry box can have many dependency descriptors, which are separated by Boolean (and/or) relationships, for example:


Immediate exits

In addition to exiting a control panel via the Cancel or OK button, you may also trigger an immediate exit from a control panel when a pulldown is selected. This is useful for taking immediate action as soon as a pulldown is selected, without having to wait until the user clicks a button.

Another example from the same control-panel macro illustrates immediate exits via a pulldown:

     *p 20 3 12 6 `None' `Points' `Hertz' `PPM' `Seconds' `1/cm' 
axtype (ex:2)

This exit descriptor states that the control panel should immediately exit with button set to 2 whenever the symbol axtype is changed by this pulldown.

The formal syntax for immediate exit requires that the parentheses and the leading ex: be present and define this parameter as an exit descriptor. The rest of the descriptor must be of the form: value. This specifies the numeric value to be given to the button symbol and tells the macro that invoked the control panel the precise exit method that was activated.

Finding your way through the menu interface

As mentioned, the FELIX menu interface is built completely from macros, with the assistance of menus and control panels. Every facet of the functioning of this interface is explicitly contained in these ASCII text files. This feature allows the interface to be altered and bugs to be fixed, without the need for a new version of FELIX. However, this feature necessarily involves a huge number of files -- there are literally hundreds of macros, menus, and control-panel files. This section is designed to help you find your way through this maze of files.

FELIX has a reserved symbol that facilitates the generation of diagnostic information about every macro, menu, and control panel invoked while the program is being run. This reserved symbol (verify) has three acceptable values (0, 1, or 2), which specify the type of information to be provided.

When verify is zero, no verification takes place and FELIX runs normally. If verify is set to one:

     def verify 1

then, every time a menu interface file (macro, menu, or control panel) is invoked, the full filename is shown in the text window. This shows you exactly what files are being accessed for every operation that is selected from the interface.

When verify is set to 2, the program gives even more diagnostic information. In addition to the filename, each FCL command is printed in the text window as it is about to be executed. This allows advanced users to see the complete literal text of each command that FELIX performs and is useful for debugging new macros or altered menu-interface macros. In fact, if you choose the "parent text" frame configuration and redirect FELIX output to a file, you can capture the actual stream of FELIX commands that are executed to a file, and then use that file to construct a new macro. However, be aware that this activity can slow down command execution, especially if a macro containing long command lines is used.