PictureFlow: Utilize "Current Playlist" menu (+ GS fixes)
When appending tracks, they were always inserted last. You can now choose from the usual options offered by the "Current Playlst" context menu to queue or to insert tracks at the requested position. The splash after appending that forced you to wait for 2s has been eliminated. Also fixes crashes on targets that use the grey_core lib if a splash showed up when playback was started, e.g. LANG_PLAYLIST_CONTROL_ACCESS_ERROR, or when PictureFlow quit. Change-Id: I661c59057b5315ba793ee1674f7a2ea1ffd7968d
This commit is contained in:
parent
bfe3dac3ba
commit
e3b8b7fa80
7 changed files with 148 additions and 104 deletions
|
@ -69,6 +69,7 @@ static const char *selected_file = NULL;
|
||||||
static char selected_file_path[MAX_PATH];
|
static char selected_file_path[MAX_PATH];
|
||||||
static int selected_file_attr = 0;
|
static int selected_file_attr = 0;
|
||||||
static int onplay_result = ONPLAY_OK;
|
static int onplay_result = ONPLAY_OK;
|
||||||
|
static bool (*ctx_playlist_insert)(int position, bool queue, bool create_new);
|
||||||
extern struct menu_item_ex file_menu; /* settings_menu.c */
|
extern struct menu_item_ex file_menu; /* settings_menu.c */
|
||||||
|
|
||||||
/* redefine MAKE_MENU so the MENU_EXITAFTERTHISMENU flag can be added easily */
|
/* redefine MAKE_MENU so the MENU_EXITAFTERTHISMENU flag can be added easily */
|
||||||
|
@ -474,7 +475,7 @@ MAKE_ONPLAYMENU( wps_playlist_menu, ID2P(LANG_PLAYLIST),
|
||||||
&playlist_save_item, &reshuffle_item, &playing_time_item
|
&playlist_save_item, &reshuffle_item, &playing_time_item
|
||||||
);
|
);
|
||||||
|
|
||||||
/* CONTEXT_[TREE|ID3DB] playlist options */
|
/* CONTEXT_[TREE|ID3DB|STD] playlist options */
|
||||||
static bool add_to_playlist(int position, bool queue)
|
static bool add_to_playlist(int position, bool queue)
|
||||||
{
|
{
|
||||||
bool new_playlist = false;
|
bool new_playlist = false;
|
||||||
|
@ -510,6 +511,10 @@ static bool add_to_playlist(int position, bool queue)
|
||||||
{
|
{
|
||||||
tagtree_insert_selection_playlist(position, queue);
|
tagtree_insert_selection_playlist(position, queue);
|
||||||
}
|
}
|
||||||
|
else if (context == CONTEXT_STD && ctx_playlist_insert != NULL)
|
||||||
|
{
|
||||||
|
ctx_playlist_insert(position, queue, false);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -774,9 +779,10 @@ static int treeplaylist_callback(int action,
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onplay_show_playlist_menu(char* path)
|
void onplay_show_playlist_menu(const char* path, void (*playlist_insert_cb))
|
||||||
{
|
{
|
||||||
context = CONTEXT_STD;
|
context = CONTEXT_STD;
|
||||||
|
ctx_playlist_insert = playlist_insert_cb;
|
||||||
selected_file = path;
|
selected_file = path;
|
||||||
if (dir_exists(path))
|
if (dir_exists(path))
|
||||||
selected_file_attr = ATTR_DIRECTORY;
|
selected_file_attr = ATTR_DIRECTORY;
|
||||||
|
@ -1939,6 +1945,7 @@ int onplay(char* file, int attr, int from, bool hotkey)
|
||||||
const struct menu_item_ex *menu;
|
const struct menu_item_ex *menu;
|
||||||
onplay_result = ONPLAY_OK;
|
onplay_result = ONPLAY_OK;
|
||||||
context = from;
|
context = from;
|
||||||
|
ctx_playlist_insert = NULL;
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
selected_file = NULL;
|
selected_file = NULL;
|
||||||
else
|
else
|
||||||
|
|
|
@ -51,6 +51,6 @@ enum hotkey_action {
|
||||||
|
|
||||||
/* needed for the playlist viewer.. eventually clean this up */
|
/* needed for the playlist viewer.. eventually clean this up */
|
||||||
void onplay_show_playlist_cat_menu(char* track_name);
|
void onplay_show_playlist_cat_menu(char* track_name);
|
||||||
void onplay_show_playlist_menu(char* path);
|
void onplay_show_playlist_menu(const char* path, void (*playlist_insert_cb));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -535,7 +535,7 @@ static int onplay_menu(int index)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
/* playlist */
|
/* playlist */
|
||||||
onplay_show_playlist_menu(current_track->name);
|
onplay_show_playlist_menu(current_track->name, NULL);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
@ -805,6 +805,7 @@ static const struct plugin_api rockbox_api = {
|
||||||
warn_on_pl_erase,
|
warn_on_pl_erase,
|
||||||
playlist_insert_playlist,
|
playlist_insert_playlist,
|
||||||
battery_current,
|
battery_current,
|
||||||
|
onplay_show_playlist_menu,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int plugin_buffer_handle;
|
static int plugin_buffer_handle;
|
||||||
|
|
|
@ -110,6 +110,7 @@ int plugin_open(const char *plugin, const char *parameter);
|
||||||
#include "rbpaths.h"
|
#include "rbpaths.h"
|
||||||
#include "core_alloc.h"
|
#include "core_alloc.h"
|
||||||
#include "screen_access.h"
|
#include "screen_access.h"
|
||||||
|
#include "onplay.h"
|
||||||
|
|
||||||
#ifdef HAVE_ALBUMART
|
#ifdef HAVE_ALBUMART
|
||||||
#include "albumart.h"
|
#include "albumart.h"
|
||||||
|
@ -154,7 +155,7 @@ int plugin_open(const char *plugin, const char *parameter);
|
||||||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||||
|
|
||||||
/* increase this every time the api struct changes */
|
/* increase this every time the api struct changes */
|
||||||
#define PLUGIN_API_VERSION 247
|
#define PLUGIN_API_VERSION 248
|
||||||
|
|
||||||
/* update this to latest version if a change to the api struct breaks
|
/* update this to latest version if a change to the api struct breaks
|
||||||
backwards compatibility (and please take the opportunity to sort in any
|
backwards compatibility (and please take the opportunity to sort in any
|
||||||
|
@ -931,6 +932,7 @@ struct plugin_api {
|
||||||
int (*playlist_insert_playlist)(struct playlist_info* playlist,
|
int (*playlist_insert_playlist)(struct playlist_info* playlist,
|
||||||
const char *filename, int position, bool queue);
|
const char *filename, int position, bool queue);
|
||||||
int (*battery_current)(void);
|
int (*battery_current)(void);
|
||||||
|
void (*onplay_show_playlist_menu)(const char* path, void (*playlist_insert_cb));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* plugin header */
|
/* plugin header */
|
||||||
|
|
|
@ -557,6 +557,12 @@ enum pf_states {
|
||||||
|
|
||||||
static int pf_state;
|
static int pf_state;
|
||||||
|
|
||||||
|
#if PF_PLAYBACK_CAPABLE
|
||||||
|
static bool insert_whole_album;
|
||||||
|
static bool old_shuffle = false;
|
||||||
|
static int old_playlist = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** code */
|
/** code */
|
||||||
static bool free_slide_prio(int prio);
|
static bool free_slide_prio(int prio);
|
||||||
bool load_new_slide(void);
|
bool load_new_slide(void);
|
||||||
|
@ -3590,68 +3596,131 @@ static void select_prev_track(void)
|
||||||
|
|
||||||
#if PF_PLAYBACK_CAPABLE
|
#if PF_PLAYBACK_CAPABLE
|
||||||
|
|
||||||
static bool pf_warn_on_pl_erase(void)
|
static bool playlist_insert(int position, bool queue, bool create_new)
|
||||||
{
|
{
|
||||||
#ifdef USEGSLIB
|
if (position == PLAYLIST_REPLACE)
|
||||||
grey_show(false);
|
|
||||||
#endif
|
|
||||||
bool ret = rb->warn_on_pl_erase();
|
|
||||||
#ifdef USEGSLIB
|
|
||||||
grey_show(true);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Puts the current tracklist into a newly created playlist and starts playling
|
|
||||||
*/
|
|
||||||
static void start_playback(bool append)
|
|
||||||
{
|
|
||||||
static int old_playlist = -1, old_shuffle = 0;
|
|
||||||
int count = 0;
|
|
||||||
int position = pf_tracks.sel;
|
|
||||||
int shuffle = rb->global_settings->playlist_shuffle;
|
|
||||||
/* reuse existing playlist if possible
|
|
||||||
* regenerate if shuffle is on or changed, since playlist index and
|
|
||||||
* selected track are "out of sync" */
|
|
||||||
if (!shuffle && !append && center_slide.slide_index == old_playlist
|
|
||||||
&& (old_shuffle == shuffle))
|
|
||||||
{
|
{
|
||||||
goto play;
|
if ((!create_new && rb->playlist_remove_all_tracks(NULL) == 0) ||
|
||||||
|
(create_new && rb->playlist_create(NULL, NULL) == 0))
|
||||||
|
position = PLAYLIST_INSERT_LAST;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
/* First, replace the current playlist with a new one */
|
|
||||||
else if (append || (rb->playlist_remove_all_tracks(NULL) == 0
|
if (!insert_whole_album)
|
||||||
&& rb->playlist_create(NULL, NULL) == 0))
|
rb->playlist_insert_track(NULL, get_track_filename(pf_tracks.sel),
|
||||||
|
position, queue, true);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
int i = 0;
|
||||||
do {
|
do {
|
||||||
rb->yield();
|
rb->yield();
|
||||||
if (rb->playlist_insert_track(NULL, get_track_filename(count),
|
if (rb->playlist_insert_track(NULL, get_track_filename(i),
|
||||||
PLAYLIST_INSERT_LAST, false, true) < 0)
|
position, queue, true) < 0)
|
||||||
break;
|
break;
|
||||||
} while(++count < pf_tracks.count);
|
if (position == PLAYLIST_INSERT_FIRST)
|
||||||
rb->playlist_sync(NULL);
|
position = PLAYLIST_INSERT;
|
||||||
|
} while(++i < pf_tracks.count);
|
||||||
}
|
}
|
||||||
else
|
rb->playlist_sync(NULL);
|
||||||
return;
|
old_playlist = create_new ? center_slide.slide_index : -1;
|
||||||
|
return true;
|
||||||
if (!append && rb->global_settings->playlist_shuffle)
|
|
||||||
position = rb->playlist_shuffle(*rb->current_tick, pf_tracks.sel);
|
|
||||||
play:
|
|
||||||
/* TODO: can we adjust selected_track if !play_selected ?
|
|
||||||
* if shuffle, we can't predict the playing track easily, and for either
|
|
||||||
* case the track list doesn't get auto scrolled*/
|
|
||||||
if(!append)
|
|
||||||
{
|
|
||||||
rb->playlist_start(position, 0, 0);
|
|
||||||
/* make warn on playlist erase work */
|
|
||||||
rb->playlist_get_current()->num_inserted_tracks = 0;
|
|
||||||
old_playlist = center_slide.slide_index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
old_playlist = -1;
|
|
||||||
old_shuffle = shuffle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void track_list_ready(void)
|
||||||
|
{
|
||||||
|
if (pf_state != pf_show_tracks)
|
||||||
|
{
|
||||||
|
rb->splash(0, ID2P(LANG_WAIT));
|
||||||
|
create_track_index(center_slide.slide_index);
|
||||||
|
reset_track_list();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Brings up "Current Playlist" menu with first
|
||||||
|
track of selection.
|
||||||
|
|
||||||
|
Onplay menu code calls back playlist_insert for
|
||||||
|
adding all of the tracks.
|
||||||
|
*/
|
||||||
|
static void show_current_playlist_menu(void)
|
||||||
|
{
|
||||||
|
#ifdef USEGSLIB
|
||||||
|
grey_show(false);
|
||||||
|
rb->lcd_clear_display();
|
||||||
|
rb->lcd_update();
|
||||||
#endif
|
#endif
|
||||||
|
track_list_ready();
|
||||||
|
insert_whole_album = pf_state != pf_show_tracks;
|
||||||
|
FOR_NB_SCREENS(i)
|
||||||
|
rb->viewportmanager_theme_enable(i, true, NULL);
|
||||||
|
rb->onplay_show_playlist_menu(get_track_filename(pf_tracks.sel),
|
||||||
|
&playlist_insert);
|
||||||
|
FOR_NB_SCREENS(i)
|
||||||
|
rb->viewportmanager_theme_undo(i, false);
|
||||||
|
if (insert_whole_album)
|
||||||
|
free_borrowed_tracks();
|
||||||
|
#ifdef USEGSLIB
|
||||||
|
grey_show(true);
|
||||||
|
#endif
|
||||||
|
mylcd_set_drawmode(DRMODE_FG);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Puts selected album's tracks into a newly created playlist and starts playing
|
||||||
|
*/
|
||||||
|
static bool start_playback(bool return_to_WPS)
|
||||||
|
{
|
||||||
|
#ifdef USEGSLIB
|
||||||
|
grey_show(false);
|
||||||
|
#if LCD_DEPTH > 1
|
||||||
|
rb->lcd_set_background(N_BRIGHT(0));
|
||||||
|
rb->lcd_set_foreground(N_BRIGHT(255));
|
||||||
|
#endif
|
||||||
|
rb->lcd_clear_display();
|
||||||
|
rb->lcd_update();
|
||||||
|
#endif /* USEGSLIB */
|
||||||
|
|
||||||
|
if (!rb->warn_on_pl_erase())
|
||||||
|
{
|
||||||
|
#ifdef USEGSLIB
|
||||||
|
grey_show(true);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
track_list_ready();
|
||||||
|
insert_whole_album = true;
|
||||||
|
int start_index = pf_tracks.sel;
|
||||||
|
bool shuffle = rb->global_settings->playlist_shuffle;
|
||||||
|
/* can't reuse playlist if it may be out of sync with our track list */
|
||||||
|
if (shuffle || center_slide.slide_index != old_playlist
|
||||||
|
|| (old_shuffle != shuffle))
|
||||||
|
{
|
||||||
|
if (!playlist_insert(PLAYLIST_REPLACE, false, true))
|
||||||
|
{
|
||||||
|
#ifdef USEGSLIB
|
||||||
|
grey_show(true);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (shuffle)
|
||||||
|
start_index = rb->playlist_shuffle(*rb->current_tick, pf_tracks.sel);
|
||||||
|
}
|
||||||
|
rb->playlist_start(start_index, 0, 0);
|
||||||
|
rb->playlist_get_current()->num_inserted_tracks = 0; /* prevent warn_on_pl_erase */
|
||||||
|
old_shuffle = shuffle;
|
||||||
|
if (return_to_WPS)
|
||||||
|
pf_cfg.last_album = center_index;
|
||||||
|
#ifdef USEGSLIB
|
||||||
|
else
|
||||||
|
grey_show(true);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* PF_PLAYBACK_CAPABLE */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Draw the current album name
|
Draw the current album name
|
||||||
|
@ -3729,28 +3798,6 @@ static void draw_album_text(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PF_PLAYBACK_CAPABLE
|
|
||||||
/**
|
|
||||||
Display an info message when items have been added to playlist
|
|
||||||
*/
|
|
||||||
static void rb_splash_added_to_playlist(void)
|
|
||||||
{
|
|
||||||
#ifdef USEGSLIB
|
|
||||||
grey_show(false);
|
|
||||||
#if LCD_DEPTH > 1
|
|
||||||
rb->lcd_set_background(N_BRIGHT(0));
|
|
||||||
rb->lcd_set_foreground(N_BRIGHT(255));
|
|
||||||
#endif
|
|
||||||
rb->lcd_clear_display();
|
|
||||||
rb->lcd_update();
|
|
||||||
#endif
|
|
||||||
rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST));
|
|
||||||
#ifdef USEGSLIB
|
|
||||||
grey_show(true);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void set_initial_slide(const char* selected_file)
|
static void set_initial_slide(const char* selected_file)
|
||||||
{
|
{
|
||||||
|
@ -4101,19 +4148,7 @@ static int pictureflow_main(const char* selected_file)
|
||||||
} else if (pf_state == pf_cover_out)
|
} else if (pf_state == pf_cover_out)
|
||||||
interrupt_cover_out_animation();
|
interrupt_cover_out_animation();
|
||||||
|
|
||||||
if( pf_state == pf_idle ) {
|
show_current_playlist_menu();
|
||||||
create_track_index(center_slide.slide_index);
|
|
||||||
reset_track_list();
|
|
||||||
start_playback(true);
|
|
||||||
free_borrowed_tracks();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rb->playlist_insert_track(NULL, get_track_filename(pf_tracks.sel),
|
|
||||||
PLAYLIST_INSERT_LAST, false, true);
|
|
||||||
rb->playlist_sync(NULL);
|
|
||||||
}
|
|
||||||
rb_splash_added_to_playlist();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4128,13 +4163,8 @@ static int pictureflow_main(const char* selected_file)
|
||||||
set_current_slide(target);
|
set_current_slide(target);
|
||||||
#if PF_PLAYBACK_CAPABLE
|
#if PF_PLAYBACK_CAPABLE
|
||||||
if(pf_cfg.auto_wps == 1) {
|
if(pf_cfg.auto_wps == 1) {
|
||||||
if (!pf_warn_on_pl_erase())
|
if (start_playback(true))
|
||||||
break;
|
return PLUGIN_GOTO_WPS;
|
||||||
create_track_index(center_slide.slide_index);
|
|
||||||
reset_track_list();
|
|
||||||
start_playback(false);
|
|
||||||
pf_cfg.last_album = center_index;
|
|
||||||
return PLUGIN_GOTO_WPS;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -4145,12 +4175,13 @@ static int pictureflow_main(const char* selected_file)
|
||||||
else if (pf_state == pf_cover_in)
|
else if (pf_state == pf_cover_in)
|
||||||
interrupt_cover_in_animation();
|
interrupt_cover_in_animation();
|
||||||
#if PF_PLAYBACK_CAPABLE
|
#if PF_PLAYBACK_CAPABLE
|
||||||
else if (pf_state == pf_show_tracks && pf_warn_on_pl_erase()) {
|
else if (pf_state == pf_show_tracks) {
|
||||||
start_playback(false);
|
|
||||||
if(pf_cfg.auto_wps != 0) {
|
if(pf_cfg.auto_wps != 0) {
|
||||||
pf_cfg.last_album = center_index;
|
if (start_playback(true))
|
||||||
return PLUGIN_GOTO_WPS;
|
return PLUGIN_GOTO_WPS;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
start_playback(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
@ -4226,6 +4257,9 @@ enum plugin_status plugin_start(const void *parameter)
|
||||||
if (configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS,
|
if (configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS,
|
||||||
CONFIG_VERSION))
|
CONFIG_VERSION))
|
||||||
{
|
{
|
||||||
|
#ifdef USEGSLIB
|
||||||
|
grey_show(false);
|
||||||
|
#endif
|
||||||
rb->splash(HZ, ID2P(LANG_ERROR_WRITING_CONFIG));
|
rb->splash(HZ, ID2P(LANG_ERROR_WRITING_CONFIG));
|
||||||
ret = PLUGIN_ERROR;
|
ret = PLUGIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -633,7 +633,7 @@ int do_shortcut_menu(void *ignored)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
onplay_show_playlist_menu(sc->u.path);
|
onplay_show_playlist_menu(sc->u.path, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHORTCUT_FILE:
|
case SHORTCUT_FILE:
|
||||||
|
|
Loading…
Reference in a new issue