8.8 Sample Menus

In this section, several sample menus are presented which demonstrate techniques for creating useful menus.

The first example is a very simple menufile with a single menu. Our menu has two choices, Display Message and Return to System.

The first choice, when selected, displays Hello World! on the screen. The second choice terminates menu.

If the menufile is in a file called example1, run this menu by typing:

menu example1

Menu displays the screen shown below.

gifs/00000001.gif

The menufile produced by menudef for this menu looks like:

menufile Untitled

menu m1

1,2 Sample Menu 1

4,9 Display Message

echo "Hello World!"

exit 1

+2,+0 Return to System

quit

Note that one choice executes the quit command to provide an exit from menu. All menus must have a quit or menu command to allow the operator to exit from the menu. The exit command in the Display Message choice forces a nonzero exit status that makes menu pause before redisplaying the menu. This is often useful when choice commands display information on the screen that would be overwritten if a menu were immediately redisplayed.

Menudef uses relative row and column numbers when practical. Inserting a new choice between other choices is easier when using relative row numbers, since you do not need to change the row numbers of the following choices.

The next example, example2, is the Demonstration Subscription System Menu. To run this menu, type:

menu example2

Menu displays the screen shown below.

gifs/00000001.gif

The choices in this menu start with numbers, which allow the operator to select a choice by typing its number in a manner similar to many other menu systems.

The following is the text listing for menufile example2, created with menudef:

menufile Untitled

menu demo

1,2 Demonstration Subscription System

4,9 1 - Enter Magazines

form -qfuad ~mag

+1,+0 2 - Enter Subscriptions

bin/sform -qfuad ~subscrpt

+3,+0 3 - List Subscribers

grace ~subscrib

+1,+0 4 - List Subscriptions

grace ~sripts

+1,+0 5 - List Magazines

grace ~magazine

+1,+0 6 - List Subscriber Labels

grace ~labels

+3,+0 X - exit

quit

The next example, example3, puts the data entry, report and exit choices from example2 in separate columns. The resulting menu is shown below.

gifs/00000001.gif

The operator can use the Up and Down Arrow keys to select choices in the data entry or report columns and can move between the data entry and report columns with the Left and Right Arrow keys. The exit choice, however, can only be reached by typing X, since the exit choice is not in the same row or column as any other choice. Placing a choice in a lone row and column may be useful if you want to insure that the operator intentionally selects a choice rather than accidentally selecting it.

Menu does not check for unreachable choices. For example, if the X - exit choice is rewritten as E1 - exit, the operator could not exit from the menu, since whenever E1 is typed, the menu cursor goes to the first choice starting with E1, E1 - Enter Magazines, rather than E1 - exit.

It is easy to create example3 from example2 with menudef by moving the choices with DELETE, UNDELETE and INSERT LINE. Note that some of the column numbers are relative, e.g., +0. This allows you to change the position of an entire column by changing just the first entry in that column. Here is the menufile example3:

menufile Untitle

menu demo

1,2 Demonstration Subscription System

4,9 Data Entry

+3,+0 E1 - Enter Magazines

form -qfuad ~mag

+2,+0 E2 - Enter Subscriptions

bin/sform -qfuad ~subscrpt

+2,+0 E3 - Enter Subscribers

form -qfuad ~sub

16,33 X - exit

quit

4,49 Reports

+3,+0 R1 - List Subscribers

grace ~subscrib

+2,+0 R2 - List Subscriptions

grace ~scripts

+2,+0 R3 - List Magazines

grace ~magazine

+2,+0 R5 - List Subscriber Labels

grace ~labels

Example4, allows the operator to list files and directories in the current working directory without typing DOS commands directly. Before displaying the menu, this menufile uses the menu commands to display the available files or directories. The C/Base ask(C-1) command is used to get responses from the operator. This is not the built-in command version of ask that is available using the built-in menu commands. The text menufile for example4 is as following:

menufile example4, BUILT_IN_COMMANDS=ON

if $# > 2

echo "usage: menu example4 [ filename ]"

exit 1

endif

if $# = 1

ask "Enter file name: " as string to name

else

set name to "$1"

endif

if ! file name

echo "File" :name: "does not exist"

ask "Create it (y/n)? " as boolean to response

if response

eval echo >$name

else

exit 1

endif

endif

set EDITOR to "edit"

menu main

1,1 Main menu

+1,+0 File Services - file $name

+3,10 1 - Change name of file

ask "Enter new file name: " as string to new

if file new

echo new : " already exists."

ask "Remove it (y/n)? " as boolean to response

if response

erase $new

else

exit 1

endif

endif

ask "Change ":name:" to ":new:"(y/n)?" as boolean to response

if response

rename $name $new

set name to new

else

exit 1

endif

+2,+0 2 - Display contents of file

grace - <$name

exit 1

+2,+0 3 - Display directory information of file

dir $name

exit 1

+2,+0 4 - Display name of file

echo "The current file name is " : name

exit 1

+2,+0 5 - Edit file

echo "Starting " : EDITOR : " on " : name : "..."

$EDITOR $name

exit 1

+2,+0 6 - Remove file

ask "Remove " :name:"(y/n)? " as boolean to response

if response

ask "Enter new file name: " as string to new

if ! file new

echo "File " : new : " does not exist."

ask "Create it (y/n)? " as boolean to response

if response

eval echo >$name

else

exit 1

endif

endif

erase $name

set name to new

endif

exit 1

