Right, well I've been tweaking it a bit and I think its now useable... attached is the diff which starts adding the sound and playback menus.. (i've ben testing on the ipod sim, and it compiles cleanyly...)
So just quickly, I want to explain the difference between adding a menu item in the current and this system.. First to make a menu 2 variables are needed. static const struct menu_item_ex *main_menu_items[] = {&sound_menu_items, &playback_items}; static const struct menu_item_ex main_menu = {MT_MENU, {main_menu_items},sizeof(main_menu_items)/sizeof(*main_menu_items),"Main Menu",0}; The first is a list of all the items in this menu (they can be sub-menus, or options, or functions to call.) The next just puts it all together so it can be used. Compare that to settings_menu.c where the list of items is needed anyway (but they are either NULL or a function to call) and ~3 functions are called to run the menu) And to actually add a option to a menu you need (for the CHOICE and BOOL options) an array of struct opt_items (which is needed in the old system also, so no big deal, BOOL will be able to reuse its array so its not so bad). Then you need to use one of the MAKE_*_OPT macros to create the 2 vairables needed. Lastly, you need to add the variable created by the macro to an array holding a list of items.. (e.g the main_menu_items above). Whereas in the old system you had to create a function which was called by the menu that had to call set_option (or similar). So, what do you think?
? dir_nav.patch ? h300 ? h300-sim ? ipod ? ipod.patch ? menu.diff ? menu_rework.h ? patch.patch ? recorder ? remote.patch ? tools/codepages ? tools/ipod_fw ? tools/mkboot ? tools/rdf2binary ? tools/uclpack Index: apps/menu.c =================================================================== RCS file: /cvsroot/rockbox/apps/menu.c,v retrieving revision 1.104 diff -u -r1.104 menu.c --- apps/menu.c 15 Aug 2006 12:27:04 -0000 1.104 +++ apps/menu.c 25 Aug 2006 02:08:47 -0000 @@ -41,6 +41,7 @@ #include "lang.h" #include "misc.h" #include "action.h" +#include "sound_menu.h" #ifdef HAVE_LCD_BITMAP #include "icons.h" @@ -165,10 +166,10 @@ return MENU_SELECTED_EXIT; } - -bool menu_run(int m) +bool menu_run(int m) { int selected; + return do_menu(NULL); while (1) { switch (selected=menu_show(m)) { @@ -356,3 +357,144 @@ #endif } } + +/******************************************************************/ +/* New menu stuff here!! + ******************************************************************/ + +static const struct opt_items bool_yesno[] = {{STR(LANG_SET_BOOL_NO)},{STR(LANG_SET_BOOL_YES)}}; +static const struct opt_items bool_onoff[] = {{STR(LANG_OFF)},{STR(LANG_ON)}}; + +/* playback options */ +MAKE_BOOL_OPT( shuffle ,0,LANG_SYSFONT_SHUFFLE,&bool_onoff,&global_settings.playlist_shuffle,0); +static const struct opt_items repeat_mode_names[] = { + { STR(LANG_OFF) }, { STR(LANG_REPEAT_ALL) }, + { STR(LANG_REPEAT_ONE) }, { STR(LANG_SHUFFLE) }, +#if (AB_REPEAT_ENABLE == 1) + { STR(LANG_REPEAT_AB) } +#endif +}; +MAKE_CHOICE_OPT(repeat, 0, LANG_REPEAT, &repeat_mode_names, NUM_REPEAT_MODES,&global_settings.repeat_mode,NULL); +static const struct menu_item_ex *playback_items_[] = {&shuffle ,&repeat}; + +static const struct menu_item_ex playback_items = + {MT_MENU,{playback_items_},sizeof(playback_items_)/sizeof(*playback_items_),"Playback Menu",0}; + + +/* sound settings */ +MAKE_SOUND_OPT( volume, 0, LANG_VOLUME, SOUND_VOLUME, &global_settings.volume ); +MAKE_SOUND_OPT( balance, 0, LANG_BALANCE, SOUND_BALANCE, &global_settings.balance ); +#ifndef HAVE_TLV320 +MAKE_SOUND_OPT( bass, 0, LANG_BASS, SOUND_BASS, &global_settings.bass ); +MAKE_SOUND_OPT( treble, 0, LANG_TREBLE, SOUND_TREBLE, &global_settings.treble ); +#endif +static const struct menu_item_ex *sound_menu_items_[] = {&volume,&balance, +#ifndef HAVE_TLV320 +&bass, &treble +#endif +}; +static const struct menu_item_ex sound_menu_items = + {MT_MENU,{sound_menu_items_},sizeof(sound_menu_items_)/sizeof(*sound_menu_items_),"Sound Menu",0}; + +static const struct menu_item_ex *main_menu_items[] = {&sound_menu_items, &playback_items}; +static const struct menu_item_ex main_menu = {MT_MENU, {main_menu_items},sizeof(main_menu_items)/sizeof(*main_menu_items),"Main Menu",0}; + +#define GET_TITLE(s,t) s!=0?(char*)s:(char*)str(t) + +char * get_menu_item_name(int selected_item,void * data, char *buffer) +{ + const struct menu_item_ex *menu = (const struct menu_item_ex *)data; + (void)buffer; + /* it should always be MT_MENU in here... but the individual items could be anything */ + menu = menu->submenus[selected_item]; + return GET_TITLE(menu->title,menu->title_lang_id); +} + +bool do_menu(const struct menu_item_ex *menu) +{ + int action; + bool done = false; + int selected; + struct gui_synclist lists; + const struct menu_item_ex *temp; + if (menu == NULL) + menu = &main_menu; + + gui_synclist_init(&lists,get_menu_item_name,(void*)menu,false,1); + gui_synclist_set_title(&lists, GET_TITLE(menu->title,menu->title_lang_id), NOICON); + gui_synclist_set_icon_callback(&lists,NULL); + gui_synclist_set_nb_items(&lists,menu->item_count); + gui_synclist_limit_scroll(&lists,true); + gui_synclist_select_item(&lists, 0); + /* + if (global_settings.talk_menu) + { + if (cb_data->type == INT && !cb_data->options) + talk_unit(cb_data->voice_unit, *(int*)variable); + else talk_id(cb_data->options[selected].voice_id, false); + } + */ + gui_synclist_draw(&lists); + while (!done) + { + + action = get_action(CONTEXT_MAINMENU,TIMEOUT_BLOCK); + if (action == ACTION_NONE) + continue; + + if (gui_synclist_do_button(&lists,action)) + { + } + else if (action == ACTION_STD_CANCEL) + { + return false; + } + else if (action == ACTION_STD_OK) + { + selected = gui_synclist_get_sel_pos(&lists); + temp = menu->submenus[selected]; + switch (temp->type) + { + case MT_MENU: + do_menu(temp); + break; + case MT_FUNCTION_CALL: + temp->function(); + break; + case MT_SETTING_BOOL: + set_option(GET_TITLE(temp->title,temp->title_lang_id), + temp->bool_opts->variable,BOOL, + (const struct opt_items*)temp->bool_opts->options,temp->item_count, + (void*)temp->bool_opts->function); /*(void*) removes the warning */ + break; + case MT_SETTING_INT: + set_int(GET_TITLE(temp->title,temp->title_lang_id), + temp->int_opts->unit,temp->int_opts->voice_unit, + temp->int_opts->variable,temp->int_opts->function, + temp->int_opts->step,temp->int_opts->min,temp->int_opts->max, + temp->int_opts->formatter); + break; + case MT_SETTING_CHOICE: + set_option(GET_TITLE(temp->title,temp->title_lang_id), + temp->choice_opts->variable,INT, + (const struct opt_items*)temp->choice_opts->options,temp->item_count, + temp->choice_opts->function); + break; + case MT_SETTING_SOUND: + set_sound(GET_TITLE(temp->title,temp->title_lang_id), + temp->sound_opts->variable,temp->sound_opts->sound_type); + break; + } + gui_synclist_draw(&lists); + } + else if(default_event_handler(action) == SYS_USB_CONNECTED) + return true; + gui_syncstatusbar_draw(&statusbars, false); + } + return false; +} + + + + + Index: apps/menu.h =================================================================== RCS file: /cvsroot/rockbox/apps/menu.h,v retrieving revision 1.44 diff -u -r1.44 menu.h --- apps/menu.h 3 Aug 2006 20:17:14 -0000 1.44 +++ apps/menu.h 25 Aug 2006 02:08:48 -0000 @@ -21,6 +21,8 @@ #define __MENU_H__ #include <stdbool.h> +#include "config.h" +#include "sound.h" /* button definitions */ #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ @@ -133,6 +135,7 @@ #define MENU_ATTACHED_USB -1 #define MENU_SELECTED_EXIT -2 + bool menu_run(int menu); int menu_cursor(int menu); char* menu_description(int menu, int position); @@ -145,4 +148,87 @@ void menu_set_cursor(int menu, int position); void menu_talk_selected(int m); + +enum menu_item_type { + MT_MENU = 0, + MT_SETTING_BOOL, + MT_SETTING_CHOICE, /* int where you have X choices, e.g reply mode */ + MT_SETTING_INT, /* int with min,max */ + MT_SETTING_SOUND, + MT_FUNCTION_CALL, /* used when the standard code wont work */ +}; + +struct setting_bool_opt { + bool *variable; + const struct opt_items** options; + void (*function)(bool); +}; + +struct setting_choice_opt { + int *variable; + const struct opt_items** options; + void (*function)(int); +}; + +struct setting_int_opt { + int *variable; + void (*function)(int); + void (*formatter)(char*, int, int, const char*); + const char* unit; + int voice_unit; + int step; + int min; + int max; +}; + +struct setting_sound_opt { + int *variable; + int sound_type; + void (*function)(int); +}; + +struct menu_item_ex { + enum menu_item_type type; + union { + const void* dummy; /* NOTE: this stops compiler warnings.. never use this variable... */ + const struct menu_item_ex **submenus; /* used with MT_MENU */ + const struct setting_bool_opt *bool_opts; /* used with MT_SETTING_BOOL */ + const struct setting_choice_opt *choice_opts; /* used with MT_SETTING_CHOICE */ + const struct setting_int_opt *int_opts; /* used with MT_SETTING_INT */ + const struct setting_sound_opt *sound_opts; /* used with MT_SETTING_SOUND */ + int (*function)(void); /* used with MT_FUNCTION_CALL */ + }; + int item_count; /* # of submenu or options items */ + char *title; + int title_lang_id; /* only checked if title == NULL */ +}; +bool do_menu(const struct menu_item_ex *menu); + +#define MAKE_BOOL_OPT(name,str,id,opt_item_list, var, func) \ + s##tatic const struct setting_bool_opt name## _opt = \ + { var, (const struct opt_items**)opt_item_list,func}; \ + s##tatic const struct menu_item_ex name = \ + { MT_SETTING_BOOL, { &name##_opt},2,str,id}; + +#define MAKE_CHOICE_OPT(name,str,id,opt_item_list,count, var, func) \ + s##tatic const struct setting_choice_opt name## _opt = \ + { var, (const struct opt_items**)opt_item_list,func}; \ + s##tatic const struct menu_item_ex name = \ + { MT_SETTING_CHOICE, { &name##_opt},count,str,id}; + +#define MAKE_INT_OPT(name,str,id,var, func, formatter, \ + unit, voice_unit, step, min, max) \ + s##tatic const struct setting_int_opt name## _opt = \ + { var, func, formatter, unit, voice_unit, step, min, max}; \ + s##tatic const struct menu_item_ex name = \ + { MT_SETTING_INT, { &name##_opt},0,str,id}; + +#define MAKE_SOUND_OPT(name,str, id, type, var) \ + s##tatic const struct setting_sound_opt name## _opt = \ + { var, type, NULL}; \ + s##tatic const struct menu_item_ex name = \ + { MT_SETTING_SOUND, { &name##_opt},0,str,id}; + + #endif /* End __MENU_H__ */ + Index: uisimulator/common/stubs.c =================================================================== RCS file: /cvsroot/rockbox/uisimulator/common/stubs.c,v retrieving revision 1.70 diff -u -r1.70 stubs.c --- uisimulator/common/stubs.c 13 Feb 2006 21:46:27 -0000 1.70 +++ uisimulator/common/stubs.c 25 Aug 2006 02:08:52 -0000 @@ -24,7 +24,6 @@ #include "screens.h" #include "button.h" -#include "menu.h" #include "string.h" #include "lcd.h"