kconfig/lxdialog: support resize

In all dialogs now properly catch KEY_RESIZE and take proper action.
In mconf try to behave sensibly when a dialog routine returns
-ERRDISPLAYTOOSMALL.

The original check for a screnn size of 80x19 is kept for now.
It may make sense to remove it later, but thats anyway what
much text is adjusted for.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
This commit is contained in:
Sam Ravnborg 2006-07-29 22:48:57 +02:00 committed by Sam Ravnborg
parent f3cbcdc955
commit c8dc68ad0f
8 changed files with 161 additions and 71 deletions

View File

@ -125,6 +125,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
} }
} }
do_resize:
if (getmaxy(stdscr) < (height + 6))
return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) < (width + 6))
return -ERRDISPLAYTOOSMALL;
max_choice = MIN(list_height, item_count()); max_choice = MIN(list_height, item_count());
/* center dialog box on screen */ /* center dialog box on screen */
@ -303,6 +309,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
case KEY_ESC: case KEY_ESC:
key = on_key_esc(dialog); key = on_key_esc(dialog);
break; break;
case KEY_RESIZE:
delwin(list);
delwin(dialog);
on_key_resize();
goto do_resize;
} }
/* Now, update everything... */ /* Now, update everything... */

View File

@ -86,6 +86,9 @@
#define ACS_DARROW 'v' #define ACS_DARROW 'v'
#endif #endif
/* error return codes */
#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
/* /*
* Color definitions * Color definitions
*/ */
@ -181,6 +184,7 @@ int item_is_tag(char tag);
/* generic key handlers */ /* generic key handlers */
int on_key_esc(WINDOW *win); int on_key_esc(WINDOW *win);
int on_key_resize(void);
void init_dialog(const char *backtitle); void init_dialog(const char *backtitle);
void reset_dialog(void); void reset_dialog(void);
@ -199,8 +203,8 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height, int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause); int width, int pause);
int dialog_textbox(const char *title, const char *file, int height, int width); int dialog_textbox(const char *title, const char *file, int height, int width);
int dialog_menu(const char *title, const char *prompt, int height, int width, int dialog_menu(const char *title, const char *prompt,
int menu_height, const void *selected, int *s_scroll); const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height, int dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height); int width, int list_height);
extern char dialog_input_result[]; extern char dialog_input_result[];

View File

@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
char *instr = dialog_input_result; char *instr = dialog_input_result;
WINDOW *dialog; WINDOW *dialog;
if (!init)
instr[0] = '\0';
else
strcpy(instr, init);
do_resize:
if (getmaxy(stdscr) <= (height - 2))
return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) <= (width - 2))
return -ERRDISPLAYTOOSMALL;
/* center dialog box on screen */ /* center dialog box on screen */
x = (COLS - width) / 2; x = (COLS - width) / 2;
y = (LINES - height) / 2; y = (LINES - height) / 2;
@ -86,11 +97,6 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
wmove(dialog, box_y, box_x); wmove(dialog, box_y, box_x);
wattrset(dialog, dlg.inputbox.atr); wattrset(dialog, dlg.inputbox.atr);
if (!init)
instr[0] = '\0';
else
strcpy(instr, init);
input_x = strlen(instr); input_x = strlen(instr);
if (input_x >= box_width) { if (input_x >= box_width) {
@ -220,6 +226,10 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
case KEY_ESC: case KEY_ESC:
key = on_key_esc(dialog); key = on_key_esc(dialog);
break; break;
case KEY_RESIZE:
delwin(dialog);
on_key_resize();
goto do_resize;
} }
} }

View File