+2,+0 7 - Select new file name

echo "The current file name is ": name

ask "Enter the new file name: " as string to new

if ! file new

echo "File " : new

ask "Create it (y/n)? " as boolean to response

if response

eval echo >$name

else

exit 1

endif

endif

set name to new

exit 1

+3,+0 8 - Exit

quit

To start example4, enter

menu example4

A menu can be reached from any other menu with the menu command, so groups of menus are not restricted to the typical tree structure. In this example, any of the menus can be directly reached from the current menu.

The ask(C-1) command is useful in choice commands to prompt the operator and get a response. Typically, ask is used in a shell variable assignment as:

ask "prompt" as "datatype" to Shvar

Shvar is a shell variable of your choosing; datatype is a data type listed in Table 8-21, and prompt is a string of characters, normally quoted. Ask displays the prompt on the screen and accepts input that matches the specified datatype. If the operator enters data that does not match the datatype, ask prompts the operator to reenter the data.

The menu commands following the menu dirs line are executed each time the Directory Services menu is displayed, as are the commands following the menu files line each time the File Services menu is displayed. In this example, the Directory Services or File Services menus are displayed whenever the menu dirs or menu files internal menu commands are executed.

When menu's built-in commands are disabled, menufile or menu commands cannot be used to change the current directory or shell variables that are used in other menus or choice commands, since each group of commands is executed by a separate shell.

Example5 demonstrates some of the built-in commands that are available with menu. If the menufile has the BUILT_IN_COMMANDS=toggle set to either ON or OFF, the -m flag is ignored. To start example5 type

menu example5 [filename]

The menufile is as follows:

menufile example5, BUILT_IN_COMMANDS=ON

if $# > 2

echo "usage: menu example4 [ filename ]"

exit 1

endif

if $# = 1

ask "Enter file name: " as string to name

else

set name to "$1"

endif

if ! file name

echo "File " :name: "does not exist"

ask "Create it (y/n)? " as boolean to response

if response

eval echo >$name

else

exit 1

endif

endif

set EDITOR to "edit"

menu main

1,1 Main menu

+1,+0 File Services - file $name

+3,10 1 - Change name of file

param change

if file new

echo new : " already exists."

ask "Remove it (y/n)? " as boolean to response

if response

erase $new

else

exit 1

endif

endif

ask "Change ":name:" to ":new:"(y/n)?" as boolean to response

if response

rename $name $new

set name to new

else

exit 1

endif

+2,+0 2 - Display contents of file

grace - <$name

exit 1

+2,+0 3 - Display directory information of file

dir $name

exit 1

+2,+0 4 - Display name of file

echo "The current file name is " : name

exit 1

+2,+0 5 - Edit file

echo "Starting " : EDITOR : " on " : name : "..."

$EDITOR $name

exit 1

+2,+0 6 - Remove file

param remove

if response

ask "Enter new file name: " as string to new

if ! file new

echo "File " : new : " does not exist."

ask "Create it (y/n)? " as boolean to response

if response

eval echo >$name

else

exit 1

endif

endif

erase $name

set name to new

endif

exit 1

+2,+0 7 - Select new file name

param new

if ! file new

echo "File " : new

ask "Create it (y/n)? " as boolean to response

if response

eval echo >$name

else

exit 1

endif

endif

set name to new

exit 1

+3,+0 8 - Exit

quit

param change

1,1 $0

4,10 Current name is '$name'

+2,+0 Enter new file name

6,35 new

FIELDSIZE=20

DATATYPE=string

REQUIRED

param remove

1,1 $0

4,10 When removing the current file '$name'

+1,+0 a new current file name must be set.

+2,+0 Do you wish to remove the current file?

+3,+0 If you intend to remove the current file '$name',

+1,+0 a new file name must be set for the file service menu.

+2,+0 Enter Name of New File

13,36 new

FIELDSIZE=20

DATATYPE=string

REQUIRED

7,52 ans

FIELDSIZE=3

DATATYPE=boolean

param newfile

1,1 $0

3,5 The current file name is $name

+2,+0 Enter the new file name

5,30 new

FIELDSIZE=20

DATATYPE=string

REQUIRED

When menu runs with our example5 menufile using the filename myname, the menu displayed is shown as follows:

gifs/00000001.gif

This menufile makes use of the built-in menu commands available with menu. The ask and param menu commands are useful when input is required from the operator. Examples of both are in the menufile example5. Each time the menu choice 1 - Change name of file is selected, a parameter form is displayed like the one shown below.

gifs/00000001.gif

Looking at the menufile for example5, you may notice that variables can be used in expressions in two ways. For example, the following two built-in echo commands display the same thing:

set color to "blue"

echo "The sky is " : color : " today."

echo "The sky is $color today."

There is a subtle difference, through. The variable color in the first echo command is concatenated between two string constants and is evaluated as an expression, while in the second echo command the value of color is substituted into the string constant. The substitution may occur anywhere, even in places where expressions are not allowed.

It is important to differentiate between substitutions and expressions. Menu evaluates expressions after any substitution. Once substitution has been performed, the expression is evaluated. Hence, substitution may alter how expressions are evaluated. For example, had the set command in the above example been:

set color to "light "" blue"

the following echo commands would look as follows after substitution:

echo "The sky is " : color : " today."

echo "The sky is light" "blue today."

The second echo statement will not work. In this case, menu detects an invalid expression, stops execution of the menu commands and displays an error.