2 * Copyright (C) 2013 IBM Corporation
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #if defined(HAVE_CONFIG_H)
26 #include <talloc/talloc.h>
27 #include <types/types.h>
28 #include <i18n/i18n.h>
32 #include "nc-subset.h"
36 struct subset_screen {
39 struct nc_scr *return_scr;
40 struct nc_widgetset *widgetset;
42 struct nc_widget_subset *options;
45 void (*on_exit)(struct cui *);
53 struct nc_widget_select *options_f;
55 struct nc_widget_button *ok_b;
56 struct nc_widget_button *cancel_b;
60 struct nc_scr *subset_screen_return_scr(struct subset_screen *screen)
62 return screen->return_scr;
65 void subset_screen_update(struct subset_screen *screen)
67 pb_debug("Exiting subset due to update\n");
68 return screen->on_exit(screen->cui);
71 static struct subset_screen *subset_screen_from_scr(struct nc_scr *scr)
73 struct subset_screen *subset_screen;
75 assert(scr->sig == pb_subset_screen_sig);
76 subset_screen = (struct subset_screen *)
77 ((char *)scr - (size_t)&((struct subset_screen *)0)->scr);
78 assert(subset_screen->scr.sig == pb_subset_screen_sig);
82 static void pad_refresh(struct subset_screen *screen)
86 getmaxyx(screen->scr.sub_ncw, rows, cols);
87 getbegyx(screen->scr.sub_ncw, y, x);
89 prefresh(screen->pad, screen->scroll_y, 0, y, x, rows, cols);
92 static void subset_screen_process_key(struct nc_scr *scr, int key)
94 struct subset_screen *screen = subset_screen_from_scr(scr);
97 handled = widgetset_process_key(screen->widgetset, key);
109 screen->on_exit(screen->cui);
114 static int subset_screen_post(struct nc_scr *scr)
116 struct subset_screen *screen = subset_screen_from_scr(scr);
117 widgetset_post(screen->widgetset);
118 nc_scr_frame_draw(scr);
119 redrawwin(scr->main_ncw);
120 wrefresh(scr->main_ncw);
125 static int subset_screen_unpost(struct nc_scr *scr)
127 struct subset_screen *screen = subset_screen_from_scr(scr);
128 widgetset_unpost(screen->widgetset);
132 struct nc_scr *subset_screen_scr(struct subset_screen *screen)
137 static void ok_click(void *arg)
139 struct subset_screen *screen = arg;
140 int idx = widget_select_get_value(screen->widgets.options_f);
141 widget_subset_callback(screen->return_scr, screen->options, idx);
145 static void cancel_click(void *arg)
147 struct subset_screen *screen = arg;
151 static void subset_screen_layout_widgets(struct subset_screen *screen)
156 widget_move(widget_select_base(screen->widgets.options_f),
158 y+= widget_height(widget_select_base(screen->widgets.options_f));
163 widget_move(widget_button_base(screen->widgets.ok_b),
165 widget_move(widget_button_base(screen->widgets.cancel_b),
166 y, screen->field_x + 14);
169 static void subset_screen_option_select(void *arg, int value)
171 struct subset_screen *screen = arg;
172 widgetset_unpost(screen->widgetset);
173 subset_screen_layout_widgets(screen);
174 widgetset_post(screen->widgetset);
178 static void subset_screen_setup_widgets(struct subset_screen *screen)
180 struct nc_widgetset *set = screen->widgetset;
181 struct nc_widget_subset *subset = screen->options;
183 build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
186 screen->widgets.options_f = widget_new_select(set, 0, 0,
187 COLS - (2 * screen->label_x));
189 widget_select_on_change(screen->widgets.options_f,
190 subset_screen_option_select, screen);
192 widget_subset_show_inactive(subset, screen->widgets.options_f);
194 screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
196 screen->widgets.cancel_b = widget_new_button(set, 0, 0, 10, _("Cancel"),
197 cancel_click, screen);
200 static void subset_screen_widget_focus(struct nc_widget *widget, void *arg)
202 struct subset_screen *screen = arg;
205 w_y = widget_y(widget) + widget_focus_y(widget);
206 s_max = getmaxy(screen->scr.sub_ncw) - 1;
208 if (w_y < screen->scroll_y)
209 screen->scroll_y = w_y;
211 else if (w_y + screen->scroll_y + 1 > s_max)
212 screen->scroll_y = 1 + w_y - s_max;
220 static void subset_screen_draw(struct subset_screen *screen)
226 * Size of pad = top space + 2 * number of available options in case
229 height = 1 + N_FIELDS + widget_subset_n_inactive(screen->options) * 2;
231 if (!screen->pad || getmaxy(screen->pad) < height) {
234 screen->pad = newpad(height, COLS);
237 if (screen->widgetset) {
238 widgetset_unpost(screen->widgetset);
239 talloc_free(screen->widgetset);
243 screen->widgetset = widgetset_create(screen, screen->scr.main_ncw,
245 widgetset_set_widget_focus(screen->widgetset,
246 subset_screen_widget_focus, screen);
248 subset_screen_setup_widgets(screen);
249 subset_screen_layout_widgets(screen);
252 widgetset_post(screen->widgetset);
255 static int subset_screen_destroy(void *arg)
257 struct subset_screen *screen = arg;
263 struct subset_screen *subset_screen_init(struct cui *cui,
264 struct nc_scr *current_scr,
265 const char *title_suffix,
267 void (*on_exit)(struct cui *))
269 struct subset_screen *screen;
271 screen = talloc_zero(cui, struct subset_screen);
272 talloc_set_destructor(screen, subset_screen_destroy);
275 screen->on_exit = on_exit;
276 screen->options = (struct nc_widget_subset *) subset;
280 screen->return_scr = current_scr;
282 nc_scr_init(&screen->scr, pb_subset_screen_sig, 0,
283 cui, subset_screen_process_key,
284 subset_screen_post, subset_screen_unpost,
287 screen->scr.frame.ltitle = talloc_strdup(screen,
289 screen->scr.frame.rtitle = NULL;
290 screen->scr.frame.help = talloc_strdup(screen,
291 _("tab=next, shift+tab=previous, x=exit"));
293 scrollok(screen->scr.sub_ncw, true);
295 subset_screen_draw(screen);