@ -179,14 +179,25 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
/* /*
* Display a menu for choosing among a number of options * Display a menu for choosing among a number of options
*/ */
int dialog_menu(const char *title, const char *prompt, int height, int width, int dialog_menu(const char *title, const char *prompt,
int menu_height, const void *selected, int *s_scroll) const void *selected, int *s_scroll)
{ {
int i, j, x, y, box_x, box_y; int i, j, x, y, box_x, box_y;
int height, width, menu_height;
int key = 0, button = 0, scroll = 0, choice = 0; int key = 0, button = 0, scroll = 0, choice = 0;
int first_item = 0, max_choice; int first_item = 0, max_choice;
WINDOW *dialog, *menu; WINDOW *dialog, *menu;
do_resize:
height = getmaxy(stdscr);
width = getmaxx(stdscr);
if (height < 15 || width < 65)
return -ERRDISPLAYTOOSMALL;
height -= 4;
width -= 5;
menu_height = height - 10;
max_choice = MIN(menu_height, item_count()); max_choice = MIN(menu_height, item_count());
/* center dialog box on screen */ /* center dialog box on screen */
@ -226,7 +237,10 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
dlg.menubox_border.atr, dlg.menubox.atr); dlg.menubox_border.atr, dlg.menubox.atr);
item_x = (menu_width - 70) / 2; if (menu_width >= 80)
item_x = (menu_width - 70) / 2;
else
item_x = 4;
/* Set choice to default item */ /* Set choice to default item */
item_foreach() item_foreach()
@ -407,6 +421,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
case KEY_ESC: case KEY_ESC:
key = on_key_esc(menu); key = on_key_esc(menu);
break; break;
case KEY_RESIZE:
on_key_resize();
delwin(menu);
delwin(dialog);
goto do_resize;
} }
} }
delwin(menu); delwin(menu);

View File

