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


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

$Part3:
$File_is="MNU_MULTI.C"
$Check_Sum_is=455924233
$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 the main routines for handling multi menus */
X
X#include <descrip>
X#include <curses>
X#include "mnu_def"
X
Vvoid _mnu_draw_multi_page(menu_window, page, current_page, current_column, cur
Xrent_item)
X/* Draws a page for a multi menu on the screen. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item;
X{
X
Xint i, j;
X
X   for (i = 0; i < page[*current_page].num_columns; i++) {
X      for (j = 0; j < page[*current_page].column[i].num_items; j++) {
X         wmove(menu_window, j, page[*current_page].column[i].start_pos);
X         wprintw(menu_window, " %s", page[*current_page].column[i].item[j]);
X         if (page[*current_page].column[i].selected[j]) {
X            wprintw(menu_window, "* ");
X         } else {
X            wprintw(menu_window, "  ");
X         }
X      }
X   }
V   wmove(menu_window, *current_item, page[*current_page].column[*current_colum
Xn].start_pos);
X   wsetattr(menu_window, _REVERSE);
V   wprintw(menu_window, " %s", page[*current_page].column[*current_column].ite
Xm[*current_item]);
X   if (page[*current_page].column[*current_column].selected[*current_item]) {
X      wprintw(menu_window, "* ");
X   } else {
X      wprintw(menu_window, "  ");
X   }
X   wclrattr(menu_window, _REVERSE);
X   wrefresh(menu_window);
X}
X
Vvoid _mnu_multi_up(menu_window, page, current_page, current_column, current_it
Xem)
X/* Handles moving up one item in a multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item;
X{
X
V   *current_item = (*current_item == 0) ? (page[*current_page].column[*current
X_column].num_items - 1) : (*current_item - 1);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vvoid _mnu_multi_down(menu_window, page, current_page, current_column, current_
Xitem)
X/* Handles moving down one item in a multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item;
X{
X
V   *current_item = (*current_item == page[*current_page].column[*current_colum
Xn].num_items - 1) ? (0) :
V
X                    (*current_item + 1);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vvoid _mnu_multi_left(menu_window, page, current_page, current_column, current_
Xitem)
X/* Handles moving left one column in a multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item;
X{
X
V   *current_column = (*current_column == 0) ? (page[*current_page].num_columns
X - 1) : (*current_column - 1);
V   *current_item = (*current_item < page[*current_page].column[*current_column
X].num_items) ? (*current_item) :
V                                                      (page[*current_page].col
Xumn[*current_column].num_items - 1);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vvoid _mnu_multi_right(menu_window, page, current_page, current_column, current
X_item)
X/* Handles moving right one column in a multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item;
X{
X
V   *current_column = (*current_column == page[*current_page].num_columns - 1)
X? (0) : (*current_column + 1);
V   *current_item = (*current_item < page[*current_page].column[*current_column
X].num_items) ? (*current_item) :
V                                                      (page[*current_page].col
Xumn[*current_column].num_items - 1);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vvoid _mnu_multi_pgup(menu_window, page, current_page, current_column, current_
Xitem)
X/* Handles moving up one page in a multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item;
X{
X
V   *current_page = (*current_page == 0) ? (*current_page) : (*current_page - 1
X);
X   *current_column = 0;
X   *current_item = 0;
X   wclear(menu_window);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vvoid _mnu_multi_pgdn(menu_window, page, current_page, current_column, current_
Xitem, num_pages)
X/* Handles moving down one page in a multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item, *num_pages;
X{
X
V   *current_page = (*current_page == *num_pages - 1) ? (*current_page) : (*cur
Xrent_page + 1);
X   *current_column = 0;
X   *current_item = 0;
X   wclear(menu_window);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vvoid _mnu_multi_home(menu_window, page, current_page, current_column, current_
Xitem)
X/* Handles moving to the top item of the left column of the top page in a
X   multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item;
X{
X
X   *current_page = 0;
X   *current_column = 0;
X   *current_item = 0;
X   wclear(menu_window);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vvoid _mnu_multi_end(menu_window, page, current_page, current_column, current_i
Xtem, num_pages)
X/* Handles moving to the bottom item of the right column of the bottom page in
X   a multi menu. */
XWINDOW *menu_window;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item, *num_pages;
X{
X
X   *current_page = *num_pages - 1;
X   *current_column = page[*current_page].num_columns - 1;
X   *current_item = page[*current_page].column[*current_column].num_items - 1;
X   wclear(menu_window);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Xvoid _mnu_multi_refresh(title_window, border_window, menu_window, title, page,
Xcurrent_page, current_column, current_item, num_title_lines)
XWINDOW *title_window, *border_window, *menu_window;
Xchar **title;
Xstruct page_type *page;
Xint *current_page, *current_column, *current_item, *num_title_lines;
X{
X
Xint i;
X
X   wclear(title_window);
X   wclear(border_window);
X   wclear(menu_window);
X   for (i = 0; i < *num_title_lines; i++) {
X      wmove(title_window, i, 0);
X      wprintw(title_window, "%s", title[i]);
X   }
X   wrefresh(title_window);
X   wmove(border_window, 0, 1);
X   for (i = 0; i < COLS - 2; i++) {
X      wprintw(border_window, "=");
X   }
X   wrefresh(border_window);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X}
X
Vchar _mnu_multi(title_dsc, num_title_lines, menu_dsc, num_menu_lines, choice,
Xselect_dsc, num_select, end_select_dsc,
V                num_end_select, choices, current_page, current_column, current
X_item)
V/* Displays menu_dsc (num_menu_lines elements) as a menu on multiple pages in
Xmultiple columns with title_dsc (num_title_lines
V   elements).  Upon pressing of either the return key, the keypad enter key, o
Xr any key described in select_dsc (num_select
V   elements), the current index into the choices array is toggled (true to fal
Xse or false to true).  Upon pressing of any key
V   described in end_select_dsc (num_end_select elements), choice is returned (
X0..num_menu_lines) as an index into
V   menu_dsc->a_pointer.  current_page, current_column, current_item are genera
Xlly meaningless to the calling program, but they
X   can be used to keep track of the values across calls. */
Xstruct dsc$descriptor *title_dsc;
Xint *num_title_lines;
Xstruct dsc$descriptor *menu_dsc;
Xint *num_menu_lines, *choice;
Xstruct dsc$descriptor *select_dsc;
Xint *num_select;
Xstruct dsc$descriptor *end_select_dsc;
Xint *num_end_select;
Xstruct dsc$descriptor *choices;
Xint *current_page, *current_column, *current_item;
X{
X
Xstruct page_type *page;
Xchar **title;
Xint num_pages, menu_window_lines, vkbd, i, j, k;
Xunsigned short int c;
XWINDOW *title_window, *menu_window, *border_window;
Xchar *select, *end_select, ch;
X
X   initscr();
X   smg$create_virtual_keyboard(&vkbd);
X   menu_window_lines = LINES - *num_title_lines - 1;
V   _mnu_divide_menu(menu_dsc, num_menu_lines, &page, &num_pages, &menu_window_
Xlines, &COLS);
X   title = malloc(*num_title_lines * sizeof(char *));
X   _mnu_divide_title(title_dsc, num_title_lines, title);
X   select = malloc((*num_select + 1) * sizeof(char));
X   _mnu_divide_select(select_dsc, num_select, select);
X   end_select = malloc((*num_select + 1) * sizeof(char));
X   _mnu_divide_select(end_select_dsc, num_end_select, end_select);
X   _mnu_divide_selected(choices, page, num_pages);
X
X   title_window = newwin(*num_title_lines, COLS, 0, 0);
X   border_window = newwin(1, COLS, *num_title_lines, 0);
X   menu_window = newwin(menu_window_lines, COLS, *num_title_lines + 1, 0);
X
X   for (i = 0; i < *num_title_lines; i++) {
X      wmove(title_window, i, 0);
X      wprintw(title_window, "%s", title[i]);
X   }
X   wrefresh(title_window);
X   wmove(border_window, 0, 1);
X   for (i = 0; i < COLS - 2; i++) {
X      wprintw(border_window, "=");
X   }
X   wrefresh(border_window);
V   _mnu_draw_multi_page(menu_window, page, current_page, current_column, curre
Xnt_item);
X
X   while (TRUE) {
X      smg$read_keystroke(&vkbd, &c);
X      ch = (char) c;
X
V      if ((( c < 256) && ((strchr(select, ch)) || (c == 13))) || (c == SMG$K_T
XRM_ENTER)) {
X         page[*current_page].column[*current_column].selected[*current_item] =
V            (page[*current_page].column[*current_column].selected[*current_ite
Xm]) ? 0 : 1;
V         _mnu_draw_multi_page(menu_window, page, current_page, current_column,
X current_item);
X      } else if ((c < 256) && (strchr(end_select, ch))) {
X         _mnu_undivide_selected(choices, page, num_pages);
X         *choice = 0;
X         for (i = 0; i < *current_page; i++) {
X            for (j = 0; j < page[i].num_columns; j++) {
X               *choice += page[i].column[j].num_items;
X            }
X         }
X         for (i = 0; i < *current_column; i++) {
X            *choice += page[*current_page].column[i].num_items;
X         }
X         *choice += *current_item;
X
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                  free(page[i].column[j].item[k]);
X               }
X               free(page[i].column[j].item);
X               free(page[i].column[j].selected);
X            }
X            free(page[i].column);
X         }
X         free(page);
X         for (i = 0; i < *num_title_lines; i++) {
X            free(title[i]);
X         }
X         free(title);
X         free(select);
X         free(end_select);
X         endwin();
X         return(ch);
X      }
X
X      switch (c) {
V         case SMG$K_TRM_UP   : _mnu_multi_up(menu_window, page, current_page,
Xcurrent_column, current_item); break;
V         case SMG$K_TRM_KP8  : _mnu_multi_up(menu_window, page, current_page,
Xcurrent_column, current_item); break;
V         case '8'            : _mnu_multi_up(menu_window, page, current_page,
Xcurrent_column, current_item); break;
X
V         case SMG$K_TRM_DOWN : _mnu_multi_down(menu_window, page, current_page
X, current_column, current_item); break;
V         case SMG$K_TRM_KP2  : _mnu_multi_down(menu_window, page, current_page
X, current_column, current_item); break;
V         case '2'            : _mnu_multi_down(menu_window, page, current_page
X, current_column, current_item); break;
X
V         case SMG$K_TRM_LEFT : _mnu_multi_left(menu_window, page, current_page
X, current_column, current_item); break;
V         case SMG$K_TRM_KP4  : _mnu_multi_left(menu_window, page, current_page
X, current_column, current_item); break;
V         case '4'            : _mnu_multi_left(menu_window, page, current_page
X, current_column, current_item); break;
X
V         case SMG$K_TRM_RIGHT: _mnu_multi_right(menu_window, page, current_pag
Xe, current_column, current_item); break;
V         case SMG$K_TRM_KP6  : _mnu_multi_right(menu_window, page, current_pag
Xe, current_column, current_item); break;
V         case '6'            : _mnu_multi_right(menu_window, page, current_pag
Xe, current_column, current_item); break;
X
V         case SMG$K_TRM_KP9  : _mnu_multi_pgup(menu_window, page, current_page
X, current_column, current_item); break;
V         case '9'            : _mnu_multi_pgup(menu_window, page, current_page
X, current_column, current_item); break;
X
V         case SMG$K_TRM_KP3  : _mnu_multi_pgdn(menu_window, page, current_page
X, current_column, current_item, &num_pages); break;
V         case '3'            : _mnu_multi_pgdn(menu_window, page, current_page
X, current_column, current_item, &num_pages); break;
X
V         case SMG$K_TRM_KP7  : _mnu_multi_home(menu_window, page, current_page
X, current_column, current_item); break;
V         case '7'            : _mnu_multi_home(menu_window, page, current_page
X, current_column, current_item); break;
X
V         case SMG$K_TRM_KP1  : _mnu_multi_end(menu_window, page, current_page,
X current_column, current_item, &num_pages); break;
V         case '1'            : _mnu_multi_end(menu_window, page, current_page,
X current_column, current_item, &num_pages); break;
X
X         case SMG$K_TRM_CTRLR : smg$repaint_screen (stdpb); break;
X         case SMG$K_TRM_CTRLW : smg$repaint_screen (stdpb); break;
X      }
X   }
X}
$GoSub Convert_File
$Goto Part4

