From f1ef5ab8a6f7f048c05ef7c25de594fca097e975 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Wed, 27 Oct 2021 01:28:46 -0400 Subject: [PATCH 1/3] menu.c do_menu code cleanup no functional changes here just removal of cruft Change-Id: Id16c3607608d8f1ddcaf219dcd346f7a996aec5d --- apps/menu.c | 132 +++++++++++++++++++++++++++------------------------- 1 file changed, 68 insertions(+), 64 deletions(-) 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; } From 8ee24d8cb47939ff04fa42b1ae9719ebeba64d29 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Wed, 27 Oct 2021 21:45:24 -0400 Subject: [PATCH 2/3] onplay calls plugins to run other plugins Change-Id: I7c1593c93debc0ac5c0f1b2e839ec0eb1bd375b7 --- apps/onplay.c | 2 ++ apps/tree.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/apps/onplay.c b/apps/onplay.c index a5a92e7c1c..83b24da78d 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -1576,6 +1576,8 @@ static bool onplay_load_plugin(void *param) int ret = filetype_load_plugin((const char*)param, selected_file); if (ret == PLUGIN_USB_CONNECTED) onplay_result = ONPLAY_RELOAD_DIR; + else if (ret == PLUGIN_GOTO_PLUGIN) + onplay_result = ONPLAY_PLUGIN; return false; } diff --git a/apps/tree.c b/apps/tree.c index f50d424a82..7fcced92c8 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -805,6 +805,7 @@ static int dirbrowse(void) { case ONPLAY_MAINMENU: return GO_TO_ROOT; + break; case ONPLAY_OK: restore = true; @@ -817,6 +818,10 @@ static int dirbrowse(void) case ONPLAY_START_PLAY: return GO_TO_WPS; break; + + case ONPLAY_PLUGIN: + return GO_TO_PLUGIN; + break; } break; } From dc24a18cef83d88f4e6ab657ca0adfccf1051474 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Fri, 22 Oct 2021 22:17:36 -0400 Subject: [PATCH 3/3] PLUGINBROWSER make resumable make the plugin browser remember the last item between invocations this has bugged me for the longest time dealing with the plugin_menu Fix a very old bug fix for reloading lang strings in the lang menu FS#8117, sending multiple ENTER_MENU_ITEM callbacks from different areas of the code makes it hard to keep track of where your callback is originating Change-Id: Ib0a61558c11ee4c772134378a7020ac0e10fc4ee --- apps/menu.c | 27 +++++++++++----- apps/menus/plugin_menu.c | 30 ++++++++++++++++-- apps/root_menu.c | 66 +++++++++++++++++++++++++++++----------- apps/tree.c | 14 ++++++--- 4 files changed, 106 insertions(+), 31 deletions(-) diff --git a/apps/menu.c b/apps/menu.c index 830bc67a11..802a16bbb8 100644 --- a/apps/menu.c +++ b/apps/menu.c @@ -187,17 +187,18 @@ static enum themable_icons menu_get_icon(int selected_item, void * data) return menu_icon; } -static void init_menu_lists(const struct menu_item_ex *menu, +static int init_menu_lists(const struct menu_item_ex *menu, struct gui_synclist *lists, int selected, bool callback, struct viewport parent[NB_SCREENS]) { if (!menu || !lists) { panicf("init_menu_lists, NULL pointer"); - return; + return 0; } int i; + int start_action = ACTION_ENTER_MENUITEM; int count = MIN(MENU_GET_COUNT(menu->flags), MAX_MENU_SUBITEMS); int type = (menu->flags&MENU_TYPE_MASK); menu_callback_type menu_callback = NULL; @@ -264,7 +265,9 @@ static void init_menu_lists(const struct menu_item_ex *menu, get_menu_callback(menu,&menu_callback); if (callback && menu_callback) - menu_callback(ACTION_ENTER_MENUITEM, menu, lists); + start_action = menu_callback(start_action, menu, lists); + + return start_action; } static int talk_menu_item(int selected_item, void *data) @@ -381,6 +384,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, int selected = start_selected? *start_selected : 0; int ret = 0; int action; + int start_action; struct gui_synclist lists; const struct menu_item_ex *temp = NULL; const struct menu_item_ex *menu = start_menu; @@ -407,8 +411,10 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, menu_callback_type menu_callback = NULL; /* if hide_theme is true, assume parent has been fixed before passed into - * this function, e.g. with viewport_set_defaults(parent, screen) */ - init_menu_lists(menu, &lists, selected, true, parent); + * this function, e.g. with viewport_set_defaults(parent, screen) + * start_action allows an action to be processed + * by menu logic by bypassing get_action on the initial run */ + start_action = init_menu_lists(menu, &lists, selected, true, parent); vps = *(lists.parent); in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID); /* load the callback, and only reload it if menu changes */ @@ -421,7 +427,13 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, { keyclick_set_callback(gui_synclist_keyclick_callback, &lists); - action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK, + if (UNLIKELY(start_action != ACTION_ENTER_MENUITEM)) + { + action = start_action; + start_action = ACTION_ENTER_MENUITEM; + } + else + action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK, list_do_action_timeout(&lists, HZ)); /* HZ so the status bar redraws corectly */ @@ -639,7 +651,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, if (!(menu->flags&MENU_EXITAFTERTHISMENU) || (temp->flags&MENU_EXITAFTERTHISMENU)) { - init_menu_lists(menu, &lists, selected, true, vps); + /* Reload menu but don't run the calback again FS#8117 */ + init_menu_lists(menu, &lists, selected, false, vps); } if (temp->flags&MENU_FUNC_CHECK_RETVAL) { diff --git a/apps/menus/plugin_menu.c b/apps/menus/plugin_menu.c index 055cfce140..7f29e61af4 100644 --- a/apps/menus/plugin_menu.c +++ b/apps/menus/plugin_menu.c @@ -24,11 +24,12 @@ #include "config.h" #include "lang.h" #include "menu.h" +#include "action.h" #include "settings.h" #include "rbpaths.h" #include "root_menu.h" #include "tree.h" - +static int reenter = 0; enum { GAMES, @@ -53,13 +54,36 @@ static int plugins_menu(void* param) browse_context_init(&browse, SHOW_PLUGINS, 0, str(items[item].id), Icon_Plugin, items[item].path, NULL); - + ret = rockbox_browse(&browse); + if (ret == GO_TO_PREVIOUS) return 0; + if (ret == GO_TO_PLUGIN) + reenter = 1; return ret; } +static int menu_callback(int action, + const struct menu_item_ex *this_item, + struct gui_synclist *this_list) +{ + (void)this_item; + static int selected = 0; + + if (action == ACTION_ENTER_MENUITEM) + { + this_list->selected_item = selected; + if (reenter-- > 0) + action = ACTION_STD_OK; + } + else if (action == ACTION_STD_OK) + { + selected = gui_synclist_get_sel_pos(this_list); + } + return action; +} + #define ITEM_FLAG (MENU_FUNC_USEPARAM|MENU_FUNC_CHECK_RETVAL) MENUITEM_FUNCTION(games_item, ITEM_FLAG, ID2P(LANG_PLUGIN_GAMES), @@ -69,6 +93,6 @@ MENUITEM_FUNCTION(apps_item, ITEM_FLAG, ID2P(LANG_PLUGIN_APPS), MENUITEM_FUNCTION(demos_item, ITEM_FLAG, ID2P(LANG_PLUGIN_DEMOS), plugins_menu, (void*)DEMOS, NULL, Icon_Folder); -MAKE_MENU(plugin_menu, ID2P(LANG_PLUGINS), NULL, +MAKE_MENU(plugin_menu, ID2P(LANG_PLUGINS), &menu_callback, Icon_Plugin, &games_item, &apps_item, &demos_item); diff --git a/apps/root_menu.c b/apps/root_menu.c index 15d03a7cda..ed6bdfdcca 100644 --- a/apps/root_menu.c +++ b/apps/root_menu.c @@ -634,6 +634,7 @@ static int item_callback(int action, } return action; } + static int get_selection(int last_screen) { int i; @@ -683,6 +684,7 @@ static inline int load_screen(int screen) last_screen = old_previous; return ret_val; } + static int load_context_screen(int selection) { const struct menu_item_ex *context_menu = NULL; @@ -709,13 +711,12 @@ static int load_plugin_screen(char *key) { int ret_val; int old_previous = last_screen; + int old_global = global_status.last_screen; last_screen = next_screen; global_status.last_screen = (char)next_screen; status_save(); - int opret = open_plugin_get_entry(key, &open_plugin_entry); - bool flush = (opret == OPEN_PLUGIN_NEEDS_FLUSHED); char *path = open_plugin_entry.path; char *param = open_plugin_entry.param; if (param[0] == '\0') @@ -723,6 +724,9 @@ static int load_plugin_screen(char *key) switch (plugin_load(path, param)) { + case PLUGIN_USB_CONNECTED: + ret_val = GO_TO_ROOT; + break; case PLUGIN_GOTO_WPS: ret_val = GO_TO_WPS; break; @@ -730,18 +734,30 @@ static int load_plugin_screen(char *key) ret_val = GO_TO_PLUGIN; break; case PLUGIN_OK: - ret_val = audio_status() ? GO_TO_PREVIOUS : GO_TO_ROOT; - break; + /* Prevents infinite loop with WPS & Plugins*/ + if (old_global == GO_TO_WPS && !audio_status()) + { + ret_val = GO_TO_ROOT; + break; + } + /*fallthrough*/ default: ret_val = GO_TO_PREVIOUS; + last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous; break; + } - if (!flush && ret_val != GO_TO_PLUGIN) - open_plugin_add_path(NULL, NULL, NULL); - - if (ret_val == GO_TO_PREVIOUS) - last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous; + if (ret_val != GO_TO_PLUGIN) + { + if (opret != OPEN_PLUGIN_NEEDS_FLUSHED || last_screen != GO_TO_WPS) + { + /* Keep the entry in case of GO_TO_PREVIOUS */ + open_plugin_entry.hash = 0; /*remove hash -- prevents flush to disk */ + open_plugin_entry.lang_id = LANG_PREVIOUS_SCREEN; + /*open_plugin_add_path(NULL, NULL, NULL);// clear entry */ + } + } return ret_val; } @@ -858,8 +874,12 @@ void root_menu(void) #endif /* With !CONFIG_TUNER previous_music is always GO_TO_WPS */ case GO_TO_PREVIOUS: + { next_screen = last_screen; + if (last_screen == GO_TO_PLUGIN)/* for WPS */ + last_screen = GO_TO_PREVIOUS; break; + } case GO_TO_PREVIOUS_BROWSER: next_screen = previous_browser; @@ -874,7 +894,8 @@ void root_menu(void) case GO_TO_PLUGIN: { char *key; - if (global_status.last_screen == GO_TO_SHORTCUTMENU) + if (global_status.last_screen == GO_TO_SHORTCUTMENU && + last_screen != GO_TO_ROOT) { shortcut_origin = last_screen; key = ID2P(LANG_SHORTCUTS); @@ -892,6 +913,9 @@ void root_menu(void) case GO_TO_SHORTCUTMENU: key = ID2P(LANG_SHORTCUTS); break; + case GO_TO_PREVIOUS: + key = ID2P(LANG_PREVIOUS_SCREEN); + break; default: key = ID2P(LANG_OPEN_PLUGIN); break; @@ -900,15 +924,23 @@ void root_menu(void) next_screen = load_plugin_screen(key); - /* shortcuts may take several trips through the GO_TO_PLUGIN case - make sure we preserve and restore the origin */ - if (next_screen == GO_TO_PREVIOUS && shortcut_origin != GO_TO_ROOT) + if (next_screen == GO_TO_PREVIOUS) { - if (shortcut_origin != GO_TO_WPS) - next_screen = shortcut_origin; - shortcut_origin = GO_TO_ROOT; + /* shortcuts may take several trips through the GO_TO_PLUGIN + case make sure we preserve and restore the origin */ + if (shortcut_origin != GO_TO_ROOT) + { + if (shortcut_origin != GO_TO_WPS) + next_screen = shortcut_origin; + shortcut_origin = GO_TO_ROOT; + } + /* skip GO_TO_PREVIOUS */ + if (last_screen == GO_TO_BROWSEPLUGINS) + { + next_screen = last_screen; + last_screen = GO_TO_PLUGIN; + } } - previous_browser = (next_screen != GO_TO_WPS) ? GO_TO_FILEBROWSER : GO_TO_PLUGIN; break; } diff --git a/apps/tree.c b/apps/tree.c index 7fcced92c8..e35f769a14 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -967,11 +967,17 @@ int rockbox_browse(struct browse_context *browse) if (*tc.dirfilter >= NUM_FILTER_MODES) { int last_context; + /* don't reset if its the same browse already loaded */ + if (tc.browse != browse || + !(tc.currdir[1] && strcmp(tc.currdir, browse->root) == 0)) + { + tc.browse = browse; + tc.selected_item = 0; + tc.dirlevel = 0; + + strlcpy(tc.currdir, browse->root, sizeof(tc.currdir)); + } - tc.browse = browse; - tc.selected_item = 0; - tc.dirlevel = 0; - strlcpy(tc.currdir, browse->root, sizeof(tc.currdir)); start_wps = false; last_context = curr_context;