X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=ui%2Fncurses%2Fnc-widgets.c;h=a6773cd39d34496b620c0e43953482b672b62cf9;hp=d17034dd685e14e42fb42294fa734aa4eb250ad6;hb=e3319e99833a30a63e3a7ed3b6b22a127bcd0d50;hpb=43e9c8147f74fba794fd280fa0fdb57af8b968f4 diff --git a/ui/ncurses/nc-widgets.c b/ui/ncurses/nc-widgets.c index d17034d..a6773cd 100644 --- a/ui/ncurses/nc-widgets.c +++ b/ui/ncurses/nc-widgets.c @@ -17,6 +17,33 @@ #define _GNU_SOURCE +#include "config.h" + +#include /* This must be included before ncurses.h */ +#if defined HAVE_NCURSESW_CURSES_H +# include +#elif defined HAVE_NCURSESW_H +# include +#elif defined HAVE_NCURSES_CURSES_H +# include +#elif defined HAVE_NCURSES_H +# include +#elif defined HAVE_CURSES_H +# include +#else +# error "Curses header file not found." +#endif + +#if defined HAVE_NCURSESW_FORM_H +# include +#elif defined HAVE_NCURSES_FORM_H +# include +#elif defined HAVE_FORM_H +# include +#else +# error "Curses form.h not found." +#endif + #include #include @@ -58,10 +85,12 @@ struct nc_widget { bool (*process_key)(struct nc_widget *, FORM *, int); void (*set_visible)(struct nc_widget *, bool); void (*move)(struct nc_widget *, int, int); + void (*field_focus)(struct nc_widget *, FIELD *); int focussed_attr; int unfocussed_attr; int height; int width; + int focus_y; int x; int y; }; @@ -101,6 +130,12 @@ struct nc_widget_button { }; static void widgetset_add_field(struct nc_widgetset *set, FIELD *field); +static void widgetset_remove_field(struct nc_widgetset *set, FIELD *field); + +static bool key_is_select(int key) +{ + return key == ' ' || key == '\r' || key == '\n' || key == KEY_ENTER; +} static bool process_key_nop(struct nc_widget *widget __attribute__((unused)), FORM *form __attribute((unused)), @@ -176,7 +211,7 @@ static bool checkbox_process_key(struct nc_widget *widget, { struct nc_widget_checkbox *checkbox = to_checkbox(widget); - if (key != ' ') + if (!key_is_select(key)) return false; checkbox->checked = !checkbox->checked; @@ -331,13 +366,8 @@ static bool select_process_key(struct nc_widget *w, FORM *form, int key) int i, new_idx; FIELD *field; - switch (key) { - case ' ': - case KEY_ENTER: - break; - default: + if (!key_is_select(key)) return false; - } field = current_field(form); new_opt = NULL; @@ -387,6 +417,19 @@ static void select_move(struct nc_widget *widget, int y, int x) field_move(select->options[i].field, y + i, x); } +static void select_field_focus(struct nc_widget *widget, FIELD *field) +{ + struct nc_widget_select *select = to_select(widget); + int i; + + for (i = 0; i < select->n_options; i++) { + if (field != select->options[i].field) + continue; + widget->focus_y = i; + return; + } +} + static int select_destructor(void *ptr) { struct nc_widget_select *select = ptr; @@ -411,6 +454,7 @@ struct nc_widget_select *widget_new_select(struct nc_widgetset *set, select->widget.process_key = select_process_key; select->widget.set_visible = select_set_visible; select->widget.move = select_move; + select->widget.field_focus = select_field_focus; select->widget.focussed_attr = A_REVERSE; select->widget.unfocussed_attr = A_NORMAL; select->top = y; @@ -466,6 +510,8 @@ void widget_select_add_option(struct nc_widget_select *select, int value, int widget_select_get_value(struct nc_widget_select *select) { + if (!select->n_options) + return -1; return select->options[select->selected_option].val; } @@ -481,6 +527,27 @@ void widget_select_on_change(struct nc_widget_select *select, select->on_change_arg = arg; } +void widget_select_drop_options(struct nc_widget_select *select) +{ + struct nc_widgetset *set = select->set; + int i; + + for (i = 0; i < select->n_options; i++) { + FIELD *field = select->options[i].field; + widgetset_remove_field(set, field); + if (field == set->cur_field) + set->cur_field = NULL; + free_field(select->options[i].field); + } + + talloc_free(select->options); + select->options = NULL; + select->n_options = 0; + select->widget.height = 0; + select->widget.focus_y = 0; + +} + static bool button_process_key(struct nc_widget *widget, FORM *form __attribute__((unused)), int key) { @@ -489,15 +556,11 @@ static bool button_process_key(struct nc_widget *widget, if (!button->click) return false; - switch (key) { - case ' ': - case '\r': - case '\n': - button->click(button->arg); - return true; - } + if (!key_is_select(key)) + return false; - return false; + button->click(button->arg); + return true; } static int button_destructor(void *ptr) @@ -593,6 +656,8 @@ bool widgetset_process_key(struct nc_widgetset *set, int key) field = current_field(set->form); widget = field_userptr(field); widget_focus_change(widget, field, true); + if (widget->field_focus) + widget->field_focus(widget, field); if (set->widget_focus) set->widget_focus(widget, set->widget_focus_arg); return true; @@ -625,6 +690,13 @@ struct nc_widgetset *widgetset_create(void *ctx, WINDOW *main, WINDOW *sub) return set; } +void widgetset_set_windows(struct nc_widgetset *set, + WINDOW *main, WINDOW *sub) +{ + set->mainwin = main; + set->subwin = sub; +} + void widgetset_set_widget_focus(struct nc_widgetset *set, widget_focus_cb cb, void *arg) { @@ -676,6 +748,23 @@ static void widgetset_add_field(struct nc_widgetset *set, FIELD *field) set->fields[set->n_fields] = NULL; } +static void widgetset_remove_field(struct nc_widgetset *set, FIELD *field) +{ + int i; + + for (i = 0; i < set->n_fields; i++) { + if (set->fields[i] == field) + break; + } + + if (i == set->n_fields) + return; + + memmove(&set->fields[i], &set->fields[i+i], + (set->n_fields - i) * sizeof(set->fields[i])); + set->n_fields--; +} + #define DECLARE_BASEFN(type) \ struct nc_widget *widget_ ## type ## _base \ (struct nc_widget_ ## type *w) \ @@ -726,3 +815,8 @@ int widget_y(struct nc_widget *widget) return widget->y; } +int widget_focus_y(struct nc_widget *widget) +{ + return widget->focus_y; +} +