From 3452146217cbb8bac3c836aa8033160a1f5a5da8 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Wed, 7 Mar 2007 13:00:46 +0000 Subject: Make the old menu aPI use the new API. Both are avialable to core and rocks, but use the new API unless you absolutly have to use the old one (and file a FS bug if you do) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12670 a1c6a512-1295-4272-9138-f99709370657 --- apps/menu.c | 390 +++++++++++++++++++++++++--------------------------------- apps/menu.h | 54 ++++---- apps/plugin.c | 8 +- apps/plugin.h | 12 +- 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 @@ #include "list.h" #include "statusbar.h" #include "buttonbar.h" - +/* needed for the old menu system */ struct menu { struct menu_item* items; + int count; int (*callback)(int, int); -#ifdef HAS_BUTTONBAR - struct gui_buttonbar buttonbar; -#endif - struct gui_synclist synclist; + int current_selection; }; - #define MAX_MENUS 6 - static struct menu menus[MAX_MENUS]; static bool inuse[MAX_MENUS] = { false }; - -static char * menu_get_itemname(int selected_item, void * data, char *buffer) -{ - struct menu *local_menus=(struct menu *)data; - (void)buffer; - return(P2STR(local_menus->items[selected_item].desc)); -} - -static int menu_find_free(void) -{ - int i; - /* Tries to find an unused slot to put the new menu */ - for ( i=0; i position; i--) - menus[menu].items[i] = menus[menu].items[i - 1]; - - /* Update the current item */ - menus[menu].items[position].desc = (unsigned char *)desc; - menus[menu].items[position].function = function; - gui_synclist_add_item(&(menus[menu].synclist)); -} - -/* - * Property function - return the "count" of menu items in "menu" - */ - -int menu_count(int menu) -{ - return gui_synclist_get_nb_items(&(menus[menu].synclist)); -} - -/* - * Allows to set the cursor position. Doesn't redraw by itself. - */ - -void menu_set_cursor(int menu, int position) -{ - gui_synclist_select_item(&(menus[menu].synclist), position); -} - -void menu_talk_selected(int m) -{ - if(global_settings.talk_menu) - { - int selected=gui_synclist_get_sel_pos(&(menus[m].synclist)); - int voice_id = P2ID(menus[m].items[selected].desc); - if (voice_id >= 0) /* valid ID given? */ - talk_id(voice_id, false); /* say it */ - } -} - -void menu_draw(int m) -{ - gui_synclist_draw(&(menus[m].synclist)); -} - -/******************************************************************/ -/* New menu stuff here!! - ******************************************************************/ - +static void init_oldmenu(const struct menu_item_ex *menu, + struct gui_synclist *lists, int selected, bool callback); +static void menu_talk_selected(int m); /* used to allow for dynamic menus */ #define MAX_MENU_SUBITEMS 64 @@ -395,6 +180,13 @@ static void init_menu_lists(const struct menu_item_ex *menu, menu_callback_type menu_callback = NULL; ICON icon = NOICON; current_subitems_count = 0; + + if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU) + { + init_oldmenu(menu, lists, selected, callback); + return; + } + for (i=0; isubmenus[i],&menu_callback); @@ -441,10 +233,18 @@ static void talk_menu_item(const struct menu_item_ex *menu, int id = -1; int type; unsigned char *str; + int sel; if (global_settings.talk_menu) { - int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu); + if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU) + { + menus[menu->value].current_selection = + gui_synclist_get_sel_pos(lists); + menu_talk_selected(menu->value); + return; + } + sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu); if ((menu->flags&MENU_TYPE_MASK) == MT_MENU) { 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) } else if (action == ACTION_STD_MENU) { + if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU) + return MENU_SELECTED_EXIT; if (menu != &root_menu_) ret = GO_TO_ROOT; else @@ -709,6 +511,12 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected) gui_buttonbar_unset(&buttonbar); gui_buttonbar_draw(&buttonbar); #endif + if ((menu->flags&MENU_TYPE_MASK) == MT_OLD_MENU) + { + selected = gui_synclist_get_sel_pos(&lists); + menus[menu->value].current_selection = selected; + return selected; + } selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu); temp = menu->submenus[selected]; if (in_stringlist) @@ -797,3 +605,141 @@ int main_menu(void) { return do_menu(NULL, 0); } + +/* wrappers for the old menu system to work with the new system */ + + +static int menu_find_free(void) +{ + int i; + /* Tries to find an unused slot to put the new menu */ + for ( i=0; ivalue].callback) + { + int val = menus[this_item->value].callback(action, this_item->value); + switch (val) + { + case MENU_SELECTED_EXIT: + return ACTION_EXIT_MENUITEM; + } + return val; + } + return action; +} + +static char* oldmenuwrapper_getname(int selected_item, + void * data, char *buffer) +{ + (void)buffer; + unsigned char* desc = menus[(intptr_t)data].items[selected_item].desc; + return P2STR(desc); +} +static void init_oldmenu(const struct menu_item_ex *menu, + struct gui_synclist *lists, int selected, bool callback) +{ + (void)callback; + gui_synclist_init(lists, oldmenuwrapper_getname, + (void*)menu->value, false, 1); + gui_synclist_set_nb_items(lists, + (menu->flags&MENU_COUNT_MASK)>>MENU_COUNT_SHIFT); + gui_synclist_limit_scroll(lists, true); + gui_synclist_select_item(lists, selected); +} + +static void menu_talk_selected(int m) +{ + int selected = menus[m].current_selection; + int voice_id = P2ID(menus[m].items[selected].desc); + if (voice_id >= 0) /* valid ID given? */ + talk_id(voice_id, false); /* say it */ +} + +int menu_show(int m) +{ + struct menu_item_ex menu; + struct menu_get_name_and_icon menu_info = + { + oldmenuwrapper_callback, + oldmenuwrapper_getname, + (void*)m, Icon_NOICON + }; + + menu.flags = (MENU_TYPE_MASK&MT_OLD_MENU) | MENU_DYNAMIC_DESC | + MENU_ITEM_COUNT(menus[m].count); + menu.value = m; + menu.menu_get_name_and_icon = &menu_info; + return do_menu(&menu, &menus[m].current_selection); +} + + +bool menu_run(int m) +{ + int selected; + while (1) { + switch (selected=menu_show(m)) + { + case MENU_SELECTED_EXIT: + return false; + + case MENU_ATTACHED_USB: + return true; + + default: + { + if (menus[m].items[selected].function && + menus[m].items[selected].function()) + return true; + gui_syncstatusbar_draw(&statusbars, true); + } + } + } + return false; +} + +/* + * Property function - return the "count" of menu items in "menu" + */ + +int menu_count(int menu) +{ + return menus[menu].count; +} + 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 @@ #include "icons.h" -struct menu_item { - unsigned char *desc; /* string or ID */ - bool (*function) (void); /* return true if USB was connected */ -}; - -int menu_init(const struct menu_item* mitems, int count, - int (*callback)(int, int), - const char *button1, const char *button2, const char *button3); -void menu_exit(int menu); - -void put_cursorxy(int x, int y, bool on); - - /* Returns below define, or number of selected menu item*/ -int menu_show(int m); -#define MENU_ATTACHED_USB -1 -#define MENU_SELECTED_EXIT -2 -#define MENU_EXIT_ALL -3 -#define MENU_RETURN_TO_WPS -4 - -bool menu_run(int menu); -int menu_cursor(int menu); -char* menu_description(int menu, int position); -void menu_delete(int menu, int position); -int menu_count(int menu); -bool menu_moveup(int menu); -bool menu_movedown(int menu); -void menu_draw(int menu); -void menu_insert(int menu, int position, char *desc, bool (*function) (void)); -void menu_set_cursor(int menu, int position); -void menu_talk_selected(int m); - - enum menu_item_type { MT_MENU = 0, MT_SETTING, @@ -67,6 +35,8 @@ enum menu_item_type { MT_FUNCTION_WITH_PARAM, MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/ MT_RETURN_VALUE, /* returns a value associated with an item */ + MT_OLD_MENU, /* used so we can wrap the old menu api + around the new api. Noone else should use this */ }; typedef int (*menu_function)(void); @@ -214,5 +184,25 @@ bool do_setting_from_menu(const struct menu_item_ex *temp); { (void*)name##_},{.callback_and_desc = & name##__}}; +/* OLD API - only use if you really have to.. Ideally this will be dropped */ +struct menu_item { + unsigned char *desc; /* string or ID */ + bool (*function) (void); /* return true if USB was connected */ +}; + +int menu_init(const struct menu_item* mitems, int count, + int (*callback)(int, int), + const char *button1, const char *button2, const char *button3); +void menu_exit(int menu); + + /* Returns below define, or number of selected menu item*/ +int menu_show(int m); +#define MENU_ATTACHED_USB -1 +#define MENU_SELECTED_EXIT -2 +#define MENU_EXIT_ALL -3 +#define MENU_RETURN_TO_WPS -4 + +bool menu_run(int menu); +int menu_count(int menu); #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 = { #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */ /* menu */ + do_menu, + /* OLD API - dont use unless you have to */ menu_init, menu_exit, menu_show, menu_run, - menu_cursor, - menu_description, - menu_delete, menu_count, - menu_draw, - menu_insert, - menu_set_cursor, set_option, set_int, 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 @@ #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 46 +#define PLUGIN_API_VERSION 47 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define PLUGIN_MIN_API_VERSION 46 +#define PLUGIN_MIN_API_VERSION 47 /* plugin return codes */ enum plugin_status { @@ -465,19 +465,15 @@ struct plugin_api { #endif /* menu */ + int (*do_menu)(const struct menu_item_ex *menu, int *start_selected); + /* OLD API - dont use unless you have to */ int (*menu_init)(const struct menu_item* mitems, int count, int (*callback)(int, int), const char *button1, const char *button2, const char *button3); void (*menu_exit)(int menu); int (*menu_show)(int m); bool (*menu_run)(int menu); - int (*menu_cursor)(int menu); - char* (*menu_description)(int menu, int position); - void (*menu_delete)(int menu, int position); int (*menu_count)(int menu); - void (*menu_draw)(int menu); - void (*menu_insert)(int menu, int position, char *desc, bool (*function) (void)); - void (*menu_set_cursor)(int menu, int position); bool (*set_option)(const char* string, void* variable, enum optiontype type, const struct opt_items* options, -- cgit