Merge branch 'master' into varvara

This commit is contained in:
Nico 2021-10-30 19:09:37 +01:00
commit 90be393276
5 changed files with 181 additions and 95 deletions

View File

@ -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,35 +176,29 @@ 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;
}
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;
@ -253,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)
@ -368,12 +382,16 @@ 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;
int start_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,16 +404,17 @@ 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;
/* 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 */
@ -403,42 +422,36 @@ 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));
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 */
/* 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 +518,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 +526,10 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
else
#endif
menu = &notquickscreen_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 +571,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 +584,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 +606,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 +633,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);
@ -634,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)
{
@ -661,8 +679,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 +749,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 +766,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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
@ -962,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;