kconfig/lxdialog: support resize
authorSam Ravnborg <sam@mars.ravnborg.org>
Sat, 29 Jul 2006 20:48:57 +0000 (22:48 +0200)
committerSam Ravnborg <sam@neptun.ravnborg.org>
Sat, 30 Sep 2006 09:19:20 +0000 (11:19 +0200)
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>
scripts/kconfig/lxdialog/checklist.c
scripts/kconfig/lxdialog/dialog.h
scripts/kconfig/lxdialog/inputbox.c
scripts/kconfig/lxdialog/menubox.c
scripts/kconfig/lxdialog/textbox.c
scripts/kconfig/lxdialog/util.c
scripts/kconfig/lxdialog/yesno.c
scripts/kconfig/mconf.c

index 39becb72444a70aedc8132f2a0f078b4fd8bcb0a..cf697080ddddd4bf47df0057f860ef681255ea29 100644 (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());
 
        /* center dialog box on screen */
@@ -303,6 +309,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
                case KEY_ESC:
                        key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       delwin(list);
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
 
                /* Now, update everything... */
index a7cfdecc2409b695cd8cd063b15e3fa8a9a8cd5d..8dea47f9d3e49a36803ed4c90223d9858a83d3de 100644 (file)
@@ -86,6 +86,9 @@
 #define ACS_DARROW 'v'
 #endif
 
+/* error return codes */
+#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
+
 /*
  *   Color definitions
  */
@@ -181,6 +184,7 @@ int item_is_tag(char tag);
 
 /* generic key handlers */
 int on_key_esc(WINDOW *win);
+int on_key_resize(void);
 
 void init_dialog(const char *backtitle);
 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 width, int pause);
 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 menu_height, const void *selected, int *s_scroll);
+int dialog_menu(const char *title, const char *prompt,
+               const void *selected, int *s_scroll);
 int dialog_checklist(const char *title, const char *prompt, int height,
                     int width, int list_height);
 extern char dialog_input_result[];
index edb7975dbaa2e2a69b6f9af4503b9ef90971ff73..05e72066b35987dfe7037f6abd2fe29a03cb016a 100644 (file)
@@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
        char *instr = dialog_input_result;
        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 */
        x = (COLS - width) / 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);
        wattrset(dialog, dlg.inputbox.atr);
 
-       if (!init)
-               instr[0] = '\0';
-       else
-               strcpy(instr, init);
-
        input_x = strlen(instr);
 
        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:
                        key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
        }
 
index d3305bad15c7a115b4345b4e83cb8bd7e9675250..fcd95a98532839269953510ca59b8a370e615783 100644 (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
  */
-int dialog_menu(const char *title, const char *prompt, int height, int width,
-                int menu_height, const void *selected, int *s_scroll)
+int dialog_menu(const char *title, const char *prompt,
+                const void *selected, int *s_scroll)
 {
        int i, j, x, y, box_x, box_y;
+       int height, width, menu_height;
        int key = 0, button = 0, scroll = 0, choice = 0;
        int first_item =  0, max_choice;
        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());
 
        /* 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,
                 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 */
        item_foreach()
@@ -407,6 +421,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
                case KEY_ESC:
                        key = on_key_esc(menu);
                        break;
+               case KEY_RESIZE:
+                       on_key_resize();
+                       delwin(menu);
+                       delwin(dialog);
+                       goto do_resize;
                }
        }
        delwin(menu);
index a99e1f497d67e54cc4fd1ec63db2b2ec72f88f1f..fabfc1ad789d674f5f91637cba70cbfc335431d0 100644 (file)
@@ -25,22 +25,36 @@ static void back_lines(int n);
 static void print_page(WINDOW * win, int height, int width);
 static void print_line(WINDOW * win, int row, int width);
 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 begin_reached, end_reached, page_length;
 static const char *buf;
 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.
  */
-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 texth, textw;
+       int height, width, boxh, boxw;
        int passed_end;
