FS#11777: enhancement for rockbox_browse()
* Add struct browse_context to be passed to rockbox_browse. * Show proper title when selecting e.g. .wps file or .sbs file from the settings menu. * Add select only mode to rockbox_browse(). when a file is selected, it's path is stored to buffer and the browser exits without 'playing' the file. this will allow to use the browser in more places to select file including plugins. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28831 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
fbd75fcc86
commit
08af5d8404
8 changed files with 196 additions and 97 deletions
|
@ -269,12 +269,16 @@ int ft_load(struct tree_context* c, const char* tempdir)
|
|||
{
|
||||
int i;
|
||||
int name_buffer_used = 0;
|
||||
bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
|
||||
DIR *dir;
|
||||
|
||||
if (tempdir)
|
||||
dir = opendir(tempdir);
|
||||
else
|
||||
{
|
||||
dir = opendir(c->currdir);
|
||||
callback_show_item = c->browse? c->browse->callback_show_item: NULL;
|
||||
}
|
||||
if(!dir)
|
||||
return -1; /* not a directory */
|
||||
|
||||
|
@ -351,7 +355,8 @@ int ft_load(struct tree_context* c, const char* tempdir)
|
|||
(*c->dirfilter == SHOW_LNG && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LNG) ||
|
||||
(*c->dirfilter == SHOW_MOD && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_MOD) ||
|
||||
(*c->dirfilter == SHOW_PLUGINS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_ROCK &&
|
||||
(dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LUA))
|
||||
(dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LUA) ||
|
||||
(callback_show_item && !callback_show_item(entry->d_name, dptr->attr, c)))
|
||||
{
|
||||
i--;
|
||||
continue;
|
||||
|
|
|
@ -246,9 +246,85 @@ static struct browse_folder_info themes = {THEME_DIR, SHOW_CFG};
|
|||
|
||||
int browse_folder(void *param)
|
||||
{
|
||||
const char *ext, *setting;
|
||||
int lang_id = -1;
|
||||
char selected[MAX_FILENAME+10];
|
||||
const struct browse_folder_info *info =
|
||||
(const struct browse_folder_info*)param;
|
||||
return rockbox_browse(info->dir, info->show_options);
|
||||
struct browse_context browse;
|
||||
browse_context_init(&browse, info->show_options, 0,
|
||||
NULL, NOICON, info->dir, NULL);
|
||||
|
||||
/* if we are in a special settings folder, center the current setting */
|
||||
switch(info->show_options)
|
||||
{
|
||||
case SHOW_LNG:
|
||||
ext = "lng";
|
||||
if (global_settings.lang_file[0])
|
||||
setting = global_settings.lang_file;
|
||||
else
|
||||
setting = "english";
|
||||
lang_id = LANG_LANGUAGE;
|
||||
break;
|
||||
case SHOW_WPS:
|
||||
ext = "wps";
|
||||
setting = global_settings.wps_file;
|
||||
lang_id = LANG_WHILE_PLAYING;
|
||||
break;
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
case SHOW_FONT:
|
||||
ext = "fnt";
|
||||
setting = global_settings.font_file;
|
||||
lang_id = LANG_CUSTOM_FONT;
|
||||
break;
|
||||
case SHOW_SBS:
|
||||
ext = "sbs";
|
||||
setting = global_settings.sbs_file;
|
||||
lang_id = LANG_BASE_SKIN;
|
||||
break;
|
||||
#if CONFIG_TUNER
|
||||
case SHOW_FMS:
|
||||
ext = "fms";
|
||||
setting = global_settings.fms_file;
|
||||
lang_id = LANG_RADIOSCREEN;
|
||||
break;
|
||||
#endif /* CONFIG_TUNER */
|
||||
#endif
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
case SHOW_RWPS:
|
||||
ext = "rwps";
|
||||
setting = global_settings.rwps_file;
|
||||
lang_id = LANG_REMOTE_WHILE_PLAYING;
|
||||
break;
|
||||
case SHOW_RSBS:
|
||||
ext = "rsbs";
|
||||
setting = global_settings.rsbs_file;
|
||||
lang_id = LANG_REMOTE_BASE_SKIN;
|
||||
break;
|
||||
#if CONFIG_TUNER
|
||||
case SHOW_RFMS:
|
||||
ext = "rfms";
|
||||
setting = global_settings.rfms_file;
|
||||
lang_id = LANG_REMOTE_RADIOSCREEN;
|
||||
break;
|
||||
#endif /* CONFIG_TUNER */
|
||||
#endif
|
||||
default:
|
||||
ext = setting = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we've found a file to center on, do it */
|
||||
if (setting)
|
||||
{
|
||||
/* if setting != NULL, ext is initialized */
|
||||
snprintf(selected, sizeof(selected), "%s.%s", setting, ext);
|
||||
browse.selected = selected;
|
||||
browse.icon = Icon_Questionmark;
|
||||
browse.title = str(lang_id);
|
||||
}
|
||||
|
||||
return rockbox_browse(&browse);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
|
|
@ -731,6 +731,7 @@ static bool browse( char *dst, int dst_size, const char *start )
|
|||
}
|
||||
rb->strcpy( a+1, dc[tree->selected_item].name );
|
||||
tree->dirfilter = &dirfilter;
|
||||
tree->browse = NULL;
|
||||
while( 1 )
|
||||
{
|
||||
if( reload )
|
||||
|
@ -880,6 +881,7 @@ static bool browse_fonts( char *dst, int dst_size )
|
|||
}
|
||||
rb->strcpy( a+1, dc[tree->selected_item].name );
|
||||
tree->dirfilter = &dirfilter;
|
||||
tree->browse = NULL;
|
||||
rb->strcpy( bbuf, FONT_DIR "/" );
|
||||
rb->set_current_file( bbuf );
|
||||
|
||||
|
|
|
@ -234,6 +234,7 @@ static bool tv_font_setting(void)
|
|||
rb->strlcat(backup.currdir, "/", MAX_PATH);
|
||||
rb->strlcat(backup.currdir, dc[tree->selected_item].name, MAX_PATH);
|
||||
tree->dirfilter = &dirfilter;
|
||||
tree->browse = NULL;
|
||||
rb->snprintf(font_path, MAX_PATH, "%s/", FONT_DIR);
|
||||
rb->set_current_file(font_path);
|
||||
count = tree->filesindir;
|
||||
|
|
|
@ -353,7 +353,13 @@ static int radio_delete_preset(void)
|
|||
|
||||
int preset_list_load(void)
|
||||
{
|
||||
return !rockbox_browse(FMPRESET_PATH, SHOW_FMR);
|
||||
char selected[MAX_PATH];
|
||||
struct browse_context browse;
|
||||
snprintf(selected, sizeof(selected), "%s.%s", global_settings.fmr_file, "fmr");
|
||||
browse_context_init(&browse, SHOW_FMR, 0,
|
||||
str(LANG_FM_PRESET_LOAD), NOICON,
|
||||
FMPRESET_PATH, selected);
|
||||
return !rockbox_browse(&browse);
|
||||
}
|
||||
|
||||
int preset_list_save(void)
|
||||
|
|
|
@ -96,6 +96,7 @@ static int browser(void* param)
|
|||
#ifdef HAVE_TAGCACHE
|
||||
struct tree_context* tc = tree_get_context();
|
||||
#endif
|
||||
struct browse_context browse;
|
||||
int filter = SHOW_SUPPORTED;
|
||||
char folder[MAX_PATH] = "/";
|
||||
/* stuff needed to remember position in file browser */
|
||||
|
@ -104,7 +105,7 @@ static int browser(void* param)
|
|||
#ifdef HAVE_TAGCACHE
|
||||
static int last_db_dirlevel = 0, last_db_selection = 0;
|
||||
#endif
|
||||
|
||||
|
||||
switch ((intptr_t)param)
|
||||
{
|
||||
case GO_TO_FILEBROWSER:
|
||||
|
@ -247,12 +248,10 @@ static int browser(void* param)
|
|||
tc->selected_item = last_db_selection;
|
||||
break;
|
||||
#endif
|
||||
case GO_TO_BROWSEPLUGINS:
|
||||
filter = SHOW_PLUGINS;
|
||||
strlcpy(folder, PLUGIN_DIR, MAX_PATH);
|
||||
break;
|
||||
}
|
||||
ret_val = rockbox_browse(folder, filter);
|
||||
|
||||
browse_context_init(&browse, filter, 0, NULL, NOICON, folder, NULL);
|
||||
ret_val = rockbox_browse(&browse);
|
||||
switch ((intptr_t)param)
|
||||
{
|
||||
case GO_TO_FILEBROWSER:
|
||||
|
@ -352,8 +351,11 @@ static int plugins_menu(void* param)
|
|||
ID2P(LANG_PLUGIN_GAMES),
|
||||
ID2P(LANG_PLUGIN_APPS), ID2P(LANG_PLUGIN_DEMOS));
|
||||
const char *folder;
|
||||
struct browse_context browse;
|
||||
char *title;
|
||||
int retval = GO_TO_PREVIOUS;
|
||||
int selection = 0, current = 0;
|
||||
|
||||
while (retval == GO_TO_PREVIOUS)
|
||||
{
|
||||
selection = do_menu(&plugins_menu_items, ¤t, NULL, false);
|
||||
|
@ -361,17 +363,22 @@ static int plugins_menu(void* param)
|
|||
{
|
||||
case 0:
|
||||
folder = PLUGIN_GAMES_DIR;
|
||||
title = str(LANG_PLUGIN_GAMES);
|
||||
break;
|
||||
case 1:
|
||||
folder = PLUGIN_APPS_DIR;
|
||||
title = str(LANG_PLUGIN_APPS);
|
||||
break;
|
||||
case 2:
|
||||
folder = PLUGIN_DEMOS_DIR;
|
||||
title = str(LANG_PLUGIN_DEMOS);
|
||||
break;
|
||||
default:
|
||||
return selection;
|
||||
}
|
||||
retval = rockbox_browse(folder, SHOW_PLUGINS);
|
||||
browse_context_init(&browse, SHOW_PLUGINS, 0,
|
||||
title, Icon_Plugin, folder, NULL);
|
||||
retval = rockbox_browse(&browse);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
|
148
apps/tree.c
148
apps/tree.c
|
@ -417,18 +417,12 @@ static int update_dir(void)
|
|||
#endif
|
||||
{
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
if (global_settings.show_path_in_browser &&
|
||||
*(tc.dirfilter) == SHOW_PLUGINS)
|
||||
if (tc.browse && tc.browse->title)
|
||||
{
|
||||
char *title;
|
||||
if (!strcmp(tc.currdir, PLUGIN_GAMES_DIR))
|
||||
title = str(LANG_PLUGIN_GAMES);
|
||||
else if (!strcmp(tc.currdir, PLUGIN_APPS_DIR))
|
||||
title = str(LANG_PLUGIN_APPS);
|
||||
else if (!strcmp(tc.currdir, PLUGIN_DEMOS_DIR))
|
||||
title = str(LANG_PLUGIN_DEMOS);
|
||||
else title = str(LANG_PLUGINS);
|
||||
gui_synclist_set_title(&tree_lists, title, Icon_Plugin);
|
||||
int icon = tc.browse->icon;
|
||||
if (icon == NOICON)
|
||||
icon = filetype_get_icon(ATTR_DIRECTORY);
|
||||
gui_synclist_set_title(&tree_lists, tc.browse->title, icon);
|
||||
}
|
||||
else if (global_settings.show_path_in_browser == SHOW_PATH_FULL)
|
||||
{
|
||||
|
@ -616,7 +610,7 @@ void set_current_file(const char *path)
|
|||
|
||||
|
||||
/* main loop, handles key events */
|
||||
static int dirbrowse()
|
||||
static int dirbrowse(void)
|
||||
{
|
||||
int numentries=0;
|
||||
char buf[MAX_PATH];
|
||||
|
@ -653,7 +647,7 @@ static int dirbrowse()
|
|||
if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0)
|
||||
{
|
||||
splash(HZ*2, ID2P(LANG_NO_FILES));
|
||||
return GO_TO_PREVIOUS; /* No files found for rockbox_browser() */
|
||||
return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */
|
||||
}
|
||||
|
||||
gui_synclist_draw(&tree_lists);
|
||||
|
@ -683,6 +677,14 @@ static int dirbrowse()
|
|||
if ( numentries == 0 )
|
||||
break;
|
||||
|
||||
if ((tc.browse->flags & BROWSE_SELECTONLY) &&
|
||||
!(dircache[tc.selected_item].attr & ATTR_DIRECTORY))
|
||||
{
|
||||
tc.browse->flags |= BROWSE_SELECTED;
|
||||
get_current_file(tc.browse->buf, tc.browse->bufsize);
|
||||
return GO_TO_PREVIOUS;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TAGCACHE
|
||||
switch (id3db?tagtree_enter(&tc):ft_enter(&tc))
|
||||
#else
|
||||
|
@ -781,6 +783,11 @@ static int dirbrowse()
|
|||
int onplay_result;
|
||||
int attr = 0;
|
||||
|
||||
/* no context menu while in select only mode
|
||||
to prevent recursive call */
|
||||
if ((tc.browse->flags & BROWSE_SELECTONLY))
|
||||
break;
|
||||
|
||||
if(!numentries)
|
||||
onplay_result = onplay(NULL, 0, curr_context, hotkey);
|
||||
else {
|
||||
|
@ -924,108 +931,77 @@ bool create_playlist(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
int rockbox_browse(const char *root, int dirfilter)
|
||||
void browse_context_init(struct browse_context *browse,
|
||||
int dirfilter, unsigned flags,
|
||||
char *title, enum themable_icons icon,
|
||||
const char *root, const char *selected)
|
||||
{
|
||||
browse->dirfilter = dirfilter;
|
||||
browse->flags = flags;
|
||||
browse->callback_show_item = NULL;
|
||||
browse->title = title;
|
||||
browse->icon = icon;
|
||||
browse->root = root;
|
||||
browse->selected = selected;
|
||||
browse->buf = NULL;
|
||||
browse->bufsize = 0;
|
||||
}
|
||||
|
||||
#define NUM_TC_BACKUP 3
|
||||
static struct tree_context backups[NUM_TC_BACKUP];
|
||||
/* do not make backup if it is not recursive call */
|
||||
static int backup_count = -1;
|
||||
int rockbox_browse(struct browse_context *browse)
|
||||
{
|
||||
static char current[MAX_PATH];
|
||||
int ret_val = 0;
|
||||
int *last_filter = tc.dirfilter;
|
||||
int dirfilter = browse->dirfilter;
|
||||
|
||||
if (backup_count >= NUM_TC_BACKUP)
|
||||
return GO_TO_PREVIOUS;
|
||||
if (backup_count >= 0)
|
||||
backups[backup_count] = tc;
|
||||
backup_count++;
|
||||
|
||||
tc.dirfilter = &dirfilter;
|
||||
tc.sort_dir = global_settings.sort_dir;
|
||||
|
||||
|
||||
reload_dir = true;
|
||||
if (dirfilter >= NUM_FILTER_MODES)
|
||||
if (*tc.dirfilter >= NUM_FILTER_MODES)
|
||||
{
|
||||
static struct tree_context backup;
|
||||
int last_context;
|
||||
const char *ext, *setting;
|
||||
|
||||
backup = tc;
|
||||
|
||||
tc.browse = browse;
|
||||
tc.selected_item = 0;
|
||||
tc.dirlevel = 0;
|
||||
memcpy(tc.currdir, root, sizeof(tc.currdir));
|
||||
strlcpy(tc.currdir, browse->root, sizeof(tc.currdir));
|
||||
start_wps = false;
|
||||
last_context = curr_context;
|
||||
|
||||
/* if we are in a special settings folder, center the current setting */
|
||||
switch(dirfilter)
|
||||
if (browse->selected)
|
||||
{
|
||||
case SHOW_LNG:
|
||||
ext = "lng";
|
||||
if (global_settings.lang_file[0])
|
||||
setting = global_settings.lang_file;
|
||||
else
|
||||
setting = "english";
|
||||
break;
|
||||
case SHOW_WPS:
|
||||
ext = "wps";
|
||||
setting = global_settings.wps_file;
|
||||
break;
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
case SHOW_RWPS:
|
||||
ext = "rwps";
|
||||
setting = global_settings.rwps_file;
|
||||
break;
|
||||
case SHOW_RSBS:
|
||||
ext = "rsbs";
|
||||
setting = global_settings.rsbs_file;
|
||||
break;
|
||||
#if CONFIG_TUNER
|
||||
case SHOW_RFMS:
|
||||
ext = "rfms";
|
||||
setting = global_settings.rfms_file;
|
||||
break;
|
||||
#endif /* CONFIG_TUNER */
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
case SHOW_FONT:
|
||||
ext = "fnt";
|
||||
setting = global_settings.font_file;
|
||||
break;
|
||||
case SHOW_SBS:
|
||||
ext = "sbs";
|
||||
setting = global_settings.sbs_file;
|
||||
break;
|
||||
#if CONFIG_TUNER
|
||||
case SHOW_FMS:
|
||||
ext = "fms";
|
||||
setting = global_settings.fms_file;
|
||||
break;
|
||||
#endif /* CONFIG_TUNER */
|
||||
#endif
|
||||
#if CONFIG_TUNER
|
||||
case SHOW_FMR:
|
||||
ext = "fmr";
|
||||
setting = global_settings.fmr_file;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ext = setting = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we've found a file to center on, do it */
|
||||
if (setting)
|
||||
{
|
||||
/* if setting != NULL, ext is initialized */
|
||||
snprintf(current, sizeof(current), "%s/%s.%s", root, setting, ext);
|
||||
snprintf(current, sizeof(current), "%s/%s",
|
||||
browse->root, browse->selected);
|
||||
set_current_file(current);
|
||||
/* set_current_file changes dirlevel, change it back */
|
||||
tc.dirlevel = 0;
|
||||
}
|
||||
|
||||
ret_val = dirbrowse();
|
||||
tc = backup;
|
||||
curr_context = last_context;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dirfilter != SHOW_ID3DB)
|
||||
tc.dirfilter = &global_settings.dirfilter;
|
||||
strcpy(current,root);
|
||||
tc.browse = browse;
|
||||
strcpy(current, browse->root);
|
||||
set_current_file(current);
|
||||
ret_val = dirbrowse();
|
||||
}
|
||||
tc.dirfilter = last_filter;
|
||||
backup_count--;
|
||||
if (backup_count >= 0)
|
||||
tc = backups[backup_count];
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
|
28
apps/tree.h
28
apps/tree.h
|
@ -24,6 +24,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <applimits.h>
|
||||
#include <file.h>
|
||||
#include "icon.h"
|
||||
|
||||
struct entry {
|
||||
short attr; /* FAT attributes + file type flags */
|
||||
|
@ -32,6 +33,26 @@ struct entry {
|
|||
};
|
||||
|
||||
|
||||
#define BROWSE_SELECTONLY 0x0001 /* exit on selecting a file */
|
||||
#define BROWSE_SELECTED 0x0100 /* this bit is set if user selected item */
|
||||
|
||||
struct tree_context;
|
||||
|
||||
struct browse_context {
|
||||
int dirfilter;
|
||||
unsigned flags; /* ored BROWSE_* */
|
||||
bool (*callback_show_item)(char *name, int attr, struct tree_context *tc);
|
||||
/* callback function to determine to show/hide
|
||||
the item for custom browser */
|
||||
char *title; /* title of the browser. if set to NULL,
|
||||
directory name is used. */
|
||||
enum themable_icons icon; /* title icon */
|
||||
const char *root; /* full path of start directory */
|
||||
const char *selected; /* name of selected file in the root */
|
||||
char *buf; /* buffer to store selected file */
|
||||
size_t bufsize; /* size of the buffer */
|
||||
};
|
||||
|
||||
/* browser context for file or db */
|
||||
struct tree_context {
|
||||
/* The directory we are browsing */
|
||||
|
@ -68,6 +89,7 @@ struct tree_context {
|
|||
int dentry_size;
|
||||
bool dirfull;
|
||||
int sort_dir; /* directory sort order */
|
||||
struct browse_context *browse;
|
||||
};
|
||||
|
||||
void tree_drawlists(void);
|
||||
|
@ -76,7 +98,11 @@ void tree_gui_init(void) INIT_ATTR;
|
|||
char* get_current_file(char* buffer, size_t buffer_len);
|
||||
void set_dirfilter(int l_dirfilter);
|
||||
void set_current_file(const char *path);
|
||||
int rockbox_browse(const char *root, int dirfilter);
|
||||
void browse_context_init(struct browse_context *browse,
|
||||
int dirfilter, unsigned flags,
|
||||
char *title, enum themable_icons icon,
|
||||
const char *root, const char *selected);
|
||||
int rockbox_browse(struct browse_context *browse);
|
||||
bool create_playlist(void);
|
||||
void resume_directory(const char *dir);
|
||||
#ifdef WIN32
|
||||
|
|
Loading…
Reference in a new issue