]> git.ozlabs.org Git - petitboot/blobdiff - ui/ncurses/nc-config.c
ui/ncurses: Allow text wrapping in select widgets
[petitboot] / ui / ncurses / nc-config.c
index 911559dcefc0240c283b9ceea6ba6c4ddeee048b..2750bbb7719189de934b9716e5eb952d7d09e06c 100644 (file)
@@ -33,7 +33,7 @@
 #include "nc-config.h"
 #include "nc-widgets.h"
 
-#define N_FIELDS       32
+#define N_FIELDS       34
 
 extern struct help_text config_help_text;
 
@@ -53,6 +53,7 @@ struct config_screen {
        bool                    show_help;
        bool                    show_subset;
        bool                    need_redraw;
+       bool                    need_update;
 
        void                    (*on_exit)(struct cui *);
 
@@ -100,6 +101,9 @@ struct config_screen {
                struct nc_widget_label          *dns_dhcp_help_l;
                struct nc_widget_label          *dns_help_l;
 
+               struct nc_widget_label          *allow_write_l;
+               struct nc_widget_select         *allow_write_f;
+
                struct nc_widget_label          *safe_mode;
                struct nc_widget_button         *ok_b;
                struct nc_widget_button         *help_b;
@@ -167,21 +171,6 @@ static void config_screen_resize(struct nc_scr *scr)
        (void)screen;
 }
 
-static int config_screen_post(struct nc_scr *scr)
-{
-       struct config_screen *screen = config_screen_from_scr(scr);
-       screen->show_subset = false;
-       widgetset_post(screen->widgetset);
-       nc_scr_frame_draw(scr);
-       if (screen->need_redraw) {
-               redrawwin(scr->main_ncw);
-               screen->need_redraw = false;
-       }
-       wrefresh(screen->scr.main_ncw);
-       pad_refresh(screen);
-       return 0;
-}
-
 static int config_screen_unpost(struct nc_scr *scr)
 {
        struct config_screen *screen = config_screen_from_scr(scr);
@@ -203,6 +192,7 @@ static int screen_process_form(struct config_screen *screen)
        struct config *config;
        int i, n_boot_opts, rc, idx;
        unsigned int *order;
+       bool allow_write;
        char mac[20];
 
        config = config_copy(screen, screen->cui->config);
@@ -331,6 +321,10 @@ static int screen_process_form(struct config_screen *screen)
                }
        }
 
+       allow_write = widget_select_get_value(screen->widgets.allow_write_f);
+       if (allow_write != config->allow_writes)
+               config->allow_writes = allow_write;
+
        config->safe_mode = false;
        rc = cui_send_config(screen->cui, config);
        talloc_free(config);
@@ -383,11 +377,11 @@ static void config_screen_layout_widgets(struct config_screen *screen)
        bool show;
 
        y = 1;
+       /* currently, the longest label we have is the DNS-servers
+        * widget, so layout our screen based on that */
        help_x = screen->field_x + 2 +
                widget_width(widget_textbox_base(screen->widgets.dns_f));
 
-       y += 1;
-
        wl = widget_label_base(screen->widgets.boot_order_l);
        widget_set_visible(wl, true);
        widget_move(wl, y, screen->label_x);
@@ -410,11 +404,11 @@ static void config_screen_layout_widgets(struct config_screen *screen)
        y += 1;
 
        widget_move(widget_button_base(screen->widgets.boot_add_b),
-                       y, screen->field_x);
+                       y++, screen->field_x);
        widget_move(widget_button_base(screen->widgets.boot_any_b),
-                       y, screen->field_x + 12);
+                       y++, screen->field_x);
        widget_move(widget_button_base(screen->widgets.boot_none_b),
-                       y, screen->field_x + 30);
+                       y, screen->field_x);
 
        wf = widget_button_base(screen->widgets.boot_add_b);
        if (widget_subset_n_inactive(screen->widgets.boot_order_f))
@@ -453,7 +447,7 @@ static void config_screen_layout_widgets(struct config_screen *screen)
                y += 1;
        }
 
-       y += 2;
+       y += 1;
 
        y += layout_pair(screen, y, screen->widgets.network_l,
                        widget_select_base(screen->widgets.network_f));
@@ -540,12 +534,18 @@ static void config_screen_layout_widgets(struct config_screen *screen)
                y += 1;
        }
 
+       layout_pair(screen, y, screen->widgets.allow_write_l,
+                   widget_select_base(screen->widgets.allow_write_f));
+       y += widget_height(widget_select_base(screen->widgets.allow_write_f));
+
+       y += 1;
+
        widget_move(widget_button_base(screen->widgets.ok_b),
                        y, screen->field_x);
        widget_move(widget_button_base(screen->widgets.help_b),
-                       y, screen->field_x + 10);
+                       y, screen->field_x + 14);
        widget_move(widget_button_base(screen->widgets.cancel_b),
-                       y, screen->field_x + 24);
+                       y, screen->field_x + 28);
 }
 
 static void config_screen_network_change(void *arg, int value)
@@ -571,7 +571,7 @@ static void config_screen_add_device(void *arg)
        struct config_screen *screen = arg;
 
        screen->show_subset = true;
-       cui_show_subset(screen->cui, _("Select an option"),
+       cui_show_subset(screen->cui, _("Select a boot device to add"),
                        screen->widgets.boot_order_f);
 }
 
