summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/menu.c390
-rw-r--r--apps/menu.h54
-rw-r--r--apps/plugin.c8
-rw-r--r--apps/plugin.h12
4 files changed, 196 insertions, 268 deletions
diff --git a/apps/menu.c b/apps/menu.c
index 62cce5a721..bc9ceea7b6 100644
--- a/apps/menu.c
+++ b/apps/menu.c
@@ -58,234 +58,19 @@
58#include "list.h" 58#include "list.h"
59#include "statusbar.h" 59#include "statusbar.h"
60#include "buttonbar.h" 60#include "buttonbar.h"
61 61/* needed for the old menu system */
62struct menu { 62struct menu {
63 struct menu_item* items; 63 struct menu_item* items;
64 int count;
64 int (*callback)(int, int); 65 int (*callback)(int, int);
65#ifdef HAS_BUTTONBAR 66 int current_selection;
66 struct gui_buttonbar buttonbar;
67#endif
68 struct gui_synclist synclist;
69}; 67};
70
71#define MAX_MENUS 6 68#define MAX_MENUS 6
72
73static struct menu menus[MAX_MENUS]; 69static struct menu menus[MAX_MENUS];
74static bool inuse[MAX_MENUS] = { false }; 70static bool inuse[MAX_MENUS] = { false };
75 71static void init_oldmenu(const struct menu_item_ex *menu,
76static char * menu_get_itemname(int selected_item, void * data, char *buffer) 72 struct gui_synclist *lists, int selected, bool callback);
77{ 73static void menu_talk_selected(int m);
78 struct menu *local_menus=(struct menu *)data;
79 (void)buffer;
80 return(P2STR(local_menus->items[selected_item].desc));
81}
82
83static int menu_find_free(void)
84{
85 int i;
86 /* Tries to find an unused slot to put the new menu */
87 for ( i=0; i<MAX_MENUS; i++ ) {
88 if ( !inuse[i] ) {
89 inuse[i] = true;
90 break;
91 }
92 }
93 if ( i == MAX_MENUS ) {
94 DEBUGF("Out of menus!\n");
95 return -1;
96 }
97 return(i);
98}
99
100int menu_init(const struct menu_item* mitems, int count, int (*callback)(int, int),
101 const char *button1, const char *button2, const char *button3)
102{
103 int menu=menu_find_free();
104 if(menu==-1)/* Out of menus */
105 return -1;
106 menus[menu].items = (struct menu_item*)mitems; /* de-const */
107 gui_synclist_init(&(menus[menu].synclist),
108 &menu_get_itemname, &menus[menu], false, 1);
109 gui_synclist_set_icon_callback(&(menus[menu].synclist), NULL);
110 gui_synclist_set_nb_items(&(menus[menu].synclist), count);
111 menus[menu].callback = callback;
112#ifdef HAS_BUTTONBAR
113 gui_buttonbar_init(&(menus[menu].buttonbar));
114 gui_buttonbar_set_display(&(menus[menu].buttonbar), &(screens[SCREEN_MAIN]) );
115 gui_buttonbar_set(&(menus[menu].buttonbar), button1, button2, button3);
116#else
117 (void)button1;
118 (void)button2;
119 (void)button3;
120#endif
121 return menu;
122}
123
124void menu_exit(int m)
125{
126 inuse[m] = false;
127}
128
129int menu_show(int m)
130{
131#ifdef HAS_BUTTONBAR
132 gui_buttonbar_draw(&(menus[m].buttonbar));
133#endif
134 bool exit = false;
135 int key;
136
137 gui_synclist_draw(&(menus[m].synclist));
138 gui_syncstatusbar_draw(&statusbars, true);
139 menu_talk_selected(m);
140 while (!exit) {
141 key = get_action(CONTEXT_MAINMENU,HZ/2);
142 /*
143 * "short-circuit" the default keypresses by running the
144 * callback function
145 * The callback may return a new key value, often this will be
146 * BUTTON_NONE or the same key value, but it's perfectly legal
147 * to "simulate" key presses by returning another value.
148 */
149 if( menus[m].callback != NULL )
150 key = menus[m].callback(key, m);
151 /* If moved, "say" the entry under the cursor */
152 if(gui_synclist_do_button(&(menus[m].synclist), key,LIST_WRAP_UNLESS_HELD))
153 menu_talk_selected(m);
154 switch( key ) {
155 case ACTION_STD_OK:
156 action_signalscreenchange();
157 return gui_synclist_get_sel_pos(&(menus[m].synclist));
158
159
160 case ACTION_STD_CANCEL:
161 case ACTION_STD_MENU:
162 exit = true;
163 break;
164
165 default:
166 if(default_event_handler(key) == SYS_USB_CONNECTED)
167 return MENU_ATTACHED_USB;
168 break;
169 }
170 gui_syncstatusbar_draw(&statusbars, false);
171 }
172 action_signalscreenchange();
173 return MENU_SELECTED_EXIT;
174}
175
176
177bool menu_run(int m)
178{
179 int selected;
180 while (1) {
181 switch (selected=menu_show(m))
182 {
183 case MENU_SELECTED_EXIT:
184 return false;
185
186 case MENU_ATTACHED_USB:
187 return true;
188
189 default:
190 {
191 if (menus[m].items[selected].function &&
192 menus[m].items[selected].function())
193 return true;
194 gui_syncstatusbar_draw(&statusbars, true);
195 }
196 }
197 }
198 return false;
199}
200
201/*
202 * Property function - return the current cursor for "menu"
203 */
204
205int menu_cursor(int menu)
206{
207 return gui_synclist_get_sel_pos(&(menus[menu].synclist));
208}
209
210/*
211 * Property function - return the "menu" description at "position"
212 */
213
214char* menu_description(int menu, int position)
215{
216 return P2STR(menus[menu].items[position].desc);
217}
218
219/*
220 * Delete the element "position" from the menu items in "menu"
221 */
222
223void menu_delete(int menu, int position)
224{
225 int i;
226 int nb_items=gui_synclist_get_nb_items(&(menus[menu].synclist));
227 /* copy the menu item from the one below */
228 for( i = position; i < nb_items - 1; i++)
229 menus[menu].items[i] = menus[menu].items[i + 1];
230
231 gui_synclist_del_item(&(menus[menu].synclist));
232}
233
234void menu_insert(int menu, int position, char *desc, bool (*function) (void))
235{
236 int i;
237 int nb_items=gui_synclist_get_nb_items(&(menus[menu].synclist));
238 if(position < 0)
239 position = nb_items;
240
241 /* Move the items below one position forward */
242 for( i = nb_items; i > position; i--)
243 menus[menu].items[i] = menus[menu].items[i - 1];
244
245 /* Update the current item */
246 menus[menu].items[position].desc = (unsigned char *)desc;
247 menus[menu].items[position].function = function;
248 gui_synclist_add_item(&(menus[menu].synclist));
249}
250
251/*
252 * Property function - return the "count" of menu items in "menu"
253 */
254
255int menu_count(int menu)
256{
257 return gui_synclist_get_nb_items(&(menus[menu].synclist));
258}
259
260/*
261 * Allows to set the cursor position. Doesn't redraw by itself.
262 */
263
264void menu_set_cursor(int menu, int position)
265{
266 gui_synclist_select_item(&(menus[menu].synclist), position);
267}
268
269void menu_talk_selected(int m)
270{
271 if(global_settings.talk_menu)
272 {
273 int selected=gui_synclist_get_sel_pos(&(menus[m].synclist));
274 int voice_id = P2ID(menus[m].items[selected].desc);
275 if (voice_id >= 0) /* valid ID given? */
276 talk_id(voice_id, false); /* say it */
277 }
278}
279
280void menu_draw(int m)
281{
282 gui_synclist_draw(&(menus[m].synclist));
283}
284
285/******************************************************************/
286/* New menu stuff here!!
287 ******************************************************************/
288
289 74
290/* used to allow for dynamic menus */ 75/* used to allow for dynamic menus */
291#define MAX_MENU_SUBITEMS 64 76#define MAX_MENU_SUBITEMS 64
@@ -395,6 +180,13 @@ static void init_menu_lists(const struct menu_item_ex *menu,
395 menu_callback_type menu_callback = NULL; 180 menu_callback_type menu_callback = NULL;
396 ICON icon = NOICON; 181 ICON icon = NOICON;
397 current_subitems_count = 0; 182 current_subitems_count = 0;
183
184 if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU)
185 {
186 init_oldmenu(menu, lists, selected, callback);
187 return;
188 }
189
398 for (i=0; i<count; i++) 190 for (i=0; i<count; i++)
399 { 191 {
400 get_menu_callback(menu->submenus[i],&menu_callback); 192 get_menu_callback(menu->submenus[i],&menu_callback);
@@ -441,10 +233,18 @@ static void talk_menu_item(const struct menu_item_ex *menu,
441 int id = -1; 233 int id = -1;
442 int type; 234 int type;
443 unsigned char *str; 235 unsigned char *str;
236 int sel;
444 237
445 if (global_settings.talk_menu) 238 if (global_settings.talk_menu)
446 { 239 {
447 int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu); 240 if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU)
241 {
242 menus[menu->value].current_selection =
243 gui_synclist_get_sel_pos(lists);
244 menu_talk_selected(menu->value);
245 return;
246 }
247 sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu);
448 if ((menu->flags&MENU_TYPE_MASK) == MT_MENU) 248 if ((menu->flags&MENU_TYPE_MASK) == MT_MENU)
449 { 249 {
450 type = menu->submenus[sel]->flags&MENU_TYPE_MASK; 250 type = menu->submenus[sel]->flags&MENU_TYPE_MASK;
@@ -674,6 +474,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected)
674 } 474 }
675 else if (action == ACTION_STD_MENU) 475 else if (action == ACTION_STD_MENU)
676 { 476 {
477 if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU)
478 return MENU_SELECTED_EXIT;
677 if (menu != &root_menu_) 479 if (menu != &root_menu_)
678 ret = GO_TO_ROOT; 480 ret = GO_TO_ROOT;
679 else 481 else
@@ -709,6 +511,12 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected)
709 gui_buttonbar_unset(&buttonbar); 511 gui_buttonbar_unset(&buttonbar);
710 gui_buttonbar_draw(&buttonbar); 512 gui_buttonbar_draw(&buttonbar);
711#endif 513#endif
514 if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU)
515 {
516 selected = gui_synclist_get_sel_pos(&lists);
517 menus[menu->value].current_selection = selected;
518 return selected;
519 }
712 selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu); 520 selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu);
713 temp = menu->submenus[selected]; 521 temp = menu->submenus[selected];
714 if (in_stringlist) 522 if (in_stringlist)
@@ -797,3 +605,141 @@ int main_menu(void)
797{ 605{
798 return do_menu(NULL, 0); 606 return do_menu(NULL, 0);
799} 607}
608
609/* wrappers for the old menu system to work with the new system */
610
611
612static int menu_find_free(void)
613{
614 int i;
615 /* Tries to find an unused slot to put the new menu */
616 for ( i=0; i<MAX_MENUS; i++ ) {
617 if ( !inuse[i] ) {
618 inuse[i] = true;
619 break;
620 }
621 }
622 if ( i == MAX_MENUS ) {
623 DEBUGF("Out of menus!\n");
624 return -1;
625 }
626 return(i);
627}
628
629int menu_init(const struct menu_item* mitems, int count, int (*callback)(int, int),
630 const char *button1, const char *button2, const char *button3)
631{
632 (void)button1;
633 (void)button2;
634 (void)button3;
635 int menu=menu_find_free();
636 if(menu==-1)/* Out of menus */
637 return -1;
638 menus[menu].items = (struct menu_item*)mitems; /* de-const */
639 menus[menu].count = count;
640 menus[menu].callback = callback;
641 menus[menu].current_selection = 0;
642 return menu;
643}
644
645void menu_exit(int m)
646{
647 inuse[m] = false;
648}
649
650
651
652static int oldmenuwrapper_callback(int action,
653 const struct menu_item_ex *this_item)
654{
655 if (menus[this_item->value].callback)
656 {
657 int val = menus[this_item->value].callback(action, this_item->value);
658 switch (val)
659 {
660 case MENU_SELECTED_EXIT:
661 return ACTION_EXIT_MENUITEM;
662 }
663 return val;
664 }
665 return action;
666}
667
668static char* oldmenuwrapper_getname(int selected_item,
669 void * data, char *buffer)
670{
671 (void)buffer;
672 unsigned char* desc = menus[(intptr_t)data].items[selected_item].desc;
673 return P2STR(desc);
674}
675static void init_oldmenu(const struct menu_item_ex *menu,
676 struct gui_synclist *lists, int selected, bool callback)
677{
678 (void)callback;
679 gui_synclist_init(lists, oldmenuwrapper_getname,
680 (void*)menu->value, false, 1);
681 gui_synclist_set_nb_items(lists,
682 (menu->flags&MENU_COUNT_MASK)>>MENU_COUNT_SHIFT);
683 gui_synclist_limit_scroll(lists, true);
684 gui_synclist_select_item(lists, selected);
685}
686
687static void menu_talk_selected(int m)
688{
689 int selected = menus[m].current_selection;
690 int voice_id = P2ID(menus[m].items[selected].desc);
691 if (voice_id >= 0) /* valid ID given? */
692 talk_id(voice_id, false); /* say it */
693}
694
695int menu_show(int m)
696{
697 struct menu_item_ex menu;
698 struct menu_get_name_and_icon menu_info =
699 {
700 oldmenuwrapper_callback,
701 oldmenuwrapper_getname,
702 (void*)m, Icon_NOICON
703 };
704
705 menu.flags = (MENU_TYPE_MASK&MT_OLD_MENU) | MENU_DYNAMIC_DESC |
706 MENU_ITEM_COUNT(menus[m].count);
707 menu.value = m;
708 menu.menu_get_name_and_icon = &menu_info;
709 return do_menu(&menu, &menus[m].current_selection);
710}
711
712
713bool menu_run(int m)
714{
715 int selected;
716 while (1) {
717 switch (selected=menu_show(m))
718 {
719 case MENU_SELECTED_EXIT:
720 return false;
721
722 case MENU_ATTACHED_USB:
723 return true;
724
725 default:
726 {
727 if (menus[m].items[selected].function &&
728 menus[m].items[selected].function())
729 return true;
730 gui_syncstatusbar_draw(&statusbars, true);
731 }
732 }
733 }
734 return false;
735}
736
737/*
738 * Property function - return the "count" of menu items in "menu"
739 */
740
741int menu_count(int menu)
742{
743 return menus[menu].count;
744}
745
diff --git a/apps/menu.h b/apps/menu.h
index fa5d7e5b93..eed15d2396 100644
--- a/apps/menu.h
+++ b/apps/menu.h
@@ -25,38 +25,6 @@
25#include "icons.h" 25#include "icons.h"
26 26
27 27
28struct menu_item {
29 unsigned char *desc; /* string or ID */
30 bool (*function) (void); /* return true if USB was connected */
31};
32
33int menu_init(const struct menu_item* mitems, int count,
34 int (*callback)(int, int),
35 const char *button1, const char *button2, const char *button3);
36void menu_exit(int menu);
37
38void put_cursorxy(int x, int y, bool on);
39
40 /* Returns below define, or number of selected menu item*/
41int menu_show(int m);
42#define MENU_ATTACHED_USB -1
43#define MENU_SELECTED_EXIT -2
44#define MENU_EXIT_ALL -3
45#define MENU_RETURN_TO_WPS -4
46
47bool menu_run(int menu);
48int menu_cursor(int menu);
49char* menu_description(int menu, int position);
50void menu_delete(int menu, int position);
51int menu_count(int menu);
52bool menu_moveup(int menu);
53bool menu_movedown(int menu);
54void menu_draw(int menu);
55void menu_insert(int menu, int position, char *desc, bool (*function) (void));
56void menu_set_cursor(int menu, int position);
57void menu_talk_selected(int m);
58
59
60enum menu_item_type { 28enum menu_item_type {
61 MT_MENU = 0, 29 MT_MENU = 0,
62 MT_SETTING, 30 MT_SETTING,
@@ -67,6 +35,8 @@ enum menu_item_type {
67 MT_FUNCTION_WITH_PARAM, 35 MT_FUNCTION_WITH_PARAM,
68 MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/ 36 MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/
69 MT_RETURN_VALUE, /* returns a value associated with an item */ 37 MT_RETURN_VALUE, /* returns a value associated with an item */
38 MT_OLD_MENU, /* used so we can wrap the old menu api
39 around the new api. Noone else should use this */
70}; 40};
71 41
72typedef int (*menu_function)(void); 42typedef int (*menu_function)(void);
@@ -214,5 +184,25 @@ bool do_setting_from_menu(const struct menu_item_ex *temp);
214 { (void*)name##_},{.callback_and_desc = & name##__}}; 184 { (void*)name##_},{.callback_and_desc = & name##__}};
215 185
216 186
187/* OLD API - only use if you really have to.. Ideally this will be dropped */
188struct menu_item {
189 unsigned char *desc; /* string or ID */
190 bool (*function) (void); /* return true if USB was connected */
191};
192
193int menu_init(const struct menu_item* mitems, int count,
194 int (*callback)(int, int),
195 const char *button1, const char *button2, const char *button3);
196void menu_exit(int menu);
197
198 /* Returns below define, or number of selected menu item*/
199int menu_show(int m);
200#define MENU_ATTACHED_USB -1
201#define MENU_SELECTED_EXIT -2
202#define MENU_EXIT_ALL -3
203#define MENU_RETURN_TO_WPS -4
204
205bool menu_run(int menu);
206int menu_count(int menu);
217 207
218#endif /* End __MENU_H__ */ 208#endif /* End __MENU_H__ */
diff --git a/apps/plugin.c b/apps/plugin.c
index 230b62b819..eb1325c827 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -370,17 +370,13 @@ static const struct plugin_api rockbox_api = {
370#endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */ 370#endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
371 371
372 /* menu */ 372 /* menu */
373 do_menu,
374 /* OLD API - dont use unless you have to */
373 menu_init, 375 menu_init,
374 menu_exit, 376 menu_exit,
375 menu_show, 377 menu_show,
376 menu_run, 378 menu_run,
377 menu_cursor,
378 menu_description,
379 menu_delete,
380 menu_count, 379 menu_count,
381 menu_draw,
382 menu_insert,
383 menu_set_cursor,
384 set_option, 380 set_option,
385 set_int, 381 set_int,
386 set_bool, 382 set_bool,
diff --git a/apps/plugin.h b/apps/plugin.h
index 62ede9bce8..c14b06f487 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -110,12 +110,12 @@
110#define PLUGIN_MAGIC 0x526F634B /* RocK */ 110#define PLUGIN_MAGIC 0x526F634B /* RocK */
111 111
112/* increase this every time the api struct changes */ 112/* increase this every time the api struct changes */
113#define PLUGIN_API_VERSION 46 113#define PLUGIN_API_VERSION 47
114 114
115/* update this to latest version if a change to the api struct breaks 115/* update this to latest version if a change to the api struct breaks
116 backwards compatibility (and please take the opportunity to sort in any 116 backwards compatibility (and please take the opportunity to sort in any
117 new function which are "waiting" at the end of the function table) */ 117 new function which are "waiting" at the end of the function table) */
118#define PLUGIN_MIN_API_VERSION 46 118#define PLUGIN_MIN_API_VERSION 47
119 119
120/* plugin return codes */ 120/* plugin return codes */
121enum plugin_status { 121enum plugin_status {
@@ -465,19 +465,15 @@ struct plugin_api {
465#endif 465#endif
466 466
467 /* menu */ 467 /* menu */
468 int (*do_menu)(const struct menu_item_ex *menu, int *start_selected);
469 /* OLD API - dont use unless you have to */
468 int (*menu_init)(const struct menu_item* mitems, int count, 470 int (*menu_init)(const struct menu_item* mitems, int count,
469 int (*callback)(int, int), 471 int (*callback)(int, int),
470 const char *button1, const char *button2, const char *button3); 472 const char *button1, const char *button2, const char *button3);
471 void (*menu_exit)(int menu); 473 void (*menu_exit)(int menu);
472 int (*menu_show)(int m); 474 int (*menu_show)(int m);
473 bool (*menu_run)(int menu); 475 bool (*menu_run)(int menu);
474 int (*menu_cursor)(int menu);
475 char* (*menu_description)(int menu, int position);
476 void (*menu_delete)(int menu, int position);
477 int (*menu_count)(int menu); 476 int (*menu_count)(int menu);
478 void (*menu_draw)(int menu);
479 void (*menu_insert)(int menu, int position, char *desc, bool (*function) (void));
480 void (*menu_set_cursor)(int menu, int position);
481 477
482 bool (*set_option)(const char* string, void* variable, 478 bool (*set_option)(const char* string, void* variable,
483 enum optiontype type, const struct opt_items* options, 479 enum optiontype type, const struct opt_items* options,