Created common signature for panel event handling functions.
[xuni.git] / src / test / options.c
blob96549fef79fa4862b33ce7d1561ea2e8602c8348
1 /*! \file options.c
3 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <ctype.h>
9 #include "SDL_image.h"
10 #include "SDL_rotozoom.h"
12 #include "options.h"
14 #include "graphics.h"
15 #include "gui.h"
16 #include "loop.h"
17 #include "memory.h"
18 #include "menu.h"
19 #include "utility.h"
21 #include "widget/widgets.h"
22 #include "widget/checkbox.h"
23 #include "widget/combobox.h"
24 #include "widget/listbox.h"
25 #include "widget/panel.h"
26 #include "widget/textbox.h"
28 #include "main.h"
30 enum wid_t {
31 WID_GRAPHICS_BUTTON,
32 WID_THEME_BUTTON,
33 WID_BACK,
34 WID_MAIN_MENU_BACKGROUND,
35 WID_GRAPHICS_BACK,
36 WID_GRAPHICS_FULLSCREEN,
37 WID_GRAPHICS_RESTRICTFOCUS,
38 WID_GRAPHICS_TEXTSCREENMODE,
39 WID_GRAPHICS_LISTSCREENMODE,
40 WID_THEME_BACK,
41 WID_THEME_FONT_FILENAME,
42 WID_THEME_THEME_NAME,
43 WID_THEME_THEME_ROUNDNESS,
44 WID_THEME_THEME_LIST,
45 WID_THEME_FONT_COMBO,
46 WID_THEME_FONTSAMPLE_LIST,
47 WIDS
50 static void get_screen_modes(struct xuni_t *xuni, struct widget_t *widget);
51 static void get_theme_names(struct xuni_t *xuni, struct widget_t *panel);
52 static void get_font_names(struct xuni_t *xuni, struct widget_t *panel);
53 static void get_main_menu_backgrounds(struct xuni_t *xuni,
54 struct widget_t *panel);
55 static void get_font_samples(struct xuni_t *xuni, struct widget_t *panel);
56 static void get_names_rec(struct xuni_t *xuni, struct widget_t *area,
57 struct widget_t *widget, enum widget_type_t type);
58 static void screen_mode_from_string(struct xuni_t *xuni, const char *mode);
60 int options_init(struct xuni_t *xuni, struct panel_data_t *data) {
61 struct widget_t *panel = data->event[PANEL_EVENT_INIT].p.init.panel;
62 struct widget_t *temppanel;
64 init_wid(xuni->gui->widget, xuni->gui->widget,
65 PANEL_OPTIONS, "options");
66 init_wid(xuni->gui->widget, xuni->gui->widget,
67 PANEL_OPTIONS_GRAPHICS, "options graphics");
68 init_wid(xuni->gui->widget, xuni->gui->widget,
69 PANEL_OPTIONS_THEME, "options theme");
71 init_wid(panel, panel, WID_GRAPHICS_BUTTON, "graphics");
72 init_wid(panel, panel, WID_THEME_BUTTON, "theme");
73 init_wid(panel, panel, WID_BACK, "back");
74 init_wid(panel, panel, WID_MAIN_MENU_BACKGROUND, "main menu background");
76 temppanel
77 = widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS_GRAPHICS);
79 init_wid(temppanel, panel, WID_GRAPHICS_BACK, "back");
80 init_wid(temppanel, panel, WID_GRAPHICS_FULLSCREEN, "fullscreen");
81 init_wid(temppanel, panel, WID_GRAPHICS_RESTRICTFOCUS,
82 "restrictfocus");
83 init_wid(temppanel, panel, WID_GRAPHICS_TEXTSCREENMODE,
84 "textscreenmode");
85 init_wid(temppanel, panel, WID_GRAPHICS_LISTSCREENMODE,
86 "listscreenmode");
88 init_wid(xuni->gui->widget, panel, WID_THEME_BACK,
89 "options theme/back");
90 init_wid(xuni->gui->widget, panel, WID_THEME_FONT_FILENAME,
91 "options theme/font filename");
92 init_wid(xuni->gui->widget, panel, WID_THEME_THEME_NAME,
93 "options theme/theme name");
94 init_wid(xuni->gui->widget, panel, WID_THEME_THEME_ROUNDNESS,
95 "options theme/theme roundness");
96 init_wid(xuni->gui->widget, panel, WID_THEME_THEME_LIST,
97 "options theme/theme list");
98 init_wid(xuni->gui->widget, panel, WID_THEME_FONT_COMBO,
99 "options theme/font combo");
100 init_wid(xuni->gui->widget, panel, WID_THEME_FONTSAMPLE_LIST,
101 "options theme/fontsample listbox");
103 add_widget_accelerator(xuni, panel,
104 widget_nameid_access(panel, WID_GRAPHICS_BUTTON), SDLK_g, KMOD_NONE);
105 add_widget_accelerator(xuni, panel,
106 widget_nameid_access(panel, WID_THEME_BUTTON), SDLK_t, KMOD_NONE);
107 add_widget_accelerator(xuni, panel,
108 widget_nameid_access(panel, WID_BACK), SDLK_ESCAPE, KMOD_NONE);
110 temppanel
111 = widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS_GRAPHICS);
112 add_widget_accelerator(xuni, temppanel,
113 widget_nameid_access(panel, WID_GRAPHICS_BACK),
114 SDLK_ESCAPE, KMOD_NONE);
116 temppanel = widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS_THEME);
117 add_widget_accelerator(xuni, temppanel,
118 widget_nameid_access(panel, WID_THEME_BACK), SDLK_ESCAPE, KMOD_NONE);
120 get_theme_names(xuni, panel);
121 get_font_names(xuni, panel);
122 get_main_menu_backgrounds(xuni, panel);
123 get_font_samples(xuni, panel);
125 return 0;
128 static void get_screen_modes(struct xuni_t *xuni, struct widget_t *widget) {
129 SDL_Rect **mode = list_graphics_modes(xuni->smode);
130 char buffer[BUFSIZ];
131 size_t x;
132 struct widget_t *area = widget->compose->widget[WID_LISTBOX_DATA];
134 xuni_memory_increment(area->compose);
135 free_panel(xuni, area->compose);
137 if(!mode) {
138 add_listbox_item(xuni, area, THEME_FONT_SANS, "No screen modes");
140 else if(mode == (SDL_Rect **)-1) {
141 add_listbox_item(xuni, area, THEME_FONT_SANS, "All screen modes");
143 else {
144 for(x = 0; mode[x]; x ++) {
145 sprintf(buffer, "%i x %i", (int)mode[x]->w, (int)mode[x]->h);
147 add_listbox_item(xuni, area, THEME_FONT_SANS, buffer);
151 /* RESCALE isn't needed, just REPOSITION works */
152 /*widget_event(xuni, widget, WIDGET_EVENT_RESCALE);*/
153 widget_event(xuni, widget, WIDGET_EVENT_REPOSITION);
156 static void get_theme_names(struct xuni_t *xuni, struct widget_t *panel) {
157 struct widget_t *area = widget_nameid_access(panel, WID_THEME_THEME_LIST)
158 ->compose->widget[WID_LISTBOX_DATA];
160 xuni_memory_increment(area->compose);
161 free_panel(xuni, area->compose);
163 get_names_rec(xuni, area, xuni->gui->widget, WIDGET_THEME);
165 widget_event(xuni, widget_nameid_access(panel, WID_THEME_THEME_LIST),
166 WIDGET_EVENT_RESCALE);
169 static void get_font_names(struct xuni_t *xuni, struct widget_t *panel) {
170 struct widget_t *area = widget_nameid_access(panel, WID_THEME_FONT_COMBO)
171 ->compose->widget[WID_COMBOBOX_DROPDOWN]
172 ->compose->widget[WID_LISTBOX_DATA];
174 xuni_memory_increment(area->compose);
175 free_panel(xuni, area->compose);
177 get_names_rec(xuni, area, find_widget(xuni->gui->widget, "font"),
178 WIDGET_FONT);
180 widget_event(xuni, widget_nameid_access(panel, WID_THEME_FONT_COMBO),
181 WIDGET_EVENT_RESCALE);
184 static void get_main_menu_backgrounds(struct xuni_t *xuni,
185 struct widget_t *panel) {
187 size_t x;
189 for(x = 0; x < sizeof(main_menu_background_names)
190 / sizeof(*main_menu_background_names); x ++) {
192 add_listbox_item(xuni, widget_nameid_access(panel,
193 WID_MAIN_MENU_BACKGROUND)->compose->widget[WID_LISTBOX_DATA],
194 THEME_FONT_SANS, main_menu_background_names[x].str);
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 const char *text = w->p.label->text;
353 use_font_by_name(xuni, THEME_FONT_SANS,
354 load_font(xuni->gui->widget, text));
356 get_font_names(xuni,
357 widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS));
362 /*if(compare_widget_name(widget, "options", "back", "box", 0)) {
363 *mode = PANEL_MAIN_MENU;
366 return 0;
369 /*void perform_back_click(struct widget_t *widget,
370 panel_type_t *mode, void *vdata, struct xuni_t *xuni) {
372 if(compare_widget_name(widget, "options", "back", "box", 0)) {
373 *mode = PANEL_MAIN_MENU;
375 else if(compare_widget_name(widget, "options graphics", "back", "box", 0)
376 || compare_widget_name(widget, "options theme", "back", "box", 0)) {
378 *mode = PANEL_OPTIONS;
379 clear_gui(xuni, PANEL_OPTIONS, 0);
383 static void screen_mode_from_string(struct xuni_t *xuni, const char *mode) {
384 long w, h;
385 char *p;
387 w = strtol(mode, &p, 0);
388 if(mode == p) return;
389 while(!isdigit(*p)) p ++;
391 mode = p;
392 h = strtol(mode, &p, 0);
393 if(mode == p) return;
395 use_screen_mode(xuni, w, h);
398 int options_graphics_deactivate(struct xuni_t *xuni,
399 struct panel_data_t *data) {
401 struct widget_t *widget
402 = data->event[PANEL_EVENT_DEACTIVATE].p.deactivate.widget;
404 switch(widget->id) {
405 case WID_GRAPHICS_TEXTSCREENMODE:
406 screen_mode_from_string(xuni, get_textbox_data(widget));
408 break;
411 return 0;
414 int options_theme_deactivate(struct xuni_t *xuni,
415 struct panel_data_t *data) {
417 struct widget_t *widget
418 = data->event[PANEL_EVENT_DEACTIVATE].p.deactivate.widget;
420 switch(widget->id) {
421 case WID_THEME_FONT_FILENAME:
422 use_font_by_name(xuni, THEME_FONT_SANS,
423 load_font(xuni->gui->widget, get_textbox_data(widget)));
425 get_font_names(xuni,
426 widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS));
428 break;
429 case WID_THEME_THEME_NAME:
430 if(use_theme_by_name(xuni, get_textbox_data(widget))) {
431 puts("*** NYI: revert to previous theme name");
434 break;
435 case WID_THEME_THEME_ROUNDNESS:
436 use_theme_roundness(xuni, xuni->theme->current,
437 100.0 / (strtod(get_textbox_data(widget), 0) * 2));
438 widget_event(xuni, xuni->gui->widget, WIDGET_EVENT_REPOSITION);
439 break;
440 default:
441 break;
444 if(widget->base && widget->base->id == WID_THEME_FONT_COMBO) {
445 if(widget->type == WIDGET_TEXTBOX) {
446 const char *text = get_textbox_data(widget);
448 use_font_by_name(xuni, THEME_FONT_SANS,
449 load_font(xuni->gui->widget, text));
451 get_font_names(xuni,
452 widget_nameid_access(xuni->gui->widget, PANEL_OPTIONS));
456 return 0;
459 int options_paint(struct xuni_t *xuni, struct panel_data_t *data) {
460 panel_type_t mode = data->event[PANEL_EVENT_PAINT].p.paint.mode;
461 /*struct options_data_t *data = vdata;*/
462 /*static int fullscreen = -1;*/
464 /*xuni->gui->panel->widget[PANEL_OPTIONS_GRAPHICS]->compose->widget[2]
465 ->p.checkbox->checked = (xuni->smode->restrictfocus == SDL_GRAB_ON);*/
467 /*if(fullscreen != xuni->smode->fullscreen) {
468 fullscreen = xuni->smode->fullscreen;
470 get_screen_modes(xuni->smode, xuni->font,
471 xuni->gui->panel->widget[PANEL_OPTIONS_GRAPHICS]->compose
472 ->widget[4]);
474 set_checkbox(
475 xuni->gui->panel->widget[PANEL_OPTIONS_GRAPHICS]->compose
476 ->widget[1], xuni->smode->fullscreen);
479 set_checkbox(widget_nameid_follow(xuni->gui->widget,
480 PANEL_OPTIONS, WID_GRAPHICS_FULLSCREEN, (size_t)-1),
481 xuni->smode->fullscreen);
483 /*clear_widget_clip(xuni, widget_nameid_follow(xuni->gui->widget,
484 PANEL_OPTIONS, WID_THEME_THEME_LIST, (size_t)-1)
485 ->compose->widget[WID_LISTBOX_DATA]);*/
487 clear_screen(xuni->smode->screen);
489 if(mode == PANEL_OPTIONS) {
490 widget_event(xuni, widget_nameid_access(xuni->gui->widget,
491 PANEL_OPTIONS), WIDGET_EVENT_PAINT);
493 else if(mode == PANEL_OPTIONS_GRAPHICS) {
494 widget_event(xuni, widget_nameid_access(xuni->gui->widget,
495 PANEL_OPTIONS_GRAPHICS), WIDGET_EVENT_PAINT);
497 else if(mode == PANEL_OPTIONS_THEME) {
498 widget_event(xuni, widget_nameid_access(xuni->gui->widget,
499 PANEL_OPTIONS_THEME), WIDGET_EVENT_PAINT);
502 paint_menu_fps(xuni, THEME_FONT_MONO);
504 update_screen(xuni);
506 return 0;
509 int options_free(struct xuni_t *xuni, struct panel_data_t *data) {
510 return 0;