@ -25,22 +25,36 @@ static void back_lines(int n);
static void print_page(WINDOW * win, int height, int width); static void print_page(WINDOW * win, int height, int width);
static void print_line(WINDOW * win, int row, int width); static void print_line(WINDOW * win, int row, int width);
static char *get_line(void); static char *get_line(void);
static void print_position(WINDOW * win, int height, int width); static void print_position(WINDOW * win);
static int hscroll; static int hscroll;
static int begin_reached, end_reached, page_length; static int begin_reached, end_reached, page_length;
static const char *buf; static const char *buf;
static const char *page; static const char *page;
/*
* refresh window content
*/
static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
int cur_y, int cur_x)
{
print_page(box, boxh, boxw);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
/* /*
* Display text from a file in a dialog box. * Display text from a file in a dialog box.
*/ */
int dialog_textbox(const char *title, const char *tbuf, int height, int width) int dialog_textbox(const char *title, const char *tbuf,
int initial_height, int initial_width)
{ {
int i, x, y, cur_x, cur_y, key = 0; int i, x, y, cur_x, cur_y, key = 0;
int texth, textw; int height, width, boxh, boxw;
int passed_end; int passed_end;
WINDOW *dialog, *text; WINDOW *dialog, *box;
begin_reached = 1; begin_reached = 1;
end_reached = 0; end_reached = 0;
@ -49,6 +63,25 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
buf = tbuf; buf = tbuf;
page = buf; /* page is pointer to start of page to be displayed */ page = buf; /* page is pointer to start of page to be displayed */
do_resize:
getmaxyx(stdscr, height, width);
if (height < 8 || width < 8)
return -ERRDISPLAYTOOSMALL;
if (initial_height != 0)
height = initial_height;
else
if (height > 4)
height -= 4;
else
height = 0;
if (initial_width != 0)
width = initial_width;
else
if (width > 5)
width -= 5;
else
width = 0;
/* center dialog box on screen */ /* center dialog box on screen */
x = (COLS - width) / 2; x = (COLS - width) / 2;
y = (LINES - height) / 2; y = (LINES - height) / 2;
@ -58,14 +91,14 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
dialog = newwin(height, width, y, x); dialog = newwin(height, width, y, x);
keypad(dialog, TRUE); keypad(dialog, TRUE);
/* Create window for text region, used for scrolling text */ /* Create window for box region, used for scrolling text */
texth = height - 4; boxh = height - 4;
textw = width - 2; boxw = width - 2;
text = subwin(dialog, texth, textw, y + 1, x + 1); box = subwin(dialog, boxh, boxw, y + 1, x + 1);
wattrset(text, dlg.dialog.atr); wattrset(box, dlg.dialog.atr);
wbkgdset(text, dlg.dialog.atr & A_COLOR); wbkgdset(box, dlg.dialog.atr & A_COLOR);
keypad(text, TRUE); keypad(box, TRUE);
/* register the new window, along with its borders */ /* register the new window, along with its borders */
draw_box(dialog, 0, 0, height, width, draw_box(dialog, 0, 0, height, width,
@ -86,11 +119,8 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
getyx(dialog, cur_y, cur_x); /* Save cursor position */ getyx(dialog, cur_y, cur_x); /* Save cursor position */
/* Print first page of text */ /* Print first page of text */
attr_clear(text, texth, textw, dlg.dialog.atr); attr_clear(box, boxh, boxw, dlg.dialog.atr);
print_page(text, texth, textw); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
print_position(dialog, height, width);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
while ((key != KEY_ESC) && (key != '\n')) { while ((key != KEY_ESC) && (key != '\n')) {
key = wgetch(dialog); key = wgetch(dialog);
@ -99,7 +129,7 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
case 'e': case 'e':
case 'X': case 'X':
case 'x': case 'x':
delwin(text); delwin(box);
delwin(dialog); delwin(dialog);
return 0; return 0;
case 'g': /* First page */ case 'g': /* First page */
@ -107,10 +137,8 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
if (!begin_reached) { if (!begin_reached) {
begin_reached = 1; begin_reached = 1;
page = buf; page = buf;
print_page(text, texth, textw); refresh_text_box(dialog, box, boxh, boxw,
print_position(dialog, height, width); cur_y, cur_x);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
} }
break; break;
case 'G': /* Last page */ case 'G': /* Last page */
@ -119,11 +147,9 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
end_reached = 1; end_reached = 1;
/* point to last char in buf */ /* point to last char in buf */
page = buf + strlen(buf); page = buf + strlen(buf);
back_lines(texth); back_lines(boxh);
print_page(text, texth, textw); refresh_text_box(dialog, box, boxh, boxw,
print_position(dialog, height, width); cur_y, cur_x);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
break; break;
case 'K': /* Previous line */ case 'K': /* Previous line */
case 'k': case 'k':
@ -138,16 +164,16 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
* point to start of next page. This is done * point to start of next page. This is done
* by calling get_line() in the following * by calling get_line() in the following
* 'for' loop. */ * 'for' loop. */
scrollok(text, TRUE); scrollok(box, TRUE);
wscrl(text, -1); /* Scroll text region down one line */ wscrl(box, -1); /* Scroll box region down one line */
scrollok(text, FALSE); scrollok(box, FALSE);
page_length = 0; page_length = 0;
passed_end = 0; passed_end = 0;
for (i = 0; i < texth; i++) { for (i = 0; i < boxh; i++) {
if (!i) { if (!i) {
/* print first line of page */ /* print first line of page */
print_line(text, 0, textw); print_line(box, 0, boxw);
wnoutrefresh(text); wnoutrefresh(box);
} else } else
/* Called to update 'end_reached' and 'page' */ /* Called to update 'end_reached' and 'page' */
get_line(); get_line();
@ -157,7 +183,7 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
passed_end = 1; passed_end = 1;
} }
print_position(dialog, height, width); print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog); wrefresh(dialog);
} }
@ -167,23 +193,21 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
case KEY_PPAGE: case KEY_PPAGE:
if (begin_reached) if (begin_reached)
break; break;
back_lines(page_length + texth); back_lines(page_length + boxh);
print_page(text, texth, textw); refresh_text_box(dialog, box, boxh, boxw,
print_position(dialog, height, width); cur_y, cur_x);
wmove(dialog, cur_y, cur_x);
wrefresh(dialog);
break; break;
case 'J': /* Next line */ case 'J': /* Next line */
case 'j': case 'j':
case KEY_DOWN: case KEY_DOWN:
if (!end_reached) { if (!end_reached) {
begin_reached = 0; begin_reached = 0;
scrollok(text, TRUE); scrollok(box, TRUE);
scroll(text); /* Scroll text region up one line */ scroll(box); /* Scroll box region up one line */
scrollok(text, FALSE); scrollok(box, FALSE);
print_line(text, texth - 1, textw); print_line(box, boxh - 1, boxw);
wnoutrefresh(text); wnoutrefresh(box);
print_position(dialog, height, width); print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog); wrefresh(dialog);
} }
@ -194,10 +218,8 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
break; break;
begin_reached = 0; begin_reached = 0;
print_page(text, texth, textw); refresh_text_box(dialog, box, boxh, boxw,
print_position(dialog, height, width); cur_y, cur_x);
wmove(dialog, cur_y, cur_x);
wrefresh(dialog);
break; break;
case '0': /* Beginning of line */ case '0': /* Beginning of line */
case 'H': /* Scroll left */ case 'H': /* Scroll left */
@ -212,9 +234,8 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
hscroll--; hscroll--;
/* Reprint current page to scroll horizontally */ /* Reprint current page to scroll horizontally */
back_lines(page_length); back_lines(page_length);
print_page(text, texth, textw); refresh_text_box(dialog, box, boxh, boxw,
wmove(dialog, cur_y, cur_x); cur_y, cur_x);
wrefresh(dialog);
break; break;
case 'L': /* Scroll right */ case 'L': /* Scroll right */
case 'l': case 'l':
@ -224,16 +245,21 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
hscroll++; hscroll++;
/* Reprint current page to scroll horizontally */ /* Reprint current page to scroll horizontally */
back_lines(page_length); back_lines(page_length);
print_page(text, texth, textw); refresh_text_box(dialog, box, boxh, boxw,
wmove(dialog, cur_y, cur_x); cur_y, cur_x);
wrefresh(dialog);
break; break;
case KEY_ESC: case KEY_ESC:
key = on_key_esc(dialog); key = on_key_esc(dialog);
break; break;
case KEY_RESIZE:
back_lines(height);
delwin(box);
delwin(dialog);
on_key_resize();
goto do_resize;
} }
} }
delwin(text); delwin(box);
delwin(dialog); delwin(dialog);
return key; /* ESC pressed */ return key; /* ESC pressed */
} }
@ -353,13 +379,13 @@ static char *get_line(void)
/* /*
* Print current position * Print current position
*/ */
static void print_position(WINDOW * win, int height, int width) static void print_position(WINDOW * win)
{ {
int percent; int percent;
wattrset(win, dlg.position_indicator.atr); wattrset(win, dlg.position_indicator.atr);
wbkgdset(win, dlg.position_indicator.atr & A_COLOR); wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
percent = (page - buf) * 100 / strlen(buf); percent = (page - buf) * 100 / strlen(buf);
wmove(win, height - 3, width - 9); wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
wprintw(win, "(%3d%%)", percent); wprintw(win, "(%3d%%)", percent);
} }

