|
|
The menu driver checks whether the virtualized character passed to it is an ETI menu request. If so, it performs the request and reports the results. If the character is not a menu request, the menu driver checks if the character is data, that is, a printable ASCII character. If so, it enters the character in the pattern buffer and looks for the first match among the item names. If no match is found, the menu driver deletes the character from the pattern buffer and returns E_NO_MATCH. If the character is not recognized as a menu request or data, the menu driver assumes the character is an application-defined command and returns E_UNKNOWN_COMMAND.
To illustrate a sample design for calling the menu driver, we will consider a program that permits interaction with a menu of astrological signs. ``Sample menu output (2)'' displays the menu.
+-----------------------------+ | Aries The Ram | | Taurus The Bull | | Gemini The Twins | | Cancer The Crab | | Leo The Lion | | Virgo The Virgin | | Libra The Balance | | Scorpio The Scorpion | | Sagittarius The Archer | | Capricorn The Goat | | Aquarius The Water Bearer| | Pisces The Fishes | +-----------------------------+
Sample menu output (2)
You have already seen much of the astrological sign program in previous examples. Its function get_request, for instance, appeared in ``Sample routine that translates keys into menu requests''. ``Sample program calling the menu driver'' shows its remaining routines.
/* This program displays a sample menu.Omitted here are the key mapping defined by get_request; application-defined routines display_menu and erase_menu; and the curses initialization routine start_curses */
#include <string.h> #include <menu.h>
static char * PGM = (char *) 0; /* program name */
static int my_driver (m, c) /* handle application commands */ MENU * m; int c; { switch (c) { case QUIT: return TRUE; break; } beep (); /* signal error */ return FALSE; }
main (argc, argv) int argc; char * argv[]; { WINDOW * w; MENU * m; ITEM ** i; ITEM ** make_items (); void free_items (); int c, done = FALSE;
PGM = argv[0]; start_curses ();
if (! (m = new_menu (make_items ()))) error ("error return from new_menu", NULL);
display_menu (m);
/* interact with user */
w = menu_win (m);
while (! done) { switch (menu_driver (m, c = get_request (w))) { case E_OK: break; case E_UNKNOWN_COMMAND: done = my_driver (m, c); break; default: beep (); /* signal error */ break; } } erase_menu (m); end_curses (); i = menu_items (m); free_menu (m); free_items (i); exit (0); }
typedef struct { char * name; char * desc; } ITEM_RECORD;
/* item definitions */
static ITEM_RECORD signs [] = { "Aries", "The Ram", "Taurus", "The Bull", "Gemini", "The Twins", "Cancer", "The Crab", "Leo", "The Lion", "Virgo", "The Virgin", "Libra", "The Balance", "Scorpio", "The Scorpion", "Sagittarius", "The Archer", "Capricorn", "The Goat", "Aquarius", "The Water Bearer", "Pisces", "The Fishes", (char *) 0, (char *) 0, };
#define MAX_ITEM 512
static ITEM * items [MAX_ITEM + 1]; /* item buffer */
static ITEM ** make_items () /* create the items */ { int i;
for (i = 0; i < MAX_ITEM && signs[i].name; ++i) items[i] = new_item (signs[i].name, signs[i].desc);
items[i] = (ITEM *) 0; return items; }
static void free_items (i) /* free the items */ ITEM ** i; { while (*i) free_item (*i++); }
Sample program calling the menu driver
Function main first calls the application-defined routine make_items to create the items from the array signs. The value returned is passed to new_menu to create the menu. Function main then initializes curses using start_curses and displays the menu using display_menu.
In its while loop, main repeatedly calls menu_driver with the character returned by get_request. If the menu driver does not recognize the character as a request or data, it returns E_UNKNOWN_COMMAND, whereupon the application-defined routine my_driver is called with the same character. Routine my_driver processes the application-defined commands. In this example, there is only one, QUIT. If the character passed does not signify QUIT, my_driver signals an error and returns FALSE and the signal prompts the user to re-enter the character. If the character passed is the QUIT character, my_driver returns TRUE. In turn, this sets done to TRUE, and the while loop is exited.
Finally, main erases the menu, terminates low-level ETI (curses), frees the menu and its items, and exits the program.
This example shows a typical design for calling the menu driver, but it is only one of several ways you can structure a menu application.
If the menu_driver recognizes and processes the input character argument, it returns E_OK. In the following error situations, the menu_driver returns the indicated value: