spec

Software for Diffraction

spec_menu()

create interactive menu from specifications

DESCRIPTION

The spec_menu() function creates interactive menus that can be used for configuring macros and other spec options. When the menu is active, the user can use arrow and control keys to navigate the options and edit strings.

While waiting for input in spec_menu(), spec will continue to poll hardware and respond to client commands if in server mode, just as spec does while waiting for input at the main command prompt.

USAGE

spec_menu(menu [, modes [, dumbterm]])

The menu argument is a two-dimensional associative array that completely describes the menu as detailed below. The first index of the array is a number that identifies an item. The second index of the array is a string that matches one of a set of keys that identify an attribute for the item. The value of the array element depends on the key.

The optional modes argument is a single value where each bit can be associated with a menu item. Up to 52 items may have associated bits.

If the number of menu items plus the number of lines needed to display the hints and "info" strings is greater than the number of rows in the terminal window, the menu items will be scrollable. The number of additional lines above or below the visible window will be displayed in the left of the screen. Navigating past the top or bottom will automatically scroll the menu.

If the width of the menu is greater than the width of the window, the menu items will be compressed or scrolled horizontally, to fit the available space. If the window is resized while within spec_menu(), the ^L command will redraw the window using the new size.

If dumbterm is nonzero, spec_menu() will not use cursor positioning. Instead, the menu options will be displayed one at a time in sequence and the user will be prompted for a value. In this mode, entering a single - for any response will jump back and prompt again for the previous item in the sequence.

The function will return a possibly modified value for modes, reflecting the user's choices. In addition, menu array elements associated with certain items will contain possibly modified values. See RETURN VALUES below. If the menu is exited with ^C or the x command, the values of the menu items on entry are restored.

TEXT FORMATTING

The strings for the "title", "head", "subhead", "desc", "text" and "info" attributes can include instances of the special sequence "\[xx]" where xx is one of the following:

"so" start text stand-out mode.
"se" end text stand-out mode.
"md" start bold (intensified) mode.
"me" end bold mode.
"us" start underline mode.
"ue" end underline mode.
"mb" start blink mode (if you want to annoy).
"mh" start half-bright mode.
"mr" start reverse video mode.

The "se" sequence turns off all modes and is the only way to turn off blink, half bright and reverse video. Half-bright mode is unlikely to be effective on xterm-like windows. The bold, half-bright, reverse, underline and blink modes can be combined. Only bold and underline can be selectively disabled.

RETURN VALUES

On a normal return with the q or ^D keys, spec_menu() will return an updated value for modes that reflects the new values of all the "bit" items. In addition, new values for "value", "svalue" and variables passed indirectly using "@" will be assigned. Elements for "alist" arrays will be changed to reflect which have been toggled on or off. Finally, for any items that have been modified, an element will be added to the menu array with a second index named "updated" and a value set to one.

COMMAND SUMMARY

     
  When Editing a Value  
     
  ^A Go to beginning of entry
  ^E Go to end of entry
  ^B or left arrow Backup one space
  ^F or right arrow Forward one space
  ^H Backward delete
  ^D Forward delete
  ^U Delete to beginning of entry
  ^K Delete to end of entry
     
  When Editing a List  
     
  <space> Select current element of list
  ^A Go to start of list
  ^E Go to end of list
  ^B or left arrow Go to previous element of list
  ^F or right arrow Go to next element of list
  ^R Set all elements in "alist"
  ^K Unset elements from next to end of "alist"
  ^U Unset elements from current to start of "alist"
     
  When Navigating the Menu  
     
  ^G Go to first item in menu
  ^J or <newline> Enters current value and moves to next
  ^M or <return> Enters current value and moves to next
  ^I or ^] or <tab> Enters current value and cycles to next sibling
  ^[ or <esc> Enters current value and cycles to previous sibling
  ^P or up arrow Previous row
  ^N or down arrow Next row
  ^L Redisplay screen
  ^D or q Save changed and exit menu
  ^C or x Abandon changes and exit menu

EXAMPLES

The standard spec macros setplot, setshow, mstartup, fly_setup and plotselect all use the spec_menu() function. Here is another example:

 def menu1 '{
     local i, menu[], modes
     local   group_size

     modes = 1
     group_size = 512
     menu[++i]["title"] = "Menu Example"
     menu[++i]["width"] = 90
     menu[++i]["desc"] = "Enable List Examples:"
     menu[  i]["bit"] = 0x0001

     menu[++i]["desc"] = "  List Example 1:"
     menu[  i]["bit_and"] = 0x0001
     menu[  i]["list"] = "Now is the time for all good men"
     menu[  i]["svalue"] = "time"

     menu[++i]["desc"] = "  List Example 2:"
     menu[  i]["bit_and"] = 0x0001
     menu[  i]["list"] = "The quick::brown fox::jumps over::the lazy dog"
     menu[  i]["delim"] = "::"
     menu[  i]["value"] = 3

     menu[++i]["desc"] = "  List Example 3:"
     menu[  i]["bit_and"] = 0x0001
     menu[  i]["list"] = "128 256 512 1024 2048 4096 8192"
     menu[  i]["@"] = "group_size"

     menu[++i]["desc"] = ""
     menu[++i]["desc"] = "Use logarithmic y-axis?"
     menu[  i]["bit"]     = PL_YLOG
     menu[++i]["desc"] = "Force y-axis minimum to zero?"
     menu[  i]["bit"]     = PL_YZERO
     menu[  i]["bit_not"] = PL_YLOG

     menu[++i]["desc"] = "Enter a random value:"
     menu[  i]["value"] = rand()

     modes = spec_menu(menu, modes)

     print modes, group_size, menu[i]["value"]
}'

Here is an example using the various ways to describe a family:

def menu2 '{
     local i, parent, modes, menu[], fam_num
     local   home_dirs[], par_val[], par2_val[]

     menu[++i]["desc"] = "Choose family members by ID:"
     menu[  i]["family"] = "tth th chi phi"
     parent = i

     menu[++i]["desc"] = " Configure motor home direction:"
     menu[  i]["parent"] = parent
     menu[  i]["value"] = "home_dirs"
     menu[  i]["toggle"] = 1
     menu[  i]["choices"] = "cw:ccw"

     menu[++i]["desc"] = "Choose family members by count:"
     menu[  i]["family"] = fam_num
     parent = i

     menu[++i]["desc"] = " Value for parameter?"
     menu[  i]["parent"] = parent
     menu[  i]["value"] = "par_val"

     local   fam_array[] = [ 0:"zzz":0, 1:"yyy":1, 2:"xxx":0, 3:"vvv":1, 4:"uuu":0 ]
     menu[++i]["desc"] = "Choose allowed siblings for family:"
     menu[  i]["alist"] = "fam_array"

     menu[++i]["desc"] = "Choose family member by \"alist\":"
     menu[  i]["family"] = "fam_array"
     parent = i

     menu[++i]["desc"] = " Values for sibling?"
     menu[  i]["parent"] = parent
     menu[  i]["value"] = "par2_val"

     spec_menu(menu, modes)

     print fam_array, home_dirs, par_val, par2_val
}'