summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2021-10-22 22:17:36 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2021-10-29 03:07:42 -0400
commitdc24a18cef83d88f4e6ab657ca0adfccf1051474 (patch)
tree3e07fe2e5fa1a75eb549bd770270d2985c8a640f
parent8ee24d8cb47939ff04fa42b1ae9719ebeba64d29 (diff)
downloadrockbox-dc24a18cef.tar.gz
rockbox-dc24a18cef.tar.bz2
rockbox-dc24a18cef.zip
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
-rw-r--r--apps/menu.c27
-rw-r--r--apps/menus/plugin_menu.c30
-rw-r--r--apps/root_menu.c66
-rw-r--r--apps/tree.c14
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;