Add 'exit' (for exit text) parameter to new_menu() for dynamic menus.

Correct calculation of menu height and whether scrolling needs (was wrong
if a height was specified that was smaller that the number of lines needed).
Move keypad(m->mw, TRUE) to stop core dump when newwin() fails.
Allow for calling code hacking m->h (to reduce number of lines displayed).
Add a MC_NOCLEAR option to leave menu text showing when doing action.
This commit is contained in:
dsl 2003-06-04 19:07:39 +00:00
parent 15cd94ddd8
commit 3f8c566477
4 changed files with 47 additions and 31 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdb.c,v 1.30 2003/06/03 11:51:56 dsl Exp $ */
/* $NetBSD: mdb.c,v 1.31 2003/06/04 19:07:39 dsl Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -196,6 +196,7 @@ write_menu_file (char *initcode)
"#define MC_NOBOX 2\n"
"#define MC_SCROLL 4\n"
"#define MC_NOSHORTCUT 8\n"
"#define MC_NOCLEAR 16\n"
"#define MC_VALID 256\n"
);
@ -212,13 +213,13 @@ write_menu_file (char *initcode)
if (do_dynamic)
(void) fprintf (out_file, "%s",
"int new_menu (char * title, menu_ent * opts, "
"int new_menu(const char *title, menu_ent *opts, "
"int numopts, \n"
"\tint x, int y, int h, int w, int mopt,\n"
"\tvoid (*post_act)(void), "
"void (*exit_act)(void), "
"char * help);\n"
"void free_menu (int menu_no);\n"
"const char *help, const char *exit);\n"
"void free_menu(int menu_no);\n"
);
(void) fprintf (out_file, "\n/* Menu names */\n");

View File