@@ -696,6 +696,7 @@ static void config_screen_setup_widgets(struct config_screen *screen,
        char *str, *ip, *mask, *gw;
        enum net_conf_type type;
        unsigned int i;
+       int add_len, clear_len, any_len, min_len = 20;
 
        build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
                        == N_FIELDS);
@@ -703,20 +704,24 @@ static void config_screen_setup_widgets(struct config_screen *screen,
        type = screen->net_conf_type;
        ifcfg = first_active_interface(config);
 
-       screen->widgets.boot_add_b = widget_new_button(set, 0, 0, 10,
-                                       _("Add Device"), config_screen_add_device,
-                                       screen);
+       add_len = max(min_len, strncols(_("Add Device")));
+       clear_len = max(min_len, strncols(_("Clear")));
+       any_len = max(min_len, strncols(_("Clear & Boot Any")));
 
-       screen->widgets.boot_none_b = widget_new_button(set, 0, 0, 10,
+       screen->widgets.boot_add_b = widget_new_button(set, 0, 0, add_len,
+                                       _("Add Device"),
+                                       config_screen_add_device, screen);
+
+       screen->widgets.boot_none_b = widget_new_button(set, 0, 0, clear_len,
                                        _("Clear"),
                                        config_screen_autoboot_none, screen);
 
-       screen->widgets.boot_any_b = widget_new_button(set, 0, 0, 16,
-                                       _("Clear & Boot Any"), config_screen_autoboot_any,
-                                       screen);
+       screen->widgets.boot_any_b = widget_new_button(set, 0, 0, any_len,
+                                       _("Clear & Boot Any"),
+                                       config_screen_autoboot_any, screen);
 
        screen->widgets.boot_order_l = widget_new_label(set, 0, 0,
-                                       _("Boot order:"));
+                                       _("Boot Order:"));
        screen->widgets.boot_order_f = widget_new_subset(set, 0, 0,
                                        COLS - screen->field_x,
                                        config_screen_update_subset);
@@ -748,7 +753,7 @@ static void config_screen_setup_widgets(struct config_screen *screen,
                widget_subset_add_option(screen->widgets.boot_order_f, label);
        }
 
-       for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_NETWORK + 4; i++) {
+       for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_UNKNOWN; i++) {
                char *label;
 
                if (i == DEVICE_TYPE_ANY)
@@ -806,7 +811,8 @@ static void config_screen_setup_widgets(struct config_screen *screen,
        }
 
        screen->widgets.network_l = widget_new_label(set, 0, 0, _("Network:"));
-       screen->widgets.network_f = widget_new_select(set, 0, 0, 50);
+       screen->widgets.network_f = widget_new_select(set, 0, 0,
+                                               COLS - screen->field_x - 1);
 
        widget_select_add_option(screen->widgets.network_f,
                                        NET_CONF_TYPE_DHCP_ALL,
@@ -900,7 +906,20 @@ static void config_screen_setup_widgets(struct config_screen *screen,
                screen->widgets.safe_mode = widget_new_label(set, 0, 0,
                         _("Selecting 'OK' will exit safe mode"));
 
-       screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
+       screen->widgets.allow_write_l = widget_new_label(set, 0, 0,
+                       _("Disk R/W:"));
+       screen->widgets.allow_write_f = widget_new_select(set, 0, 0,
+                                               COLS - screen->field_x - 1);
+
+       widget_select_add_option(screen->widgets.allow_write_f, 0,
+                               _("Prevent all writes to disk"),
+                               !config->allow_writes);
+
+       widget_select_add_option(screen->widgets.allow_write_f, 1,
+                               _("Allow bootloader scripts to modify disks"),
+                               config->allow_writes);
+
+       screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
                        ok_click, screen);
        screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"),
                        help_click, screen);
@@ -983,10 +1002,38 @@ void config_screen_update(struct config_screen *screen,
                const struct config *config,
                const struct system_info *sysinfo)
 {
+       if (screen->cui->current != config_screen_scr(screen)) {
+               screen->need_update = true;
+               return;
+       }
+
        config_screen_draw(screen, config, sysinfo);
        pad_refresh(screen);
 }
 
+static int config_screen_post(struct nc_scr *scr)
+{
+       struct config_screen *screen = config_screen_from_scr(scr);
+       screen->show_subset = false;
+
+       if (screen->need_update) {
+               config_screen_draw(screen, screen->cui->config,
+                                  screen->cui->sysinfo);
+               screen->need_update = false;
+       } else {
+               widgetset_post(screen->widgetset);
+       }
+
+       nc_scr_frame_draw(scr);
+       if (screen->need_redraw) {
+               redrawwin(scr->main_ncw);
+               screen->need_redraw = false;
+       }
+       wrefresh(screen->scr.main_ncw);
+       pad_refresh(screen);
+       return 0;
+}
+
 static int config_screen_destroy(void *arg)
 {
        struct config_screen *screen = arg;
@@ -1012,6 +1059,7 @@ struct config_screen *config_screen_init(struct cui *cui,
        screen->cui = cui;
        screen->on_exit = on_exit;
        screen->need_redraw = false;
+       screen->need_update = false;
        screen->label_x = 2;
        screen->field_x = 17;