summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)
187 return menu_icon; 187 return menu_icon;
188} 188}
189 189
190static void init_menu_lists(const struct menu_item_ex *menu, 190static int init_menu_lists(const struct menu_item_ex *menu,
191 struct gui_synclist *lists, int selected, bool callback, 191 struct gui_synclist *lists, int selected, bool callback,
192 struct viewport parent[NB_SCREENS]) 192 struct viewport parent[NB_SCREENS])
193{ 193{
194 if (!menu || !lists) 194 if (!menu || !lists)
195 { 195 {
196 panicf("init_menu_lists, NULL pointer"); 196 panicf("init_menu_lists, NULL pointer");
197 return; 197 return 0;
198 } 198 }
199 199
200 int i; 200 int i;
201 int start_action = ACTION_ENTER_MENUITEM;
201 int count = MIN(MENU_GET_COUNT(menu->flags), MAX_MENU_SUBITEMS); 202 int count = MIN(MENU_GET_COUNT(menu->flags), MAX_MENU_SUBITEMS);
202 int type = (menu->flags&MENU_TYPE_MASK); 203 int type = (menu->flags&MENU_TYPE_MASK);
203 menu_callback_type menu_callback = NULL; 204 menu_callback_type menu_callback = NULL;
@@ -264,7 +265,9 @@ static void init_menu_lists(const struct menu_item_ex *menu,
264 265
265 get_menu_callback(menu,&menu_callback); 266 get_menu_callback(menu,&menu_callback);
266 if (callback && menu_callback) 267 if (callback && menu_callback)
267 menu_callback(ACTION_ENTER_MENUITEM, menu, lists); 268 start_action = menu_callback(start_action, menu, lists);
269
270 return start_action;
268} 271}
269 272
270static int talk_menu_item(int selected_item, void *data) 273static 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,
381 int selected = start_selected? *start_selected : 0; 384 int selected = start_selected? *start_selected : 0;
382 int ret = 0; 385 int ret = 0;
383 int action; 386 int action;
387 int start_action;
384 struct gui_synclist lists; 388 struct gui_synclist lists;
385 const struct menu_item_ex *temp = NULL; 389 const struct menu_item_ex *temp = NULL;
386 const struct menu_item_ex *menu = start_menu; 390 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,
407 menu_callback_type menu_callback = NULL; 411 menu_callback_type menu_callback = NULL;
408 412
409 /* if hide_theme is true, assume parent has been fixed before passed into 413 /* if hide_theme is true, assume parent has been fixed before passed into
410 * this function, e.g. with viewport_set_defaults(parent, screen) */ 414 * this function, e.g. with viewport_set_defaults(parent, screen)
411 init_menu_lists(menu, &lists, selected, true, parent); 415 * start_action allows an action to be processed
416 * by menu logic by bypassing get_action on the initial run */
417 start_action = init_menu_lists(menu, &lists, selected, true, parent);
412 vps = *(lists.parent); 418 vps = *(lists.parent);
413 in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID); 419 in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID);
414 /* load the callback, and only reload it if menu changes */ 420 /* 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,
421 { 427 {
422 keyclick_set_callback(gui_synclist_keyclick_callback, &lists); 428 keyclick_set_callback(gui_synclist_keyclick_callback, &lists);
423 429
424 action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK, 430 if (UNLIKELY(start_action != ACTION_ENTER_MENUITEM))
431 {
432 action = start_action;
433 start_action = ACTION_ENTER_MENUITEM;
434 }
435 else
436 action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK,
425 list_do_action_timeout(&lists, HZ)); 437 list_do_action_timeout(&lists, HZ));
426 /* HZ so the status bar redraws corectly */ 438 /* HZ so the status bar redraws corectly */
427 439
@@ -639,7 +651,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
639 if (!(menu->flags&MENU_EXITAFTERTHISMENU) || 651 if (!(menu->flags&MENU_EXITAFTERTHISMENU) ||
640 (temp->flags&MENU_EXITAFTERTHISMENU)) 652 (temp->flags&MENU_EXITAFTERTHISMENU))
641 { 653 {
642 init_menu_lists(menu, &lists, selected, true, vps); 654 /* Reload menu but don't run the calback again FS#8117 */
655 init_menu_lists(menu, &lists, selected, false, vps);
643 } 656 }
644 if (temp->flags&MENU_FUNC_CHECK_RETVAL) 657 if (temp->flags&MENU_FUNC_CHECK_RETVAL)
645 { 658 {
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 @@
24#include "config.h" 24#include "config.h"
25#include "lang.h" 25#include "lang.h"
26#include "menu.h" 26#include "menu.h"
27#include "action.h"
27#include "settings.h" 28#include "settings.h"
28#include "rbpaths.h" 29#include "rbpaths.h"
29#include "root_menu.h" 30#include "root_menu.h"
30#include "tree.h" 31#include "tree.h"
31 32static int reenter = 0;
32 33
33enum { 34enum {
34 GAMES, 35 GAMES,
@@ -53,13 +54,36 @@ static int plugins_menu(void* param)
53 54
54 browse_context_init(&browse, SHOW_PLUGINS, 0, str(items[item].id), 55 browse_context_init(&browse, SHOW_PLUGINS, 0, str(items[item].id),
55 Icon_Plugin, items[item].path, NULL); 56 Icon_Plugin, items[item].path, NULL);
56 57
57 ret = rockbox_browse(&browse); 58 ret = rockbox_browse(&browse);
59
58 if (ret == GO_TO_PREVIOUS) 60 if (ret == GO_TO_PREVIOUS)
59 return 0; 61 return 0;
62 if (ret == GO_TO_PLUGIN)
63 reenter = 1;
60 return ret; 64 return ret;
61} 65}
62 66
67static int menu_callback(int action,
68 const struct menu_item_ex *this_item,
69 struct gui_synclist *this_list)
70{
71 (void)this_item;
72 static int selected = 0;
73
74 if (action == ACTION_ENTER_MENUITEM)
75 {
76 this_list->selected_item = selected;
77 if (reenter-- > 0)
78 action = ACTION_STD_OK;
79 }
80 else if (action == ACTION_STD_OK)
81 {
82 selected = gui_synclist_get_sel_pos(this_list);
83 }
84 return action;
85}
86
63#define ITEM_FLAG (MENU_FUNC_USEPARAM|MENU_FUNC_CHECK_RETVAL) 87#define ITEM_FLAG (MENU_FUNC_USEPARAM|MENU_FUNC_CHECK_RETVAL)
64 88
65MENUITEM_FUNCTION(games_item, ITEM_FLAG, ID2P(LANG_PLUGIN_GAMES), 89MENUITEM_FUNCTION(games_item, ITEM_FLAG, ID2P(LANG_PLUGIN_GAMES),
@@ -69,6 +93,6 @@ MENUITEM_FUNCTION(apps_item, ITEM_FLAG, ID2P(LANG_PLUGIN_APPS),
69MENUITEM_FUNCTION(demos_item, ITEM_FLAG, ID2P(LANG_PLUGIN_DEMOS), 93MENUITEM_FUNCTION(demos_item, ITEM_FLAG, ID2P(LANG_PLUGIN_DEMOS),
70 plugins_menu, (void*)DEMOS, NULL, Icon_Folder); 94 plugins_menu, (void*)DEMOS, NULL, Icon_Folder);
71 95
72MAKE_MENU(plugin_menu, ID2P(LANG_PLUGINS), NULL, 96MAKE_MENU(plugin_menu, ID2P(LANG_PLUGINS), &menu_callback,
73 Icon_Plugin, 97 Icon_Plugin,
74 &games_item, &apps_item, &demos_item); 98 &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,
634 } 634 }
635 return action; 635 return action;
636} 636}
637
637static int get_selection(int last_screen) 638static int get_selection(int last_screen)
638{ 639{
639 int i; 640 int i;
@@ -683,6 +684,7 @@ static inline int load_screen(int screen)
683 last_screen = old_previous; 684 last_screen = old_previous;
684 return ret_val; 685 return ret_val;
685} 686}
687
686static int load_context_screen(int selection) 688static int load_context_screen(int selection)
687{ 689{
688 const struct menu_item_ex *context_menu = NULL; 690 const struct menu_item_ex *context_menu = NULL;
@@ -709,13 +711,12 @@ static int load_plugin_screen(char *key)
709{ 711{
710 int ret_val; 712 int ret_val;
711 int old_previous = last_screen; 713 int old_previous = last_screen;
714 int old_global = global_status.last_screen;
712 last_screen = next_screen; 715 last_screen = next_screen;
713 global_status.last_screen = (char)next_screen; 716 global_status.last_screen = (char)next_screen;
714 status_save(); 717 status_save();
715 718
716
717 int opret = open_plugin_get_entry(key, &open_plugin_entry); 719 int opret = open_plugin_get_entry(key, &open_plugin_entry);
718 bool flush = (opret == OPEN_PLUGIN_NEEDS_FLUSHED);
719 char *path = open_plugin_entry.path; 720 char *path = open_plugin_entry.path;
720 char *param = open_plugin_entry.param; 721 char *param = open_plugin_entry.param;
721 if (param[0] == '\0') 722 if (param[0] == '\0')
@@ -723,6 +724,9 @@ static int load_plugin_screen(char *key)
723 724
724 switch (plugin_load(path, param)) 725 switch (plugin_load(path, param))
725 { 726 {
727 case PLUGIN_USB_CONNECTED:
728 ret_val = GO_TO_ROOT;
729 break;
726 case PLUGIN_GOTO_WPS: 730 case PLUGIN_GOTO_WPS:
727 ret_val = GO_TO_WPS; 731 ret_val = GO_TO_WPS;
728 break; 732 break;
@@ -730,18 +734,30 @@ static int load_plugin_screen(char *key)
730 ret_val = GO_TO_PLUGIN; 734 ret_val = GO_TO_PLUGIN;
731 break; 735 break;
732 case PLUGIN_OK: 736 case PLUGIN_OK:
733 ret_val = audio_status() ? GO_TO_PREVIOUS : GO_TO_ROOT; 737 /* Prevents infinite loop with WPS & Plugins*/
734 break; 738 if (old_global == GO_TO_WPS && !audio_status())
739 {
740 ret_val = GO_TO_ROOT;
741 break;
742 }
743 /*fallthrough*/
735 default: 744 default:
736 ret_val = GO_TO_PREVIOUS; 745 ret_val = GO_TO_PREVIOUS;
746 last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous;
737 break; 747 break;
738 }
739 748
740 if (!flush && ret_val != GO_TO_PLUGIN) 749 }
741 open_plugin_add_path(NULL, NULL, NULL);
742 750
743 if (ret_val == GO_TO_PREVIOUS) 751 if (ret_val != GO_TO_PLUGIN)
744 last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous; 752 {
753 if (opret != OPEN_PLUGIN_NEEDS_FLUSHED || last_screen != GO_TO_WPS)
754 {
755 /* Keep the entry in case of GO_TO_PREVIOUS */
756 open_plugin_entry.hash = 0; /*remove hash -- prevents flush to disk */
757 open_plugin_entry.lang_id = LANG_PREVIOUS_SCREEN;
758 /*open_plugin_add_path(NULL, NULL, NULL);// clear entry */
759 }
760 }
745 return ret_val; 761 return ret_val;
746} 762}
747 763
@@ -858,8 +874,12 @@ void root_menu(void)
858#endif /* With !CONFIG_TUNER previous_music is always GO_TO_WPS */ 874#endif /* With !CONFIG_TUNER previous_music is always GO_TO_WPS */
859 875
860 case GO_TO_PREVIOUS: 876 case GO_TO_PREVIOUS:
877 {
861 next_screen = last_screen; 878 next_screen = last_screen;
879 if (last_screen == GO_TO_PLUGIN)/* for WPS */
880 last_screen = GO_TO_PREVIOUS;
862 break; 881 break;
882 }
863 883
864 case GO_TO_PREVIOUS_BROWSER: 884 case GO_TO_PREVIOUS_BROWSER:
865 next_screen = previous_browser; 885 next_screen = previous_browser;
@@ -874,7 +894,8 @@ void root_menu(void)
874 case GO_TO_PLUGIN: 894 case GO_TO_PLUGIN:
875 { 895 {
876 char *key; 896 char *key;
877 if (global_status.last_screen == GO_TO_SHORTCUTMENU) 897 if (global_status.last_screen == GO_TO_SHORTCUTMENU &&
898 last_screen != GO_TO_ROOT)
878 { 899 {
879 shortcut_origin = last_screen; 900 shortcut_origin = last_screen;
880 key = ID2P(LANG_SHORTCUTS); 901 key = ID2P(LANG_SHORTCUTS);
@@ -892,6 +913,9 @@ void root_menu(void)
892 case GO_TO_SHORTCUTMENU: 913 case GO_TO_SHORTCUTMENU:
893 key = ID2P(LANG_SHORTCUTS); 914 key = ID2P(LANG_SHORTCUTS);
894 break; 915 break;
916 case GO_TO_PREVIOUS:
917 key = ID2P(LANG_PREVIOUS_SCREEN);
918 break;
895 default: 919 default:
896 key = ID2P(LANG_OPEN_PLUGIN); 920 key = ID2P(LANG_OPEN_PLUGIN);
897 break; 921 break;
@@ -900,15 +924,23 @@ void root_menu(void)
900 924
901 next_screen = load_plugin_screen(key); 925 next_screen = load_plugin_screen(key);
902 926
903 /* shortcuts may take several trips through the GO_TO_PLUGIN case 927 if (next_screen == GO_TO_PREVIOUS)
904 make sure we preserve and restore the origin */
905 if (next_screen == GO_TO_PREVIOUS && shortcut_origin != GO_TO_ROOT)
906 { 928 {
907 if (shortcut_origin != GO_TO_WPS) 929 /* shortcuts may take several trips through the GO_TO_PLUGIN
908 next_screen = shortcut_origin; 930 case make sure we preserve and restore the origin */
909 shortcut_origin = GO_TO_ROOT; 931 if (shortcut_origin != GO_TO_ROOT)
932 {
933 if (shortcut_origin != GO_TO_WPS)
934 next_screen = shortcut_origin;
935 shortcut_origin = GO_TO_ROOT;
936 }
937 /* skip GO_TO_PREVIOUS */
938 if (last_screen == GO_TO_BROWSEPLUGINS)
939 {
940 next_screen = last_screen;
941 last_screen = GO_TO_PLUGIN;
942 }
910 } 943 }
911
912 previous_browser = (next_screen != GO_TO_WPS) ? GO_TO_FILEBROWSER : GO_TO_PLUGIN; 944 previous_browser = (next_screen != GO_TO_WPS) ? GO_TO_FILEBROWSER : GO_TO_PLUGIN;
913 break; 945 break;
914 } 946 }
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)
967 if (*tc.dirfilter >= NUM_FILTER_MODES) 967 if (*tc.dirfilter >= NUM_FILTER_MODES)
968 { 968 {
969 int last_context; 969 int last_context;
970 /* don't reset if its the same browse already loaded */
971 if (tc.browse != browse ||
972 !(tc.currdir[1] && strcmp(tc.currdir, browse->root) == 0))
973 {
974 tc.browse = browse;
975 tc.selected_item = 0;
976 tc.dirlevel = 0;
977
978 strlcpy(tc.currdir, browse->root, sizeof(tc.currdir));
979 }
970 980
971 tc.browse = browse;
972 tc.selected_item = 0;
973 tc.dirlevel = 0;
974 strlcpy(tc.currdir, browse->root, sizeof(tc.currdir));
975 start_wps = false; 981 start_wps = false;
976 last_context = curr_context; 982 last_context = curr_context;
977 983