Created common signature for panel event handling functions.
[xuni.git] / src / test / menu.c
blob0d8f7024b29bb5d9bbdbe96a5bbd34ea821995fb
1 /*! \file menu.c
3 */
5 #include <string.h>
7 #include "SDL_image.h"
8 #include "SDL_rotozoom.h"
10 #include "menu.h"
12 #include "error.h"
13 #include "graphics.h"
14 #include "gui.h"
15 #include "loop.h"
16 #include "memory.h"
17 #include "xuni.h"
18 #include "resource/resource.h"
20 #include "widget/widgets.h"
21 #include "widget/button.h"
22 #include "widget/image.h"
24 #include "main.h"
25 #include "version.h"
27 enum wid_t {
28 WID_ORION_BACKGROUND,
29 WID_MOON_BACKGROUND,
30 WID_PARALLAX_BACKGROUND_0,
31 WID_PARALLAX_BACKGROUND_1,
32 WID_PARALLAX_BACKGROUND_2,
33 WID_PARALLAX_BACKGROUND_3,
34 WID_VERSION_LABEL,
35 WID_NEWGAME,
36 WID_MULTIPLAYER,
37 WID_LOADGAME,
38 WID_OPTIONS,
39 WID_HELP,
40 WID_QUIT,
41 WID_NEWGAME_IMAGE,
42 WID_MULTIPLAYER_IMAGE,
43 WID_LOADGAME_IMAGE,
44 WID_OPTIONS_IMAGE,
45 WID_HELP_IMAGE,
46 WID_QUIT_IMAGE,
47 WIDS
50 struct string_index_t main_menu_background_names[MAIN_MENU_BACKGROUNDS] = {
51 {"Black", MAIN_MENU_BACKGROUND_BLACK},
52 {"Moon with parallax clouds",
53 MAIN_MENU_BACKGROUND_MOON_WITH_PARALLAX_CLOUDS},
54 {"Orion nebula", MAIN_MENU_BACKGROUND_ORION_NEBULA},
55 {"Orion nebula frame update", MAIN_MENU_BACKGROUND_ORION_NEBULA_FRAME},
56 {"Parallax clouds", MAIN_MENU_BACKGROUND_PARALLAX_CLOUDS}
59 static void set_hover_visible(struct gui_t *gui, struct widget_t *menu);
61 void switch_main_menu_background(struct widget_t *panel, const char *name) {
62 size_t index = string_to_index(main_menu_background_names,
63 sizeof(main_menu_background_names)
64 / sizeof(*main_menu_background_names), name);
65 static size_t wids[] = {
66 WID_ORION_BACKGROUND,
67 WID_MOON_BACKGROUND,
68 WID_PARALLAX_BACKGROUND_0,
69 WID_PARALLAX_BACKGROUND_1,
70 WID_PARALLAX_BACKGROUND_2,
71 WID_PARALLAX_BACKGROUND_3
73 static struct {
74 int frameupdate;
75 int enable[6];
76 } data[] = {
77 {1, {0, 1, 0, 1, 1, 1}},
78 {0, {1, 0, 0, 0, 0, 0}},
79 {1, {1, 0, 0, 0, 0, 0}},
80 {1, {0, 0, 1, 1, 0, 0}},
81 {0, {0, 0, 0, 0, 0, 0}}
83 size_t x;
85 if(index != (size_t)-1) {
86 panel->p.panel->frameupdate = data[index].frameupdate;
88 for(x = 0; x < sizeof(wids) / sizeof(*wids); x ++) {
89 if(data[index].enable[x]) {
90 widget_nameid_access(panel, wids[x])->visibility
91 |= WIDGET_VISIBILITY_VISIBLE;
93 else {
94 widget_nameid_access(panel, wids[x])->visibility
95 &= ~WIDGET_VISIBILITY_VISIBLE;
101 int menu_init(struct xuni_t *xuni, struct panel_data_t *data) {
102 struct widget_t *panel = data->event[PANEL_EVENT_INIT].p.init.panel;
104 init_wid(xuni->gui->widget, xuni->gui->widget,
105 PANEL_MAIN_MENU, "main menu");
107 init_wid(xuni->gui->widget, panel, WID_ORION_BACKGROUND,
108 "main menu/orion background");
109 init_wid(xuni->gui->widget, panel, WID_MOON_BACKGROUND,
110 "main menu/moon background");
111 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_0,
112 "main menu/parallax background 0");
113 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_1,
114 "main menu/parallax background 1");
115 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_2,
116 "main menu/parallax background 2");
117 init_wid(xuni->gui->widget, panel, WID_PARALLAX_BACKGROUND_3,
118 "main menu/parallax background 3");
119 init_wid(xuni->gui->widget, panel, WID_VERSION_LABEL,
120 "main menu/version label");
121 init_wid(xuni->gui->widget, panel, WID_NEWGAME, "main menu/newgame");
122 init_wid(xuni->gui->widget, panel, WID_MULTIPLAYER,
123 "main menu/multiplayer");
124 init_wid(xuni->gui->widget, panel, WID_LOADGAME, "main menu/loadgame");
125 init_wid(xuni->gui->widget, panel, WID_OPTIONS, "main menu/options");
126 init_wid(xuni->gui->widget, panel, WID_HELP, "main menu/help");
127 init_wid(xuni->gui->widget, panel, WID_QUIT, "main menu/quit");
128 init_wid(xuni->gui->widget, panel, WID_NEWGAME_IMAGE,
129 "main menu/newgame image");
130 init_wid(xuni->gui->widget, panel, WID_MULTIPLAYER_IMAGE,
131 "main menu/multiplayer image");
132 init_wid(xuni->gui->widget, panel, WID_LOADGAME_IMAGE,
133 "main menu/loadgame image");
134 init_wid(xuni->gui->widget, panel, WID_OPTIONS_IMAGE,
135 "main menu/options image");
136 init_wid(xuni->gui->widget, panel, WID_HELP_IMAGE,
137 "main menu/help image");
138 init_wid(xuni->gui->widget, panel, WID_QUIT_IMAGE,
139 "main menu/quit image");
141 add_widget_accelerator(xuni, panel,
142 widget_nameid_access(panel, WID_NEWGAME), SDLK_n, KMOD_NONE);
143 add_widget_accelerator(xuni, panel,
144 widget_nameid_access(panel, WID_OPTIONS), SDLK_o, KMOD_NONE);
145 add_widget_accelerator(xuni, panel,
146 widget_nameid_access(panel, WID_QUIT), SDLK_q, KMOD_NONE);
148 xuni_memory_free((void *)
149 widget_nameid_access(panel, WID_VERSION_LABEL)->p.label->text);
150 widget_nameid_access(panel, WID_VERSION_LABEL)->p.label->text
151 = xuni_memory_duplicate_string(get_xuni_version_string());
153 widget_event(xuni, widget_nameid_access(panel, WID_VERSION_LABEL),
154 WIDGET_EVENT_RESCALE);
156 /*data->quality.x0 = 300.0;
157 data->quality.y0 = 500.0;
158 data->quality.x1 = 600.0;
159 data->quality.y1 = 200.0;*/
161 return 0;
164 int menu_start(struct xuni_t *xuni, struct panel_data_t *data) {
165 set_caption("Main menu");
167 return 0;
170 int menu_event(struct xuni_t *xuni, struct panel_data_t *data) {
171 panel_type_t *mode = data->event[PANEL_EVENT_EVENT].p.event.mode;
172 SDL_Event *event = data->event[PANEL_EVENT_EVENT].p.event.event;
173 int repaint = 0;
175 switch(event->type) {
176 case SDL_KEYDOWN:
177 switch(event->key.keysym.sym) {
178 case SDLK_F4:
179 if(event->key.keysym.mod & KMOD_ALT) *mode = PANEL_NONE;
180 break;
181 default: break;
183 break;
184 case SDL_QUIT:
185 *mode = PANEL_NONE;
186 break;
187 case SDL_KEYUP:
188 case SDL_MOUSEMOTION:
189 break;
190 default:
191 repaint = 1;
192 break;
195 return repaint;
198 int menu_click(struct xuni_t *xuni, struct panel_data_t *data) {
199 panel_type_t *mode = data->event[PANEL_EVENT_CLICK].p.click.mode;
200 struct widget_t *widget = data->event[PANEL_EVENT_CLICK].p.click.widget;
202 switch(widget->id) {
203 case WID_NEWGAME:
204 *mode = PANEL_GAME;
205 break;
206 case WID_OPTIONS:
207 *mode = PANEL_OPTIONS;
208 break;
209 case WID_QUIT:
210 *mode = PANEL_NONE;
211 break;
212 default:
213 break;
216 return 0; /* ignored */
219 static void set_hover_visible(struct gui_t *gui, struct widget_t *menu) {
220 size_t x;
222 for(x = WID_NEWGAME_IMAGE; x <= WID_QUIT_IMAGE; x ++) {
223 if(gui->sel.p.widget && gui->sel.p.widget == widget_nameid_follow(
224 menu, x + (WID_NEWGAME - WID_NEWGAME_IMAGE), (size_t)-1)) {
226 widget_nameid_access(menu, x)->visibility
227 |= WIDGET_VISIBILITY_VISIBLE;
229 else {
230 widget_nameid_access(menu, x)->visibility
231 &= ~WIDGET_VISIBILITY_VISIBLE;
236 int menu_paint(struct xuni_t *xuni, struct panel_data_t *data) {
237 struct widget_t *panel
238 = widget_nameid_access(xuni->gui->widget, PANEL_MAIN_MENU);
240 /*lock_screen(xuni->smode->screen);*/
241 clear_screen(xuni->smode->screen);
242 /*unlock_screen(xuni->smode->screen);*/
244 set_hover_visible(xuni->gui, panel);
246 widget_event(xuni, panel, WIDGET_EVENT_PAINT);
248 paint_menu_fps(xuni, THEME_FONT_MONO);
250 if(panel->p.panel->frameupdate) {
251 paint_cursor(xuni, get_theme_widget(xuni, THEME_DEFAULT_CURSOR));
254 update_screen(xuni);
256 return 0;
259 void paint_menu_fps(struct xuni_t *xuni, size_t font) {
260 static unsigned long count = 0, total = 0, lastfps = 0;
261 static Uint32 lasttick = 0;
262 Uint32 tick = SDL_GetTicks();
263 char buffer[BUFSIZ];
264 SDL_Surface *text;
266 if(tick >= lasttick + 1000) {
267 lasttick = tick;
268 lastfps = count;
269 count = 0;
272 count ++;
273 total ++;
275 sprintf(buffer, "%3lu FPS | %lu (+%3lu) frames | %lu.%03lu seconds",
276 lastfps, total, count, (unsigned long)tick / 1000,
277 (unsigned long)tick % 1000);
278 text = render_text(xuni, get_theme_widget(xuni, font), buffer,
279 255, 255, 255);
281 blit_surface(xuni->smode->screen, text, 10, 10);
283 free_surface(text);
286 int menu_free(struct xuni_t *xuni, struct panel_data_t *data) {
287 return 0;