-       WINDOW *dialog, *text;
+       WINDOW *dialog, *box;
 
        begin_reached = 1;
        end_reached = 0;
@@ -49,6 +63,25 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
        buf = tbuf;
        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 */
        x = (COLS - width) / 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);
        keypad(dialog, TRUE);
 
-       /* Create window for text region, used for scrolling text */
-       texth = height - 4;
-       textw = width - 2;
-       text = subwin(dialog, texth, textw, y + 1, x + 1);
-       wattrset(text, dlg.dialog.atr);
-       wbkgdset(text, dlg.dialog.atr & A_COLOR);
+       /* Create window for box region, used for scrolling text */
+       boxh = height - 4;
+       boxw = width - 2;
+       box = subwin(dialog, boxh, boxw, y + 1, x + 1);
+       wattrset(box, dlg.dialog.atr);
+       wbkgdset(box, dlg.dialog.atr & A_COLOR);
 
-       keypad(text, TRUE);
+       keypad(box, TRUE);
 
        /* register the new window, along with its borders */
        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 */
 
        /* Print first page of text */
-       attr_clear(text, texth, textw, dlg.dialog.atr);
-       print_page(text, texth, textw);
-       print_position(dialog, height, width);
-       wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
-       wrefresh(dialog);
+       attr_clear(box, boxh, boxw, dlg.dialog.atr);
+       refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
 
        while ((key != KEY_ESC) && (key != '\n')) {
                key = wgetch(dialog);
@@ -99,7 +129,7 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                case 'e':
                case 'X':
                case 'x':
-                       delwin(text);
+                       delwin(box);
                        delwin(dialog);
                        return 0;
                case 'g':       /* First page */
@@ -107,10 +137,8 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                        if (!begin_reached) {
                                begin_reached = 1;
                                page = buf;
-                               print_page(text, texth, textw);
-                               print_position(dialog, height, width);
-                               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
-                               wrefresh(dialog);
+                               refresh_text_box(dialog, box, boxh, boxw,
+                                                cur_y, cur_x);
                        }
                        break;
                case 'G':       /* Last page */
@@ -119,11 +147,9 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                        end_reached = 1;
                        /* point to last char in buf */
                        page = buf + strlen(buf);
-                       back_lines(texth);
-                       print_page(text, texth, textw);
-                       print_position(dialog, height, width);
-                       wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
-                       wrefresh(dialog);
+                       back_lines(boxh);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case 'K':       /* Previous line */
                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
                                 * by calling get_line() in the following
                                 * 'for' loop. */
-                               scrollok(text, TRUE);
-                               wscrl(text, -1);        /* Scroll text region down one line */
-                               scrollok(text, FALSE);
+                               scrollok(box, TRUE);
+                               wscrl(box, -1); /* Scroll box region down one line */
+                               scrollok(box, FALSE);
                                page_length = 0;
                                passed_end = 0;
-                               for (i = 0; i < texth; i++) {
+                               for (i = 0; i < boxh; i++) {
                                        if (!i) {
                                                /* print first line of page */
-                                               print_line(text, 0, textw);
-                                               wnoutrefresh(text);
+                                               print_line(box, 0, boxw);
+                                               wnoutrefresh(box);
                                        } else
                                                /* Called to update 'end_reached' and 'page' */
                                                get_line();
@@ -157,7 +183,7 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                                                passed_end = 1;
                                }
 
-                               print_position(dialog, height, width);
+                               print_position(dialog);
                                wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
                                wrefresh(dialog);
                        }
@@ -167,23 +193,21 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                case KEY_PPAGE:
                        if (begin_reached)
                                break;
-                       back_lines(page_length + texth);
-                       print_page(text, texth, textw);
-                       print_position(dialog, height, width);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       back_lines(page_length + boxh);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case 'J':       /* Next line */
                case 'j':
                case KEY_DOWN:
                        if (!end_reached) {
                                begin_reached = 0;
-                               scrollok(text, TRUE);
-                               scroll(text);   /* Scroll text region up one line */
-                               scrollok(text, FALSE);
-                               print_line(text, texth - 1, textw);
-                               wnoutrefresh(text);
-                               print_position(dialog, height, width);
+                               scrollok(box, TRUE);
+                               scroll(box);    /* Scroll box region up one line */
+                               scrollok(box, FALSE);
+                               print_line(box, boxh - 1, boxw);
+                               wnoutrefresh(box);
+                               print_position(dialog);
                                wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
                                wrefresh(dialog);
                        }
@@ -194,10 +218,8 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                                break;
 
                        begin_reached = 0;
-                       print_page(text, texth, textw);
-                       print_position(dialog, height, width);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case '0':       /* Beginning of line */
                case 'H':       /* Scroll left */
@@ -212,9 +234,8 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                                hscroll--;
                        /* Reprint current page to scroll horizontally */
                        back_lines(page_length);
-                       print_page(text, texth, textw);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case 'L':       /* Scroll right */
                case 'l':
@@ -224,16 +245,21 @@ int dialog_textbox(const char *title, const char *tbuf, int height, int width)
                        hscroll++;
                        /* Reprint current page to scroll horizontally */
                        back_lines(page_length);
-                       print_page(text, texth, textw);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case KEY_ESC:
                        key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       back_lines(height);
+                       delwin(box);
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
        }
