diff --git a/apps/menu.c b/apps/menu.c index 4991b05383..830bc67a11 100644 --- a/apps/menu.c +++ b/apps/menu.c @@ -67,6 +67,12 @@ static int current_subitems[MAX_MENU_SUBITEMS]; static int current_subitems_count = 0; static int talk_menu_item(int selected_item, void *data); +struct menu_data_t +{ + const struct menu_item_ex *menu; + int selected; +}; + static void get_menu_callback(const struct menu_item_ex *m, menu_callback_type *menu_callback) { @@ -76,6 +82,19 @@ static void get_menu_callback(const struct menu_item_ex *m, *menu_callback = m->menu_callback; } +static bool query_audio_status(int *old_audio_status) +{ + bool redraw_list = false; + /* query audio status to see if it changed */ + int new_audio_status = audio_status(); + if (*old_audio_status != new_audio_status) + { /* force a redraw if anything changed the audio status from outside */ + *old_audio_status = new_audio_status; + redraw_list = true; + } + return redraw_list; +} + static int get_menu_selection(int selected_item, const struct menu_item_ex *menu) { int type = (menu->flags&MENU_TYPE_MASK); @@ -128,8 +147,7 @@ static const char* get_menu_item_name(int selected_item, type = (menu->flags&MENU_TYPE_MASK); if ((type == MT_SETTING) || (type == MT_SETTING_W_TEXT)) { - const struct settings_list *v - = find_setting(menu->variable, NULL); + const struct settings_list *v = find_setting(menu->variable, NULL); if (v) return str(v->lang_id); else return "Not Done yet!"; @@ -158,20 +176,13 @@ static enum themable_icons menu_get_icon(int selected_item, void * data) if (menu_icon == Icon_NOICON) { - switch (menu->flags&MENU_TYPE_MASK) - { - case MT_SETTING: - case MT_SETTING_W_TEXT: - menu_icon = Icon_Menu_setting; - break; - case MT_MENU: - menu_icon = Icon_Submenu; - break; - case MT_FUNCTION_CALL: - case MT_RETURN_VALUE: - menu_icon = Icon_Menu_functioncall; - break; - } + unsigned int flags = (menu->flags&MENU_TYPE_MASK); + if(flags == MT_MENU) + menu_icon = Icon_Submenu; + else if (flags == MT_SETTING || flags == MT_SETTING_W_TEXT) + menu_icon = Icon_Menu_setting; + else if (flags == MT_FUNCTION_CALL || flags == MT_RETURN_VALUE) + menu_icon = Icon_Menu_functioncall; } return menu_icon; } @@ -368,12 +379,15 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, struct viewport parent[NB_SCREENS], bool hide_theme) { int selected = start_selected? *start_selected : 0; + int ret = 0; int action; struct gui_synclist lists; const struct menu_item_ex *temp = NULL; const struct menu_item_ex *menu = start_menu; - int ret = 0; + + bool in_stringlist, done = false; bool redraw_lists; + int old_audio_status = audio_status(); #ifdef HAVE_TOUCHSCREEN @@ -386,10 +400,9 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, FOR_NB_SCREENS(i) viewportmanager_theme_enable(i, !hide_theme, NULL); - const struct menu_item_ex *menu_stack[MAX_MENUS]; - int menu_stack_selected_item[MAX_MENUS]; + struct menu_data_t mstack[MAX_MENUS]; /* menu, selected */ int stack_top = 0; - bool in_stringlist, done = false; + struct viewport *vps = NULL; menu_callback_type menu_callback = NULL; @@ -403,42 +416,30 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, gui_synclist_draw(&lists); gui_synclist_speak_item(&lists); + while (!done) { - int new_audio_status; - redraw_lists = false; keyclick_set_callback(gui_synclist_keyclick_callback, &lists); + action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK, - list_do_action_timeout(&lists, HZ)); + list_do_action_timeout(&lists, HZ)); + /* HZ so the status bar redraws corectly */ /* query audio status to see if it changed */ - new_audio_status = audio_status(); - if (old_audio_status != new_audio_status) - { /* force a redraw if anything changed the audio status - * from outside */ - redraw_lists = true; - old_audio_status = new_audio_status; - } - /* HZ so the status bar redraws corectly */ + redraw_lists = query_audio_status(&old_audio_status); if (menu_callback) { - int old_action = action; - action = menu_callback(action, menu, &lists); - if (action == ACTION_EXIT_AFTER_THIS_MENUITEM) - { - action = old_action; - ret = MENU_SELECTED_EXIT; /* will exit after returning - from selection */ - } - else if (action == ACTION_REDRAW) - { - action = old_action; + int new_action = menu_callback(action, menu, &lists); + if (new_action == ACTION_EXIT_AFTER_THIS_MENUITEM) + ret = MENU_SELECTED_EXIT; /* exit after return from selection */ + else if (new_action == ACTION_REDRAW) redraw_lists = true; - } + else + action = new_action; } - if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD)) + if (LIKELY(gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))) continue; #ifdef HAVE_QUICKSCREEN else if (action == ACTION_STD_QUICKSCREEN) @@ -505,7 +506,6 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, ID2P(LANG_ONPLAY_MENU_TITLE), NULL, ID2P(LANG_RESET_SETTING)); const struct menu_item_ex *menu; - int menu_selection = 0; const struct settings_list *setting = find_setting(temp->variable, NULL); #ifdef HAVE_QUICKSCREEN @@ -514,7 +514,10 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, else #endif menu = ¬quickscreen_able_option; - switch (do_menu(menu, &menu_selection, NULL, false)) + + int msel = do_menu(menu, NULL, NULL, false); + + switch (msel) { case GO_TO_PREVIOUS: break; @@ -556,10 +559,12 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, } else if (action == ACTION_STD_CANCEL) { - bool exiting_menu = false; - in_stringlist = false; /* might be leaving list, so stop scrolling */ gui_synclist_scroll_stop(&lists); + + bool exiting_menu = false; + in_stringlist = false; + if (menu_callback) menu_callback(ACTION_EXIT_MENUITEM, menu, &lists); @@ -567,15 +572,16 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, done = true; else if ((menu->flags&MENU_TYPE_MASK) == MT_MENU) exiting_menu = true; + if (stack_top > 0) { stack_top--; - menu = menu_stack[stack_top]; + menu = mstack[stack_top].menu; + int msel = mstack[stack_top].selected; if (!exiting_menu && (menu->flags&MENU_EXITAFTERTHISMENU)) done = true; else - init_menu_lists(menu, &lists, - menu_stack_selected_item[stack_top], false, vps); + init_menu_lists(menu, &lists, msel, false, vps); redraw_lists = true; /* new menu, so reload the callback */ get_menu_callback(menu, &menu_callback); @@ -588,19 +594,18 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, } else if (action == ACTION_STD_OK) { - int type = (menu->flags&MENU_TYPE_MASK); /* entering an item that may not be a list, so stop scrolling */ gui_synclist_scroll_stop(&lists); + redraw_lists = true; + + int type = (menu->flags&MENU_TYPE_MASK); selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu); if (type == MT_MENU) temp = menu->submenus[selected]; - else + else if (!in_stringlist) type = -1; - redraw_lists = true; - if (in_stringlist) - type = (menu->flags&MENU_TYPE_MASK); - else if (temp) + if (!in_stringlist && temp) { type = (temp->flags&MENU_TYPE_MASK); get_menu_callback(temp, &menu_callback); @@ -616,8 +621,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, case MT_MENU: if (stack_top < MAX_MENUS) { - menu_stack[stack_top] = menu; - menu_stack_selected_item[stack_top] = selected; + mstack[stack_top].menu = menu; + mstack[stack_top].selected = selected; stack_top++; menu = temp; init_menu_lists(menu, &lists, 0, true, vps); @@ -661,8 +666,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, } else if (stack_top < MAX_MENUS) { - menu_stack[stack_top] = menu; - menu_stack_selected_item[stack_top] = selected; + mstack[stack_top].menu = menu; + mstack[stack_top].selected = selected; stack_top++; menu = temp; init_menu_lists(menu,&lists,0,false, vps); @@ -731,8 +736,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, the selected item from the menu do_menu() was called from */ if (stack_top > 0) { - menu = menu_stack[0]; - init_menu_lists(menu,&lists,menu_stack_selected_item[0],true, vps); + menu = mstack[0].menu; + init_menu_lists(menu,&lists,mstack[0].selected,true, vps); } *start_selected = get_menu_selection( gui_synclist_get_sel_pos(&lists), menu); @@ -748,6 +753,5 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, tsm == old_global_mode)) touchscreen_set_mode(tsm); #endif - return ret; }