From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP 11-OCT-1988 10:44
To:	ARISIA::EVERHART
Subj:	MENU 2 OF 4


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Mon, 10 OCT 88 22:09:38 PDT
Received: from CUNYVM.CUNY.EDU by KL.SRI.COM with TCP; Mon, 10 Oct 88 21:52:27 PDT
Received: from LOYVAX.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 7363; Mon, 10 Oct 88 23:42:55 EDT
Date:     Mon, 10 Oct 88 23:42 EDT
From:     MARKUS%LOYVAX.BITNET@CUNYVM.CUNY.EDU
Subject:  MENU 2 OF 4
To:       INFO-VAX@KL.SRI.COM
X-Original-To:  INFO-VAX@KL.SRI.COM, MARKUS

$Part2:
$File_is="MNU.DOC"
$Check_Sum_is=90637797
$Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X
X`009These menu routines are designed to give a standard menu interface
Xto any program.  At present, two versions of the menuing system are available:
Xsingle choice menus which allow one choice from the menu, and multiple choice
Xmenus which allow the user to choose from a number of items in the menu.
XFeatures include automatic positioning of the menu items on the screen,
Xmultiple page and column format, context positioning of the current item,
Xand pre-selection of items on multiple choice menus.
X
X*****************************************************************************
X
X_mnu_single(title_dsc, num_title_lines, menu_dsc, num_menu_lines, choice,
V            select_dsc, num_select, current_page, current_column, current_item
X)
X
XReturns a character (byte) that corresponds to the character entered to exit
Xfrom the menu.  If the keypad enter is used, ASCII 13 is returned.
X
XArguments:
X
Xtitle_dsc`009Descriptor pointing to an array of strings containing the lines
X`009`009of the title.
X
Vnum_title_lines`009Integer containing the number of lines in the title passed
Xby
X`009`009reference.
X
Xmenu_dsc`009Descriptor pointing to an array of strings containing the items
X`009`009of the menu.
X
Xnum_menu_lines`009Integer containing the number of items in the menu passed by
X`009`009reference.
X
Xchoice`009`009Integer returning the index into menu_dsc->dsc$a_pointer
X`009`009(0..num_menu_lines) upon exiting the menu passed by reference.
X
Xselect_dsc`009Descriptor pointing to a string of the characters that describe
X`009`009the valid characters for exiting the menu.  (In addition,
X`009`009<RETURN> and the keypad <ENTER> are assumed to be valid.)
X
Xnum_select`009Integer containing the number of characters pointed to by
X`009`009select_dsc passed by reference.
X
Vcurrent_page`009Integer containing the current page to be used when the menu i
Xs
X`009`009started passed by reference.
X
Vcurrent_column`009Integer containing the current column to be used when the me
Xnu
X`009`009is started passed by reference.
X
Vcurrent_item`009Integer containing the current item to be used when the menu i
Xs
X`009`009started passed by reference.
X
X******************************************************************************
X
X_mnu_multi(title_dsc, num_title_lines, menu_dsc, num_menu_lines, choice,
X           select_dsc, num_select, end_select_dsc, num_end_select, choices,
X           current_page, current_column, current_item)
X
XReturns a character (byte) that corresponds to the character entered to exit
Xfrom the menu.
X
XArguments:
X
Xtitle_dsc`009Descriptor pointing to an array of strings containing the lines
X`009`009of the title.
X
Vnum_title_lines`009Integer containing the number of lines in the title passed
Xby
X`009`009reference.
X
Xmenu_dsc`009Descriptor pointing to an array of strings containing the items
X`009`009of the menu.
X
Xnum_menu_lines`009Integer containing the number of items in the menu passed by
X`009`009reference.
X
Xchoice`009`009Integer returning the index into menu_dsc->dsc$a_pointer
X`009`009(0..num_menu_lines) upon exiting the menu passed by reference.
X
Xselect_dsc`009Descriptor pointing to a string of the characters that describe
X`009`009the valid characters for selecting items in the menu.  (In
X`009`009addition, <RETURN> and the keypad <ENTER> are assumed to be
X`009`009valid.)
X
Xnum_select`009Integer containing the number of characters pointed to by
X`009`009select_dsc passed by reference.
X
Vend_select_dsc`009Descriptor pointing to a string of the characters that descr
Xibe
X`009`009the valid characters for exiting the menu.
X
Xnum_end_select`009Integer containing the number of characters pointed to by
X`009`009end_select_dsc passed by reference.
X
Vcurrent_page`009Integer containing the current page to be used when the menu i
Xs
X`009`009started passed by reference.
X
Vcurrent_column`009Integer containing the current column to be used when the me
Xnu
X`009`009is started passed by reference.
X
Vcurrent_item`009Integer containing the current item to be used when the menu i
Xs
X`009`009started passed by reference.
X
X/* Copyright 1988 Markus Plummer
X   This package may be freely distributed with the restriction that proper
X   credit is given to the author and that neither Markus Plummer nor Loyola
X   College is held responsible for any problems incurred through the use of
X   this package. (I did my best anyway.) */
$GoSub Convert_File
$File_is="MNU_DEF.H"
$Check_Sum_is=1745891659
$Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X/* Copyright 1988 Markus Plummer
X   This package may be freely distributed with the restriction that proper
X   credit is given to the author and that neither Markus Plummer nor Loyola
X   College is held responsible for any problems incurred through the use of
X   this package. (I did my best anyway.) */
X
X/* This file contains two structures common two all menu types... */
Xstruct column_type {             /* Holds items and info for each column. */
X   int start_pos;                /* Where the column begins on the screen. */
X   int num_items;                /* The number of items in the column. */
V   char *selected;               /* Array of boolean.  Is the item selected? *
X/
X   char **item;                  /* The array of strings. */
X};
X
Xstruct page_type {               /* Holds columns and info for each page. */
X   int num_columns;              /* Number of columns on the page. */
X   struct column_type *column;   /* The array of actual columns. */
X};
$GoSub Convert_File
$File_is="MNU_DIVIDE.C"
$Check_Sum_is=50601815
$Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X/* Copyright 1988 Markus Plummer
X   This package may be freely distributed with the restriction that proper
X   credit is given to the author and that neither Markus Plummer nor Loyola
X   College is held responsible for any problems incurred through the use of
X   this package. (I did my best anyway.) */
X
V/* This file contains the routines which break the one dimensional array of it
Xems
X   into pages of columns. */
X#include <descrip>
X#include <curses>
X#include "mnu_def"
X
Vvoid _mnu_divide_menu(menu_list, num_items, page, num_pages, win_height, win_w
Xidth)
X/* Divides the menu items in menu_list (descriptor in contiguous array format
X   into page the page array. */
Xstruct dsc$descriptor *menu_list;
Xint *num_items;
Xstruct page_type **page;
Xint *num_pages, *win_height, *win_width;
X{
X
Xint total_columns, current_column, offset, max_len, local_max_len, i, j, k, l;
Xshort int data_size, data_length;
Xchar data_type;
Xchar *current_ptr, *tmp;
X
X   /* First figure out what kind of descriptor we are working with. */
X   data_type = menu_list->dsc$b_dtype;
V   data_size = (data_type == DSC$K_DTYPE_VT) ? (menu_list->dsc$w_length + 2) :
X (menu_list->dsc$w_length);
X   if (data_type == DSC$K_DTYPE_VT) {
X      max_len = 0;
X      for (i = 0; i < *num_items; i++) {
V         max_len = (menu_list->dsc$a_pointer[i*data_size] > max_len) ? (menu_l
Xist->dsc$a_pointer[i*data_size]) : (max_len);
X      }
X   } else {
X      max_len = data_size;
X   }
X   tmp = malloc(max_len + 1);
X
X   /* Then figure out the layout of the items. */
X   total_columns = ((*num_items - 1) / *win_height) + 1;
X   *num_pages = ((total_columns - 1) / (*win_width / (max_len + 3))) + 1;
X   current_column = 0;
X   current_ptr = menu_list->dsc$a_pointer;
X   *page = malloc(*num_pages * sizeof(struct page_type));
X   for (i = 0; i < *num_pages; i++) {
X      if (data_type == DSC$K_DTYPE_VT) {
X         local_max_len = 0;
X         for (j = 0; j < *num_items; j++) {
V            local_max_len = (menu_list->dsc$a_pointer[j * data_size] > local_m
Xax_len) ? (menu_list->dsc$a_pointer[j * data_size]) : (local_max_len);
X         }
X      } else {
X         local_max_len = data_size;
X      }
V      (*page)[i].num_columns = (total_columns % *num_pages > i) ? ((total_colu
Xmns / *num_pages) + 1) :
V                                                                 (total_column
Xs / *num_pages);
V      (*page)[i].column = malloc((*page)[i].num_columns * sizeof(struct column
X_type));
X      for (j = 0; j < (*page)[i].num_columns; j++) {
V         (*page)[i].column[j].start_pos = (*win_width / 2) - (((*page)[i].num_
Xcolumns * (local_max_len + 3)) / 2) + ((local_max_len + 3) * j);
V         (*page)[i].column[j].num_items = (*num_items % total_columns > curren
Xt_column) ? ((*num_items / total_columns) + 1) :
V
X          (*num_items / total_columns);
X         current_column++;
V         (*page)[i].column[j].item = malloc((*page)[i].column[j].num_items * s
Xizeof(char *));
X
X/* Actually copy the data from the descriptor to the item in the column in the
X   page. */
X         for (k = 0; k < (*page)[i].column[j].num_items; k++) {
X            if (data_type == DSC$K_DTYPE_VT) {
X               data_length = current_ptr[0];
X               offset = 2;
X            } else {
X               data_length = data_size;
X               offset = 0;
X            }
X            for (l=0; l < data_length; l++) {
X               tmp[l] = current_ptr[l + offset];
X            }
X            tmp[l] = '\0';
X            current_ptr = current_ptr + data_size;
X            (*page)[i].column[j].item[k] = malloc(strlen(tmp));
X            strcpy((*page)[i].column[j].item[k], tmp);
X         }
X      }
X   }
X   free(tmp);
X}
X
Xvoid _mnu_divide_title(title_list, num_title_lines, title)
X/* Decodes the descriptored array of strings (contiguous format) title_list
X   into a C format array of strings title. */
Xstruct dsc$descriptor *title_list;
Xint *num_title_lines;
Xchar **title;
X{
X
Xint k, l, offset, data_size, data_length;
Xchar data_type, *tmp, *current_ptr;
X
X   data_type = title_list->dsc$b_dtype;
V   data_size = (data_type == DSC$K_DTYPE_VT) ? (title_list->dsc$w_length + 2)
X: (title_list->dsc$w_length);
X   tmp = malloc(data_size + 1);
X   current_ptr = title_list->dsc$a_pointer;
X   for (k = 0; k < *num_title_lines; k++) {
X      if (data_type == DSC$K_DTYPE_VT) {
X         data_length = current_ptr[0];
X         offset = 2;
X      } else {
X         data_length = data_size;
X         offset = 0;
X      }
X      for (l=0; l < data_length; l++) {
X         tmp[l] = current_ptr[l + offset];
X      }
X      tmp[l] = '\0';
X      current_ptr = current_ptr + data_size;
X      title[k] = malloc(strlen(tmp));
X      strcpy(title[k], tmp);
X   }
X   free(tmp);
X}
X
Xvoid _mnu_divide_select(select_list, num_select, select)
X/* Decodes the descriptored array of characters select_list that defines the
X   keys that select into the C array select. */
Xstruct dsc$descriptor *select_list;
Xint *num_select;
Xchar *select;
X{
Xint i, offset;
Xchar *current_ptr;
X
X   current_ptr = select_list->dsc$a_pointer;
X   if (select_list->dsc$b_dtype == DSC$K_DTYPE_VT) {
X      offset = 2;
X   } else {
X      offset = 0;
X   }
X   for (i = 0; i < *num_select; i++) {
X      select[i] = current_ptr[i + offset];
X   }
X   select[i] = '\0';
X}
X
X_mnu_divide_selected(choices, page, num_pages)
X/* Decodes the descriptored boolean array choices into the corresponding pages
X   so they match up w/ their items. */
Xstruct dsc$descriptor *choices;
Xstruct page_type *page;
Xint num_pages;
X{
X
Xint i, j, k, l;
X
X   l = 0;
X   for (i = 0; i < num_pages; i++) {
X      for (j = 0; j < page[i].num_columns; j++) {
V         page[i].column[j].selected = malloc(page[i].column[j].num_items * siz
Xeof(char));
X         for (k = 0; k < page[i].column[j].num_items; k++) {
X            page[i].column[j].selected[k] = choices->dsc$a_pointer[l++];
X         }
X      }
X   }
X}
X
X_mnu_undivide_selected(choices, page, num_pages)
X/* Copies the data in the pages for what items are and aren't selected back
X   into the descriptored boolean array choices). */
Xstruct dsc$descriptor *choices;
Xstruct page_type *page;
Xint num_pages;
X{
X
Xint i, j, k, l;
X
X   l = 0;
X   for (i = 0; i < num_pages; i++) {
X      for (j = 0; j < page[i].num_columns; j++) {
X         for (k = 0; k < page[i].column[j].num_items; k++) {
X            choices->dsc$a_pointer[l++] = page[i].column[j].selected[k];
X         }
X      }
X   }
X}
$GoSub Convert_File
$Goto Part3

