Made clicking and dragging on scrollbar seek boxes scroll the widget.
[xuni.git] / src / test / options.c
blob05a9bc5847c630e492aa95d0df9031e538d85802
1 /*! \file options.c
3 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <ctype.h>
9 #include "options.h"
11 #include "graphics.h"
12 #include "gui.h"
13 #include "loop.h"
14 #include "memory.h"
15 #include "menu.h"
16 #include "utility.h"
18 #include "widget/widgets.h"
19 #include "widget/checkbox.h"
20 #include "widget/combobox.h"
21 #include "widget/listbox.h"
22 #include "widget/panel.h"
23 #include "widget/textbox.h"
25 #include "main.h"
27 enum wid_t {
28 WID_GRAPHICS_BUTTON,
29 WID_THEME_BUTTON,
30 WID_BACK,
31 WID_MAIN_MENU_BACKGROUND,
32 WID_GRAPHICS_BACK,
33 WID_GRAPHICS_FULLSCREEN,
34 WID_GRAPHICS_RESTRICTFOCUS,
35 WID_GRAPHICS_TEXTSCREENMODE,
36 WID_GRAPHICS_LISTSCREENMODE,
37 WID_THEME_BACK,
38 WID_THEME_FONT_FILENAME,
39 WID_THEME_THEME_NAME,
40 WID_THEME_THEME_ROUNDNESS,
41 WID_THEME_THEME_LIST,
42 WID_THEME_FONT_COMBO,
43 WID_THEME_FONTSAMPLE_LIST,
44 WIDS
47 static void get_screen_modes(struct xuni_t *xuni, struct widget_t *widget);
48 static void get_theme_names(struct xuni_t *xuni, struct widget_t *panel);
49 static void get_font_names(struct xuni_t *xuni, struct widget_t *panel);
50 static void get_main_menu_backgrounds(struct xuni_t *xuni,
51 struct widget_t *panel);
52 static void get_font_samples(struct xuni_t *xuni, struct widget_t *panel);
53 static void get_names_rec(struct xuni_t *xuni, struct widget_t *area,
54 struct widget_t *widget, enum widget_type_t type);
55 static void screen_mode_from_string(struct xuni_t *xuni, const char *mode);
57 int options_init(struct xuni_t *xuni, struct panel_data_t *data) {
58 struct widget_t *panel = data->event[PANEL_EVENT_INIT].p.init.panel;
59 struct widget_t *temppanel;
61 init_wid(xuni->gui->widget, xuni->gui->widget,
62 PANEL_OPTIONS, "options");
63 init_wid(xuni->gui->widget, xuni->gui->widget,
64 PANEL_OPTIONS_GRAPHICS, "options graphics");
65 init_wid(xuni->gui->widget, xuni->gui->widget,
66 PANEL_OPTIONS_THEME, "options theme");
68 init_wid(panel, panel, WID_GRAPHICS_BUTTON, "graphics");
69 init_wid(panel, panel, WID_THEME_BUTTON, "theme");
70 init_wid(panel, panel, WID_BACK, "back");
71 init_wid(panel, panel, WID_MAIN_MENU_BACKGROUND, "main menu background");
73 temppanel
74 = widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS_GRAPHICS);
76 init_wid(temppanel, panel, WID_GRAPHICS_BACK, "back");
77 init_wid(temppanel, panel, WID_GRAPHICS_FULLSCREEN, "fullscreen");
78 init_wid(temppanel, panel, WID_GRAPHICS_RESTRICTFOCUS,
79 "restrictfocus");
80 init_wid(temppanel, panel, WID_GRAPHICS_TEXTSCREENMODE,
81 "textscreenmode");
82 init_wid(temppanel, panel, WID_GRAPHICS_LISTSCREENMODE,
83 "listscreenmode");
85 init_wid(xuni->gui->widget, panel, WID_THEME_BACK,
86 "options theme/back");
87 init_wid(xuni->gui->widget, panel, WID_THEME_FONT_FILENAME,
88 "options theme/font filename");
89 init_wid(xuni->gui->widget, panel, WID_THEME_THEME_NAME,
90 "options theme/theme name");
91 init_wid(xuni->gui->widget, panel, WID_THEME_THEME_ROUNDNESS,
92 "options theme/theme roundness");
93 init_wid(xuni->gui->widget, panel, WID_THEME_THEME_LIST,
94 "options theme/theme list");
95 init_wid(xuni->gui->widget, panel, WID_THEME_FONT_COMBO,
96 "options theme/font combo");
97 init_wid(xuni->gui->widget, panel, WID_THEME_FONTSAMPLE_LIST,
98 "options theme/fontsample listbox");
100 add_widget_accelerator(xuni, panel,
101 widget_nameid_access(panel, WID_GRAPHICS_BUTTON), SDLK_g, KMOD_NONE);
102 add_widget_accelerator(xuni, panel,
103 widget_nameid_access(panel, WID_THEME_BUTTON), SDLK_t, KMOD_NONE);
104 add_widget_accelerator(xuni, panel,
105 widget_nameid_access(panel, WID_BACK), SDLK_ESCAPE, KMOD_NONE);
107 temppanel
108 = widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS_GRAPHICS);
109 add_widget_accelerator(xuni, temppanel,
110 widget_nameid_access(panel, WID_GRAPHICS_BACK),
111 SDLK_ESCAPE, KMOD_NONE);
113 temppanel = widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS_THEME);
114 add_widget_accelerator(xuni, temppanel,
115 widget_nameid_access(panel, WID_THEME_BACK), SDLK_ESCAPE, KMOD_NONE);
117 get_theme_names(xuni, panel);
118 get_font_names(xuni, panel);
119 get_main_menu_backgrounds(xuni, panel);
120 get_font_samples(xuni, panel);
122 return 0;
125 static void get_screen_modes(struct xuni_t *xuni, struct widget_t *widget) {
126 SDL_Rect **mode = list_graphics_modes(xuni->smode);
127 char buffer[BUFSIZ];
128 size_t x;
129 struct widget_t *area = widget->compose->widget[WID_LISTBOX_DATA];
131 xuni_memory_increment(area->compose);
132 free_panel(xuni, area->compose);
134 if(!mode) {
135 add_listbox_item(xuni, area, THEME_FONT_SANS, "No screen modes");
137 else if(mode == (SDL_Rect **)-1) {
138 add_listbox_item(xuni, area, THEME_FONT_SANS, "All screen modes");
140 else {
141 for(x = 0; mode[x]; x ++) {
142 sprintf(buffer, "%i x %i", (int)mode[x]->w, (int)mode[x]->h);
144 add_listbox_item(xuni, area, THEME_FONT_SANS, buffer);
148 /* RESCALE isn't needed, just REPOSITION works */
149 /*widget_event(xuni, widget, WIDGET_EVENT_RESCALE);*/
150 widget_event(xuni, widget, WIDGET_EVENT_REPOSITION);
153 static void get_theme_names(struct xuni_t *xuni, struct widget_t *panel) {
154 struct widget_t *area = widget_nameid_access(panel, WID_THEME_THEME_LIST)
155 ->compose->widget[WID_LISTBOX_DATA];
157 xuni_memory_increment(area->compose);
158 free_panel(xuni, area->compose);
160 get_names_rec(xuni, area, xuni->gui->widget, WIDGET_THEME);
162 widget_event(xuni, widget_nameid_access(panel, WID_THEME_THEME_LIST),
163 WIDGET_EVENT_RESCALE);
166 static void get_font_names(struct xuni_t *xuni, struct widget_t *panel) {
167 struct widget_t *area = widget_nameid_access(panel, WID_THEME_FONT_COMBO)
168 ->compose->widget[WID_COMBOBOX_DROPDOWN]
169 ->compose->widget[WID_LISTBOX_DATA];
171 xuni_memory_increment(area->compose);
172 free_panel(xuni, area->compose);
174 get_names_rec(xuni, area, find_widget(xuni->gui->widget, "font"),
175 WIDGET_FONT);
177 widget_event(xuni, widget_nameid_access(panel, WID_THEME_FONT_COMBO),
178 WIDGET_EVENT_RESCALE);
181 static void get_main_menu_backgrounds(struct xuni_t *xuni,
182 struct widget_t *panel) {
184 size_t x;
186 for(x = 0; x < sizeof(main_menu_background_names)
187 / sizeof(*main_menu_background_names); x ++) {
189 add_listbox_item(xuni, widget_nameid_access(panel,
190 WID_MAIN_MENU_BACKGROUND)->compose->widget[WID_LISTBOX_DATA],
191 THEME_FONT_SANS, main_menu_background_names[x].str);
194 widget_event(xuni, widget_nameid_access(panel, WID_MAIN_MENU_BACKGROUND),
195 WIDGET_EVENT_RESCALE);
198 static void get_font_samples(struct xuni_t *xuni, struct widget_t *panel) {
199 struct widget_t *area
200 = widget_nameid_access(panel, WID_THEME_FONTSAMPLE_LIST)
201 ->compose->widget[WID_LISTBOX_DATA];
202 struct widget_t *themepanel = widget_nameid_access(xuni->gui->widget,
203 PANEL_OPTIONS_THEME);
204 struct widget_t *widget;
205 size_t x;
207 xuni_memory_increment(area->compose);
208 free_panel(xuni, area->compose);
210 for(x = 0; x < themepanel->compose->widgets; x ++) {
211 widget = themepanel->compose->widget[x];
213 if(strstr(widget->name, "fontsample text")) {
214 add_allocate_widget_compose(area, "listbox item");
216 init_widget_pos(last_compose_widget(area),
217 0, 0, 0, 0, POS_PACK_TOP);
219 last_compose_widget(area)->type = WIDGET_LABEL;
221 xuni_memory_increment(widget->p.label);
222 last_compose_widget(area)->p.label = widget->p.label;
224 last_compose_widget(area)->visibility
225 &= ~WIDGET_VISIBILITY_INDEPENDENT;
229 widget_event(xuni, widget_nameid_access(panel, WID_THEME_FONTSAMPLE_LIST),
230 WIDGET_EVENT_RESCALE);
233 static void get_names_rec(struct xuni_t *xuni, struct widget_t *area,
234 struct widget_t *widget, enum widget_type_t type) {
236 const char *text;
237 size_t x;
239 if(!widget) return;
241 if(widget->type == (size_t)type) {
242 if(type == WIDGET_FONT) {
243 text = widget->p.font->name;
245 else text = widget->name;
247 add_listbox_item(xuni, area, THEME_FONT_SANS, text);
250 if(widget->compose) {
251 for(x = 0; x < widget->compose->widgets; x ++) {
252 get_names_rec(xuni, area, widget->compose->widget[x], type);
257 int options_start(struct xuni_t *xuni, struct panel_data_t *data) {
258 set_caption("Options and preferences");
260 return 0;
263 int options_event(struct xuni_t *xuni, struct panel_data_t *data) {
264 panel_type_t *mode = data->event[PANEL_EVENT_EVENT].p.event.mode;
265 SDL_Event *event = data->event[PANEL_EVENT_EVENT].p.event.event;
266 int repaint = 0;
268 switch(event->type) {
269 case SDL_QUIT:
270 *mode = PANEL_MAIN_MENU;
271 break;
272 default:
273 break;
276 return repaint;
279 int options_click(struct xuni_t *xuni, struct panel_data_t *data) {
280 panel_type_t *mode = data->event[PANEL_EVENT_CLICK].p.click.mode;
281 struct widget_t *widget = data->event[PANEL_EVENT_CLICK].p.click.widget;
282 struct widget_t *w;
284 switch(widget->id) {
285 /* Options menu */
286 case WID_GRAPHICS_BUTTON:
287 *mode = PANEL_OPTIONS_GRAPHICS;
288 clear_gui(xuni, PANEL_OPTIONS_GRAPHICS, 0);
289 break;
290 case WID_THEME_BUTTON:
291 *mode = PANEL_OPTIONS_THEME;
292 clear_gui(xuni, PANEL_OPTIONS_THEME, 0);
293 break;
294 case WID_BACK:
295 *mode = PANEL_MAIN_MENU;
296 break;
297 case WID_MAIN_MENU_BACKGROUND:
298 w = listbox_sel_item(widget);
299 if(w) {
300 switch_main_menu_background(
301 widget_nameid_access(xuni->gui->widget, PANEL_MAIN_MENU),
302 w->p.label->text);
305 break;
307 /* Options graphics menu */
308 case WID_GRAPHICS_BACK:
309 *mode = PANEL_OPTIONS;
310 clear_gui(xuni, PANEL_OPTIONS, 0);
311 break;
312 case WID_GRAPHICS_FULLSCREEN:
313 if(!toggle_fullscreen(xuni->smode)) {
314 get_screen_modes(xuni,
315 widget_nameid_follow(xuni->gui->widget,
316 PANEL_OPTIONS, WID_GRAPHICS_LISTSCREENMODE, (size_t)-1));
318 return 1;
321 break;
322 case WID_GRAPHICS_RESTRICTFOCUS:
323 xuni->smode->restrictfocus = set_focus(!xuni->smode->restrictfocus);
324 break;
325 case WID_GRAPHICS_LISTSCREENMODE:
326 w = listbox_sel_item(widget);
327 if(w) screen_mode_from_string(xuni, w->p.label->text);
329 break;
331 /* Options theme menu */
332 case WID_THEME_BACK:
333 *mode = PANEL_OPTIONS;
334 clear_gui(xuni, PANEL_OPTIONS, 0);
335 break;
336 case WID_THEME_THEME_LIST:
337 w = listbox_sel_item(widget);
338 if(w) {
339 use_theme_by_name(xuni, w->p.label->text);
340 widget_event(xuni, xuni->gui->widget, WIDGET_EVENT_REPOSITION);
343 break;
346 if(widget->base && widget->base->id == WID_THEME_FONT_COMBO) {
347 if(widget->type == WIDGET_LISTBOX) {
348 struct widget_t *w = listbox_sel_item(widget);
350 if(w) {
351 use_font_by_name(xuni, THEME_FONT_SANS,
352 load_font(xuni->gui->widget, w->p.label->text));
354 get_font_names(xuni,
355 widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS));
360 /*if(compare_widget_name(widget, "options", "back", "box", 0)) {
361 *mode = PANEL_MAIN_MENU;
364 return 0;
367 /*void perform_back_click(struct widget_t *widget,
368 panel_type_t *mode, void *vdata, struct xuni_t *xuni) {
370 if(compare_widget_name(widget, "options", "back", "box", 0)) {
371 *mode = PANEL_MAIN_MENU;
373 else if(compare_widget_name(widget, "options graphics", "back", "box", 0)
374 || compare_widget_name(widget, "options theme", "back", "box", 0)) {
376 *mode = PANEL_OPTIONS;
377 clear_gui(xuni, PANEL_OPTIONS, 0);
381 static void screen_mode_from_string(struct xuni_t *xuni, const char *mode) {
382 long w, h;
383 char *p;
385 w = strtol(mode, &p, 0);
386 if(mode == p) return;
387 while(!isdigit(*p)) p ++;
389 mode = p;
390 h = strtol(mode, &p, 0);
391 if(mode == p) return;
393 use_screen_mode(xuni, w, h);
396 int options_graphics_deactivate(struct xuni_t *xuni,
397 struct panel_data_t *data) {
399 struct widget_t *widget
400 = data->event[PANEL_EVENT_DEACTIVATE].p.deactivate.widget;
402 switch(widget->id) {
403 case WID_GRAPHICS_TEXTSCREENMODE:
404 screen_mode_from_string(xuni, get_textbox_data(widget));
406 break;
409 return 0;
412 int options_theme_deactivate(struct xuni_t *xuni,
413 struct panel_data_t *data) {
415 struct widget_t *widget
416 = data->event[PANEL_EVENT_DEACTIVATE].p.deactivate.widget;
418 switch(widget->id) {
419 case WID_THEME_FONT_FILENAME:
420 use_font_by_name(xuni, THEME_FONT_SANS,
421 load_font(xuni->gui->widget, get_textbox_data(widget)));
423 get_font_names(xuni,
424 widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS));
426 break;
427 case WID_THEME_THEME_NAME:
428 if(use_theme_by_name(xuni, get_textbox_data(widget))) {
429 puts("*** NYI: revert to previous theme name");
432 break;
433 case WID_THEME_THEME_ROUNDNESS:
434 use_theme_roundness(xuni, xuni->theme->current,
435 100.0 / (strtod(get_textbox_data(widget), 0) * 2));
436 widget_event(xuni, xuni->gui->widget, WIDGET_EVENT_REPOSITION);
437 break;
438 default:
439 break;
442 if(widget->base && widget->base->id == WID_THEME_FONT_COMBO) {
443 if(widget->type == WIDGET_TEXTBOX) {
444 const char *text = get_textbox_data(widget);
446 use_font_by_name(xuni, THEME_FONT_SANS,
447 load_font(xuni->gui->widget, text));
449 get_font_names(xuni,
450 widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS));
454 return 0;
457 int options_paint(struct xuni_t *xuni, struct panel_data_t *data) {
458 panel_type_t mode = data->event[PANEL_EVENT_PAINT].p.paint.mode;
459 /*struct options_data_t *data = vdata;*/
460 /*static int fullscreen = -1;*/
462 /*xuni->gui->panel->widget[PANEL_OPTIONS_GRAPHICS]->compose->widget[2]
463 ->p.checkbox->checked = (xuni->smode->restrictfocus == SDL_GRAB_ON);*/
465 /*if(fullscreen != xuni->smode->fullscreen) {
466 fullscreen = xuni->smode->fullscreen;
468 get_screen_modes(xuni->smode, xuni->font,
469 xuni->gui->panel->widget[PANEL_OPTIONS_GRAPHICS]->compose
470 ->widget[4]);
472 set_checkbox(
473 xuni->gui->panel->widget[PANEL_OPTIONS_GRAPHICS]->compose
474 ->widget[1], xuni->smode->fullscreen);
477 set_checkbox(widget_nameid_follow(xuni->gui->widget,
478 PANEL_OPTIONS, WID_GRAPHICS_FULLSCREEN, (size_t)-1),
479 xuni->smode->fullscreen);
481 /*clear_widget_clip(xuni, widget_nameid_follow(xuni->gui->widget,
482 PANEL_OPTIONS, WID_THEME_THEME_LIST, (size_t)-1)
483 ->compose->widget[WID_LISTBOX_DATA]);*/
485 clear_screen(xuni->smode->screen);
487 if(mode == PANEL_OPTIONS) {
488 widget_event(xuni, widget_nameid_access(xuni->gui->widget,
489 PANEL_OPTIONS), WIDGET_EVENT_PAINT);
491 else if(mode == PANEL_OPTIONS_GRAPHICS) {
492 widget_event(xuni, widget_nameid_access(xuni->gui->widget,
493 PANEL_OPTIONS_GRAPHICS), WIDGET_EVENT_PAINT);
495 else if(mode == PANEL_OPTIONS_THEME) {
496 widget_event(xuni, widget_nameid_access(xuni->gui->widget,
497 PANEL_OPTIONS_THEME), WIDGET_EVENT_PAINT);
500 paint_menu_fps(xuni, THEME_FONT_MONO);
502 update_screen(xuni);
504 return 0;
507 int options_free(struct xuni_t *xuni, struct panel_data_t *data) {
508 return 0;