Add scrollable menus. Tweek testm's Makefile to remake if menu_sys.def

is modified.
This commit is contained in:
phil 1998-06-25 09:58:57 +00:00
parent de27f1befc
commit 1063113ca9
7 changed files with 152 additions and 62 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdb.c,v 1.5 1998/06/24 06:46:23 phil Exp $ */
/* $NetBSD: mdb.c,v 1.6 1998/06/25 09:58:57 phil Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -160,6 +160,7 @@ write_menu_file (char *initcode)
" int mopt;\n"
" int numopts;\n"
" int cursel;\n"
" int topline;\n"
" char **opts;\n"
" WINDOW *mw;\n"
" char *helpstr;\n"
@ -168,6 +169,7 @@ write_menu_file (char *initcode)
"/* defines for mopt field. */\n"
"#define NOEXITOPT 1\n"
"#define NOBOX 2\n"
"#define SCROLL 4\n"
"\n"
"/* initilization flag */\n"
"extern int __m_endwin;\n"
@ -218,7 +220,7 @@ write_menu_file (char *initcode)
(void) fprintf (out_file, "static struct menudesc menus[] = {\n");
for (i=0; i<menu_no; i++) {
(void) fprintf (out_file,
"\t{%s,%d,%d,%d,%d,%d,%d,0,optstr%d,NULL,",
"\t{%s,%d,%d,%d,%d,%d,%d,0,0,optstr%d,NULL,",
menus[i]->info->title, menus[i]->info->y,
menus[i]->info->x, menus[i]->info->h,
menus[i]->info->w, menus[i]->info->mopt,

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdb.h,v 1.2 1998/06/24 06:46:24 phil Exp $ */
/* $NetBSD: mdb.h,v 1.3 1998/06/25 09:58:57 phil Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -89,5 +89,6 @@ struct menu_info {
/* defines for mopt */
#define NOEXITOPT 1
#define NOBOX 2
#define SCROLL 4
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: menu_sys.def,v 1.6 1998/06/24 14:44:52 phil Exp $ */
/* $NetBSD: menu_sys.def,v 1.7 1998/06/25 09:58:57 phil Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -50,11 +50,13 @@
#define KEYPAD_UP_ARROW 257
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
/* Initialization state. */
static int __menu_init = 0;
int __m_endwin = 0;
static int max_lines = 0;
static char *scrolltext = " <: page up, >: page down";
/* prototypes for in here! */
@ -132,7 +134,7 @@ static int menucmd (WINDOW *w)
return REQ_REDISPLAY;
}
if (isalpha(ch) || ch == '?')
if (isalpha(ch) || ch == '?' || ch == '<' || ch == '>')
return (ch);
mbeep();
@ -144,23 +146,44 @@ static void init_menu (struct menudesc *m)
{
int max;
char **p;
int add=4;
if (m->mopt & NOBOX)
add = 2;
int add, exitadd;
add = ((m->mopt & NOBOX) ? 2 : 4);
exitadd = ((m->mopt & NOEXITOPT) ? 0 : 1);
max = strlen(m->title);
/* Calculate h? */
/* Calculate h? h == number of visible options. */
if (m->h == 0) {
m->h = m->numopts + ((m->mopt & NOEXITOPT) ? 0 : 1)
- (max ? 0 : 2);
m->h = m->numopts + exitadd;
if (m->h + m->y + add >= max_lines && (m->mopt & SCROLL))
m->h = max_lines - m->y - add - 1;
}
/* Check window heights and set scrolling */
if (m->h < m->numopts + exitadd) {
if (m->mopt & SCROLL) {
if (m->h < 3) {
endwin();
(void) fprintf (stderr,
"Window too small for menu \"%s\"\n",
m->title);
exit(1);
}
} else {
endwin();
(void) fprintf (stderr,
"Menu too big for menu \"%s\"\n",
m->title);
exit(1);
}
} else
m->mopt &= ~SCROLL;
/* Calculate w? */
if (m->w == 0) {
p = m->opts;
if (m->mopt & SCROLL)
max = strlen(scrolltext);
while (*p) {
max = MAX(max,strlen(*p));
p++;
@ -183,14 +206,16 @@ static void init_menu (struct menudesc *m)
static void post_menu (struct menudesc *m)
{
int i;
int hasbox, cury;
int hasbox, cury, maxy, selrow, lastopt;
int tadd;
if (m->mopt & NOBOX) {
cury = 0;
maxy = m->h;
hasbox = 0;
} else {
cury = 1;
maxy = m->h+1;
hasbox = 1;
}
@ -199,34 +224,66 @@ static void post_menu (struct menudesc *m)
if (tadd) {
mvwaddstr(m->mw, cury, cury, m->title);
cury += 2;
maxy += 2;
}
for (i=0; i<m->numopts; i++, cury++) {
/* Set defaults, calculate lastopt. */
selrow = -1;
if (m->mopt & SCROLL) {
lastopt = MIN(m->numopts, m->topline+m->h-1);
maxy -= 1;
} else
lastopt = m->numopts;
for (i=m->topline; i<lastopt; i++, cury++) {
if (m->cursel == i) {
mvwaddstr (m->mw, cury, hasbox, ">");
wstandout(m->mw);
selrow = cury;
} else
mvwaddstr (m->mw, cury, hasbox, " ");
waddstr (m->mw, m->opts[i]);
if (m->cursel == i)
wstandend(m->mw);
wclrtoeol(m->mw);
}
if (!(m->mopt & NOEXITOPT))
mvwaddstr (m->mw, cury, hasbox, " x: Exit");
/* Add the exit option. */
if (!(m->mopt & NOEXITOPT) && cury < maxy) {
if (m->cursel >= m->numopts) {
mvwaddstr (m->mw, cury, hasbox, ">");
wstandout(m->mw);
selrow = cury;
} else
mvwaddstr (m->mw, cury, hasbox, " ");
waddstr (m->mw, "x: Exit");
if (m->cursel >= m->numopts)
wstandend(m->mw);
wclrtoeol(m->mw);
cury++;
}
/* Add the scroll line */
if (m->mopt & SCROLL) {
mvwaddstr (m->mw, cury, hasbox, scrolltext);
if (selrow < 0)
selrow = cury;
}
/* Add the box. */
if (!(m->mopt & NOBOX))
box(m->mw, '*', '*');
wmove(m->mw,tadd+hasbox+m->cursel, hasbox);
wmove(m->mw, selrow, hasbox);
}
static void process_help (struct menudesc *m, int num)
{
char *help = m->helpstr;
int lineoff = 0;
int lineoff = 0;
int curoff = 0;
int again;
int winin;
int winin;
/* Is there help? */
if (!help) {
@ -235,7 +292,7 @@ static void process_help (struct menudesc *m, int num)
}
/* Display the help information. */
do {
do {
if (lineoff < curoff) {
help = m->helpstr;
curoff = 0;
@ -260,15 +317,19 @@ static void process_help (struct menudesc *m, int num)
switch (winin) {
case '<':
case 'u':
case KEYPAD_UP_ARROW:
case KEYPAD_UP_ARROW:
if (lineoff)
lineoff -= max_lines - 2;
else
again = 1;
break;
case '>':
case 'd':
case KEYPAD_DOWN_ARROW:
case KEYPAD_DOWN_ARROW:
if (*help)
lineoff += max_lines - 2;
else
again = 1;
break;
case 'q':
break;
@ -282,67 +343,77 @@ static void process_help (struct menudesc *m, int num)
wclear(stdscr);
wrefresh(stdscr);
process_item (&num, -2);
post_menu (m);
wrefresh (m->mw);
}
static void process_req (struct menudesc *m, int num, int req)
{
int ch;
int lastsel = m->cursel;
int hasexit = (m->mopt & NOEXITOPT ? 0 : 1 );
int hasbox = (m->mopt & NOBOX ? 0 : 1);
int tadd = strlen(m->title) ? 2 : 0;
int refresh = 0;
if (req == REQ_EXECUTE)
return;
else if (req == REQ_NEXT_ITEM) {
if (m->cursel < m->numopts + hasexit - 1)
if (m->cursel < m->numopts + hasexit - 1) {
m->cursel++;
else
refresh = 1;
} else
mbeep();
} else if (req == REQ_PREV_ITEM) {
if (m->cursel > 0)
if (m->cursel > 0) {
m->cursel--;
else
refresh = 1;
} else
mbeep();
} else if (req == REQ_REDISPLAY) {
wclear(stdscr);
wrefresh(stdscr);
process_item (&num, -2);
post_menu (m);
wrefresh (m->mw);
refresh = 1;
} else if (req == '?') {
process_help (m, num);
refresh = 1;
} else if (req == '<') {
if (m->topline == 0)
mbeep();
else {
m->topline -= m->h-1;
wclear (m->mw);
refresh = 1;
}
} else if (req == '>') {
if (m->topline + m->h - 1 > m->numopts + hasexit)
mbeep();
else {
m->topline += m->h-1;
wclear (m->mw);
refresh = 1;
}
} else {
ch = tolower (req);
if (ch == 'x' && hasexit)
if (ch == 'x' && hasexit) {
m->cursel = m->numopts;
else {
refresh = 1;
} else {
ch = ch - 'a';
if (ch < 0 || ch >= m->numopts)
mbeep();
else
else {
m->cursel = ch;
refresh = 1;
}
}
}
if (m->cursel != lastsel) {
mvwaddstr (m->mw, lastsel+tadd+hasbox, hasbox, " ");
if (lastsel < m->numopts)
waddstr (m->mw, m->opts[lastsel]);
else
waddstr (m->mw, "x: Exit");
mvwaddstr (m->mw, m->cursel+tadd+hasbox, hasbox, ">");
wstandout(m->mw);
if (m->cursel < m->numopts)
waddstr (m->mw, m->opts[m->cursel]);
else
waddstr (m->mw, "x: Exit");
wstandend(m->mw);
wmove(m->mw,tadd+hasbox+m->cursel, hasbox);
wrefresh(m->mw);
if (refresh) {
post_menu (m);
wrefresh (m->mw);
}
}
@ -368,15 +439,16 @@ void process_menu (int num)
__menu_init = 1;
}
if (__m_endwin) {
wclear(stdscr);
wclear(stdscr);
wrefresh(stdscr);
__m_endwin = 0;
}
if (m->mw == NULL)
init_menu (m);
/* Always preselect 0! */
/* Always preselect option 0 and display from 0! */
m->cursel = 0;
m->topline = 0;
while (!done) {
last_num = num;
@ -416,3 +488,4 @@ void process_menu (int num)
/* Process the exit action */
process_item (&num, -1);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.y,v 1.3 1998/06/24 06:46:24 phil Exp $ */
/* $NetBSD: parse.y,v 1.4 1998/06/25 09:58:57 phil Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -56,7 +56,7 @@ static optn_info *cur_optn;
%token <i_value> X Y W H NO BOX SUB HELP MENU NEXT EXIT ACTION ENDWIN OPTION
%token <i_value> TITLE DEFAULT DISPLAY ERROR
%token <i_value> TITLE DEFAULT DISPLAY ERROR SCROLLABLE
%token <s_value> STRING NAME CODE INT_CONST CHAR_CONST
%type <s_value> init_code system helpstr
@ -124,9 +124,11 @@ opt_list : "," opt
;
opt : NO EXIT { cur_menu->info->mopt |= NOEXITOPT; }
| NO BOX { cur_menu->info->mopt |= NOBOX; }
| EXIT { cur_menu->info->mopt &= ~NOEXITOPT; }
| NO BOX { cur_menu->info->mopt |= NOBOX; }
| BOX { cur_menu->info->mopt &= ~NOBOX; }
| NO SCROLLABLE { cur_menu->info->mopt &= ~SCROLL; }
| SCROLLABLE { cur_menu->info->mopt |= SCROLL; }
| X "=" INT_CONST { cur_menu->info->x = atoi($3); }
| Y "=" INT_CONST { cur_menu->info->y = atoi($3); }
| W "=" INT_CONST { cur_menu->info->w = atoi($3); }

View File

@ -1,4 +1,4 @@
/* $NetBSD: scan.l,v 1.4 1998/06/24 06:46:24 phil Exp $ */
/* $NetBSD: scan.l,v 1.5 1998/06/25 09:58:58 phil Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -96,6 +96,8 @@ display { return DISPLAY; }
error { return ERROR; }
scrollable { return SCROLLABLE; }
\"([^\"\n]*(\\\")?)*\" {
yylval.s_value = strdup (yytext);
max_strlen = max_strlen > strlen(yytext)

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.6 1998/06/24 14:46:54 phil Exp $
# $NetBSD: Makefile,v 1.7 1998/06/25 09:58:58 phil Exp $
MENUC!=cd $(.CURDIR)/..; \
printf "xxx: .MAKE\n\t@echo \$${.OBJDIR}/menuc\n" | ${MAKE} -s -f-
@ -15,7 +15,7 @@ NOMAN= noman
CLEANFILES+= menu_defs.c menu_defs.h
menu_defs.c menu_defs.h: menus.mc ${MENUC}
menu_defs.c menu_defs.h: menus.mc ${MENUC} ${.CURDIR}/../menu_sys.def
MENUDEF=${.CURDIR}/.. ${MENUC} ${.CURDIR}/menus.mc
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: menus.mc,v 1.3 1998/06/24 06:46:25 phil Exp $ */
/* $NetBSD: menus.mc,v 1.4 1998/06/25 09:58:58 phil Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -54,6 +54,9 @@ menu root, title " Main Menu of Test System";
option "Try a sub menu",
sub menu submenu
;
option "A scrollable menu",
sub menu scrollit
;
option "Run a shell...",
action (endwin) { system ("/bin/sh"); }
;
@ -155,3 +158,10 @@ menu lowerleft, title "lower left", y=20, x=2, no exit;
menu middle, no box;
option "Just Exit!", exit;
menu scrollit, scrollable, h=4, title " Scrollable Menu";
option "option 1", action {};
option "option 2", action {};
option "option 3", action {};
option "option 4", action {};
option "option 5", action {};
option "option 6", action {};