From e3b8b7fa80320f0c8bbc84d4364ea83b5991db20 Mon Sep 17 00:00:00 2001 From: Christian Soffke Date: Wed, 29 Dec 2021 20:24:51 +0100 Subject: [PATCH] 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 --- apps/onplay.c | 11 +- apps/onplay.h | 2 +- apps/playlist_viewer.c | 2 +- apps/plugin.c | 1 + apps/plugin.h | 4 +- apps/plugins/pictureflow/pictureflow.c | 230 ++++++++++++++----------- apps/shortcuts.c | 2 +- 7 files changed, 148 insertions(+), 104 deletions(-) diff --git a/apps/onplay.c b/apps/onplay.c index 93c7c93624..61ef8acad5 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -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 diff --git a/apps/onplay.h b/apps/onplay.h index 27f0436403..bff8dafff0 100644 --- a/apps/onplay.h +++ b/apps/onplay.h @@ -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 diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index 63d8697ee8..b0f30ea8a1 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c @@ -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: diff --git a/apps/plugin.c b/apps/plugin.c index bd7f74e65f..0168a26323 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -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; diff --git a/apps/plugin.h b/apps/plugin.h index 38d44530b0..d4d86e50bd 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -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 */ diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index 2217c15678..d2b9ae5190 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c @@ -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) { -#ifdef USEGSLIB - 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)) + if (position == PLAYLIST_REPLACE) { - 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 - && rb->playlist_create(NULL, NULL) == 0)) + + 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(count), - PLAYLIST_INSERT_LAST, false, true) < 0) + if (rb->playlist_insert_track(NULL, get_track_filename(i), + position, queue, true) < 0) break; - } while(++count < pf_tracks.count); - rb->playlist_sync(NULL); + if (position == PLAYLIST_INSERT_FIRST) + position = PLAYLIST_INSERT; + } while(++i < pf_tracks.count); } - 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; + 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 + 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 @@ -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,13 +4163,8 @@ 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; - return PLUGIN_GOTO_WPS; + if (start_playback(true)) + return PLUGIN_GOTO_WPS; } else #endif @@ -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; - return PLUGIN_GOTO_WPS; + 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; } diff --git a/apps/shortcuts.c b/apps/shortcuts.c index 3672178647..b0a949933c 100644 --- a/apps/shortcuts.c +++ b/apps/shortcuts.c @@ -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: