Remove the special-case behavior for fire actions that return

DITEM_FAILURE - formerly they would simply act as an implicit "continue",
but this is wrong.  If you want this behavior, you should now return
with the DITEM_CONTINUE flag set.

Also make the semantics of DITEM_RESTORE quite a bit different - rather
than restore the screen back to pre-menu state, we restore the menu
itself.  This is more correct for a variety of reasons when dealing with
nested menus (whoops!).
This commit is contained in:
Jordan K. Hubbard 1996-04-18 13:21:26 +00:00
parent 86d34adf67
commit c50c22c798
7 changed files with 104 additions and 176 deletions

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: menu1.c,v 1.2 1996/04/07 03:20:52 jkh Exp $
* $Id: menu1.c,v 1.3 1996/04/16 12:17:22 jkh Exp $
*/
#include <stdio.h>
@ -29,10 +29,6 @@ static enum { nowhere, berlin, rome, ny } where;
static int
_menu1_berlin_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == berlin) {
dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
}
@ -40,19 +36,12 @@ _menu1_berlin_action(dialogMenuItem *self)
where = berlin;
dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
}
static int
_menu1_rome_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == rome) {
dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
}
@ -60,19 +49,12 @@ _menu1_rome_action(dialogMenuItem *self)
where = rome;
dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
}
static int
_menu1_ny_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == ny) {
dialog_mesgbox("Say what?", "You're already there!", -1, -1);
}
@ -80,10 +62,7 @@ _menu1_ny_action(dialogMenuItem *self)
where = ny;
dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
}
/* menu1 - show off the "fire" action hook */

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: menu2.c,v 1.2 1996/04/07 03:20:54 jkh Exp $
* $Id: menu2.c,v 1.3 1996/04/16 12:17:23 jkh Exp $
*/
#include <stdio.h>
@ -29,61 +29,37 @@ static enum { nowhere, berlin, rome, ny } where;
static int
_menu1_berlin_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == berlin) {
if (where == berlin)
dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
}
else {
where = berlin;
dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
}
static int
_menu1_rome_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == rome) {
if (where == rome)
dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
}
else {
where = rome;
dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
}
static int
_menu1_ny_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == ny) {
if (where == ny)
dialog_mesgbox("Say what?", "You're already there!", -1, -1);
}
else {
where = ny;
dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
}
/* menu1 - show off the "fire" action hook */

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: menu3.c,v 1.2 1996/04/07 03:20:55 jkh Exp $
* $Id: menu3.c,v 1.3 1996/04/16 12:17:24 jkh Exp $
*/
#include <stdio.h>
@ -35,14 +35,8 @@ stop(dialogMenuItem *self)
static int
maybe(dialogMenuItem *self)
{
WINDOW *w;
w = dupwin(newscr);
dialog_mesgbox("!", "I said don't rush me! I'm THINKING!", -1, -1);
touchwin(w);
wrefresh(w);
delwin(w);
return DITEM_FAILURE;
return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
}
/* Dummy menu just to show of the ability */
@ -60,7 +54,7 @@ preinsure(dialogMenuItem *self, int is_selected)
/* This has to be here first if you want to see selection traverse properly in the invoking menu */
refresh();
w = dupwin(newscr);
DialogX = 1;
DialogY = 13;

View File

@ -44,7 +44,7 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
l, k, scroll = 0, max_choice, *status;
int redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *list, *save;
WINDOW *dialog, *list;
unsigned char **items;
dialogMenuItem *ditems;
@ -109,14 +109,12 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
y = (LINES - height)/2;
draw:
save = dupwin(newscr);
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width, y, x);
return -1;
@ -155,7 +153,6 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
if (list == NULL) {
delwin(dialog);
delwin(save);
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
y + box_y + 1, x + box_x + 1);
@ -204,19 +201,17 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
/* Shortcut to OK? */
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
int st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else {
delwin(dialog);
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
int st;
WINDOW *save;
save = dupwin(newscr);
st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
delwin(dialog);
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
delwin(save);
}
else {
delwin(dialog);
@ -228,27 +223,23 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
}
}
}
delwin(save);
return 0;
}
/* Shortcut to cancel? */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
int st;
WINDOW *save;
save = dupwin(newscr);
st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
delwin(save);
}
delwin(dialog);
delwin(save);
return 1;
}
@ -315,31 +306,34 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
char lbra = 0, rbra = 0, mark = 0;
if (ditems) {
if (ditems[scroll+choice].fire) {
int st = ditems[scroll+choice].fire(&ditems[scroll+choice]);
if (ditems[scroll + choice].fire) {
int st;
WINDOW *save;
save = dupwin(newscr);
st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
if (st & DITEM_REDRAW) {
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice,
DREF(ditems, scroll + i));
for (i = 0; i < max_choice; i++) {
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
status[scroll + i], i, i == choice, DREF(ditems, scroll + i));
}
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4,
cur_x, cur_y);
wrefresh(dialog);
}
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
if (st & DITEM_RECREATE) {
else if (st & DITEM_RECREATE) {
delwin(save);
delwin(dialog);
goto draw;
}
else if (st & DITEM_LEAVE_MENU) {
delwin(save);
if (st & DITEM_LEAVE_MENU) {
/* Allow a fire action to take us out of the menu */
key = ESC;
break;
@ -475,7 +469,6 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
}
}
delwin(dialog);
delwin(save);
return button;
break;
@ -501,7 +494,6 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
}
}
delwin(dialog);
delwin(save);
return -1; /* ESC pressed */
}
/* End of dialog_checklist() */

View File

