home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Jason Aller Floppy Collection
/
125.img
/
PRO-C4.ZIP
/
BENCH1.ZIP
/
BENCH
/
OPTION.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-28
|
12KB
|
500 lines
/* ==( bench/option.c )== */
/* ----------------------------------------------- */
/* Pro-C Copyright (C) 1988 - 1990 Vestronix Inc. */
/* Modification to this source is not supported */
/* by Vestronix Inc. */
/* All Rights Reserved */
/* ----------------------------------------------- */
/* Written Nig 1-Jan-87 */
/* Modified SBF 5-Feb-90 see comments below */
/* ----------------------------------------------- */
/* %W% (%H% %T%) */
/*
* Modifications
*
* 11-Dec-89 Geo - V2 version
* 25-Oct-89 Geo - 1.32 Merge
* 23-Jan-90 Bob - general direction routine
* 5-Feb-90 SBF - added space select for toggles
*/
# include <stdio.h>
# include <bench.h>
# ifdef ANSI
int keytrig(char *, int *);
int get_direction(struct optab *, int, int);
static void is_it_lower(int, int, int, struct optab *);
static void is_it_left(int, int, int, struct optab *);
# else
int keytrig();
int get_direction();
static void is_it_lower();
static void is_it_left();
# endif
int trigger_attr = BOLD;
/*
* Menu structure for selecting options
* A simple list of row, col, and string
* - the proceedure inits itself when the address
* of the option table changes so it can be called
* with different option lists
* - the choice variable will be modified if it exceeds
* the range of items available (cf. code)
* - the list will terminate with a NULL, the row coord
* is used as the normal attribute, the col coord is used
* as the hi-light attribute
*/
/* Hatty & Natty should be picked up each time ? allows dynamic highlighting */
extern struct window_rec *winptr;
/*
* Flag set by dsp_opt to
* be used in do_options to
* indicated selection
*/
int selattr = FALSE;
static int ccol, crow, row, col, oldfunc;
static int omin, omax, save;
void dsp_opt(optabs, choice)
struct optab optabs[];
int *choice;
{
struct optab *optr;
int hatty, norm;
int posn, ch;
int i;
static struct optab *loptab = (struct optab *)0;
static int lchoice = 0, cnt;
char *forceupper();
/* Reset the address */
if (optabs == (struct optab *)0)
{
loptab = optabs;
lchoice = 0;
return;
}
/* Reset the counter && highlight attribute */
for (optr = &optabs[0]; optr->text != NULL; optr++)
;
hatty = (selattr == FALSE) ? optr->col : trigger_attr;
norm = optr->row;
cnt = (int)(optr - optabs);
cnt--;
/* Wrap around */
if (*choice < 0)
*choice = cnt;
else if (*choice > cnt)
*choice = 0;
/* If a new structure change or a new window */
if (loptab != optabs || W_NEWIN)
{
/* Set this baby up */
loptab = optabs;
for (i = 0, optr = &optabs[0]; i <= cnt; i++, optr++)
{
disp_w(optr->row, optr->col, norm, optr->text + ((*optr->text == '~') ? 1 : 0));
/* High light the trigger character */
ch = keytrig(optr->text, &posn);
poke_w(optr->row, optr->col + posn, trigger_attr, ch);
}
for (i = 0, optr = &optabs[0]; i <= cnt; i++, optr++)
if (i == *choice)
{
disp_w(optr->row, optr->col, hatty, optr->text + ((*optr->text == '~') ? 1 : 0));
(void)keytrig(optr->text, &posn);
moveto_w(optr->row, optr->col + posn);
break;
}
lchoice = *choice;
return;
}
/* Now high light one and blank the other
* Must do this even if lchoice == *choice
* cos it might have used selected highlight
*/
optr = &optabs[lchoice];
disp_w(optr->row, optr->col, norm, optr->text + ((*optr->text == '~') ? 1 : 0));
/* High light the trigger character */
ch = keytrig(optr->text, &posn);
poke_w(optr->row, optr->col + posn, trigger_attr, ch);
optr = &optabs[*choice];
disp_w(optr->row, optr->col, hatty, optr->text + ((*optr->text == '~') ? 1 : 0));
(void)keytrig(optr->text, &posn);
moveto_w(optr->row, optr->col + posn);
lchoice = *choice;
}
char *forceupper(str)
char *str;
{
static char tmp[80];
strcpy(tmp, str);
strupr(tmp);
return(tmp);
}
/* This is a hack until better menus arrive */
/* High light thisun */
void dsp_sel_opt(optabs, choice)
struct optab optabs[];
int *choice;
{
struct optab *optr;
int posn;
/* I assume all is okay */
optr = &optabs[*choice];
disp_w(optr->row, optr->col, trigger_attr, optr->text + ((*optr->text == '~') ? 1 : 0));
(void)keytrig(optr->text, &posn);
moveto_w(optr->row, optr->col + posn);
}
int do_options(options, curfunc, helpnum)
struct optab options[];
int curfunc, helpnum;
{
int cc, iopt, oldfunc;
int dummy; /* Used to keep dummy happy */
# ifdef MOUSE
int r, c, w, h;
mouse_level++;
# endif
ichar = 0; /* clear ichar */
dsp_opt(options, &curfunc);
do
{
keys_w(K_F1, help_prompt, K_CR, accept_prompt, K_ESC, exit_prompt, 0);
cc = inchar();
if (cc <= 'z') /* Only do this if it is near [a-z] */
if (islower(cc)) /* this should trap >8bit values ! */
cc = toupper(cc);
/*
* get absolute window coordinates
*/
# ifdef MOUSE
abs_w(&r, &c, &w, &h);
# endif
for (iopt = 0; options[iopt].text != NULL; iopt++)
{
# ifdef MOUSE
int key;
key = (int)keytrig(options[iopt].text, &dummy);
mouse_add_object(
(unsigned char)r + options[iopt].row,
(unsigned char)c + options[iopt].col,
(unsigned char)r + options[iopt].row,
(unsigned char)c + options[iopt].col +
strlen(options[iopt].text + ((*options[iopt].text == '~') ? 1 : 0)) - 1, key, iopt, NULL);
# endif
if (keytrig(options[iopt].text, &dummy) == cc)
{
/* Reset the display and set this alight */
selattr = TRUE;
dsp_opt(options, &iopt);
selattr = FALSE; /* Does nothing when UNIX is active */
# ifdef MOUSE
mouse_delete_level(mouse_level--);
# endif
ichar = K_CR; /* like we actually pressed it */
return(iopt);
}
}
oldfunc = curfunc;
switch (cc)
{
# ifdef MOUSE
case M_PRESS :
case M_RELEASE :
if (!mouse_check_bounds())
{
int dummy;
mouse_click(&dummy, cc);
}
else if (mouse_click(&curfunc, cc))
dsp_opt(options, &curfunc);
break;
# endif
case ' ':
if (*options[curfunc].text == '~')
{
cc = K_CR;
break;
}
else
cc = K_RIGHT;
case K_DOWN :
case K_UP :
case K_RIGHT :
case K_LEFT :
/*
* find the next element base on the key pressed
*/
curfunc = get_direction(options, curfunc, cc);
dsp_opt(options, &curfunc);
break;
case '?' :
case K_HELP :
help_msg(helpnum);
break;
case K_TAB :
case K_ESC :
ichar = cc; /* set ichar in case anyone's interested */
# ifdef MOUSE
mouse_delete_level(mouse_level--);
# endif
return(-1);
}
}
while (cc != K_CR && cc != M_ESC && cc != K_TAB);
ichar = cc;
/* Reset the display and set this alight */
selattr = TRUE;
dsp_opt(options, &curfunc);
selattr = FALSE;
# ifdef MOUSE
mouse_delete_level(mouse_level--);
# endif
return(curfunc);
}
/*
* Return Character which is used as a trigger
* withinn a prompt string
* - " coMpute " yields 'M'
* - " nothing " yields 'N' 'cos no uppercase letter
* - " !dos " yields '!' special case
* - " 2choice " yields '2' special case for leading numbers. SMV
*/
int keytrig(str, posn)
char *str;
int *posn;
{
int first;
char *ptr = str;
if (*str == '~')
{
str++;
ptr++;
}
/* Point to first non-space */
while (*str && isspace(*str))
str++;
*posn = (int)(str - ptr);
first = *str;
while (*str)
{
/* '!' often used for !Shell */
if (isupper(*str) || *str == '!' || isdigit(*str))
{
*posn = (int)(str - ptr);
return(*str);
}
str++;
}
if (first <= 'z' && islower(first)) /* See previous stuff */
first = toupper(first);
return(first);
}
/*
* function to find the next element to move to based on which key was pressed
* all movement is broken down into 4 direction UP, DOWN, LEFT, RIGHT
*
* if no match is found in the current direction then wrap around is tried.
* if there is no wrap around then simple increment/decrement the current
* index (RN, Jan 23, 1990)
*/
int get_direction(options, curfunc, key)
struct optab options[];
int curfunc;
int key;
{
int iopt, voffset, hoffset;
crow = options[curfunc].row; /* current column */
ccol = options[curfunc].col; /* current row */
omin = omax = save = oldfunc = curfunc;
voffset = (key == K_UP) ? -1 : 1; /* vertical offset */
hoffset = (key == K_LEFT) ? -1 : 1; /* horizontal offset */
if (key == K_UP || key == K_DOWN)
{
/*
* in this section we deal with vertical movement up/down
*/
for (iopt = 0; options[iopt].text != NULL; iopt++)
{
if (iopt != curfunc) /* we don't want the current index */
{
row = options[iopt].row;
col = options[iopt].col;
if (col == ccol) /* must be same column for a vertical match */
{
if (row == crow)
{
/*
* if we have the same row then the object probably overlap
* this case handles the "space select" type of action
*/
if (iopt == (curfunc + voffset))
return(iopt);
}
is_it_lower(key, iopt, curfunc, options);
}
}
}
/*
* we must go through the list a second time to check all of the item
* that don't match the col
*/
for (iopt = 0; options[iopt].text != NULL; iopt++)
{
row = options[iopt].row;
is_it_lower(key, iopt, curfunc, options);
}
if (oldfunc == save)
if (omin == oldfunc && omax == oldfunc)
save += voffset; /* no wrap index found (default) */
else
save = (voffset < 0) ? omax : omin; /* go to wrap index */
return(save); /* return the new index */
}
/*
* this section handles horizontal movement
*/
for (iopt = 0; options[iopt].text != NULL; iopt++)
{
if (iopt != curfunc)
{
row = options[iopt].row;
col = options[iopt].col;
if (row == crow)
is_it_left(key, iopt, curfunc, options);
}
}
if (oldfunc == save)
if (omin == oldfunc && omax == oldfunc)
save += hoffset; /* no wrap index found (default) */
else
save = (hoffset < 0) ? omax : omin; /* go to wrap index */
return(save); /* return the new index */
}
/*
* This function check to see an optab item (iopt) is
* above or below the current one.
* Max and omin positions are also checked
*/
static void is_it_lower(key, iopt, curfunc, options)
int key, iopt, curfunc;
struct optab options[];
{
if (row > crow)
{
if (key == K_DOWN)
if (save == curfunc || (row < options[save].row))
save = iopt; /* closest match so far */
if (row > options[omax].row)
omax = iopt; /* this is the lowest match so far */
}
else
{
if (row < crow)
{
/*
* this element is above the current one
*/
if (key == K_UP)
if (save == curfunc || (row > options[save].row))
save = iopt; /* closest match so far */
if (row < options[omin].row)
omin = iopt; /* this is the highest match so far */
}
}
}
/*
* This function check to see an optab item (iopt) is
* to the left or right of the current one.
* Max and omin positions are also checked
*/
static void is_it_left(key, iopt, curfunc, options)
int key, iopt, curfunc;
struct optab options[];
{
if (col > ccol)
{
/*
* this item is to the right of the current one
*/
if (key == K_RIGHT)
if (save == curfunc || (col < options[save].col))
save = iopt; /* good candidate so let's save it */
if (col > options[omax].col)
omax = iopt; /* furthest right so far */
}
if (col < ccol)
{
/*
* this item is to the left of the current one
*/
if (col < ccol)
{
if (key == K_LEFT)
if (save == curfunc || (col > options[save].col))
save = iopt; /* good candidate so let's save it */
if (col < options[omin].col)
omin = iopt; /* furthest left so far */
}
}
}