@ -1,4 +1,4 @@
/* $NetBSD: menu_sys.def,v 1.37 2003/06/03 11:51:56 dsl Exp $ */
/* $NetBSD: menu_sys.def,v 1.38 2003/06/04 19:07:39 dsl Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -146,15 +146,12 @@ init_menu(struct menudesc *m)
wmax = strlen(m->title);
/* Calculate h? h == number of visible options. */
if (m->h == 0) {
if (m->h == 0)
m->h = m->numopts + exithadd;
if (m->h + m->y + hadd >= max_lines && (m->mopt & MC_SCROLL)) {
hadd++;
m->h = max_lines - m->y - hadd;
}
}
else
m->h -= hadd;
m->h = MIN(m->h, max_lines - m->y - hadd);
/* Check window heights and set scrolling */
if (m->h < m->numopts + exithadd) {
if (!(m->mopt & MC_SCROLL) || m->h < 3) {
endwin();
@ -163,17 +160,21 @@ init_menu(struct menudesc *m)
m->title);
exit(1);
}
hadd++;
m->h--;
} else
m->mopt &= ~MC_SCROLL;
#if 0
/* check for screen fit */
if (m->y + m->h + hadd > max_lines) {
endwin();
(void)fprintf(stderr,
"Screen too short for menu \"%s\"\n", m->title);
"Screen too short (%d + %d + %d > %d) for menu \"%s\"\n",
m->y, m->h, hadd, max_lines, m->title);
exit(1);
}
#endif
/* Calculate w? */
if (m->w == 0) {
@ -199,7 +200,6 @@ init_menu(struct menudesc *m)
/* Get the windows. */
m->mw = newwin(m->h + hadd, m->w + wadd, m->y, m->x);
keypad(m->mw, TRUE); /* enable multi-key assembling for win */
if (m->mw == NULL) {
endwin();
@ -207,6 +207,7 @@ init_menu(struct menudesc *m)
"Could not create window for menu \"%s\"\n", m->title);
exit(1);
}
keypad(m->mw, TRUE); /* enable multi-key assembling for win */
/* XXX is it even worth doing this right? */
if (has_colors()) {
@ -248,7 +249,7 @@ draw_menu_line(struct menudesc *m, int i, int cury, char opt, const char *text)
static void
draw_menu(struct menudesc *m)
{
int i;
int opt;
int hasbox, cury, maxy;
int tadd;
@ -274,18 +275,23 @@ draw_menu(struct menudesc *m)
maxy += tadd;
}
for (i = m->topline; i < m->numopts; i++) {
for (opt = m->topline; opt < m->numopts; opt++) {
if (cury >= maxy)
break;
draw_menu_line(m, i, cury++, opt_ch(i), m->opts[i].opt_name);
draw_menu_line(m, opt, cury++, opt_ch(opt),
m->opts[opt].opt_name);
}
/* Add the exit option. */
if (!(m->mopt & MC_NOEXITOPT) && cury < maxy)
draw_menu_line(m, m->numopts, cury++, 'x', m->exitstr);
if (!(m->mopt & MC_NOEXITOPT)) {
if (cury < maxy)
draw_menu_line(m, m->numopts, cury++, 'x', m->exitstr);
else
opt = 0;
}
/* Add the scroll line */
if (m->mopt & MC_SCROLL)
if (opt != m->numopts || m->topline != 0)
mvwaddstr(m->mw, cury, hasbox, scrolltext);
/* Add the box. */
@ -435,7 +441,7 @@ process_req(struct menudesc *m, int num, int req)
return;
}
m->topline = MIN(m->topline + m->h,
m->numopts + hasexit - m->h);
MAX(m->numopts + hasexit - m->h, 0));
m->cursel = MIN(m->numopts + hasexit - 1, m->cursel + m->h);
wclear(m->mw);
break;
@ -567,8 +573,10 @@ process_menu(int num, void *arg)
process_req(m, num, req);
sel = m->cursel;
wclear(m->mw);
wrefresh(m->mw);
if (!(m->mopt & MC_NOCLEAR)) {
wclear(m->mw);
wrefresh(m->mw);
}
/* Process the items */
if (sel < m->numopts) {
@ -604,6 +612,11 @@ process_menu(int num, void *arg)
}
}
if (m->mopt & MC_NOCLEAR) {
wclear(m->mw);
wrefresh(m->mw);
}
/* Process the exit action */
if (m->exit_act)
(*m->exit_act)();
@ -632,9 +645,10 @@ double_menus(void)
}
int
new_menu(char * title, menu_ent * opts, int numopts,
new_menu(const char *title, menu_ent *opts, int numopts,
int x, int y, int h, int w, int mopt,
void (*post_act)(void), void (*exit_act)(void), char * help)
void (*post_act)(void), void (*exit_act)(void),
const char * help, const char *exit)
{
int ix;
@ -661,7 +675,7 @@ new_menu(char * title, menu_ent * opts, int numopts,
menus[ix].post_act = post_act;
menus[ix].exit_act = exit_act;
menus[ix].helpstr = help;
menus[ix].exitstr = "Exit";
menus[ix].exitstr = exit ? exit : "Exit";
init_menu(&menus[ix]);

View File

@ -1,4 +1,4 @@
.\" $NetBSD: menuc.1,v 1.16 2003/05/09 08:20:27 wiz Exp $
.\" $NetBSD: menuc.1,v 1.17 2003/06/04 19:07:39 dsl Exp $
.\"
.\" Copyright 1997 Piermont Information Systems Inc.
.\" All rights reserved.
@ -372,6 +372,7 @@ struct menudesc {
#define MC_NOBOX 2
#define MC_SCROLL 4
#define MC_NOSHORTCUT 8
#define MC_NOCLEAR 16
int new_menu (char * title, menu_ent * opts, int numopts,
int x, int y, int h, int w, int mopt,

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.4 2000/08/15 02:09:12 phil Exp $ */
/* $NetBSD: main.c,v 1.5 2003/06/04 19:07:40 dsl Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -47,7 +47,7 @@ int main(void)
{
/* Menu processing */
process_menu (MENU_root);
process_menu (MENU_root, NULL);
return 0;
}
@ -120,7 +120,7 @@ void do_dynamic(void)
(void) fprintf (stderr, "Dynamic memu creation failure. \n");
exit (1);
}
process_menu (menu_no);
process_menu (menu_no, NULL);
free_menu (menu_no);
}