@ -48,6 +48,7 @@
#define DITEM_REDRAW (1 << 17)
#define DITEM_RECREATE (1 << 18)
#define DITEM_RESTORE (1 << 19)
#define DITEM_CONTINUE (1 << 20)
/* negative offsets for buttons in item lists, if specified */

View File

@ -42,7 +42,7 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
l, k, scroll = 0, max_choice, redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *menu, *save;
WINDOW *dialog, *menu;
unsigned char **items;
dialogMenuItem *ditems;
@ -100,14 +100,12 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
y = DialogY ? DialogY : (LINES - height)/2;
draw:
save = dupwin(newscr);
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
return -1;
@ -145,7 +143,6 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
/* create new window for the menu */
menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
if (menu == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", menu_height,menu_width,y+box_y+1,x+box_x+1);
return -1;
@ -193,41 +190,36 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
int status;
WINDOW *save;
save = dupwin(newscr);
status = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
if (DITEM_STATUS(status) == DITEM_FAILURE)
continue;
else {
delwin(dialog);
if (status & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
if (status & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
delwin(save);
}
else {
delwin(dialog);
else
strcpy(result, items[(scroll + choice) * 2]);
}
delwin(save);
delwin(dialog);
return 0;
}
/* Shortcut to cancel? */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
int status;
WINDOW *save;
save = dupwin(newscr);
status = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
if (DITEM_STATUS(status) == DITEM_FAILURE)
continue;
else if (status & DITEM_RESTORE) {
if (status & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
delwin(save);
}
delwin(dialog);
delwin(save);
return 1;
}
@ -384,25 +376,27 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
to accept some hints as to what to do in the aftermath. */
if (ditems && ditems[scroll + choice].fire) {
int status;
WINDOW *save;
save = dupwin(newscr);
status = ditems[scroll + choice].fire(&ditems[scroll + choice]);
if (DITEM_STATUS(status) == DITEM_FAILURE)
continue;
else if (status & DITEM_RESTORE) {
if (status & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
else if (status & DITEM_RECREATE) {
delwin(save);
delwin(dialog);
delwin(save);
goto draw;
}
delwin(save);
if (status & DITEM_CONTINUE)
continue;
}
else if (result)
strcpy(result, items[(scroll+choice)*2]);
}
delwin(dialog);
delwin(save);
return button;
case ESC:
@ -427,7 +421,6 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
}
delwin(dialog);
delwin(save);
return -1; /* ESC pressed */
}
/* End of dialog_menu() */

View File

@ -44,7 +44,7 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
l, k, scroll = 0, max_choice, *status, was_on = 0;
int redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *list, *save;
WINDOW *dialog, *list;
unsigned char **items;
dialogMenuItem *ditems;
@ -122,14 +122,12 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
y = DialogY ? DialogY : (LINES - height)/2;
draw:
save = dupwin(newscr);
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
return -1;
@ -167,7 +165,6 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
/* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
if (list == NULL) {
delwin(save);
delwin(dialog);
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height,list_width,y+box_y+1,x+box_x+1);
@ -214,20 +211,17 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
int st;
WINDOW *save;
save = dupwin(newscr);
st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE)
continue;
else {
delwin(dialog);
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
delwin(save);
}
else {
delwin(dialog);
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
@ -236,32 +230,30 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
}
}
}
delwin(save);
delwin(dialog);
return 0;
}
/* Shortcut to cancel */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
int st;
WINDOW *save;
save = dupwin(newscr);
st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
delwin(save);
}
delwin(dialog);
delwin(save);
return 1;
}
/* Check if key pressed matches first character of any item tag in list */
for (i = 0; i < max_choice; i++)
if (toupper(key) == toupper(items[(scroll+i)*3][0]))
if (toupper(key) == toupper(items[(scroll + i) * 3][0]))
break;
if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
@ -293,7 +285,7 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
}
else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll+choice < item_no-1) {
if (scroll + choice < item_no - 1) {
/* Scroll list up */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
@ -321,31 +313,33 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
continue;
else if (ditems) {
if (ditems[scroll + choice].fire) {
int st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
int st;
WINDOW *save;
save = dupwin(newscr);
st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
if (st & DITEM_REDRAW) {
for (i = 0; i < max_choice; i++)
for (i = 0; i < max_choice; i++) {
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
status[scroll + i], i, i == choice,
DREF(ditems, scroll + i));
}
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
}
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
if (st & DITEM_RECREATE) {
else if (st & DITEM_RECREATE) {
delwin(save);
delwin(dialog);
goto draw;
}
else if (st & DITEM_LEAVE_MENU) {
delwin(save);
if (st & DITEM_LEAVE_MENU) {
/* Allow a fire action to take us out of the menu */
key = ESC;
break;
@ -372,12 +366,12 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
if (i != choice) {
/* De-highlight current item */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 +1], status[scroll+choice], choice, FALSE,
DREF(ditems, scroll + choice));
print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 +1],
status[scroll + choice], choice, FALSE, DREF(ditems, scroll + choice));
/* Highlight new item */
choice = i;
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE,
DREF(ditems, scroll + choice));
print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1],
status[scroll + choice], choice, TRUE, DREF(ditems, scroll + choice));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
@ -455,12 +449,12 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
case '\n':
if (!button && result) {
if (ditems && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
int st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
int st;
WINDOW *save;
save = dupwin(newscr);
st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
@ -469,6 +463,7 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
delwin(dialog);
goto draw;
}
delwin(save);
}
else {
*result = '\0';
@ -481,7 +476,6 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
}
}
delwin(dialog);
delwin(save);
return button;
break;
@ -506,7 +500,6 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
}
delwin(dialog);
delwin(save);
free(status);
return -1; /* ESC pressed */
}