View File

@ -509,6 +509,12 @@ int on_key_esc(WINDOW *win)
return -1; return -1;
} }
/* redraw screen in new size */
int on_key_resize(void)
{
dialog_clear();
return KEY_RESIZE;
}
struct dialog_list *item_cur; struct dialog_list *item_cur;
struct dialog_list item_nil; struct dialog_list item_nil;

View File

@ -44,6 +44,12 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
int i, x, y, key = 0, button = 0; int i, x, y, key = 0, button = 0;
WINDOW *dialog; WINDOW *dialog;
do_resize:
if (getmaxy(stdscr) < (height + 4))
return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) < (width + 4))
return -ERRDISPLAYTOOSMALL;
/* center dialog box on screen */ /* center dialog box on screen */
x = (COLS - width) / 2; x = (COLS - width) / 2;
y = (LINES - height) / 2; y = (LINES - height) / 2;
@ -96,6 +102,10 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
case KEY_ESC: case KEY_ESC:
key = on_key_esc(dialog); key = on_key_esc(dialog);
break; break;
case KEY_RESIZE:
delwin(dialog);
on_key_resize();
goto do_resize;
} }
} }

View File

@ -606,9 +606,8 @@ static void conf(struct menu *menu)
reset_dialog(); reset_dialog();
res = dialog_menu(prompt ? prompt : _("Main Menu"), res = dialog_menu(prompt ? prompt : _("Main Menu"),
_(menu_instructions), _(menu_instructions),
rows, cols, rows - 10,
active_menu, &s_scroll); active_menu, &s_scroll);
if (res == 1 || res == KEY_ESC) if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break; break;
if (!item_activate_selected()) if (!item_activate_selected())
continue; continue;
@ -617,7 +616,10 @@ static void conf(struct menu *menu)
submenu = item_data(); submenu = item_data();
active_menu = item_data(); active_menu = item_data();
sym = submenu->sym; if (submenu)
sym = submenu->sym;
else
sym = NULL;
switch (res) { switch (res) {
case 0: case 0:
@ -683,7 +685,7 @@ static void conf(struct menu *menu)
static void show_textbox(const char *title, const char *text, int r, int c) static void show_textbox(const char *title, const char *text, int r, int c)
{ {
reset_dialog(); reset_dialog();
dialog_textbox(title, text, r ? r : rows, c ? c : cols); dialog_textbox(title, text, r, c);
} }
static void show_helptext(const char *title, const char *text) static void show_helptext(const char *title, const char *text)
@ -756,6 +758,8 @@ static void conf_choice(struct menu *menu)
break; break;
case KEY_ESC: case KEY_ESC:
return; return;
case -ERRDISPLAYTOOSMALL:
return;
} }
} }
} }