Began implementing listboxes. They are very rudimentary right now, without scrolling...
[xuni.git] / src / options.c
blob9bbc771ad14ac9d02d4a64eb40d990afa71b13a1
1 /*! \file options.c
3 */
5 #include "SDL_image.h"
6 #include "SDL_rotozoom.h"
7 #include "options.h"
8 #include "font.h"
9 #include "graphics.h"
10 #include "gui.h"
11 #include "loop.h"
12 #include "menu.h"
13 #include "xuni.h"
15 static void resize_options_images(struct options_data_t *data,
16 struct smode_t *smode, struct font_t *font, struct theme_t *theme,
17 struct gui_t *gui);
18 static void resize_theme_fontsample(struct options_data_t *data,
19 struct font_t *font);
20 static void get_screen_modes(struct smode_t *smode, struct widget_t *widget);
21 static void paint_theme_fontsample(struct smode_t *smode,
22 struct options_data_t *data);
23 static void free_resize_options(struct options_data_t *data,
24 struct gui_t *gui);
26 void init_options(struct options_data_t *data, struct smode_t *smode,
27 struct font_t *font, struct theme_t *theme, struct gui_t *gui) {
29 data->mode = OMODE_NORMAL;
31 /* Allocate the options menu widgets. */
32 add_allocate_widget(gui->panel[PANEL_OPTIONS], 0, WIDGET_BUTTON);
33 add_allocate_widget(gui->panel[PANEL_OPTIONS], 1, WIDGET_BUTTON);
34 add_allocate_widget(gui->panel[PANEL_OPTIONS], 2, WIDGET_BUTTON);
36 /* Allocate the graphics widgets. */
37 add_allocate_widget(
38 gui->panel[PANEL_OPTIONS_GRAPHICS], 100, WIDGET_BUTTON);
39 add_allocate_widget(
40 gui->panel[PANEL_OPTIONS_GRAPHICS], 101, WIDGET_CHECKBOX);
41 add_allocate_widget(
42 gui->panel[PANEL_OPTIONS_GRAPHICS], 102, WIDGET_CHECKBOX);
43 add_allocate_widget(
44 gui->panel[PANEL_OPTIONS_GRAPHICS], 103, WIDGET_TEXTBOX);
45 add_allocate_widget(
46 gui->panel[PANEL_OPTIONS_GRAPHICS], 104, WIDGET_LISTBOX);
48 /* Initialize the theme widgets. */
49 add_allocate_widget(gui->panel[PANEL_OPTIONS_THEME], 200, WIDGET_BUTTON);
51 get_screen_modes(smode, gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[4]);
53 data->loaded = 0;
54 resize_options_images(data, smode, font, theme, gui);
55 data->loaded = 1;
58 static void resize_options_images(struct options_data_t *data,
59 struct smode_t *smode, struct font_t *font, struct theme_t *theme,
60 struct gui_t *gui) {
62 if(data->loaded) free_resize_options(data, gui);
64 /* Set the options menu widgets. */
65 set_button(gui->panel[PANEL_OPTIONS]->widget[0],
66 font->sans, "Graphics",
67 (smode->width - smode->width / 3) / 2,
68 smode->height / 8,
69 smode->width / 3, smode->height / 15);
70 set_button(gui->panel[PANEL_OPTIONS]->widget[1],
71 font->sans, "Theme",
72 (smode->width - smode->width / 3) / 2,
73 smode->height / 8 + smode->height / 15 * 1.3,
74 smode->width / 3, smode->height / 15);
75 set_button(gui->panel[PANEL_OPTIONS]->widget[2],
76 font->sans, "Return to main menu",
77 (smode->width - smode->width / 3) / 2,
78 smode->height / 8 + smode->height / 15 * 1.3 * 2,
79 smode->width / 3, smode->height / 15);
81 /* Set the graphics widgets. */
82 set_button(gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[0],
83 font->sans, "Return to options",
84 (smode->width - smode->width / 4) / 2,
85 smode->height / 8 + smode->height / 15 * 1.3,
86 smode->width / 4, smode->height / 15);
87 set_checkbox(gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[1],
88 font->sans, "Fullscreen",
89 smode->fullscreen, (smode->width - smode->width / 4) / 2,
90 smode->height / 8 + smode->height / 15 * 1.3 * 2,
91 smode->width / 3, smode->height / 15, smode->width / 20);
92 set_checkbox(gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[2],
93 font->sans, "Restrict cursor",
94 smode->restrictfocus, (smode->width - smode->width / 4) / 2,
95 smode->height / 8 + smode->height / 15 * 1.3 * 3,
96 smode->width / 3, smode->height / 15, smode->width / 20);
98 char buffer[BUFSIZ];
99 sprintf(buffer, "%ix%ix%i",
100 smode->width, smode->height, smode->depth);
102 set_textbox_data(gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[3],
103 buffer, strlen(buffer));
105 set_textbox(gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[3],
106 font->sans,
107 (smode->width - smode->width / 4) / 2,
108 smode->height / 8 + smode->height / 15 * 1.3 * 4,
109 smode->width / 3, smode->height / 15);
112 set_listbox(gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[4],
113 (smode->width - smode->width / 4) / 2,
114 smode->height / 8 + smode->height / 15 * 1.3 * 5,
115 smode->width / 4, smode->height / 15 * 3);
117 /* Set the theme widgets. */
118 set_button(gui->panel[PANEL_OPTIONS_THEME]->widget[0],
119 font->sans, "Return to options",
120 (smode->width - smode->width / 4) / 2,
121 smode->height / 8 + smode->height / 15 * 1.3,
122 smode->width / 4, smode->height / 15);
124 resize_theme_fontsample(data, font);
126 /*data->text.menu = TTF_RenderText_Blended(font->sans, "Menu", white);*/
129 static void resize_theme_fontsample(struct options_data_t *data,
130 struct font_t *font) {
132 static const char *fontsample_text[] = {
133 "1234567890",
134 "abcdefghijklmnopqrstuvwxyz",
135 "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
136 "How quickly daft jumping zebras vex.",
137 "!@#$%^&*()`~-_=+[{]}\\|;:'\",<.>/?"
139 size_t x;
141 for(x = 0; x < sizeof(fontsample_text)/sizeof(*fontsample_text); x ++) {
142 data->gui.theme.fontsample[x] = render_white_text(font->sans,
143 fontsample_text[x]);
147 static void get_screen_modes(struct smode_t *smode, struct widget_t *widget) {
148 SDL_Rect **mode = list_graphics_modes(smode);
149 char buffer[BUFSIZ];
150 size_t x;
152 if(!mode) {
153 add_listbox_item(widget, "No screen modes", 15);
155 else if(mode == (SDL_Rect **)-1) {
156 add_listbox_item(widget, "All screen modes", 16);
158 else {
159 for(x = 0; mode[x]; x ++) {
160 sprintf(buffer, "%i x %i", mode[x]->w, mode[x]->h);
161 add_listbox_item(widget, buffer, strlen(buffer));
166 void start_options(struct options_data_t *data) {
167 set_caption("Options and preferences");
169 data->mode = OMODE_NORMAL;
172 int options_event(enum loop_mode_t *mode, SDL_Event *event,
173 struct options_data_t *data, struct smode_t *smode, struct font_t *font,
174 struct theme_t *theme, struct gui_t *gui) {
176 int repaint = 0;
178 switch(event->type) {
179 case SDL_KEYUP:
180 if(data->mode == OMODE_NORMAL) {
181 switch(event->key.keysym.sym) {
182 case SDLK_g:
183 data->mode = OMODE_GRAPHICS;
184 repaint = 1;
185 clear_gui(gui);
186 break;
187 case SDLK_t:
188 data->mode = OMODE_THEME;
189 repaint = 1;
190 clear_gui(gui);
191 break;
192 default:
193 break;
197 switch(event->key.keysym.sym) {
198 case SDLK_ESCAPE:
199 if(gui->active.widget) {
200 repaint = 1;
202 revert_widget(gui->active.widget);
204 clear_active(&gui->active);
206 else if(data->mode != OMODE_NORMAL) {
207 data->mode = OMODE_NORMAL;
208 repaint = 1;
209 clear_gui(gui);
211 else *mode = MODE_MENU;
213 break;
214 default: break;
216 break;
217 case SDL_QUIT:
218 *mode = MODE_MENU;
219 break;
220 case SDL_VIDEORESIZE:
221 resize_options_images(data, smode, font, theme, gui);
222 break;
223 default:
224 break;
227 return repaint;
230 int set_options_widget_sel(int xp, int yp, int click,
231 struct options_data_t *data, struct smode_t *smode,
232 struct theme_t *theme, struct gui_t *gui) {
234 if(data->mode == OMODE_NORMAL) {
235 if(set_widget_sel_repaint(&gui->sel, xp, yp, click,
236 gui->panel[PANEL_OPTIONS]->widget,
237 gui->panel[PANEL_OPTIONS]->widgets)) {
239 return 1;
242 else if(data->mode == OMODE_GRAPHICS) {
243 if(set_widget_sel_repaint(&gui->sel, xp, yp, click,
244 gui->panel[PANEL_OPTIONS_GRAPHICS]->widget,
245 gui->panel[PANEL_OPTIONS_GRAPHICS]->widgets)) {
247 return 1;
250 else if(data->mode == OMODE_THEME) {
251 if(set_widget_sel_repaint(&gui->sel, xp, yp, click,
252 gui->panel[PANEL_OPTIONS_THEME]->widget,
253 gui->panel[PANEL_OPTIONS_THEME]->widgets)) {
255 return 1;
259 return 0;
262 int options_perform_click(int id, enum loop_mode_t *mode,
263 enum options_mode_t *omode, struct options_data_t *data,
264 struct smode_t *smode, struct gui_t *gui) {
266 if(id < 100) {
267 perform_widget_click(gui->panel[PANEL_OPTIONS]->widget[id]);
269 else if(id < 200) {
270 perform_widget_click(
271 gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[id-100]);
273 else if(id < 300) {
274 perform_widget_click(gui->panel[PANEL_OPTIONS_THEME]->widget[id-200]);
277 switch(id) {
278 case 0:
279 *omode = OMODE_GRAPHICS;
280 clear_gui(gui);
281 break;
282 case 1:
283 *omode = OMODE_THEME;
284 clear_gui(gui);
285 break;
286 case 2:
287 *mode = MODE_MENU;
288 break;
289 case 100:
290 *omode = OMODE_NORMAL;
291 clear_gui(gui);
292 break;
293 case 101: /* paint_widget() !!! */
294 /*data->gui.graphics.widget[1].p.checkbox->checked
295 = !data->gui.graphics.widget[1].p.checkbox->checked;*/
296 toggle_fullscreen(smode); /* !!! Use return value for repaint */
297 break;
298 case 102: /* toggle restrict cursor */
299 smode->restrictfocus = set_focus(!smode->restrictfocus);
300 break;
301 case 200:
302 *omode = OMODE_NORMAL;
303 clear_gui(gui);
304 default:
305 break;
308 return 0;
311 void paint_options(struct options_data_t *data, struct smode_t *smode,
312 struct font_t *font, struct theme_t *theme, struct gui_t *gui) {
314 /*if(gui->active.widget) printf("%s\n", gui->active.widget->p.textbox->data);*/
316 gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[1]->p.checkbox->checked
317 = smode->fullscreen;
318 gui->panel[PANEL_OPTIONS_GRAPHICS]->widget[2]->p.checkbox->checked
319 = (smode->restrictfocus == SDL_GRAB_ON);
321 SDL_FillRect(smode->screen, NULL,
322 SDL_MapRGB(smode->screen->format, 0, 0, 0));
324 if(data->mode == OMODE_NORMAL) {
325 paint_widget_array(smode, font, theme, gui,
326 gui->panel[PANEL_OPTIONS]->widget,
327 gui->panel[PANEL_OPTIONS]->widgets);
329 else if(data->mode == OMODE_GRAPHICS) {
330 paint_widget_array(smode, font, theme, gui,
331 gui->panel[PANEL_OPTIONS_GRAPHICS]->widget,
332 gui->panel[PANEL_OPTIONS_GRAPHICS]->widgets);
334 else if(data->mode == OMODE_THEME) {
335 paint_widget_array(smode, font, theme, gui,
336 gui->panel[PANEL_OPTIONS_THEME]->widget,
337 gui->panel[PANEL_OPTIONS_THEME]->widgets);
339 paint_theme_fontsample(smode, data);
342 paint_menu_fps(smode->screen, font);
344 SDL_UpdateRect(smode->screen, 0, 0, 0, 0);
347 static void paint_theme_fontsample(struct smode_t *smode,
348 struct options_data_t *data) {
350 size_t x;
351 int maxw = 0;
353 for(x = 0; x < sizeof(data->gui.theme.fontsample)
354 / sizeof(*data->gui.theme.fontsample); x ++) {
356 if(data->gui.theme.fontsample[x]->w > maxw) {
357 maxw = data->gui.theme.fontsample[x]->w;
361 for(x = 0; x < sizeof(data->gui.theme.fontsample)
362 / sizeof(*data->gui.theme.fontsample); x ++) {
364 blit_surface(smode->screen, data->gui.theme.fontsample[x],
365 (smode->width - maxw) / 2,
366 smode->height / 8 + smode->height / 15 * 1.3 * 4
367 + data->gui.theme.fontsample[x]->h * x);
371 static void free_resize_options(struct options_data_t *data,
372 struct gui_t *gui) {
374 size_t x;
376 /*free_panel(gui->panel[PANEL_OPTIONS]);
377 free_panel(gui->panel[PANEL_OPTIONS_GRAPHICS]);
378 free_panel(gui->panel[PANEL_OPTIONS_THEME]);*/
380 for(x = 0; x < sizeof(data->gui.theme.fontsample)
381 / sizeof(*data->gui.theme.fontsample); x ++) {
383 SDL_FreeSurface(data->gui.theme.fontsample[x]);
387 void free_options(struct options_data_t *data, struct gui_t *gui) {
388 free_resize_options(data, gui);