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:
Christian Soffke 2021-12-29 20:24:51 +01:00 committed by William Wilgus
parent bfe3dac3ba
commit e3b8b7fa80
7 changed files with 148 additions and 104 deletions

View file

@ -69,6 +69,7 @@ static const char *selected_file = NULL;
static char selected_file_path[MAX_PATH];
static int selected_file_attr = 0;
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 */
/* 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
);
/* CONTEXT_[TREE|ID3DB] playlist options */
/* CONTEXT_[TREE|ID3DB|STD] playlist options */
static bool add_to_playlist(int position, bool queue)
{
bool new_playlist = false;
@ -510,6 +511,10 @@ static bool add_to_playlist(int position, bool queue)
{
tagtree_insert_selection_playlist(position, queue);
}
else if (context == CONTEXT_STD && ctx_playlist_insert != NULL)
{
ctx_playlist_insert(position, queue, false);
}
else
#endif
{
@ -774,9 +779,10 @@ static int treeplaylist_callback(int 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;
ctx_playlist_insert = playlist_insert_cb;
selected_file = path;
if (dir_exists(path))
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;
onplay_result = ONPLAY_OK;
context = from;
ctx_playlist_insert = NULL;
if (file == NULL)
selected_file = NULL;
else

View file

@ -51,6 +51,6 @@ enum hotkey_action {
/* needed for the playlist viewer.. eventually clean this up */
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

View file

@ -535,7 +535,7 @@ static int onplay_menu(int index)
{
case 0:
/* playlist */
onplay_show_playlist_menu(current_track->name);
onplay_show_playlist_menu(current_track->name, NULL);
ret = 0;
break;
case 1:

View file

@ -805,6 +805,7 @@ static const struct plugin_api rockbox_api = {
warn_on_pl_erase,
playlist_insert_playlist,
battery_current,
onplay_show_playlist_menu,
};
static int plugin_buffer_handle;

View file

@ -110,6 +110,7 @@ int plugin_open(const char *plugin, const char *parameter);
#include "rbpaths.h"
#include "core_alloc.h"
#include "screen_access.h"
#include "onplay.h"
#ifdef HAVE_ALBUMART
#include "albumart.h"
@ -154,7 +155,7 @@ int plugin_open(const char *plugin, const char *parameter);
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* 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
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,
const char *filename, int position, bool queue);
int (*battery_current)(void);
void (*onplay_show_playlist_menu)(const char* path, void (*playlist_insert_cb));
};
/* plugin header */

View file

@ -557,6 +557,12 @@ enum pf_states {
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 */
static bool free_slide_prio(int prio);
bool load_new_slide(void);
@ -3590,68 +3596,131 @@ static void select_prev_track(void)
#if PF_PLAYBACK_CAPABLE
static bool pf_warn_on_pl_erase(void)
static bool playlist_insert(int position, bool queue, bool create_new)
{
if (position == PLAYLIST_REPLACE)
{
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;
}
if (!insert_whole_album)
rb->playlist_insert_track(NULL, get_track_filename(pf_tracks.sel),
position, queue, true);
else
{
int i = 0;
do {
rb->yield();
if (rb->playlist_insert_track(NULL, get_track_filename(i),
position, queue, true) < 0)
break;
if (position == PLAYLIST_INSERT_FIRST)
position = PLAYLIST_INSERT;
} while(++i < pf_tracks.count);
}
rb->playlist_sync(NULL);
old_playlist = create_new ? center_slide.slide_index : -1;
return true;
}
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
bool ret = rb->warn_on_pl_erase();
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
return ret;
mylcd_set_drawmode(DRMODE_FG);
}
/*
* Puts the current tracklist into a newly created playlist and starts playling
* Puts selected album's tracks into a newly created playlist and starts playing
*/
static void start_playback(bool append)
static bool start_playback(bool return_to_WPS)
{
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;
}
/* First, replace the current playlist with a new one */
else if (append || (rb->playlist_remove_all_tracks(NULL) == 0
&& rb->playlist_create(NULL, NULL) == 0))
{
do {
rb->yield();
if (rb->playlist_insert_track(NULL, get_track_filename(count),
PLAYLIST_INSERT_LAST, false, true) < 0)
break;
} while(++count < pf_tracks.count);
rb->playlist_sync(NULL);
}
else
return;
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;
}
#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
@ -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)
{
@ -4101,19 +4148,7 @@ static int pictureflow_main(const char* selected_file)
} else if (pf_state == pf_cover_out)
interrupt_cover_out_animation();
if( pf_state == pf_idle ) {
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();
show_current_playlist_menu();
}
break;
#endif
@ -4128,12 +4163,7 @@ static int pictureflow_main(const char* selected_file)
set_current_slide(target);
#if PF_PLAYBACK_CAPABLE
if(pf_cfg.auto_wps == 1) {
if (!pf_warn_on_pl_erase())
break;
create_track_index(center_slide.slide_index);
reset_track_list();
start_playback(false);
pf_cfg.last_album = center_index;
if (start_playback(true))
return PLUGIN_GOTO_WPS;
}
else
@ -4145,12 +4175,13 @@ static int pictureflow_main(const char* selected_file)
else if (pf_state == pf_cover_in)
interrupt_cover_in_animation();
#if PF_PLAYBACK_CAPABLE
else if (pf_state == pf_show_tracks && pf_warn_on_pl_erase()) {
start_playback(false);
else if (pf_state == pf_show_tracks) {
if(pf_cfg.auto_wps != 0) {
pf_cfg.last_album = center_index;
if (start_playback(true))
return PLUGIN_GOTO_WPS;
}
else
start_playback(false);
}
#endif
break;
@ -4226,6 +4257,9 @@ enum plugin_status plugin_start(const void *parameter)
if (configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS,
CONFIG_VERSION))
{
#ifdef USEGSLIB
grey_show(false);
#endif
rb->splash(HZ, ID2P(LANG_ERROR_WRITING_CONFIG));
ret = PLUGIN_ERROR;
}

View file

@ -633,7 +633,7 @@ int do_shortcut_menu(void *ignored)
}
else
{
onplay_show_playlist_menu(sc->u.path);
onplay_show_playlist_menu(sc->u.path, NULL);
}
break;
case SHORTCUT_FILE: