Index: apps/main_menu.c =================================================================== --- apps/main_menu.c (revision 12108) +++ apps/main_menu.c (working copy) @@ -375,7 +375,7 @@ return false; } #endif - +#if 0 bool main_menu(void) { int m; @@ -445,7 +445,7 @@ return result; } - +#endif /* ----------------------------------------------------------------- * vim: et sw=4 ts=8 sts=4 tw=78 */ Index: apps/action.h =================================================================== --- apps/action.h (revision 12108) +++ apps/action.h (working copy) @@ -154,6 +154,10 @@ ACTION_REC_F3, /* main menu */ + ACTION_REQUEST_MENUITEM, + ACTION_EXIT_MENUITEM, + ACTION_ENTER_MENUITEM, + ACTION_MENU_WPS, /* id3db */ Index: apps/settings.c =================================================================== --- apps/settings.c (revision 12108) +++ apps/settings.c (working copy) @@ -875,6 +875,29 @@ #endif } +const struct settings_list* find_setting(void* variable) +{ + int i; + for(i=0;ilang_id) + talk_id(setting->lang_id,false); +} + bool set_bool(const char* string, bool* variable ) { return set_bool_options(string, variable, Index: apps/menu.c =================================================================== --- apps/menu.c (revision 12108) +++ apps/menu.c (working copy) @@ -35,12 +35,14 @@ #include "usb.h" #include "panic.h" #include "settings.h" +#include "settings_list.h" #include "status.h" #include "screens.h" #include "talk.h" #include "lang.h" #include "misc.h" #include "action.h" +#include "menus/exported_menus.h" #ifdef HAVE_LCD_BITMAP #include "icons.h" @@ -356,3 +358,265 @@ #endif } } + +/******************************************************************/ +/* New menu stuff here!! + ******************************************************************/ + + +/* used to allow for dynamic menus */ +#define MAX_MENU_SUBITEMS 64 +static int current_subitems[MAX_MENU_SUBITEMS]; +static int current_subitems_count = 0; + +#define GET_MENU_CALLBACK(m,cb) \ + if (m->flags&MENU_HAS_DESC) \ + cb = m->callback_and_desc->menu_callback; \ + else cb = m->menu_callback; + +static int get_menu_selection(int selected_item, const struct menu_item_ex *menu) +{ + int type = (menu->flags&MENU_TYPE_MASK); + if (type == MT_MENU && (selected_itemflags&MENU_TYPE_MASK); + selected_item = get_menu_selection(selected_item, menu); + + (void)buffer; + /* only MT_MENU or MT_RETURN_ID is allowed in here */ + if (type == MT_RETURN_ID) + { + return (char*)menu->strings[selected_item]; + } + + menu = menu->submenus[selected_item]; + if (type == MT_SETTING) + { + const struct settings_list *v + = find_setting(menu->variable); + if (v) + return str(v->lang_id); + else return "Not Done yet!"; + } + return P2STR(menu->callback_and_desc->desc); +} + +static void init_menu_lists(const struct menu_item_ex *menu, + struct gui_synclist *lists, int selected, bool callback) +{ + int i, count = (menu->flags&MENU_COUNT_MASK)>>MENU_COUNT_SHIFT; + menu_callback_type menu_callback; + current_subitems_count = 0; + for (i=0; isubmenus[i],menu_callback); + if (menu_callback) + { + if (menu_callback(ACTION_REQUEST_MENUITEM,menu->submenus[i]) + != ACTION_EXIT_MENUITEM) + { + current_subitems[current_subitems_count] = i; + current_subitems_count++; + } + } + else + { + current_subitems[current_subitems_count] = i; + current_subitems_count++; + } + } + + gui_synclist_init(lists,get_menu_item_name,(void*)menu,false,1); + gui_synclist_set_title(lists, P2STR(menu->callback_and_desc->desc), NOICON); + gui_synclist_set_icon_callback(lists,NULL); + gui_synclist_set_nb_items(lists,current_subitems_count); + gui_synclist_limit_scroll(lists,true); + gui_synclist_select_item(lists, selected); + + GET_MENU_CALLBACK(menu,menu_callback); + if (callback && menu_callback) + menu_callback(ACTION_ENTER_MENUITEM,menu); +} + +static void talk_menu_item(const struct menu_item_ex *menu, + struct gui_synclist *lists) +{ + int id = -1; + if (global_settings.talk_menu) + { + int sel = get_menu_selection(gui_synclist_get_sel_pos(lists),menu); + if ((menu->flags&MENU_TYPE_MASK) == MT_MENU) + { + if ((menu->submenus[sel]->flags&MENU_TYPE_MASK) == MT_SETTING) + talk_setting(menu->submenus[sel]->variable); + else + { + id = P2ID(menu->submenus[sel]->callback_and_desc->desc); + if (id != -1) + talk_id(id,false); + } + } + } +} + +int do_menu(const struct menu_item_ex *start_menu) +{ + int action; + int selected = 0; + struct gui_synclist lists; + const struct menu_item_ex *temp, *menu; + int ret = 0; + + const struct menu_item_ex *menu_stack[MAX_MENUS]; + int menu_stack_selected_item[MAX_MENUS]; + int stack_top = 0; + bool in_stringlist; + bool apply_settings = false; + menu_callback_type menu_callback; + if (start_menu == NULL) + menu = &main_menu_; + else menu = start_menu; + + init_menu_lists(menu,&lists,selected,true); + in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID); + + talk_menu_item(menu, &lists); + + gui_synclist_draw(&lists); + gui_syncstatusbar_draw(&statusbars, true); + action_signalscreenchange(); + + while (ret == 0) + { + action = get_action(CONTEXT_MAINMENU,HZ); + /* HZ so the status bar redraws corectly */ + if (action == ACTION_NONE) + { + gui_syncstatusbar_draw(&statusbars, true); + continue; + } + + GET_MENU_CALLBACK(menu,menu_callback); + if (menu_callback) + { + action = menu_callback(action,menu); + } + + if (gui_synclist_do_button(&lists,action,LIST_WRAP_UNLESS_HELD)) + { + talk_menu_item(menu, &lists); + } + else if (action == ACTION_MENU_WPS) + { + ret = MENU_RETURN_TO_WPS; + } + else if ((action == ACTION_STD_CANCEL) || + (action == ACTION_STD_MENU)) + { + if (in_stringlist) + in_stringlist = false; + if (stack_top > 0) + { + GET_MENU_CALLBACK(menu,menu_callback); + if (menu_callback) + { + if (menu_callback(action,menu) == + ACTION_EXIT_MENUITEM) + break; + } + stack_top--; + menu = menu_stack[stack_top]; + init_menu_lists(menu,&lists,menu_stack_selected_item[stack_top],false); + talk_menu_item(menu, &lists); + } + else + { + break; + } + } + else if (action == ACTION_STD_OK) + { + int type; + selected = get_menu_selection(gui_synclist_get_sel_pos(&lists),menu); + temp = menu->submenus[selected]; + if (in_stringlist) + type = (menu->flags&MENU_TYPE_MASK); + else type = (temp->flags&MENU_TYPE_MASK); + GET_MENU_CALLBACK(temp,menu_callback); + if (menu_callback) + { + action = menu_callback(ACTION_ENTER_MENUITEM,temp); + if (action == ACTION_EXIT_MENUITEM) + break; + } + switch (type) + { + case MT_MENU: + if (stack_top < MAX_MENUS) + { + menu_stack[stack_top] = menu; + menu_stack_selected_item[stack_top] + = gui_synclist_get_sel_pos(&lists); + stack_top++; + init_menu_lists(temp,&lists,0,true); + menu = temp; + talk_menu_item(menu, &lists); + } + break; + case MT_FUNCTION_CALL: + action_signalscreenchange(); + temp->function(); + break; + case MT_FUNCTION_WITH_PARAM: + action_signalscreenchange(); + temp->func_with_param->function( + temp->func_with_param->param); + break; + case MT_SETTING: + /* load_setting_screen( + (struct settings_list *)find_setting( + temp->global_settings_variable)); + apply_settings = true; + */ break; + case MT_RETURN_ID: + if (in_stringlist) + { + action_signalscreenchange(); + return selected; + } + else if (stack_top < MAX_MENUS) + { + menu_stack[stack_top] = menu; + menu_stack_selected_item[stack_top] = selected; + stack_top++; + menu = temp; + init_menu_lists(menu,&lists,0,false); + in_stringlist = true; + } + break; + } + GET_MENU_CALLBACK(temp,menu_callback); + if (type != MT_MENU && menu_callback) + menu_callback(ACTION_EXIT_MENUITEM,temp); + } + else if(default_event_handler(action) == SYS_USB_CONNECTED) + ret = MENU_ATTACHED_USB; + gui_syncstatusbar_draw(&statusbars, true); + gui_synclist_draw(&lists); + } + if (apply_settings) + settings_apply(); + action_signalscreenchange(); + return ret; +} + +int main_menu(void) +{ + return do_menu(NULL); +} Index: apps/settings.h =================================================================== --- apps/settings.h (revision 12108) +++ apps/settings.h (working copy) @@ -571,6 +571,9 @@ const char* no_str, int no_voice, void (*function)(bool)); +void talk_setting(void *variable); +const struct settings_list* find_setting(void* variable); + bool set_bool(const char* string, bool* variable ); bool set_option(const char* string, void* variable, enum optiontype type, const struct opt_items* options, int numoptions, void (*function)(int)); Index: apps/menus/exported_menus.h =================================================================== --- apps/menus/exported_menus.h (revision 0) +++ apps/menus/exported_menus.h (revision 0) @@ -0,0 +1,54 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2006 Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _EXPORTED_MENUS_H +#define _EXPORTED_MENUS_H + +#include "menu.h" +/* not needed for plugins and just causes compile error, possibly fix proberly later */ +#ifndef PLUGIN +#include "playlist.h" +#if 0 +int main_menu(void); /* apps/menu.c */ +bool recording_menu(void); /* recording_menu.c */ +bool sound_menu(void); /* sound_menu.c */ +bool set_sound(const unsigned char * string, + int* variable, int setting); /* sound_menu.c */ +int save_playlist_screen(struct playlist_info* playlist); /* playlist_menu.c */ +#endif +extern const struct menu_item_ex + main_menu_; +#if 0 + , /* main_menu.c */ + display_menu, /* display_menu.c */ + playback_settings, /* playback_menu.c */ +#ifdef HAVE_RECORDING + recording_settings_menu, /* recording_menu.c */ +#endif + sound_settings, /* sound_menu.c */ + playlist_menu; /* playlist_menu.c */ +#endif +#if CONFIG_CODEC == SWCODEC +/* in playback_menu.c, used by many settings to set crossfade + after retrning from option screen */ +//int setcrossfadeonexit_callback(int action,const struct menu_item_ex *this_item); +#endif /* CONFIG_CODEC == SWCODEC */ + + +#endif /* ! PLUGIN */ +#endif /*_EXPORTED_MENUS_H */ Index: apps/menus/main_menu.c =================================================================== --- apps/menus/main_menu.c (revision 0) +++ apps/menus/main_menu.c (revision 0) @@ -0,0 +1,43 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2007 Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include "config.h" +#include "menu.h" +#include "settings_menu.h" + + + + +MAKE_FUNCTION_CALL(settings_menu_,"Settings Menu",(menu_function)settings_menu,NULL); +MAKE_FUNCTION_CALL(manage_settings_menu_,"Manage Settings",(menu_function)manage_settings_menu,NULL); + + + + + + + + + + + +MAKE_MENU(main_menu_, "Main Menu", NULL,&settings_menu_,&manage_settings_menu_); Index: apps/menu.h =================================================================== --- apps/menu.h (revision 12108) +++ apps/menu.h (working copy) @@ -22,94 +22,8 @@ #include -/* button definitions */ -#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ - (CONFIG_KEYPAD == IRIVER_H300_PAD) -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT2 BUTTON_OFF -#define MENU_EXIT_MENU BUTTON_MODE -#define MENU_ENTER BUTTON_RIGHT -#define MENU_ENTER2 BUTTON_SELECT -#define MENU_RC_EXIT BUTTON_RC_STOP -#define MENU_RC_EXIT_MENU BUTTON_RC_MODE -#define MENU_RC_ENTER BUTTON_RC_ON -#define MENU_RC_ENTER2 BUTTON_RC_MENU - -#elif CONFIG_KEYPAD == RECORDER_PAD - -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT2 BUTTON_OFF -#define MENU_EXIT_MENU BUTTON_F1 -#define MENU_ENTER BUTTON_RIGHT -#define MENU_ENTER2 BUTTON_PLAY - -#define MENU_RC_EXIT BUTTON_RC_STOP -#define MENU_RC_ENTER BUTTON_RC_PLAY - -#elif CONFIG_KEYPAD == PLAYER_PAD -#define MENU_EXIT BUTTON_STOP -#define MENU_EXIT_MENU BUTTON_MENU -#define MENU_ENTER BUTTON_PLAY - -#define MENU_RC_EXIT BUTTON_RC_STOP -#define MENU_RC_ENTER BUTTON_RC_PLAY - -#elif CONFIG_KEYPAD == ONDIO_PAD -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT_MENU BUTTON_MENU -#define MENU_ENTER BUTTON_RIGHT - -#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD) - -/* TODO: Check menu button assignments */ - -#define MENU_NEXT BUTTON_DOWN -#define MENU_PREV BUTTON_UP -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT_MENU BUTTON_MENU -#define MENU_ENTER BUTTON_RIGHT -#define MENU_ENTER2 BUTTON_SELECT - -#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD - -#define MENU_NEXT BUTTON_DOWN -#define MENU_PREV BUTTON_UP -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT_MENU BUTTON_PLAY -#define MENU_ENTER BUTTON_RIGHT - -#elif CONFIG_KEYPAD == IAUDIO_X5_PAD - -#define MENU_NEXT BUTTON_DOWN -#define MENU_PREV BUTTON_UP -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT_MENU BUTTON_REC -#define MENU_ENTER BUTTON_RIGHT -#define MENU_ENTER2 BUTTON_SELECT - -#elif CONFIG_KEYPAD == GIGABEAT_PAD - -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT2 BUTTON_A -#define MENU_EXIT_MENU BUTTON_MENU -#define MENU_ENTER BUTTON_RIGHT -#define MENU_ENTER2 BUTTON_SELECT -#define MENU_NEXT BUTTON_DOWN -#define MENU_PREV BUTTON_UP - -#elif CONFIG_KEYPAD == IRIVER_H10_PAD - -#define MENU_NEXT BUTTON_SCROLL_DOWN -#define MENU_PREV BUTTON_SCROLL_UP -#define MENU_EXIT BUTTON_LEFT -#define MENU_EXIT_MENU BUTTON_REW -#define MENU_ENTER BUTTON_RIGHT -#define MENU_ENTER2 BUTTON_FF - -#endif - struct menu_item { unsigned char *desc; /* string or ID */ bool (*function) (void); /* return true if USB was connected */ @@ -125,6 +39,8 @@ 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); @@ -138,4 +54,80 @@ void menu_set_cursor(int menu, int position); void menu_talk_selected(int m); + +enum menu_item_type { + MT_MENU = 0, + MT_SETTING, + MT_FUNCTION_CALL, /* used when the standard code wont work */ + MT_FUNCTION_WITH_PARAM, + MT_RETURN_ID, /* returns the position of the selected item on selection (starting at 0)*/ +}; + +typedef int (*menu_function)(void); +struct menu_func_with_param { + int (*function)(void* param); + void *param; +}; + +#define MENU_TYPE_MASK 0xF /* MT_* type */ +#define MENU_HAS_DESC 0x10 +#define MENU_COUNT_MASK (~(MENU_TYPE_MASK|MENU_HAS_DESC)) /* unless we need more flags*/ +#define MENU_COUNT_SHIFT 5 + +struct menu_item_ex { + int flags; /* above defines */ + union { + const struct menu_item_ex **submenus; /* used with MT_MENU */ + void *variable; /* used with MT_SETTING, + must be in the settings_list.c list */ + int (*function)(void); /* used with MT_FUNCTION_CALL */ + const struct menu_func_with_param *func_with_param; /* MT_FUNCTION_WITH_PARAM */ + const char **strings; /* used with MT_RETURN_ID */ + }; + union { + int (*menu_callback)(int action, const struct menu_item_ex *this_item); + const struct menu_callback_with_desc { + int (*menu_callback)(int action, const struct menu_item_ex *this_item); + unsigned char *desc; /* string or ID */ + } *callback_and_desc; + }; +}; + +typedef int (*menu_callback_type)(int action, const struct menu_item_ex *this_item); +int do_menu(const struct menu_item_ex *menu); + +#define MENU_ITEM_COUNT(c) (c<