1
0
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:
Jordan K. Hubbard 1997-01-17 08:19:19 +00:00
parent 8d26fa1ec7
commit a59ff6e254
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21790
4 changed files with 189 additions and 157 deletions

View File

@ -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() */
/*

View File

@ -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
*/

View File

@ -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() */
/*

View File

@ -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