summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorMichiel Van Der Kolk <not.valid@email.address>2005-03-03 20:02:39 +0000
committerMichiel Van Der Kolk <not.valid@email.address>2005-03-03 20:02:39 +0000
commit31f215ea39006a0d8e7f8308f56c2ab135e3aa28 (patch)
tree6b8dcfaebf0e6fe153c85469eb65591832a9e7f9 /apps/plugins
parentcd040ddd7cfa2b68ee27639698e644c92f8fd5de (diff)
downloadrockbox-31f215ea39006a0d8e7f8308f56c2ab135e3aa28.tar.gz
rockbox-31f215ea39006a0d8e7f8308f56c2ab135e3aa28.zip
ack, forgot to add file
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6121 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/rockboy/menu.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/apps/plugins/rockboy/menu.c b/apps/plugins/rockboy/menu.c
new file mode 100644
index 0000000000..0d21fca867
--- /dev/null
+++ b/apps/plugins/rockboy/menu.c
@@ -0,0 +1,303 @@
1/*********************************************************************/
2/* menu.c - user menu for rockboy */
3/* */
4/* Note: this file only exposes one function: do_user_menu(). */
5/*********************************************************************/
6
7#include "stdlib.h"
8#include "string.h"
9#include "button.h"
10#include "rockmacros.h"
11
12/* load/save state function declarations */
13static void do_slot_menu(bool is_load);
14
15#define MENU_CANCEL (-1)
16static int do_menu(char *title, char **items, size_t num_items, int sel_item);
17
18/* main menu items */
19#define MAIN_MENU_TITLE "RockBoy Menu"
20typedef enum {
21 ITEM_BACK,
22 ITEM_LOAD,
23 ITEM_SAVE,
24 ITEM_OPT,
25 ITEM_QUIT,
26 ITEM_LAST
27} MainMenuItem;
28
29/* strings for the main menu */
30static const char *main_menu[] = {
31 "Back to Game",
32 "Load State...",
33 "Save State...",
34 "Options...",
35 "Quit RockBoy"
36};
37
38typedef enum {
39 ITEM_SLOT1,
40 ITEM_SLOT2,
41 ITEM_SLOT3,
42 ITEM_SLOT4,
43 ITEM_SLOT5
44} SlotMenuItem;
45
46/* this is evil, but we snprintf() into it later :( */
47static const char *slot_menu[] = {
48 "1. ",
49 "2. ",
50 "3. ",
51 "4. ",
52 "5. "
53};
54
55/*
56 * do_user_menu - create the user menu on the screen.
57 *
58 * Returns USER_MENU_QUIT if the user selected "quit", otherwise
59 * returns zero.
60 *
61 * Note: this is the only non-static function in this file at the
62 * moment. In the future I may turn do_menu/etc into a proper API, in
63 * which case they'll be exposed as well.
64 *
65 */
66int do_user_menu(void) {
67 int mi, ret, num_items;
68 bool done = false;
69
70 /* set defaults */
71 ret = 0; /* return value */
72 mi = 0; /* initial menu selection */
73 num_items = sizeof(main_menu) / sizeof(char*);
74
75 /* loop until we should exit menu */
76 while (!done) {
77 /* get item selection */
78 mi = do_menu(MAIN_MENU_TITLE, (char**) main_menu, num_items, mi);
79
80 /* handle selected menu item */
81 switch (mi) {
82 case ITEM_QUIT:
83 ret = USER_MENU_QUIT;
84 case MENU_CANCEL:
85 case ITEM_BACK:
86 done = true;
87 break;
88 case ITEM_LOAD:
89 do_slot_menu(1);
90 break;
91 case ITEM_SAVE:
92 do_slot_menu(0);
93 break;
94 }
95 }
96
97 /* return somethin' */
98 return ret;
99}
100
101/*
102 * do_load_menu - prompt the user for a memory slot
103 *
104 * TOOD
105 *
106 */
107static void do_slot_menu(bool is_load) {
108 int i, mi, ret, num_items;
109 bool done = false;
110 char *title;
111
112 /* set defaults */
113 ret = 0; /* return value */
114 mi = 0; /* initial menu selection */
115 num_items = sizeof(slot_menu) / sizeof(char*);
116
117 /* create menu items */
118 for (i = 0; i < num_items; i++) {
119 /* TODO: get slot info here */
120 snprintf((char*) slot_menu[i], sizeof(slot_menu[i]), "%2d. %s", i + 1, "<empty>");
121 }
122
123 /* set menu title */
124 title = is_load ? "Load State" : "Save State";
125
126 /* loop until we should exit menu */
127 while (!done) {
128 /* get item selection */
129 mi = do_menu(title, (char**) slot_menu, num_items, mi);
130
131 /* handle selected menu item */
132 if (mi == MENU_CANCEL) {
133 done = true;
134 break;
135 } else {
136 if (is_load) {
137 /* TODO: load slot here */
138 } else {
139 /* TODO: save slot here */
140 }
141 }
142 }
143}
144
145/*********************************************************************/
146/* MENU FUNCTIONS */
147/*********************************************************************/
148/* at some point i'll make this a generic menu interface, but for now,
149 * these defines will suffice */
150#define MENU_X 10
151#define MENU_Y 10
152#define MENU_WIDTH (LCD_WIDTH - 2 * MENU_X)
153#define MENU_HEIGHT (LCD_HEIGHT - 2 * MENU_Y)
154#define MENU_RECT MENU_X, MENU_Y, MENU_WIDTH, MENU_HEIGHT
155#define SHADOW_RECT MENU_X + 1, MENU_Y + 1, MENU_WIDTH, MENU_HEIGHT
156#define MENU_ITEM_PAD 2
157
158/*
159 * select_item - select menu item (after deselecting current item)
160 */
161static void select_item(char *title, int curr_item, size_t item_i) {
162 int x, y, w, h;
163
164 /* get size of title, use that as height ofr all lines */
165 rb->lcd_getstringsize(title, &w, &h);
166 h += MENU_ITEM_PAD * 2;
167
168 /* calc x and width */
169 x = MENU_X + MENU_ITEM_PAD;
170 w = MENU_WIDTH - 2 * MENU_ITEM_PAD;
171
172 /* if there is a current item, then deselect it */
173 if (curr_item >= 0) {
174 /* deselect old item */
175 y = MENU_Y + h + MENU_ITEM_PAD * 2; /* account for title */
176 y += h * curr_item;
177 rb->lcd_invertrect(x, y, w, h);
178 }
179
180 /* select new item */
181 curr_item = item_i;
182
183 /* select new item */
184 y = MENU_Y + h + MENU_ITEM_PAD * 2; /* account for title */
185 y += h * curr_item;
186 rb->lcd_invertrect(x, y, w, h);
187
188 /* update the menu window */
189 rb->lcd_update_rect(MENU_RECT);
190}
191
192/*
193 * draw_menu - draw menu on screen
194 *
195 * Returns MENU_CANCEL if the user cancelled, or the item number of the
196 * selected item.
197 *
198 */
199static void draw_menu(char *title, char **items, size_t num_items) {
200 size_t i;
201 int x, y, w, h, by;
202
203 /* set to default? font */
204 /* rb->lcd_setfont(0); */
205
206 /* draw the outline */
207 rb->lcd_fillrect(SHADOW_RECT);
208 rb->lcd_clearrect(MENU_RECT);
209 rb->lcd_drawrect(MENU_RECT);
210
211 /* calculate x/y */
212 x = MENU_X + MENU_ITEM_PAD;
213 y = MENU_Y + MENU_ITEM_PAD * 2;
214 rb->lcd_getstringsize(title, &w, &h);
215 h += MENU_ITEM_PAD * 2;
216
217 /* draw menu stipple */
218 for (i = MENU_Y; i < (size_t) y + h; i += 2)
219 rb->lcd_drawline(MENU_X, i, MENU_X + MENU_WIDTH, i);
220
221 /* clear title rect */
222 rb->lcd_clearrect((LCD_WIDTH - w) / 2 - 2, y - 2, w + 4, h);
223
224 /* draw centered title on screen */
225 rb->lcd_putsxy((LCD_WIDTH - w)/2, y, title);
226
227 /* calculate base Y for items */
228 by = y + h + MENU_ITEM_PAD;
229
230 /* iterate over each item and draw it on the screen */
231 for (i = 0; i < num_items; i++)
232 rb->lcd_putsxy(x, by + h * i, items[i]);
233
234 /* update the screen */
235 rb->lcd_update();
236}
237
238/*
239 * do_menu - draw menu on screen.
240 *
241 * Draw a menu titled @title on the screen, with @num_items elements
242 * from @items, and select the @sel element. If in doubt, set @sel to
243 * -1 :).
244 *
245 */
246static int do_menu(char *title, char **items, size_t num_items, int sel) {
247 int btn, sel_item, ret, curr_item;
248 bool done = false;
249 ret = MENU_CANCEL;
250
251 /* draw menu on screen and select the first item */
252 draw_menu(title, items, num_items);
253 curr_item = -1;
254 select_item(title, curr_item, sel);
255 curr_item = sel;
256
257 /* make sure button state is empty */
258 while (rb->button_get(false) != BUTTON_NONE)
259 rb->yield();
260
261 /* loop until the menu is finished */
262 while (!done) {
263 /* grab a button */
264 btn = rb->button_get(true);
265
266 /* handle the button */
267 switch (btn) {
268 case BUTTON_DOWN:
269 /* select next item in list */
270 sel_item = curr_item + 1;
271 if (sel_item >= (int) num_items)
272 sel_item = 0;
273 select_item(title, curr_item, sel_item);
274 curr_item = sel_item;
275 break;
276 case BUTTON_UP:
277 /* select prev item in list */
278 sel_item = curr_item - 1;
279 if (sel_item < 0)
280 sel_item = num_items - 1;
281 select_item(title, curr_item, sel_item);
282 curr_item = sel_item;
283 break;
284 case BUTTON_RIGHT:
285 /* select current item */
286 ret = curr_item;
287 done = true;
288 break;
289 case BUTTON_LEFT:
290 case BUTTON_SELECT:
291 /* cancel out of menu */
292 ret = MENU_CANCEL;
293 done = true;
294 break;
295 }
296
297 /* give the OS some love */
298 rb->yield();
299 }
300
301 /* return selected item */
302 return ret;
303}