home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************/
- /* File Id. Tmenu.C */
- /* Author. Chris Balthrop */
- /* from Lmenu.c by Stan Milam. */
- /* Date Written. 09oct91 */
- /* */
- /* */
- /* Comments: The routines in this file allow the creation*/
- /* and use of Top line style menus. Moreover, more than */
- /* one Top menu per window is allowed. More than one menu */
- /* can be stacked into one window. The Mouse can be used */
- /* to make selection and scroll the menus or the arrow & */
- /* PgDn/PgUp keys can be used. Home & End keys move to */
- /* first and last menus respectively. */
- /**********************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <conio.h>
- #include "pcw.i"
- #include "pcwproto.h"
- #include "keys.h"
- #include "menu.h"
-
- #define MSGROW 2
- #define ITEMROW 1
-
- /* Prototype the internal functions */
-
- static void change_menu(TMNUTYPE *menu);
- static void change_bar_pos(TMNUTYPE *menu, int crnt_bar);
- static int search_menu(TMNUTYPE *menu, int select_char);
- static int search_mouse_select(TMNUTYPE *menu, int col);
- static int get_max_bars(TMNUFLDS *ttmp);
-
- /***********************************************************/
- /* Maketmenu */
- /* */
- /* This function when invoked will draw the Top style menu */
- /* pointed to by *menu. See the TMNUTYPE definition in */
- /* menu.h. */
- /***********************************************************/
-
- WNDPTR *maketmenu(TMNUTYPE *menu) {
-
- MENU_WND *twnd; /* Pointer to menu window */
-
- twnd = &menu->twnd; /* Establish adressablity */
- setborder(twnd->btype); /* Set borders & colors */
- titlecolor(twnd->tfclr, twnd->tbclr);
- bordercolor(twnd->bfclr, twnd->bbclr);
-
- /* Frame the menu window and store handle in menu structure */
- twnd->wnd = wframe(twnd->urow, twnd->ucol,
- twnd->lrow, twnd->lcol,
- twnd->fcolor, twnd->bcolor);
-
- /* Check to see of okay */
- if (twnd->wnd == NULL) return(NULL);
-
- /* Wframe may have adjusted boundries */
- twnd->urow = twnd->wnd->urow;
- twnd->ucol = twnd->wnd->ucol;
- twnd->lrow = twnd->wnd->lrow;
- twnd->lcol = twnd->wnd->lcol;
-
- /* Draw the arrows */
- qputchar(twnd->urow+1,twnd->ucol,twnd->bfclr,twnd->bbclr,24);
- qputchar(twnd->urow+1,twnd->lcol,twnd->bfclr,twnd->bbclr,25);
-
- /* Title wnd, Fill window with menu contents & return */
- wtitle(twnd->wnd, twnd->tvloc, twnd->thloc, twnd->title);
- change_menu(menu);
- return(twnd->wnd);
- }
-
- /***********************************************************/
- /* TmenuInput */
- /* */
- /* When invoked will manipulate Top style menu. Returns */
- /* the select_key in the TMNUFLDS. */
- /***********************************************************/
-
- int tmenuinput(TMNUTYPE *menu) {
-
- TMNUFLDS *ttmp, **stmp; /* Pointers to menus */
- MENU_WND *twnd; /* Pointer the menu parms */
- int ch; /* For keyin() function */
- int max_bars, max_menus; /* How many menus & bars */
- int crnt_wnd, crnt_bar; /* Keep track menus & bars */
- int row, col, bstatus; /* For Mouse */
-
- stmp = (TMNUFLDS **) menu->tlist;
- ttmp = stmp[menu->wnd_pos]; /* Get address of 1st menu */
- twnd = &menu->twnd; /* Get address of wnd parms */
-
- if (mpresent) hide_mouse(); /* Turn the mouse off so */
- re_order(twnd->wnd,NORMAL); /* We can reorder the windows */
- if (mpresent) show_mouse(); /* And finally turn it on */
- for (max_menus = 0;stmp[max_menus] != NULL;max_menus++);
- max_menus--; /* and adjust */
- max_bars = get_max_bars(ttmp); /* Get # selects this menu */
- if (mpresent) show_mouse(); /* Turn on the mouse */
-
- for(;;) { /* Loop forever */
- crnt_bar = menu->bar_pos; /* Track current bar pos */
- crnt_wnd = menu->wnd_pos; /* And menu position */
-
- ch = keyin();
- switch (ch) { /* Which one? */
- case ENTER : /* Selects bar pos */
- case BOTH_MOUSE_KEY :
- return(ttmp[menu->bar_pos].select_key);
- case RITE_MOUSE_KEY :
- if (menu->wnd_pos == 0) break;
- menu->bar_pos = menu->wnd_pos = 0;
- change_menu(menu);
- ttmp = stmp[0];
- max_bars = get_max_bars(ttmp);
- break;
- case LEFT_MOUSE_KEY :
- get_mpos(&row, &col, &bstatus);
- if (row == twnd->wnd->urow+1) { /* Select row? */
- /* If hot spot */
- if (search_mouse_select(menu, col)) {
- change_bar_pos(menu,crnt_bar); /* Change */
- /* return */
- return(ttmp[menu->bar_pos].select_key);
- }
- else {
- if (col == twnd->wnd->ucol) { /* Up arrow? */
- menu->wnd_pos--; /* Decrement menu index */
- if (menu->wnd_pos < 0) /* Check if okay */
- /* No - last menu */
- menu->wnd_pos = max_menus;
- menu->bar_pos = 0; /* First bar pos */
- change_menu(menu); /* Next menu */
- /* Address new menu */
- ttmp = stmp[menu->wnd_pos];
- /* # bars new menu */
- max_bars = get_max_bars(ttmp);
- }
- else { /* Down arrow */
- if (col == twnd->wnd->lcol) {
- menu->wnd_pos++;
- if (stmp[menu->wnd_pos] == NULL)
- menu->wnd_pos = 0;
- menu -> bar_pos = 0;
- change_menu(menu);
- ttmp = stmp[menu->wnd_pos];
- max_bars = get_max_bars(ttmp);
- }
- }
- }
- }
- break;
- case LEFTARROW : /* Prev bar pos */
- case SHFTTAB :
- menu->bar_pos--;
- if (menu->bar_pos < 0) /* Check if < 0 */
- menu->bar_pos = max_bars; /* Set to max bar */
- change_bar_pos(menu, crnt_bar); /* Change bar pos */
- break;
- case RITEARROW : /* Next bar position */
- case TAB :
- menu->bar_pos++; /* Bump & check */
- if (ttmp[menu->bar_pos].select_key == 0)
- menu->bar_pos = 0; /* First one if at end */
- change_bar_pos(menu, crnt_bar); /* Change bars */
- break;
- case UPARROW : /* Prev Menu */
- case PGUP:
- if (max_menus == 0) break;
- menu->wnd_pos--; /* Decrement menu index */
- if (menu->wnd_pos < 0) menu->wnd_pos = max_menus;
- menu->bar_pos = 0; /* Set bar index to first */
- change_menu(menu); /* Put out new menu */
- ttmp = stmp[menu->wnd_pos]; /* Address new menu */
- max_bars = get_max_bars(ttmp); /* Count selections */
- break;
- case DOWNARROW : /* Next menu */
- case PGDN:
- if (max_menus == 0) break;
- menu->wnd_pos++; /* Bump menu index */
- if (stmp[menu->wnd_pos] == NULL) /* See if at end */
- menu->wnd_pos = 0; /* And set to first */
- menu->bar_pos = 0; /* First bar of menu */
- change_menu(menu); /* Put out new menu */
- ttmp = stmp[menu->wnd_pos]; /* Address new menu */
- max_bars = get_max_bars(ttmp);/* Count the selects */
- break;
- case HOME : /* First menu */
- case ESC :
- if (menu->wnd_pos == 0) break;
- menu->bar_pos = menu->wnd_pos = 0;
- change_menu(menu);
- ttmp = stmp[0];
- max_bars = get_max_bars(ttmp);
- break;
- case END: /* Last Menu */
- if (menu->wnd_pos == max_menus) break;
- menu->bar_pos = 0;
- menu->wnd_pos = max_menus;
- change_menu(menu);
- ttmp = stmp[menu->wnd_pos];
- max_bars = get_max_bars(ttmp);
- break;
- default :
- if (search_menu(menu, ch)) { /* Search for select match */
- if (crnt_wnd != menu->wnd_pos) { /* In another menu? */
- change_menu(menu); /* Put out new menu */
- ttmp = stmp[menu->wnd_pos]; /* Address new menu */
- return(ttmp[menu->bar_pos].select_key); /* Return */
- }
- if (crnt_bar != menu->bar_pos) { /* Same menu,dif bar */
- change_bar_pos(menu, crnt_bar); /* Chg bar pos */
- return(ttmp[menu->bar_pos].select_key); /* Return */
- }
- else /* Must be crnt bar so return */
- return(ttmp[menu->bar_pos].select_key);
- }
- }
- }
- #ifndef __TURBOC__
- return 0;
- #endif
- }
-
- /***********************************************************/
- /* Change_Menu */
- /* */
- /* When invoked puts menu pointed to by menu->wnd_pos in */
- /* the window. Bar position is determined by menu->bar_pos*/
- /***********************************************************/
-
- static void change_menu(TMNUTYPE *menu) {
-
- int tcv1, col, length;
- TMNUFLDS *ttmp, **stmp;
- MENU_WND *twnd;
-
- twnd = &menu->twnd;
- stmp = (TMNUFLDS **) menu->tlist;
- ttmp = stmp[menu->wnd_pos];
- if (mpresent) hide_mouse();
- clr_wnd(twnd->wnd, 1);
- for (tcv1 = 0; ttmp[tcv1].select_key != (char) NULL; tcv1++)
- wputs(twnd->wnd, ITEMROW, ttmp[tcv1].select_col, ttmp[tcv1].item);
- col = ttmp[menu->bar_pos].select_col;
- length = strlen(ttmp[menu->bar_pos].item);
- w_chg_attr(twnd->wnd,ITEMROW, col, twnd->cfclr, twnd->cbclr, length);
- if (mpresent) show_mouse();
- }
-
- /***********************************************************/
- /* Search_Menu */
- /* */
- /* Searches thru all menus looking for a select_key match */
- /* with keyboard input. All characters are converted to */
- /* upper case. Returns non-zero if found. Zero if not */
- /* found. If a match is found the menu index and bar index*/
- /* are changed to point to the selected item. */
- /***********************************************************/
-
- static int search_menu(TMNUTYPE *menu, int select_char) {
-
- TMNUFLDS *ttmp, **stmp; /* Menu Pointers */
- int tcv1, tcv2, ch; /* Index variables */
-
- stmp = (TMNUFLDS **) menu->tlist; /* Address menu lists */
- select_char = toupper(select_char); /* Uppercase keybd input */
- for (tcv1 = 0; stmp[tcv1] != NULL; tcv1++) { /* Get the menu list */
- ttmp = stmp[tcv1]; /* One menu list at a time */
- for (tcv2 = 0; ttmp[tcv2].select_key != (char) NULL; tcv2++) {
- /* Uppercase select_key */
- ch = (char) toupper(ttmp[tcv2].select_key);
- if (ch == select_char) { /* Do they match ? */
- menu->bar_pos = tcv2; /* Set bar index */
- menu->wnd_pos = tcv1; /* Set menu index */
- return(1); /* Return TRUE */
- }
- }
- }
- return (0); /* No matches */
- }
-
- /**********************************************************/
- /* Search_Mouse_Select */
- /* */
- /* Runs through all items in a menu to determine if the */
- /* rat was on the item. If a match is found the bar index*/
- /* is updated to reflect the selected item and we return */
- /* a non-zero return code to indicate a match was found. */
- /**********************************************************/
-
- static int search_mouse_select(TMNUTYPE *menu, int col) {
-
- MENU_WND *twnd;
- TMNUFLDS *ttmp, **stmp;
- int tcv, item_len, item_col;
-
- twnd = &menu->twnd; /* Establish Addressability */
- stmp = (TMNUFLDS **) menu->tlist;
- ttmp = stmp[menu->wnd_pos];
-
- /* If inside the window determine column in the window */
- if (col > twnd->wnd->ucol) col -= twnd->wnd->ucol;
- else return(0); /* Otherwise not in window so exit */
- /* Search thru all items in list */
- for (tcv = 0; ttmp[tcv].select_key != 0; tcv++) {
- /* Get items column */
- item_col = ttmp[tcv].select_col;
- /* Determine its length on the screen */
- item_len = (item_col + strlen(ttmp[tcv].item)) - 1;
- /* If mouse on the item */
- if (col >= item_col && col <= item_len) {
- menu->bar_pos = tcv; /* Set the bar index */
- return(1); /* Return True */
- }
- }
- return(0); /* No match found */
- }
-
- /**********************************************************/
- /* Change_Bar_Pos */
- /* */
- /* Changes the bar position in the window by changing the */
- /* attribute of the current bar to normal window attribute*/
- /* and changing the attribute of the new item to the color*/
- /* specified for bar color. Got it. Okay, test in five */
- /* minutes! */
- /**********************************************************/
-
- static void change_bar_pos(TMNUTYPE *menu, int crnt_bar) {
-
- int col, length;
- TMNUFLDS *ttmp, **stmp;
- MENU_WND *twnd;
-
- twnd = &menu->twnd; /* Establish addressability */
- stmp = (TMNUFLDS **) menu->tlist;
- ttmp = stmp[menu->wnd_pos];
- if (mpresent) hide_mouse(); /* If rat home hide from neighbors! */
-
- /* Get len and col of item on scrn and change color attribute */
- length = strlen(ttmp[crnt_bar].item);
- col = ttmp[crnt_bar].select_col;
- w_chg_attr(twnd->wnd,ITEMROW,col,twnd->fcolor,twnd->bcolor,length);
-
- /* Change new item color attribute */
- length = strlen(ttmp[menu->bar_pos].item);
- col = ttmp[menu->bar_pos].select_col;
- w_chg_attr(twnd->wnd,ITEMROW,col, twnd->cfclr, twnd->cbclr,length);
-
- if (mpresent) show_mouse(); /* Finally turn back on the mouse */
- }
-
- /**********************************************************/
- /* Get_Max_Bars */
- /* */
- /* Used to count how many selections for a given menu. */
- /**********************************************************/
-
- static int get_max_bars(TMNUFLDS *ttmp) {
-
- int i;
-
- for (i = 0; ttmp[i].select_key != 0; i++); i--;
- return(i);
- }
-