-       delwin(text);
+       delwin(box);
        delwin(dialog);
        return key;             /* ESC pressed */
 }
@@ -353,13 +379,13 @@ static char *get_line(void)
 /*
  * Print current position
  */
-static void print_position(WINDOW * win, int height, int width)
+static void print_position(WINDOW * win)
 {
        int percent;
 
        wattrset(win, dlg.position_indicator.atr);
        wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
        percent = (page - buf) * 100 / strlen(buf);
-       wmove(win, height - 3, width - 9);
+       wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
        wprintw(win, "(%3d%%)", percent);
 }
index cb21dc4dd9fc21fe697a855f5e5258c07cabb646..ebc781b493d7c8a86ca7d95bae7f943bbb5430a9 100644 (file)
@@ -509,6 +509,12 @@ int on_key_esc(WINDOW *win)
        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_nil;
index 8364f9dd01c3340f8676cc9d7c70ad35a599e0f2..ee0a04e3e012ecd4ba119cd153d96a08ded7b2a2 100644 (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;
        WINDOW *dialog;
 
+do_resize:
+       if (getmaxy(stdscr) < (height + 4))
+               return -ERRDISPLAYTOOSMALL;
+       if (getmaxx(stdscr) < (width + 4))
+               return -ERRDISPLAYTOOSMALL;
+
        /* center dialog box on screen */
        x = (COLS - width) / 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:
                        key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
        }
 
index ef75d6c3d3e52806f27c52c8af3ca3d7a697a048..f7abca4348298d3f12de74ee9861c2ef6d90a28e 100644 (file)
@@ -606,9 +606,8 @@ static void conf(struct menu *menu)
                reset_dialog();
                res = dialog_menu(prompt ? prompt : _("Main Menu"),
                                  _(menu_instructions),
-                                 rows, cols, rows - 10,
                                  active_menu, &s_scroll);
-               if (res == 1 || res == KEY_ESC)
+               if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
                        break;
                if (!item_activate_selected())
                        continue;
@@ -617,7 +616,10 @@ static void conf(struct menu *menu)
 
                submenu = item_data();
                active_menu = item_data();
-               sym = submenu->sym;
+               if (submenu)
+                       sym = submenu->sym;
+               else
+                       sym = NULL;
 
                switch (res) {
                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)
 {
        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)
@@ -756,6 +758,8 @@ static void conf_choice(struct menu *menu)
                        break;
                case KEY_ESC:
                        return;
+               case -ERRDISPLAYTOOSMALL:
+                       return;
                }
        }
 }