10 #include "SDL_rotozoom.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"
34 WID_MAIN_MENU_BACKGROUND
,
36 WID_GRAPHICS_FULLSCREEN
,
37 WID_GRAPHICS_RESTRICTFOCUS
,
38 WID_GRAPHICS_TEXTSCREENMODE
,
39 WID_GRAPHICS_LISTSCREENMODE
,
41 WID_THEME_FONT_FILENAME
,
43 WID_THEME_THEME_ROUNDNESS
,
46 WID_THEME_FONTSAMPLE_LIST
,
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");
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
,
83 init_wid(temppanel
, panel
, WID_GRAPHICS_TEXTSCREENMODE
,
85 init_wid(temppanel
, panel
, WID_GRAPHICS_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
);
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
);
128 static void get_screen_modes(struct xuni_t
*xuni
, struct widget_t
*widget
) {
129 SDL_Rect
**mode
= list_graphics_modes(xuni
->smode
);
132 struct widget_t
*area
= widget
->compose
->widget
[WID_LISTBOX_DATA
];
134 xuni_memory_increment(area
->compose
);
135 free_panel(xuni
, area
->compose
);
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");
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"),
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
) {
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
;
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
) {
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");
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
;
268 switch(event
->type
) {
270 *mode
= PANEL_MAIN_MENU
;
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
;
286 case WID_GRAPHICS_BUTTON
:
287 *mode
= PANEL_OPTIONS_GRAPHICS
;
288 clear_gui(xuni
, PANEL_OPTIONS_GRAPHICS
, 0);
290 case WID_THEME_BUTTON
:
291 *mode
= PANEL_OPTIONS_THEME
;
292 clear_gui(xuni
, PANEL_OPTIONS_THEME
, 0);
295 *mode
= PANEL_MAIN_MENU
;
297 case WID_MAIN_MENU_BACKGROUND
:
298 w
= listbox_sel_item(widget
);
300 switch_main_menu_background(
301 widget_nameid_access(xuni
->gui
->widget
, PANEL_MAIN_MENU
),
307 /* Options graphics menu */
308 case WID_GRAPHICS_BACK
:
309 *mode
= PANEL_OPTIONS
;
310 clear_gui(xuni
, PANEL_OPTIONS
, 0);
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));
322 case WID_GRAPHICS_RESTRICTFOCUS
:
323 xuni
->smode
->restrictfocus
= set_focus(!xuni
->smode
->restrictfocus
);
325 case WID_GRAPHICS_LISTSCREENMODE
:
326 w
= listbox_sel_item(widget
);
327 if(w
) screen_mode_from_string(xuni
, w
->p
.label
->text
);
331 /* Options theme menu */
333 *mode
= PANEL_OPTIONS
;
334 clear_gui(xuni
, PANEL_OPTIONS
, 0);
336 case WID_THEME_THEME_LIST
:
337 w
= listbox_sel_item(widget
);
339 use_theme_by_name(xuni
, w
->p
.label
->text
);
340 widget_event(xuni
, xuni
->gui
->widget
, WIDGET_EVENT_REPOSITION
);
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
);
351 const char *text
= w
->p
.label
->text
;
353 use_font_by_name(xuni
, THEME_FONT_SANS
,
354 load_font(xuni
->gui
->widget
, text
));
357 widget_nameid_access(xuni
->gui
->widget
, PANEL_OPTIONS
));
362 /*if(compare_widget_name(widget, "options", "back", "box", 0)) {
363 *mode = PANEL_MAIN_MENU;
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
) {
387 w
= strtol(mode
, &p
, 0);
388 if(mode
== p
) return;
389 while(!isdigit(*p
)) 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
;
405 case WID_GRAPHICS_TEXTSCREENMODE
:
406 screen_mode_from_string(xuni
, get_textbox_data(widget
));
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
;
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
)));
426 widget_nameid_access(xuni
->gui
->widget
, PANEL_OPTIONS
));
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");
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
);
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
));
452 widget_nameid_access(xuni
->gui
->widget
, PANEL_OPTIONS
));
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
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
);
509 int options_free(struct xuni_t
*xuni
, struct panel_data_t
*data
) {