mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-12 09:58:36 +00:00
Go on one of my periodic rampages through this code, trying to make
it DTRT. In the process, discover the usual 10-15 evil bogons which have been lurking in it for years. This closes, for one thing, the recent report Mike Smith made about nested checklist menus returning with the scrolling region messed up.
This commit is contained in:
parent
8d26fa1ec7
commit
a59ff6e254
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21790
@ -40,9 +40,10 @@ int
|
||||
dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
int list_height, int cnt, void *it, unsigned char *result)
|
||||
{
|
||||
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, item_no = 0, *status;
|
||||
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button, choice,
|
||||
l, k, scroll, max_choice, item_no = 0, *status;
|
||||
int redraw_menu = FALSE;
|
||||
int rval = 0;
|
||||
char okButton, cancelButton;
|
||||
WINDOW *dialog, *list;
|
||||
unsigned char **items = NULL;
|
||||
@ -56,6 +57,7 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
|
||||
draw:
|
||||
choice = scroll = button = 0;
|
||||
/* Previous calling syntax, e.g. just a list of strings? */
|
||||
if (cnt >= 0) {
|
||||
items = it;
|
||||
@ -170,14 +172,14 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
|
||||
/* Print the list */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
|
||||
print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
|
||||
display_helpline(dialog, height-1, width);
|
||||
display_helpline(dialog, height - 1, width);
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
x = width / 2 - 11;
|
||||
y = height - 2;
|
||||
/* Is this a fancy new style argument string where we get to override
|
||||
* the buttons, or an old style one where they're fixed?
|
||||
*/
|
||||
@ -225,12 +227,13 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
}
|
||||
}
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return 0;
|
||||
rval = 0;
|
||||
key = ESC; /* Lemme out! */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shortcut to cancel? */
|
||||
else if (toupper(key) == cancelButton) {
|
||||
if (toupper(key) == cancelButton) {
|
||||
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
|
||||
int st;
|
||||
WINDOW *save;
|
||||
@ -244,9 +247,9 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
delwin(save);
|
||||
}
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
rval = 1;
|
||||
key = ESC; /* I gotta go! */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if key pressed matches first character of any item tag in list */
|
||||
@ -254,26 +257,28 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
|
||||
break;
|
||||
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || key == KEY_UP ||
|
||||
key == KEY_DOWN || key == ' ' || key == '+' || key == '-' || key == '' || key == '') {
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
|
||||
KEY_IS_UP(key) || KEY_IS_DOWN(key) || key == ' ') {
|
||||
|
||||
if (key >= '1' && key <= MIN('9', '0'+max_choice))
|
||||
i = key - '1';
|
||||
|
||||
else if (key == KEY_UP || key == '-' || key == '') {
|
||||
else if (KEY_IS_UP(key)) {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
/* Scroll list down */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (list_height > 1) {
|
||||
/* De-highlight current first item before scrolling down */
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
|
||||
print_item(list, items[scroll * 3], items[scroll * 3 + 1], status[scroll], 0,
|
||||
FALSE, DREF(ditems, scroll));
|
||||
scrollok(list, TRUE);
|
||||
wscrl(list, -1);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll--;
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
|
||||
TRUE, DREF(ditems, scroll));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
@ -283,22 +288,26 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
else
|
||||
i = choice - 1;
|
||||
}
|
||||
else if (key == KEY_DOWN || key == '+' || key == '') {
|
||||
else if (KEY_IS_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) {
|
||||
/* De-highlight current last item before scrolling up */
|
||||
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
|
||||
status[scroll+max_choice-1], max_choice-1, FALSE, DREF(ditems, scroll + max_choice - 1));
|
||||
print_item(list, items[(scroll + max_choice - 1) * 3],
|
||||
items[(scroll + max_choice - 1) * 3 + 1],
|
||||
status[scroll + max_choice - 1], max_choice - 1,
|
||||
FALSE, DREF(ditems, scroll + max_choice - 1));
|
||||
scrollok(list, TRUE);
|
||||
scroll(list);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll++;
|
||||
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
|
||||
status[scroll+max_choice-1], max_choice-1, TRUE, DREF(ditems, scroll + max_choice - 1));
|
||||
print_item(list, items[(scroll + max_choice - 1) * 3],
|
||||
items[(scroll + max_choice - 1) * 3 + 1],
|
||||
status[scroll + max_choice - 1], max_choice - 1, TRUE,
|
||||
DREF(ditems, scroll + max_choice - 1));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
@ -317,13 +326,14 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
WINDOW *save;
|
||||
|
||||
save = dupwin(newscr);
|
||||
st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
|
||||
st = ditems[scroll + choice].fire(&ditems[scroll + choice]); /* Call "fire" action */
|
||||
if (st & DITEM_RESTORE) {
|
||||
touchwin(save);
|
||||
wrefresh(save);
|
||||
}
|
||||
delwin(save);
|
||||
if (st & DITEM_REDRAW) {
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wclear(list);
|
||||
for (i = 0; i < item_no; i++)
|
||||
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
|
||||
for (i = 0; i < max_choice; i++) {
|
||||
@ -335,10 +345,10 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
}
|
||||
delwin(save);
|
||||
if (st & DITEM_LEAVE_MENU) {
|
||||
/* Allow a fire action to take us out of the menu */
|
||||
key = ESC;
|
||||
rval = 0;
|
||||
break;
|
||||
}
|
||||
else if (st & DITEM_RECREATE) {
|
||||
@ -365,7 +375,7 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
rbra = ']';
|
||||
if (!mark)
|
||||
mark = 'X';
|
||||
wprintw(list, "%c%c%c", lbra, status[scroll+choice] ? mark : ' ', rbra);
|
||||
wprintw(list, "%c%c%c", lbra, status[scroll + choice] ? mark : ' ', rbra);
|
||||
wnoutrefresh(list);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
@ -375,13 +385,13 @@ dialog_checklist(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);
|
||||
@ -469,26 +479,27 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
}
|
||||
}
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return button;
|
||||
rval = button;
|
||||
key = ESC; /* Bail out! */
|
||||
break;
|
||||
|
||||
/* Let me outta here! */
|
||||
case ESC:
|
||||
rval = -1;
|
||||
break;
|
||||
|
||||
/* Help! */
|
||||
case KEY_F(1):
|
||||
case '?':
|
||||
display_helpfile();
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (redraw_menu) {
|
||||
wclear(list);
|
||||
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));
|
||||
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);
|
||||
wrefresh(dialog);
|
||||
@ -497,9 +508,8 @@ dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return -1; /* ESC pressed */
|
||||
return rval;
|
||||
}
|
||||
/* End of dialog_checklist() */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -85,6 +85,10 @@
|
||||
#endif
|
||||
#endif /* HAVE_NCURSES */
|
||||
|
||||
/* Travel key conventions */
|
||||
#define KEY_IS_UP(key) ((key) == KEY_UP || (key) == '-' || key == '\020' /* ^P */)
|
||||
#define KEY_IS_DOWN(key) ((key) == KEY_DOWN || (key) == '+' || key == '\016' /* ^N */)
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
|
@ -39,18 +39,18 @@ int
|
||||
dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height,
|
||||
int cnt, void *it, unsigned char *result, int *ch, int *sc)
|
||||
{
|
||||
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, item_no, redraw_menu = FALSE;
|
||||
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button, choice,
|
||||
l, k, scroll, max_choice, item_no, redraw_menu = FALSE;
|
||||
char okButton, cancelButton;
|
||||
int rval = 0;
|
||||
WINDOW *dialog, *menu;
|
||||
unsigned char **items = NULL;
|
||||
dialogMenuItem *ditems;
|
||||
|
||||
draw:
|
||||
if (ch) /* restore menu item info */
|
||||
choice = *ch;
|
||||
if (sc)
|
||||
scroll = *sc;
|
||||
choice = ch ? *ch : 0;
|
||||
scroll = sc ? *sc : 0;
|
||||
button = 0;
|
||||
|
||||
/* If item_no is a positive integer, use old item specification format */
|
||||
if (cnt >= 0) {
|
||||
@ -77,30 +77,30 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
item_x = 0;
|
||||
/* Find length of longest item in order to center menu */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
l = strlen(items[i*2]);
|
||||
l = strlen(items[i * 2]);
|
||||
for (j = 0; j < item_no; j++) {
|
||||
k = strlen(items[j*2 + 1]);
|
||||
k = strlen(items[j * 2 + 1]);
|
||||
tag_x = MAX(tag_x, l + k + 2);
|
||||
}
|
||||
item_x = MAX(item_x, l);
|
||||
}
|
||||
if (height < 0)
|
||||
height = strheight(prompt)+menu_height+4+2;
|
||||
height = strheight(prompt) + menu_height + 4 + 2;
|
||||
if (width < 0) {
|
||||
i = strwidth(prompt);
|
||||
j = ((title != NULL) ? strwidth(title) : 0);
|
||||
width = MAX(i,j);
|
||||
width = MAX(width,tag_x+4)+4;
|
||||
width = MAX(i, j);
|
||||
width = MAX(width, tag_x + 4) + 4;
|
||||
}
|
||||
width = MAX(width,24);
|
||||
width = MAX(width, 24);
|
||||
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
/* center dialog box on screen */
|
||||
x = DialogX ? DialogX : (COLS - width)/2;
|
||||
y = DialogY ? DialogY : (LINES - height)/2;
|
||||
x = DialogX ? DialogX : (COLS - width) / 2;
|
||||
y = DialogY ? DialogY : (LINES - height) / 2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
@ -109,45 +109,46 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
dialog = newwin(height, width, y, x);
|
||||
if (dialog == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
|
||||
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height, width, y, x);
|
||||
return -1;
|
||||
}
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
wmove(dialog, height - 3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
for (i = 0; i < width - 2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
wmove(dialog, height - 2, 1);
|
||||
for (i = 0; i < width - 2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
wmove(dialog, 0, (width - strlen(title)) / 2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
wmove(dialog, 1, 2);
|
||||
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
|
||||
print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
|
||||
|
||||
menu_width = width-6;
|
||||
menu_width = width - 6;
|
||||
getyx(dialog, cur_y, cur_x);
|
||||
box_y = cur_y + 1;
|
||||
box_x = (width - menu_width)/2 - 1;
|
||||
box_x = (width - menu_width) / 2 - 1;
|
||||
|
||||
/* 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(dialog);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
keypad(menu, TRUE);
|
||||
@ -160,14 +161,15 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
|
||||
/* Print the menu */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice, DREF(ditems, scroll + i));
|
||||
print_item(menu, items[(scroll + i) * 2], items[(scroll + i) * 2 + 1], i,
|
||||
i == choice, DREF(ditems, scroll + i));
|
||||
wnoutrefresh(menu);
|
||||
print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
|
||||
|
||||
display_helpline(dialog, height-1, width);
|
||||
display_helpline(dialog, height - 1, width);
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
x = width / 2 - 11;
|
||||
y = height - 2;
|
||||
|
||||
if (ditems && result) {
|
||||
cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
|
||||
@ -185,7 +187,6 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
}
|
||||
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
|
||||
@ -207,12 +208,13 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
}
|
||||
else if (result)
|
||||
strcpy(result, items[(scroll + choice) * 2]);
|
||||
delwin(menu);
|
||||
delwin(dialog);
|
||||
return 0;
|
||||
rval = 0;
|
||||
key = ESC; /* Punt! */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shortcut to cancel? */
|
||||
else if (toupper(key) == cancelButton) {
|
||||
if (toupper(key) == cancelButton) {
|
||||
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
|
||||
int status;
|
||||
WINDOW *save;
|
||||
@ -225,34 +227,33 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
}
|
||||
delwin(save);
|
||||
}
|
||||
delwin(menu);
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
rval = 1;
|
||||
key = ESC; /* Run away! */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Check if key pressed matches first character of any item tag in menu */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*2][0]))
|
||||
if (key < 0x100 && toupper(key) == toupper(items[(scroll + i) * 2][0]))
|
||||
break;
|
||||
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
|
||||
key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+' || key == '' || key == '') {
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || KEY_IS_UP(key) || KEY_IS_DOWN(key)) {
|
||||
if (key >= '1' && key <= MIN('9', '0'+max_choice))
|
||||
i = key - '1';
|
||||
else if (key == KEY_UP || key == '-' || key == '') {
|
||||
else if (KEY_IS_UP(key)) {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
/* Scroll menu down */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (menu_height > 1) {
|
||||
/* De-highlight current first item before scrolling down */
|
||||
print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, FALSE, DREF(ditems, scroll));
|
||||
print_item(menu, items[scroll * 2], items[scroll * 2 + 1], 0, FALSE, DREF(ditems, scroll));
|
||||
scrollok(menu, TRUE);
|
||||
wscrl(menu, -1);
|
||||
scrollok(menu, FALSE);
|
||||
}
|
||||
scroll--;
|
||||
print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, TRUE, DREF(ditems, scroll));
|
||||
print_item(menu, items[scroll * 2], items[scroll * 2 + 1], 0, TRUE, DREF(ditems, scroll));
|
||||
wnoutrefresh(menu);
|
||||
print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
@ -262,21 +263,23 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
else
|
||||
i = choice - 1;
|
||||
}
|
||||
else if (key == KEY_DOWN || key == '+' || key == '')
|
||||
else if (KEY_IS_DOWN(key))
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll+choice < item_no-1) {
|
||||
if (scroll + choice < item_no - 1) {
|
||||
/* Scroll menu up */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (menu_height > 1) {
|
||||
/* De-highlight current last item before scrolling up */
|
||||
print_item(menu, items[(scroll + max_choice - 1) * 2], items[(scroll + max_choice - 1) * 2 + 1],
|
||||
print_item(menu, items[(scroll + max_choice - 1) * 2],
|
||||
items[(scroll + max_choice - 1) * 2 + 1],
|
||||
max_choice-1, FALSE, DREF(ditems, scroll + max_choice - 1));
|
||||
scrollok(menu, TRUE);
|
||||
scroll(menu);
|
||||
scrollok(menu, FALSE);
|
||||
}
|
||||
scroll++;
|
||||
print_item(menu, items[(scroll + max_choice - 1) * 2], items[(scroll + max_choice - 1) * 2 + 1],
|
||||
print_item(menu, items[(scroll + max_choice - 1) * 2],
|
||||
items[(scroll + max_choice - 1) * 2 + 1],
|
||||
max_choice - 1, TRUE, DREF(ditems, scroll + max_choice - 1));
|
||||
wnoutrefresh(menu);
|
||||
print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
|
||||
@ -304,16 +307,10 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
|
||||
/* save info about menu item position */
|
||||
if (ch)
|
||||
*ch = choice;
|
||||
if (sc)
|
||||
*sc = scroll;
|
||||
|
||||
switch (key) {
|
||||
case KEY_PPAGE:
|
||||
if (scroll > height-4) { /* can we go up? */
|
||||
scroll -= (height-4);
|
||||
if (scroll > height - 4) { /* can we go up? */
|
||||
scroll -= (height - 4);
|
||||
} else {
|
||||
scroll = 0;
|
||||
}
|
||||
@ -323,7 +320,8 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
case KEY_NPAGE:
|
||||
if (scroll + menu_height >= item_no-1 - menu_height) { /* can we go down a full page? */
|
||||
scroll = item_no - menu_height;
|
||||
if (scroll < 0) scroll = 0;
|
||||
if (scroll < 0)
|
||||
scroll = 0;
|
||||
} else {
|
||||
scroll += menu_height;
|
||||
}
|
||||
@ -338,7 +336,8 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
|
||||
case KEY_END:
|
||||
scroll = item_no - menu_height;
|
||||
if (scroll < 0) scroll = 0;
|
||||
if (scroll < 0)
|
||||
scroll = 0;
|
||||
choice = max_choice - 1;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
@ -381,7 +380,12 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
delwin(save);
|
||||
if (status & DITEM_CONTINUE)
|
||||
continue;
|
||||
else if (status & DITEM_RECREATE && !(status & DITEM_LEAVE_MENU)) {
|
||||
else if (status & DITEM_LEAVE_MENU) {
|
||||
/* Allow a fire action to take us out of the menu */
|
||||
key = ESC;
|
||||
break;
|
||||
}
|
||||
else if (status & DITEM_RECREATE) {
|
||||
delwin(menu);
|
||||
delwin(dialog);
|
||||
dialog_clear();
|
||||
@ -392,19 +396,26 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
else if (result)
|
||||
strcpy(result, items[(scroll+choice)*2]);
|
||||
}
|
||||
delwin(menu);
|
||||
delwin(dialog);
|
||||
return button;
|
||||
rval = button;
|
||||
key = ESC;
|
||||
break;
|
||||
|
||||
case ESC:
|
||||
rval = -1;
|
||||
break;
|
||||
|
||||
case KEY_F(1):
|
||||
case '?':
|
||||
display_helpfile();
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* save info about menu item position */
|
||||
if (ch)
|
||||
*ch = choice;
|
||||
if (sc)
|
||||
*sc = scroll;
|
||||
|
||||
if (redraw_menu) {
|
||||
for (i = 0; i < max_choice; i++) {
|
||||
print_item(menu, items[(scroll + i) * 2], items[(scroll + i) * 2 + 1], i, i == choice,
|
||||
@ -416,12 +427,10 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
redraw_menu = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
delwin(menu);
|
||||
delwin(dialog);
|
||||
return -1; /* ESC pressed */
|
||||
return rval;
|
||||
}
|
||||
/* End of dialog_menu() */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -40,9 +40,10 @@ int
|
||||
dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
|
||||
int cnt, void *it, unsigned char *result)
|
||||
{
|
||||
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, *status, item_no = 0, was_on = 0;
|
||||
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button, choice,
|
||||
l, k, scroll, max_choice, *status, item_no = 0, was_on = 0;
|
||||
int redraw_menu = FALSE;
|
||||
int rval = 0;
|
||||
char okButton, cancelButton;
|
||||
WINDOW *dialog, *list;
|
||||
unsigned char **items = NULL;
|
||||
@ -56,6 +57,7 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
|
||||
draw:
|
||||
button = choice = scroll = 0;
|
||||
/* Previous calling syntax, e.g. just a list of strings? */
|
||||
if (cnt >= 0) {
|
||||
items = it;
|
||||
@ -98,30 +100,30 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
item_x = 0;
|
||||
/* Find length of longest item in order to center radiolist */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
l = strlen(items[i*3]);
|
||||
l = strlen(items[i * 3]);
|
||||
for (j = 0; j < item_no; j++) {
|
||||
k = strlen(items[j*3 + 1]);
|
||||
k = strlen(items[j * 3 + 1]);
|
||||
check_x = MAX(check_x, l + k + 6);
|
||||
}
|
||||
item_x = MAX(item_x, l);
|
||||
}
|
||||
if (height < 0)
|
||||
height = strheight(prompt)+list_height+4+2;
|
||||
height = strheight(prompt) + list_height + 4 + 2;
|
||||
if (width < 0) {
|
||||
i = strwidth(prompt);
|
||||
j = ((title != NULL) ? strwidth(title) : 0);
|
||||
width = MAX(i,j);
|
||||
width = MAX(width,check_x+4)+4;
|
||||
width = MAX(i, j);
|
||||
width = MAX(width, check_x + 4) + 4;
|
||||
}
|
||||
width = MAX(width,24);
|
||||
width = MAX(width, 24);
|
||||
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
/* center dialog box on screen */
|
||||
x = DialogX ? DialogX : (COLS - width)/2;
|
||||
y = DialogY ? DialogY : (LINES - height)/2;
|
||||
x = DialogX ? DialogX : (COLS - width) / 2;
|
||||
y = DialogY ? DialogY : (LINES - height) / 2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
@ -130,45 +132,46 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
dialog = newwin(height, width, y, x);
|
||||
if (dialog == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
|
||||
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height, width, y, x);
|
||||
return -1;
|
||||
}
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
wmove(dialog, height - 3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
for (i = 0; i < width - 2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
wmove(dialog, height - 2, 1);
|
||||
for (i = 0; i < width - 2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
wmove(dialog, 0, (width - strlen(title)) / 2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
wmove(dialog, 1, 2);
|
||||
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
|
||||
print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
|
||||
|
||||
list_width = width-6;
|
||||
list_width = width - 6;
|
||||
getyx(dialog, cur_y, cur_x);
|
||||
box_y = cur_y + 1;
|
||||
box_x = (width - list_width)/2 - 1;
|
||||
box_x = (width - list_width) / 2 - 1;
|
||||
|
||||
/* 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(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);
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
keypad(list, TRUE);
|
||||
@ -181,14 +184,14 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
|
||||
/* Print the list */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
|
||||
print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
|
||||
display_helpline(dialog, height-1, width);
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
x = width/ 2 - 11;
|
||||
y = height - 2;
|
||||
if (ditems && result) {
|
||||
cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
|
||||
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
|
||||
@ -203,8 +206,8 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
okButton = 'O';
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
|
||||
@ -233,12 +236,13 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
}
|
||||
}
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return 0;
|
||||
rval = 0;
|
||||
key = ESC;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shortcut to cancel */
|
||||
else if (toupper(key) == cancelButton) {
|
||||
if (toupper(key) == cancelButton) {
|
||||
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
|
||||
int st;
|
||||
WINDOW *save;
|
||||
@ -251,9 +255,9 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
delwin(save);
|
||||
}
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
rval = 1;
|
||||
key = ESC;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if key pressed matches first character of any item tag in list */
|
||||
@ -262,23 +266,25 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
break;
|
||||
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
|
||||
key == KEY_UP || key == KEY_DOWN || key == ' ' || key == '+' || key == '-' || key == '' || key == '') {
|
||||
KEY_IS_UP(key) || KEY_IS_DOWN(key) || key == ' ') {
|
||||
if (key >= '1' && key <= MIN('9', '0' + max_choice))
|
||||
i = key - '1';
|
||||
else if (key == KEY_UP || key == '-' || key == '') {
|
||||
else if (KEY_IS_UP(key)) {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
/* Scroll list down */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (list_height > 1) {
|
||||
/* De-highlight current first item before scrolling down */
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
|
||||
FALSE, DREF(ditems, scroll));
|
||||
scrollok(list, TRUE);
|
||||
wscrl(list, -1);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll--;
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
|
||||
TRUE, DREF(ditems, scroll));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
@ -288,22 +294,26 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
else
|
||||
i = choice - 1;
|
||||
}
|
||||
else if (key == KEY_DOWN || key == '+' || key == '') {
|
||||
else if (KEY_IS_DOWN(key)) {
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll + choice < item_no - 1) {
|
||||
/* Scroll list up */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (list_height > 1) {
|
||||
/* De-highlight current last item before scrolling up */
|
||||
print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
|
||||
status[scroll + max_choice - 1], max_choice - 1, FALSE, DREF(ditems, scroll + max_choice - 1));
|
||||
print_item(list, items[(scroll + max_choice - 1) * 3],
|
||||
items[(scroll + max_choice - 1) * 3 + 1],
|
||||
status[scroll + max_choice - 1], max_choice - 1,
|
||||
FALSE, DREF(ditems, scroll + max_choice - 1));
|
||||
scrollok(list, TRUE);
|
||||
scroll(list);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll++;
|
||||
print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
|
||||
status[scroll + max_choice - 1], max_choice - 1, TRUE, DREF(ditems, scroll + max_choice - 1));
|
||||
print_item(list, items[(scroll + max_choice - 1) * 3],
|
||||
items[(scroll + max_choice - 1) * 3 + 1],
|
||||
status[scroll + max_choice - 1], max_choice - 1,
|
||||
TRUE, DREF(ditems, scroll + max_choice - 1));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
@ -327,7 +337,9 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
touchwin(save);
|
||||
wrefresh(save);
|
||||
}
|
||||
delwin(save);
|
||||
if (st & DITEM_REDRAW) {
|
||||
wclear(list);
|
||||
for (i = 0; i < item_no; i++)
|
||||
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
|
||||
|
||||
@ -340,7 +352,6 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
delwin(save);
|
||||
if (st & DITEM_LEAVE_MENU) {
|
||||
/* Allow a fire action to take us out of the menu */
|
||||
key = ESC;
|
||||
@ -363,8 +374,8 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
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));
|
||||
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);
|
||||
@ -464,24 +475,24 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
}
|
||||
}
|
||||
}
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return button;
|
||||
rval = button;
|
||||
key = ESC;
|
||||
break;
|
||||
|
||||
case ESC:
|
||||
rval = -1;
|
||||
break;
|
||||
|
||||
case KEY_F(1):
|
||||
case '?':
|
||||
display_helpfile();
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (redraw_menu) {
|
||||
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));
|
||||
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);
|
||||
wrefresh(dialog);
|
||||
@ -491,10 +502,8 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
|
||||
delwin(list);
|
||||
delwin(dialog);
|
||||
return -1; /* ESC pressed */
|
||||
return rval; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_radiolist() */
|
||||
|
||||
|
||||
/*
|
||||
* Print list item
|
||||
|
Loading…
Reference in New Issue
Block a user