mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-01 00:18:15 +01:00
Add changes to:
o Support a new, fully backwards-compatible API for controling individual items in dialog menus. o Write a man page. o Add some test code.
This commit is contained in:
parent
49f8ea7107
commit
fa8dc2c075
@ -1,7 +1,9 @@
|
||||
# Makefile for libdialog
|
||||
# $Id: Makefile,v 1.12 1995/05/04 09:45:29 ache Exp $
|
||||
# $Id: Makefile,v 1.13 1995/08/06 12:22:47 bde Exp $
|
||||
|
||||
LIB= dialog
|
||||
MAN3= dialog.3
|
||||
|
||||
SHLIB_MAJOR= 3
|
||||
SHLIB_MINOR= 0
|
||||
SRCS= kernel.c rc.c checklist.c inputbox.c menubox.c msgbox.c \
|
||||
|
@ -3,6 +3,8 @@
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* Substantial rennovation: 12/18/95, Jordan K. Hubbard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
@ -23,8 +25,10 @@
|
||||
#include "dialog.priv.h"
|
||||
|
||||
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected);
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected,
|
||||
dialogMenuItem *me);
|
||||
|
||||
#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
|
||||
|
||||
static int list_width, check_x, item_x;
|
||||
|
||||
@ -32,23 +36,46 @@ static int list_width, check_x, item_x;
|
||||
/*
|
||||
* Display a dialog box with a list of options that can be turned on or off
|
||||
*/
|
||||
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result)
|
||||
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width,
|
||||
int list_height, int item_no, 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;
|
||||
l, k, scroll = 0, max_choice, *status;
|
||||
int redraw_menu = FALSE;
|
||||
char okButton, cancelButton;
|
||||
WINDOW *dialog, *list;
|
||||
unsigned char **items;
|
||||
dialogMenuItem *ditems;
|
||||
|
||||
/* Allocate space for storing item on/off status */
|
||||
if ((status = malloc(sizeof(int)*item_no)) == NULL) {
|
||||
if ((status = alloca(sizeof(int) * abs(item_no))) == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++)
|
||||
status[i] = !strcasecmp(items[i*3 + 2], "on");
|
||||
|
||||
/* Previous calling syntax, e.g. just a list of strings? */
|
||||
if (item_no >= 0) {
|
||||
items = it;
|
||||
ditems = NULL;
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++)
|
||||
status[i] = !strcasecmp(items[i*3 + 2], "on");
|
||||
}
|
||||
/* It's the new specification format - fake the rest of the code out */
|
||||
else {
|
||||
item_no = abs(item_no);
|
||||
ditems = it;
|
||||
items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
|
||||
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
status[i] = ditems[i].checked ? (*ditems[i].checked)(&ditems[i]) : FALSE;
|
||||
items[i*3] = ditems[i].prompt;
|
||||
items[i*3 + 1] = ditems[i].title;
|
||||
items[i*3 + 2] = status[i] ? "on" : "off";
|
||||
}
|
||||
}
|
||||
max_choice = MIN(list_height, item_no);
|
||||
|
||||
check_x = 0;
|
||||
@ -63,23 +90,23 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
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;
|
||||
i = strwidth(prompt);
|
||||
j = ((title != NULL) ? strwidth(title) : 0);
|
||||
width = MAX(i,j);
|
||||
width = MAX(width,check_x+4)+4;
|
||||
}
|
||||
width = MAX(width,24);
|
||||
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
width = COLS;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
height = LINES;
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
@ -87,11 +114,11 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
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);
|
||||
exit(1);
|
||||
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);
|
||||
@ -113,31 +140,32 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
exit(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);
|
||||
|
||||
/* draw a box around the list items */
|
||||
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
|
||||
draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);
|
||||
|
||||
check_x = (list_width - check_x) / 2;
|
||||
item_x = check_x + item_x + 6;
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
@ -145,49 +173,83 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
/* Is this a fancy new style argument string where we get to override
|
||||
* the buttons, or an old style one where they're fixed?
|
||||
*/
|
||||
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,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : FALSE);
|
||||
okButton = toupper(ditems[OK_BUTTON].prompt[0]);
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : TRUE);
|
||||
}
|
||||
else {
|
||||
cancelButton = 'C';
|
||||
print_button(dialog, "Cancel", y, x + 14, FALSE);
|
||||
okButton = 'O';
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
|
||||
/* Shortcut to OK? */
|
||||
if (toupper(key) == okButton) {
|
||||
if (ditems && result && ditems[OK_BUTTON].fire) {
|
||||
if ((*ditems[OK_BUTTON].fire)(&ditems[OK_BUTTON]) == DITEM_FAILURE)
|
||||
continue;
|
||||
else
|
||||
delwin(dialog);
|
||||
}
|
||||
else {
|
||||
delwin(dialog);
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++) {
|
||||
if (status[i]) {
|
||||
strcat(result, items[i*3]);
|
||||
strcat(result, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Shortcut to cancel? */
|
||||
else if (toupper(key) == cancelButton) {
|
||||
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
|
||||
if ((*ditems[CANCEL_BUTTON].fire)(&ditems[CANCEL_BUTTON]) == DITEM_FAILURE)
|
||||
continue;
|
||||
}
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check if key pressed matches first character of any item tag in list */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
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 == '-' ) {
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || key == KEY_UP ||
|
||||
key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
|
||||
|
||||
if (key >= '1' && key <= MIN('9', '0'+max_choice))
|
||||
i = key - '1';
|
||||
|
||||
else if (key == KEY_UP || key == '-') {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll--;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll down */
|
||||
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);
|
||||
|
||||
#else
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
#endif
|
||||
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);
|
||||
@ -200,30 +262,17 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
else if (key == KEY_DOWN || key == '+') {
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll+choice < item_no-1) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll++;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll up */
|
||||
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);
|
||||
|
||||
#else
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
#endif
|
||||
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);
|
||||
@ -234,11 +283,49 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
i = choice + 1;
|
||||
}
|
||||
else if (key == ' ') { /* Toggle item status */
|
||||
status[scroll+choice] = !status[scroll+choice];
|
||||
char lbra = 0, rbra = 0, mark = 0;
|
||||
|
||||
if (ditems) {
|
||||
if (ditems[scroll+choice].fire) {
|
||||
int st = (*ditems[scroll+choice].fire)(&ditems[scroll+choice]);
|
||||
|
||||
if (st == DITEM_LEAVE_MENU) {
|
||||
/* Allow a fire action to take us out of the menu */
|
||||
key = ESC;
|
||||
break;
|
||||
}
|
||||
else if (st == DITEM_FAILURE)
|
||||
continue;
|
||||
else if (st == DITEM_REDRAW) {
|
||||
for (i = 0; i < max_choice; i++) {
|
||||
status[scroll + i] = ditems[scroll + i].checked ?
|
||||
(*ditems[scroll + i].checked)(&ditems[scroll + 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);
|
||||
wrefresh(dialog);
|
||||
}
|
||||
}
|
||||
status[scroll+choice] = ditems[scroll+choice].checked ?
|
||||
(*ditems[scroll+choice].checked)(&ditems[scroll+choice]) : FALSE;
|
||||
lbra = ditems[scroll+choice].lbra;
|
||||
rbra = ditems[scroll+choice].rbra;
|
||||
mark = ditems[scroll+choice].mark;
|
||||
}
|
||||
else
|
||||
status[scroll+choice] = !status[scroll+choice];
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
wmove(list, choice, check_x);
|
||||
wattrset(list, check_selected_attr);
|
||||
wprintw(list, "[%c]", status[scroll+choice] ? 'X' : ' ');
|
||||
if (!lbra)
|
||||
lbra = '[';
|
||||
if (!rbra)
|
||||
rbra = ']';
|
||||
if (!mark)
|
||||
mark = 'X';
|
||||
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);
|
||||
@ -248,11 +335,13 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
@ -261,99 +350,118 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case KEY_PPAGE:
|
||||
if (scroll > height-4) { /* can we go up? */
|
||||
scroll -= (height-4);
|
||||
} else {
|
||||
scroll = 0;
|
||||
}
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
if (scroll + list_height >= item_no-1 - list_height) { /* can we go down a full page? */
|
||||
scroll = item_no - list_height;
|
||||
if (scroll < 0) scroll = 0;
|
||||
} else {
|
||||
scroll += list_height;
|
||||
}
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
case KEY_PPAGE: /* can we go up? */
|
||||
if (scroll > height - 4)
|
||||
scroll -= (height-4);
|
||||
else
|
||||
scroll = 0;
|
||||
choice = 0;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
case KEY_END:
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_NPAGE: /* can we go down a full page? */
|
||||
if (scroll + list_height >= item_no-1 - list_height) {
|
||||
scroll = item_no - list_height;
|
||||
if (scroll < 0) scroll = 0;
|
||||
choice = max_choice - 1;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
case 'O':
|
||||
case 'o':
|
||||
delwin(dialog);
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
if (status[i]) {
|
||||
strcat(result, items[i*3]);
|
||||
strcat(result, "\n");
|
||||
}
|
||||
free(status);
|
||||
return 0;
|
||||
case 'C':
|
||||
case 'c':
|
||||
delwin(dialog);
|
||||
free(status);
|
||||
return 1;
|
||||
case TAB:
|
||||
case KEY_BTAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
if (!button) {
|
||||
button = 1; /* Indicates "Cancel" button is selected */
|
||||
print_button(dialog, " OK ", y, x, FALSE);
|
||||
print_button(dialog, "Cancel", y, x+14, TRUE);
|
||||
}
|
||||
else {
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\r':
|
||||
delwin(dialog);
|
||||
if (!button) {
|
||||
if (scroll < 0)
|
||||
scroll = 0;
|
||||
}
|
||||
else
|
||||
scroll += list_height;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_HOME: /* go to the top */
|
||||
scroll = 0;
|
||||
choice = 0;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_END: /* Go to the bottom */
|
||||
scroll = item_no - list_height;
|
||||
if (scroll < 0)
|
||||
scroll = 0;
|
||||
choice = max_choice - 1;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
/* swap the selection of OK/Cancel buttons */
|
||||
case TAB:
|
||||
case KEY_BTAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
button = !button;
|
||||
if (ditems && result) {
|
||||
if (button) {
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : !button);
|
||||
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : button);
|
||||
}
|
||||
else {
|
||||
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : button);
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : !button);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (button) {
|
||||
print_button(dialog, " OK ", y, x, !button);
|
||||
print_button(dialog, "Cancel", y, x + 14, button);
|
||||
}
|
||||
else {
|
||||
print_button(dialog, "Cancel", y, x + 14, button);
|
||||
print_button(dialog, " OK ", y, x, !button);
|
||||
}
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
|
||||
/* Select either the OK or Cancel button */
|
||||
case '\n':
|
||||
case '\r':
|
||||
if (!button && result) {
|
||||
if (ditems && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
|
||||
if ((*ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire)(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]) ==
|
||||
DITEM_FAILURE)
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
for (i = 0; i < item_no; i++) {
|
||||
if (status[i]) {
|
||||
strcat(result, items[i*3]);
|
||||
strcat(result, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
free(status);
|
||||
return button;
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
delwin(dialog);
|
||||
return button;
|
||||
break;
|
||||
|
||||
/* Let me outta here! */
|
||||
case ESC:
|
||||
break;
|
||||
|
||||
/* Help! */
|
||||
case KEY_F(1):
|
||||
case '?':
|
||||
display_helpfile();
|
||||
break;
|
||||
display_helpfile();
|
||||
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);
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
redraw_menu = FALSE;
|
||||
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));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
redraw_menu = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delwin(dialog);
|
||||
free(status);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_checklist() */
|
||||
@ -362,7 +470,8 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
/*
|
||||
* Print list item
|
||||
*/
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected)
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected,
|
||||
dialogMenuItem *me)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -373,7 +482,9 @@ static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int
|
||||
waddch(win, ' ');
|
||||
wmove(win, choice, check_x);
|
||||
wattrset(win, selected ? check_selected_attr : check_attr);
|
||||
wprintw(win, "[%c]", status ? 'X' : ' ');
|
||||
wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '[',
|
||||
status ? me && me->mark ? me->mark : 'X' : ' ',
|
||||
me && me->rbra ? me->rbra : ']');
|
||||
wattrset(win, menubox_attr);
|
||||
waddch(win, ' ');
|
||||
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
|
||||
|
381
gnu/lib/libdialog/dialog.3
Normal file
381
gnu/lib/libdialog/dialog.3
Normal file
@ -0,0 +1,381 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1995, Jordan Hubbard
|
||||
.\"
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This manual page may be used, modified, copied, distributed, and
|
||||
.\" sold, in both source and binary form provided that the above
|
||||
.\" copyright and these terms are retained, verbatim, as the first
|
||||
.\" lines of this file. Under no circumstances is the author
|
||||
.\" responsible for the proper functioning of the software described herein
|
||||
.\" nor does the author assume any responsibility for damages incurred with
|
||||
.\" its use.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd December 18, 1995
|
||||
.Dt dialog 3
|
||||
.Os FreeBSD 2
|
||||
.Sh NAME
|
||||
.Nm draw_shadow ,
|
||||
.Nm draw_box ,
|
||||
.Nm line_edit ,
|
||||
.Nm strheight ,
|
||||
.Nm strwidth ,
|
||||
.Nm dialog_create_rc,
|
||||
.Nm dialog_yesno ,
|
||||
.Nm dialog_prgbox ,
|
||||
.Nm dialog_msgbox ,
|
||||
.Nm dialog_textbox ,
|
||||
.Nm dialog_menu ,
|
||||
.Nm dialog_checklist ,
|
||||
.Nm dialog_radiolist ,
|
||||
.Nm dialog_inputbox ,
|
||||
.Nm dialog_clear_norefresh ,
|
||||
.Nm dialog_clear ,
|
||||
.Nm dialog_update ,
|
||||
.Nm dialog_fselect ,
|
||||
.Nm dialog_notify ,
|
||||
.Nm dialog_mesgbox ,
|
||||
.Nm dialog_gauge ,
|
||||
.Nm init_dialog ,
|
||||
.Nm end_dialog ,
|
||||
.Nm use_helpfile ,
|
||||
.Nm use_helpline ,
|
||||
.Nm get_helpline ,
|
||||
.Nm restore_helpline .
|
||||
.Nd Provide a simple ncurses-based "GUI" interface.
|
||||
.Sh DESCRIPTION
|
||||
The dialog library attempts to provide a fairly simplistic set of
|
||||
fixed-presentation menus, input boxes, gauges, file requestors and
|
||||
other general purpose "GUI" (a bit of a stretch, since it uses
|
||||
ncurses) objects. Since the library also had its roots in a
|
||||
shell-script writer's utility (see the \fBdialog(1)\fR command), the
|
||||
early API was somewhat primitively based on strings being passed in or
|
||||
out and parsed. This API was later extended to take either the
|
||||
original arguments or arrays of \fBdialogMenuItem\fR structures,
|
||||
giving the user much more control over the internal behavior of each
|
||||
control. The \fBdialogMenuItem\fR structure internals are public:
|
||||
|
||||
.nf
|
||||
typedef struct _dmenu_item {
|
||||
char *\fBprompt\fR;
|
||||
char *\fBtitle\fR;
|
||||
int (*\fBchecked\fR)(struct _dmenu_item *self);
|
||||
int (*\fBfire\fR)(struct _dmenu_item *self);
|
||||
void *\fBdata\fR;
|
||||
char \fBlbra\fR, \fBmark\fR, \fBrbra\fR;
|
||||
} \fBdialogMenuItem\fR;
|
||||
.fi
|
||||
|
||||
The \fBprompt\fR and \fBtitle\fR strings are pretty much self-explanatory,
|
||||
and the \fBchecked\fR and \fBfire\fR function pointers provide optional
|
||||
display and action hooks (the \fBdata\fR variable being available for
|
||||
the convenience of those hooks) when more tightly coupled feedback between
|
||||
a menu object and user code is required. A number of clever tricks for
|
||||
simulating various kinds of item types can also be done by adjusting the
|
||||
values of \fBlbra\fR (default: '['), \fB\mark\fR (default: '*' for radio
|
||||
menus, 'X' for check menus) and \fBrbra\fR (default: ']') and declaring
|
||||
a reasonable \fBchecked\fR hook, which should return TRUE for the `marked' state
|
||||
and FALSE for `unmarked.' If an item has a \fBfire\fR hook associated
|
||||
with it, it will also be called whenever the item is "toggled" in some way
|
||||
and should return one of the following codes:
|
||||
.nf
|
||||
|
||||
#define DITEM_SUCCESS 0 /* Successful completion */
|
||||
#define DITEM_FAILURE -1 /* Failed to "fire" */
|
||||
#define DITEM_LEAVE_MENU -2 /* Treat selection as "Ok" */
|
||||
#define DITEM_REDRAW -3 /* Menu has changed, redraw it */
|
||||
.fi
|
||||
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dialog.h>
|
||||
.Ft "void"
|
||||
.Fn draw_shadow "WINDOW *win" "int y" "int x" "int height" "int width"
|
||||
|
||||
Draws a shadow in curses window \fBwin\fR using the dimensions
|
||||
of \fBx, y, width\fR and \fBheight\fR. Returns 0 on success, -1 on failure.
|
||||
|
||||
.Ft "void"
|
||||
.Fn draw_box "WINDOW *win" "int y" "int x" "int height" "int width" "chtype box" "chtype border"
|
||||
|
||||
Draws a bordered box using the dimensions of \fBx, y, width\fR and
|
||||
\fBheight\fR. The attributes from \fBbox\fR and \fBborder\fR are
|
||||
used, if specified, while painting the box and border regions of the
|
||||
object.
|
||||
|
||||
.Ft "int"
|
||||
.Fn line_edit "WINDOW *dialog" "int box_y" "int box_x" "int flen" "int box_width" "chtype attrs" "int first" "u_char *result"
|
||||
|
||||
Invoke a simple line editor with an edit box of dimensions \fBbox_x,
|
||||
box_y\fR and \fBbox_width\fR. The field length is constrained by
|
||||
\fBflen\fR, starting at the \fBfirst\fR character specified and
|
||||
optionally displayed with character attributes \fBattrs\fR. The
|
||||
string being edited is stored in \fBresult\fR.
|
||||
|
||||
Returns 0 on success, -1 on failure.
|
||||
|
||||
.Ft "int"
|
||||
.Fn strheight "const char *p"
|
||||
|
||||
Returns the height of string in \fBp\fR, counting newlines.
|
||||
|
||||
.Ft "int"
|
||||
.Fn strwidth "const char *p"
|
||||
|
||||
Returns the width of string in \fBp\fR, counting newlines.
|
||||
|
||||
.Ft "void"
|
||||
.Fn dialog_create_rc "u_char *filename"
|
||||
|
||||
Dump dialog library settings into \fBfilename\fR for later retreival
|
||||
as defaults. Returns 0 on success, -1 on failure.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_yesno "u_char *title" "u_char *prompt" "int height" "int width"
|
||||
|
||||
Display a text box using \fBtitle\fR and \fBprompt\fR strings of dimensions
|
||||
\fBheight\fR and \fBwidth\fR. Also paint a pair of \fBYes\fR and \fBNo\fR
|
||||
buttons at the bottom. If the \fBYes\fR button is chosen, return FALSE.
|
||||
If \fBNo\fR, return TRUE.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_prgbox "u_char *title" "u_char *line" "int height" "int width" "int pause" "int use_shell"
|
||||
|
||||
Display a text box of dimensions \fBheight\fR and \fBwidth\fR
|
||||
containing the output of command \fBline\fR. If \fBuse_shell\fR is
|
||||
TRUE, \fBline\fR is passed as an argument to \fBsh(1)\fR, otherwise it
|
||||
is simply passed to \fBexec(3)\fR. If \fBpause\fR is TRUE, a final
|
||||
confirmation requestor will be put up when execution terminates.
|
||||
|
||||
Returns 0 on success, -1 on failure.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_textbox "u_char *title" "u_char *prompt" "int height" "int width"
|
||||
|
||||
Display a text box containing the contents of string \fBprompt\fR of dimensions
|
||||
\fBheight\fR and \fBwidth\fR.
|
||||
|
||||
Returns 0 on success, -1 on failure.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_menu "u_char *title" "u_char *prompt" "int height" "int width" "int menu_height" "int item_no" "void *itptr" "u_char *result, int *ch, int *sc"
|
||||
|
||||
Display a menu of dimensions \fBheight\fR and \fBwidth\fR with an
|
||||
optional internal menu height of \fBmenu_height\fR. The \fBitem_no\fR
|
||||
and \fBitptr\fR arguments are of particular importance since they,
|
||||
together, determine which of the 2 available APIs to use. To use the
|
||||
older and traditional interface, \fBitem_no\fR should be a positive
|
||||
integer representing the number of string pointer pairs to find in
|
||||
\fBitptr\fR (which should be of type \fBchar **\fR), the strings are
|
||||
expected to be in prompt and title order for each item and the
|
||||
\fBresult\fR parameter is expected to point to an array where the
|
||||
prompt string of the item selected will be copied. To use the newer
|
||||
interface, \fBitem_no\fR should be a \fInegative\fR integer
|
||||
representing the number of \fBdialogMenuItem\fR structures pointed to
|
||||
by \fBitptr\fR (which should be of type \fBdialogMenuItem *\fR), one
|
||||
structure per item. In the new interface, the \fBresult\fR variable
|
||||
is used as a simple boolean (not a pointer) and should be NULL if
|
||||
\fBitptr\fR only points to menu items and the default \fBOK\fR and
|
||||
\fBCancel\fR buttons are desired. If \fBresult\fR is non-NULL, then
|
||||
\fBitptr\fR is actually expected to point 2 locations \fBpast\fR the
|
||||
start of the menu item list. \fBitptr\fR[-1] is then expected to
|
||||
point to an item representing the \fBCancel\fR button, from which the
|
||||
\fBprompt\fR and \fBfire\fR actions are used to override the default
|
||||
behavior, and \fBitptr\fR[-2] to the same for the \fBOK\fR button.
|
||||
|
||||
Using either API behavior, the \fBch\fR and \fBsc\fR values may be passed in to preserve current
|
||||
item selection and scroll position values across calls.
|
||||
|
||||
Returns 0 on success, 1 on Cancel and -1 on failure or ESC.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_checklist "u_char *title" "u_char *prompt" "int height" "int width" "int m_height" "int item_no" "void *itptr" "u_char *result"
|
||||
|
||||
Display a menu of dimensions \fBheight\fR and \fBwidth\fR with an
|
||||
optional internal menu height of \fBmenu_height\fR. The \fBitem_no\fR
|
||||
and \fBitptr\fR arguments are of particular importance since they,
|
||||
together, determine which of the 2 available APIs to use. To use the
|
||||
older and traditional interface, \fBitem_no\fR should be a positive
|
||||
integer representing the number of string pointer tuples to find in
|
||||
\fBitptr\fR (which should be of type \fBchar **\fR), the strings are
|
||||
expected to be in prompt, title and state ("on" or "off") order for
|
||||
each item and the \fBresult\fR parameter is expected to point to an
|
||||
array where the prompt string of the item(s) selected will be
|
||||
copied. To use the newer interface, \fBitem_no\fR should be a
|
||||
\fInegative\fR integer representing the number of \fBdialogMenuItem\fR
|
||||
structures pointed to by \fBitptr\fR (which should be of type
|
||||
\fBdialogMenuItem *\fR), one structure per item. In the new interface,
|
||||
the \fBresult\fR variable is used as a simple boolean (not a pointer)
|
||||
and should be NULL if \fBitptr\fR only points to menu items and the
|
||||
default \fBOK\fR and \fBCancel\fR buttons are desired. If
|
||||
\fBresult\fR is non-NULL, then \fBitptr\fR is actually expected to
|
||||
point 2 locations \fBpast\fR the start of the menu item list.
|
||||
\fBitptr\fR[-1] is then expected to point to an item representing the
|
||||
\fBCancel\fR button, from which the \fBprompt\fR and \fBfire\fR
|
||||
actions are used to override the default behavior, and \fBitptr\fR[-2]
|
||||
to the same for the \fBOK\fR button.
|
||||
|
||||
In the standard API model, the menu supports the selection of multiple items,
|
||||
each of which is marked with an `X' character to denote selection. When
|
||||
the OK button is selected, the prompt values for all items selected are
|
||||
concatenated into the \fBresult\fR string.
|
||||
|
||||
In the new API model, it is not actually necessary to preserve
|
||||
"checklist" semantics at all since practically everything about how
|
||||
each item is displayed or marked as "selected" is fully configurable.
|
||||
You could have a single checklist menu that actually contained a group
|
||||
of items with "radio" behavior, "checklist" behavior and standard menu
|
||||
item behavior. The only reason to call \fBdialog_checklist\fR over
|
||||
\fBdialog_radiolist\fR in the new API model is to inherit the base
|
||||
behavior, you're no longer constrained by it.
|
||||
|
||||
Returns 0 on success, 1 on Cancel and -1 on failure or ESC.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_radiolist "u_char *title" "u_char *prompt" "int height" "int width" "int m_height" "int item_no" "void *it" "u_char *result"
|
||||
|
||||
Display a menu of dimensions \fBheight\fR and \fBwidth\fR with an
|
||||
optional internal menu height of \fBmenu_height\fR. The \fBitem_no\fR
|
||||
and \fBitptr\fR arguments are of particular importance since they,
|
||||
together, determine which of the 2 available APIs to use. To use the
|
||||
older and traditional interface, \fBitem_no\fR should be a positive
|
||||
integer representing the number of string pointer tuples to find in
|
||||
\fBitptr\fR (which should be of type \fBchar **\fR), the strings are
|
||||
expected to be in prompt, title and state ("on" or "off") order for
|
||||
each item and the \fBresult\fR parameter is expected to point to an
|
||||
array where the prompt string of the item(s) selected will be
|
||||
copied. To use the newer interface, \fBitem_no\fR should be a
|
||||
\fInegative\fR integer representing the number of \fBdialogMenuItem\fR
|
||||
structures pointed to by \fBitptr\fR (which should be of type
|
||||
\fBdialogMenuItem *\fR), one structure per item. In the new interface,
|
||||
the \fBresult\fR variable is used as a simple boolean (not a pointer)
|
||||
and should be NULL if \fBitptr\fR only points to menu items and the
|
||||
default \fBOK\fR and \fBCancel\fR buttons are desired. If
|
||||
\fBresult\fR is non-NULL, then \fBitptr\fR is actually expected to
|
||||
point 2 locations \fBpast\fR the start of the menu item list.
|
||||
\fBitptr\fR[-1] is then expected to point to an item representing the
|
||||
\fBCancel\fR button, from which the \fBprompt\fR and \fBfire\fR
|
||||
actions are used to override the default behavior, and \fBitptr\fR[-2]
|
||||
does the same for the traditional \fBOK\fR button.
|
||||
|
||||
In the standard API model, the menu supports the selection of only one
|
||||
of multiple items, the currently active item marked with an `*'
|
||||
character to denote selection. When the OK button is selected, the
|
||||
prompt value for this item is copied into the \fBresult\fR string.
|
||||
|
||||
In the new API model, it is not actually necessary to preserve
|
||||
"radio button" semantics at all since practically everything about how
|
||||
each item is displayed or marked as "selected" is fully configurable.
|
||||
You could have a single radio menu that actually contained a group
|
||||
of items with "checklist" behavior, "radio" behavior and standard menu
|
||||
item behavior. The only reason to call \fBdialog_radiolist\fR over
|
||||
\fBdialog_checklistlist\fR in the new API model is to inherit the base
|
||||
behavior.
|
||||
|
||||
Returns 0 on success, 1 on Cancel and -1 on failure or ESC.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_inputbox "u_char *title" "u_char *prompt" "int height" "int width" "u_char *result"
|
||||
|
||||
Displays a single-line text input field in a box displaying \fBtitle\fR and \fBprompt\fR
|
||||
of dimensions \fBheight\fR and \fBwidth\fR. The field entered is stored in \fBresult\fR.
|
||||
|
||||
Returns 0 on success, -1 on failure or ESC.
|
||||
|
||||
.Ft "char *"
|
||||
.Fn dialog_fselect "char *dir" "char *fmask"
|
||||
|
||||
Brings up a file selector dialog starting at \fBdir\fR and showing only those file names
|
||||
matching \fBfmask\fR.
|
||||
|
||||
Returns filename selected or NULL.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_dselect "char *dir" "char *fmask"
|
||||
|
||||
Brings up a directory selector dialog starting at \fBdir\fR and showing only those directory names
|
||||
matching \fBfmask\fR.
|
||||
|
||||
Returns directory name selected or NULL.
|
||||
|
||||
.Ft "void"
|
||||
.Fn dialog_notify "char *msg"
|
||||
|
||||
Bring up a generic "hey, you!" notifier dialog containing \fBmsg\fR.
|
||||
|
||||
.Ft "int"
|
||||
.Fn dialog_mesgbox "u_char *title" "u_char *prompt" "int height" "int width"
|
||||
|
||||
Like a notifier dialog, but with more control over \fBtitle\fR, \fBprompt\fR, \fBwidth\fR and
|
||||
\fBheight\fR. This object will also wait for user confirmation, unlike \fBdialog_notify\fR.
|
||||
|
||||
Returns 0 on success, -1 on failure.
|
||||
|
||||
.Ft "void"
|
||||
.Fn dialog_gauge "u_char *title" "u_char *prompt" "int y" "int x" "int height" "int width" "int perc"
|
||||
|
||||
Display a horizontal bar-graph style gauge. A value of \fB100\fR for \fBperc\fR constitutes
|
||||
a full gauge, a value of \fB0\fR an empty one.
|
||||
|
||||
.Ft "void"
|
||||
.Fn use_helpfile "char *helpfile"
|
||||
|
||||
For any menu supporting context sensitive help, invoke the text box
|
||||
object on this file whenever the \fBF1\fR key is pressed.
|
||||
|
||||
|
||||
.Ft "void"
|
||||
.Fn use_helpline "char *helpline"
|
||||
|
||||
Display this line of helpful text below any menu being displayed.
|
||||
|
||||
.Ft "char *"
|
||||
.Fn get_helpline "void"
|
||||
|
||||
Get the current value of the helpful text line.
|
||||
|
||||
.Ft "void"
|
||||
.Fn dialog_clear_norefresh "void"
|
||||
|
||||
Clear the screen back to the dialog background color, but don't refresh the contents
|
||||
just yet.
|
||||
|
||||
.Ft "void"
|
||||
.Fn dialog_clear "void"
|
||||
|
||||
Clear the screen back to the dialog background color immediately.
|
||||
|
||||
.Ft "void"
|
||||
.Fn dialog_update "void"
|
||||
|
||||
Do any pending screen refreshes now.
|
||||
|
||||
.Ft "void"
|
||||
.Fn init_dialog "void"
|
||||
|
||||
Initialize the dialog library (call this routine before any other dialog API calls).
|
||||
|
||||
.Ft "void"
|
||||
.Fn end_dialog "void"
|
||||
|
||||
Shut down the dialog library (call this if you need to get back to sanity).
|
||||
|
||||
.Sh SEE ALSO
|
||||
.Xr dialog 1 ,
|
||||
.Xr ncurses 3
|
||||
|
||||
.Sh AUTHORS
|
||||
The primary author would appear to be Savio Lam <lam836@cs.cuhk.hk> with contributions over
|
||||
the years by Stuart Herbert <S.Herbert@sheffield.ac.uk>, Marc van Kempen <wmbfmk@urc.tue.nl>,
|
||||
Andrey Chernov <ache@freebsd.org> and Jordan Hubbard <jkh@freebsd.org>.
|
||||
|
||||
.Sh HISTORY
|
||||
These functions appeared in
|
||||
.Em FreeBSD-2.0
|
||||
as the \fBdialog(1)\fR command and were soon split into library
|
||||
and command by Andrey Chernov. Marc van Kempen implemented most of the
|
||||
extra controls and objects and Jordan Hubbard added the dialogMenuItem
|
||||
renovations and this man page.
|
||||
.Sh BUGS
|
||||
Sure!
|
@ -1,8 +1,13 @@
|
||||
#ifndef _DIALOG_H_INCLUDE
|
||||
#define _DIALOG_H_INCLUDE
|
||||
|
||||
/*
|
||||
* dialog.h -- common declarations for all dialog modules
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* Substantial rennovation: 12/18/95, Jordan K. Hubbard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
@ -33,6 +38,26 @@
|
||||
|
||||
#endif
|
||||
|
||||
/* special return codes for `fire' actions */
|
||||
#define DITEM_SUCCESS 0
|
||||
#define DITEM_FAILURE -1
|
||||
#define DITEM_LEAVE_MENU -2
|
||||
#define DITEM_REDRAW -3
|
||||
|
||||
/* negative offsets for buttons in item lists, if specified */
|
||||
#define OK_BUTTON -2
|
||||
#define CANCEL_BUTTON -1
|
||||
|
||||
/* for use in describing more exotic behaviors */
|
||||
typedef struct _dmenu_item {
|
||||
char *prompt;
|
||||
char *title;
|
||||
int (*checked)(struct _dmenu_item *self);
|
||||
int (*fire)(struct _dmenu_item *self);
|
||||
void *data;
|
||||
char lbra, mark, rbra;
|
||||
} dialogMenuItem;
|
||||
|
||||
#define VERSION "0.4"
|
||||
#define MAX_LEN 2048
|
||||
|
||||
@ -87,7 +112,7 @@ extern bool use_shadow;
|
||||
void draw_shadow(WINDOW *win, int y, int x, int height, int width);
|
||||
#endif
|
||||
void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border);
|
||||
int line_edit(WINDOW* dialog, int box_y, int box_x, int flen, int box_width, chtype attrs, int first, unsigned char *result);
|
||||
int line_edit(WINDOW *dialog, int box_y, int box_x, int flen, int box_width, chtype attrs, int first, unsigned char *result);
|
||||
int strheight(const char *p);
|
||||
int strwidth(const char *p);
|
||||
|
||||
@ -96,9 +121,12 @@ int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int wi
|
||||
int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell);
|
||||
int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause);
|
||||
int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width);
|
||||
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result, int *ch, int *sc);
|
||||
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result);
|
||||
int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result);
|
||||
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height,
|
||||
int item_no, void *itptr, unsigned char *result, int *ch, int *sc);
|
||||
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
|
||||
int item_no, void *itptr, unsigned char *result);
|
||||
int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
|
||||
int item_no, void *itptr, unsigned char *result);
|
||||
int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result);
|
||||
void dialog_clear_norefresh(void);
|
||||
void dialog_clear(void);
|
||||
@ -115,5 +143,6 @@ void use_helpfile(char *helpfile);
|
||||
void use_helpline(char *helpline);
|
||||
char *get_helpline(void);
|
||||
void restore_helpline(char *helpline);
|
||||
void dialog_gauge(char *title, char *prompt, int y, int x,
|
||||
int height, int width, int perc);
|
||||
void dialog_gauge(char *title, char *prompt, int y, int x, int height, int width, int perc);
|
||||
|
||||
#endif /* _DIALOG_H_INCLUDE */
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Change these if you want
|
||||
*/
|
||||
@ -163,13 +164,15 @@ extern int parse_rc(void);
|
||||
#ifdef HAVE_NCURSES
|
||||
void color_setup(void);
|
||||
#endif
|
||||
|
||||
void attr_clear(WINDOW *win, int height, int width, chtype attr);
|
||||
void print_autowrap(WINDOW *win, unsigned char *prompt, int height, int width, int maxwidth, int y, int x, int center, int rawmode);
|
||||
void print_autowrap(WINDOW *win, unsigned char *prompt, int height, int width, int maxwidth,
|
||||
int y, int x, int center, int rawmode);
|
||||
void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected);
|
||||
FILE *raw_popen(const char *program, char * const *argv, const char *type);
|
||||
int raw_pclose(FILE *iop);
|
||||
void display_helpfile(void);
|
||||
void display_helpline(WINDOW *w, int y, int width);
|
||||
void print_arrows(WINDOW *dialog, int scroll, int menu_height, int item_no,
|
||||
int box_x, int box_y, int tag_x, int cur_x, int cur_y);
|
||||
void print_arrows(WINDOW *dialog, int scroll, int menu_height, int item_no, int box_x,
|
||||
int box_y, int tag_x, int cur_x, int cur_y);
|
||||
|
||||
|
@ -319,7 +319,7 @@ void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected)
|
||||
|
||||
wmove(win, y, x);
|
||||
wattrset(win, selected ? button_active_attr : button_inactive_attr);
|
||||
waddstr(win, "<");
|
||||
waddstr(win, selected ? "[" : " ");
|
||||
temp = strspn(label, " ");
|
||||
label += temp;
|
||||
wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
|
||||
@ -330,7 +330,7 @@ void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected)
|
||||
wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
|
||||
waddstr(win, label+1);
|
||||
wattrset(win, selected ? button_active_attr : button_inactive_attr);
|
||||
waddstr(win, ">");
|
||||
waddstr(win, selected ? "]" : " ");
|
||||
wmove(win, y, x+temp+1);
|
||||
}
|
||||
/* End of print_button() */
|
||||
|
@ -3,6 +3,8 @@
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* Substantial rennovation: 12/18/95, Jordan K. Hubbard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
@ -30,17 +32,38 @@ static int menu_width, tag_x, item_x;
|
||||
/*
|
||||
* Display a menu for choosing among a number of options
|
||||
*/
|
||||
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result, int *ch, int *sc)
|
||||
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height,
|
||||
int item_no, 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, redraw_menu = FALSE;
|
||||
char okButton, cancelButton;
|
||||
WINDOW *dialog, *menu;
|
||||
unsigned char **items;
|
||||
dialogMenuItem *ditems;
|
||||
|
||||
if (ch) /* restore menu item info */
|
||||
choice = *ch;
|
||||
if (sc)
|
||||
scroll = *sc;
|
||||
|
||||
/* If item_no is a positive integer, use old item specification format */
|
||||
if (item_no >= 0) {
|
||||
items = it;
|
||||
ditems = NULL;
|
||||
}
|
||||
/* It's the new specification format - fake the rest of the code out */
|
||||
else {
|
||||
item_no = abs(item_no);
|
||||
ditems = it;
|
||||
items = (unsigned char **)alloca((item_no * 2) * sizeof(unsigned char *));
|
||||
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
items[i*2] = ditems[i].prompt;
|
||||
items[i*2 + 1] = ditems[i].title;
|
||||
}
|
||||
}
|
||||
max_choice = MIN(menu_height, item_no);
|
||||
|
||||
tag_x = 0;
|
||||
@ -55,19 +78,19 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
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;
|
||||
i = strwidth(prompt);
|
||||
j = ((title != NULL) ? strwidth(title) : 0);
|
||||
width = MAX(i,j);
|
||||
width = MAX(width,tag_x+4)+4;
|
||||
}
|
||||
width = MAX(width,24);
|
||||
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
width = COLS;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
height = LINES;
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
@ -80,7 +103,7 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
if (dialog == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
@ -117,7 +140,7 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
if (menu == NULL) {
|
||||
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);
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
keypad(menu, TRUE);
|
||||
|
||||
@ -137,13 +160,51 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
|
||||
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,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : FALSE);
|
||||
okButton = toupper(ditems[OK_BUTTON].prompt[0]);
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : TRUE);
|
||||
}
|
||||
else {
|
||||
cancelButton = 'C';
|
||||
print_button(dialog, "Cancel", y, x + 14, FALSE);
|
||||
okButton = 'O';
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
|
||||
/* Shortcut to OK? */
|
||||
if (toupper(key) == okButton) {
|
||||
if (ditems && result && ditems[OK_BUTTON].fire) {
|
||||
if ((*ditems[OK_BUTTON].fire)(&ditems[OK_BUTTON]) == DITEM_FAILURE)
|
||||
continue;
|
||||
else
|
||||
delwin(dialog);
|
||||
}
|
||||
else {
|
||||
delwin(dialog);
|
||||
strcpy(result, items[(scroll+choice)*2]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Shortcut to cancel? */
|
||||
else if (toupper(key) == cancelButton) {
|
||||
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
|
||||
if ((*ditems[CANCEL_BUTTON].fire)(&ditems[CANCEL_BUTTON]) == DITEM_FAILURE)
|
||||
continue;
|
||||
}
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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]))
|
||||
@ -156,18 +217,6 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
else if (key == KEY_UP || key == '-') {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll--;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint menu to scroll down */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll menu down */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (menu_height > 1) {
|
||||
@ -179,7 +228,6 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
}
|
||||
scroll--;
|
||||
print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(menu);
|
||||
print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
@ -192,18 +240,6 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
else if (key == KEY_DOWN || key == '+')
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll+choice < item_no-1) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll++;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint menu to scroll up */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll menu up */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (menu_height > 1) {
|
||||
@ -215,7 +251,6 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
}
|
||||
scroll++;
|
||||
print_item(menu, items[(scroll+max_choice-1)*2], items[(scroll+max_choice-1)*2 + 1], max_choice-1, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(menu);
|
||||
print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
@ -255,6 +290,7 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
}
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_NPAGE:
|
||||
if (scroll + menu_height >= item_no-1 - menu_height) { /* can we go down a full page? */
|
||||
scroll = item_no - menu_height;
|
||||
@ -264,56 +300,75 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
}
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_HOME:
|
||||
scroll = 0;
|
||||
choice = 0;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_END:
|
||||
scroll = item_no - menu_height;
|
||||
if (scroll < 0) scroll = 0;
|
||||
choice = max_choice - 1;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
case 'O':
|
||||
case 'o':
|
||||
delwin(dialog);
|
||||
strcpy(result, items[(scroll+choice)*2]);
|
||||
return 0;
|
||||
case 'C':
|
||||
case 'c':
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
|
||||
case KEY_BTAB:
|
||||
case TAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
if (!button) {
|
||||
button = 1; /* Indicates "Cancel" button is selected */
|
||||
print_button(dialog, " OK ", y, x, FALSE);
|
||||
print_button(dialog, "Cancel", y, x+14, TRUE);
|
||||
}
|
||||
else {
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
button = !button;
|
||||
if (ditems && result) {
|
||||
if (button) {
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : !button);
|
||||
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : button);
|
||||
}
|
||||
else {
|
||||
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : button);
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : !button);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (button) {
|
||||
print_button(dialog, " OK ", y, x, !button);
|
||||
print_button(dialog, "Cancel", y, x + 14, button);
|
||||
}
|
||||
else {
|
||||
print_button(dialog, "Cancel", y, x + 14, button);
|
||||
print_button(dialog, " OK ", y, x, !button);
|
||||
}
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
delwin(dialog);
|
||||
if (!button)
|
||||
if (!button) {
|
||||
if (ditems && ditems[scroll + choice].fire) {
|
||||
if ((*ditems[scroll + choice].fire)(&ditems[scroll + choice]) == DITEM_FAILURE)
|
||||
continue;
|
||||
}
|
||||
else if (result)
|
||||
strcpy(result, items[(scroll+choice)*2]);
|
||||
return button;
|
||||
}
|
||||
delwin(dialog);
|
||||
return button;
|
||||
|
||||
case ESC:
|
||||
break;
|
||||
|
||||
case KEY_F(1):
|
||||
case '?':
|
||||
display_helpfile();
|
||||
break;
|
||||
}
|
||||
|
||||
if (redraw_menu) {
|
||||
for (i = 0; i < max_choice; i++) {
|
||||
print_item(menu, items[(scroll+i)*2],
|
||||
@ -325,7 +380,7 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
|
||||
redraw_menu = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delwin(dialog);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
* AUTHOR: Stuart Herbert - S.Herbert@sheffield.ac.uk
|
||||
* (from checklist.c by Savio Lam (lam836@cs.cuhk.hk))
|
||||
*
|
||||
* Substantial rennovation: 12/18/95, Jordan K. Hubbard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
@ -24,8 +26,10 @@
|
||||
#include "dialog.priv.h"
|
||||
|
||||
|
||||
static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected);
|
||||
static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected,
|
||||
dialogMenuItem *me);
|
||||
|
||||
#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
|
||||
|
||||
static int list_width, check_x, item_x;
|
||||
|
||||
@ -33,32 +37,61 @@ static int list_width, check_x, item_x;
|
||||
/*
|
||||
* Display a dialog box with a list of options that can be turned on or off
|
||||
*/
|
||||
int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result)
|
||||
int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
|
||||
int item_no, 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, was_on = 0;
|
||||
int redraw_menu = FALSE;
|
||||
char okButton, cancelButton;
|
||||
WINDOW *dialog, *list;
|
||||
unsigned char **items;
|
||||
dialogMenuItem *ditems;
|
||||
|
||||
/* Allocate space for storing item on/off status */
|
||||
if ((status = malloc(sizeof(int)*item_no)) == NULL) {
|
||||
if ((status = alloca(sizeof(int)*item_no)) == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
status[i] = !strcasecmp(items[i*3 + 2], "on");
|
||||
if (status[i])
|
||||
if (was_on) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nOnly one status can be ON in dialog_radiolist().\n");
|
||||
exit(-1);
|
||||
} else
|
||||
was_on = 1;
|
||||
|
||||
/* Previous calling syntax, e.g. just a list of strings? */
|
||||
if (item_no >= 0) {
|
||||
items = it;
|
||||
ditems = NULL;
|
||||
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
status[i] = !strcasecmp(items[i*3 + 2], "on");
|
||||
if (status[i]) {
|
||||
if (was_on)
|
||||
status[i] = FALSE;
|
||||
else
|
||||
was_on = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* It's the new specification format - fake the rest of the code out */
|
||||
else {
|
||||
item_no = abs(item_no);
|
||||
ditems = it;
|
||||
items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
status[i] = ditems[i].checked ? (*ditems[i].checked)(&ditems[i]) : FALSE;
|
||||
if (status[i]) {
|
||||
if (was_on)
|
||||
status[i] = FALSE;
|
||||
else
|
||||
was_on = 1;
|
||||
}
|
||||
items[i*3] = ditems[i].prompt;
|
||||
items[i*3 + 1] = ditems[i].title;
|
||||
items[i*3 + 2] = status[i] ? "on" : "off";
|
||||
}
|
||||
}
|
||||
max_choice = MIN(list_height, item_no);
|
||||
|
||||
|
||||
check_x = 0;
|
||||
item_x = 0;
|
||||
/* Find length of longest item in order to center radiolist */
|
||||
@ -71,23 +104,23 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
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;
|
||||
i = strwidth(prompt);
|
||||
j = ((title != NULL) ? strwidth(title) : 0);
|
||||
width = MAX(i,j);
|
||||
width = MAX(width,check_x+4)+4;
|
||||
}
|
||||
width = MAX(width,24);
|
||||
|
||||
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
width = COLS;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
height = LINES;
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
@ -96,10 +129,10 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
if (dialog == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
|
||||
exit(1);
|
||||
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);
|
||||
@ -122,21 +155,21 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
wattrset(dialog, dialog_attr);
|
||||
wmove(dialog, 1, 2);
|
||||
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
|
||||
|
||||
|
||||
list_width = width-6;
|
||||
getyx(dialog, cur_y, cur_x);
|
||||
box_y = cur_y + 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) {
|
||||
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);
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
keypad(list, TRUE);
|
||||
|
||||
|
||||
/* draw a box around the list items */
|
||||
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
|
||||
|
||||
@ -145,7 +178,7 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
@ -153,49 +186,78 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
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,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : FALSE);
|
||||
okButton = toupper(ditems[OK_BUTTON].prompt[0]);
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : TRUE);
|
||||
}
|
||||
else {
|
||||
cancelButton = 'C';
|
||||
print_button(dialog, "Cancel", y, x + 14, FALSE);
|
||||
okButton = 'O';
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
|
||||
/* See if its the short-cut to "OK" */
|
||||
if (toupper(key) == okButton) {
|
||||
if (ditems && result && ditems[OK_BUTTON].fire) {
|
||||
if ((*ditems[OK_BUTTON].fire)(&ditems[OK_BUTTON]) == DITEM_FAILURE)
|
||||
continue;
|
||||
else
|
||||
delwin(dialog);
|
||||
}
|
||||
else {
|
||||
delwin(dialog);
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++) {
|
||||
if (status[i]) {
|
||||
strcat(result, items[i*3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Shortcut to cancel */
|
||||
else if (toupper(key) == cancelButton) {
|
||||
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
|
||||
if ((*ditems[CANCEL_BUTTON].fire)(&ditems[CANCEL_BUTTON]) == DITEM_FAILURE)
|
||||
continue;
|
||||
}
|
||||
delwin(dialog);
|
||||
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]))
|
||||
break;
|
||||
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
|
||||
key == KEY_UP || key == KEY_DOWN || key == ' ' ||
|
||||
key == '+' || key == '-' ) {
|
||||
if (key >= '1' && key <= MIN('9', '0'+max_choice))
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
|
||||
key == KEY_UP || key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
|
||||
if (key >= '1' && key <= MIN('9', '0' + max_choice))
|
||||
i = key - '1';
|
||||
else if (key == KEY_UP || key == '-') {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll--;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll down */
|
||||
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);
|
||||
|
||||
#else
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
#endif
|
||||
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);
|
||||
@ -208,30 +270,19 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
else if (key == KEY_DOWN || key == '+') {
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll+choice < item_no-1) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll++;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll up */
|
||||
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);
|
||||
|
||||
#else
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
#endif
|
||||
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);
|
||||
@ -242,28 +293,47 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
i = choice + 1;
|
||||
}
|
||||
else if (key == ' ') { /* Toggle item status */
|
||||
if (!status[scroll+choice])
|
||||
{
|
||||
for (i=0; i<item_no; i++)
|
||||
status[i]=0;
|
||||
status[scroll+choice]=1;
|
||||
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);
|
||||
wnoutrefresh(list);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
if (status[scroll + choice])
|
||||
continue;
|
||||
else if (ditems) {
|
||||
if (ditems[scroll + choice].fire) {
|
||||
int st = (*ditems[scroll + choice].fire)(&ditems[scroll + choice]);
|
||||
|
||||
if (st == DITEM_LEAVE_MENU) {
|
||||
/* Allow a fire action to take us out of the menu */
|
||||
key = ESC;
|
||||
break;
|
||||
}
|
||||
else if (st == DITEM_FAILURE)
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < item_no; i++)
|
||||
status[i] = ditems[i].checked ? (*ditems[i].checked)(&ditems[i]) : FALSE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < item_no; i++)
|
||||
status[i] = 0;
|
||||
status[scroll + choice] = TRUE;
|
||||
}
|
||||
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));
|
||||
wnoutrefresh(list);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
@ -273,93 +343,109 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
|
||||
switch (key) {
|
||||
case KEY_PPAGE:
|
||||
if (scroll > height-4) { /* can we go up? */
|
||||
if (scroll > height-4) /* can we go up? */
|
||||
scroll -= (height-4);
|
||||
} else {
|
||||
else
|
||||
scroll = 0;
|
||||
}
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_NPAGE:
|
||||
if (scroll + list_height >= item_no-1 - list_height) { /* can we go down a full page? */
|
||||
scroll = item_no - list_height;
|
||||
if (scroll < 0) scroll = 0;
|
||||
} else {
|
||||
scroll += list_height;
|
||||
if (scroll < 0)
|
||||
scroll = 0;
|
||||
}
|
||||
else
|
||||
scroll += list_height;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_HOME:
|
||||
scroll = 0;
|
||||
choice = 0;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_END:
|
||||
scroll = item_no - list_height;
|
||||
if (scroll < 0) scroll = 0;
|
||||
if (scroll < 0)
|
||||
scroll = 0;
|
||||
choice = max_choice - 1;
|
||||
redraw_menu = TRUE;
|
||||
break;
|
||||
case 'O':
|
||||
case 'o':
|
||||
delwin(dialog);
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
if (status[i]) {
|
||||
strcpy(result, items[i*3]);
|
||||
break;
|
||||
}
|
||||
free(status);
|
||||
return 0;
|
||||
case 'C':
|
||||
case 'c':
|
||||
delwin(dialog);
|
||||
free(status);
|
||||
return 1;
|
||||
case KEY_BTAB:
|
||||
case TAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
if (!button) {
|
||||
button = 1; /* Indicates "Cancel" button is selected */
|
||||
print_button(dialog, " OK ", y, x, FALSE);
|
||||
print_button(dialog, "Cancel", y, x+14, TRUE);
|
||||
}
|
||||
else {
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
delwin(dialog);
|
||||
if (!button) {
|
||||
|
||||
case KEY_BTAB:
|
||||
case TAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
button = !button;
|
||||
if (ditems && result) {
|
||||
if (button) {
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : !button);
|
||||
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : button);
|
||||
}
|
||||
else {
|
||||
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
|
||||
ditems[CANCEL_BUTTON].checked ? (*ditems[CANCEL_BUTTON].checked)(&ditems[CANCEL_BUTTON]) : button);
|
||||
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
|
||||
ditems[OK_BUTTON].checked ? (*ditems[OK_BUTTON].checked)(&ditems[OK_BUTTON]) : !button);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (button) {
|
||||
print_button(dialog, " OK ", y, x, !button);
|
||||
print_button(dialog, "Cancel", y, x + 14, button);
|
||||
}
|
||||
else {
|
||||
print_button(dialog, "Cancel", y, x + 14, button);
|
||||
print_button(dialog, " OK ", y, x, !button);
|
||||
}
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
if (!button && result) {
|
||||
if (ditems && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
|
||||
if ((*ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire)(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]) == DITEM_FAILURE)
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
for (i = 0; i < item_no; i++) {
|
||||
if (status[i]) {
|
||||
strcpy(result, items[i*3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(status);
|
||||
return button;
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
delwin(dialog);
|
||||
return button;
|
||||
break;
|
||||
|
||||
case ESC:
|
||||
break;
|
||||
|
||||
case KEY_F(1):
|
||||
case '?':
|
||||
display_helpfile();
|
||||
break;
|
||||
display_helpfile();
|
||||
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);
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
redraw_menu = FALSE;
|
||||
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));
|
||||
wnoutrefresh(list);
|
||||
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
|
||||
wrefresh(dialog);
|
||||
redraw_menu = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,7 +459,8 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in
|
||||
/*
|
||||
* Print list item
|
||||
*/
|
||||
static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected)
|
||||
static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected,
|
||||
dialogMenuItem *me)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -384,7 +471,9 @@ static void print_item(WINDOW *win, char *tag, char *item, int status, int choic
|
||||
waddch(win, ' ');
|
||||
wmove(win, choice, check_x);
|
||||
wattrset(win, selected ? check_selected_attr : check_attr);
|
||||
wprintw(win, "(%c)", status ? '*' : ' ');
|
||||
wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '(',
|
||||
status ? me && me->mark ? me->mark : '*' : ' ',
|
||||
me && me->rbra ? me->rbra : ')');
|
||||
wattrset(win, menubox_attr);
|
||||
waddch(win, ' ');
|
||||
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
|
||||
|
Loading…
Reference in New Issue
Block a user