summaryrefslogtreecommitdiffstats
path: root/apps/plugins/pictureflow
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pictureflow')
-rw-r--r--apps/plugins/pictureflow/pictureflow.c596
1 files changed, 392 insertions, 204 deletions
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c
index 2f075a7e61..87ad1a403f 100644
--- a/apps/plugins/pictureflow/pictureflow.c
+++ b/apps/plugins/pictureflow/pictureflow.c
@@ -33,6 +33,7 @@
#include "lib/grey.h"
#include "lib/mylcd.h"
#include "lib/feature_wrappers.h"
+#include "lib/id3.h"
/******************************* Globals ***********************************/
static fb_data *lcd_fb;
@@ -44,6 +45,7 @@ static fb_data *lcd_fb;
#if PF_PLAYBACK_CAPABLE
#include "lib/playback_control.h"
+#include "lib/mul_id3.h"
#endif
#define PF_PREV ACTION_STD_PREV
@@ -151,8 +153,12 @@ const struct button_mapping pf_context_buttons[] =
{PF_QUIT, BUTTON_POWER, BUTTON_NONE},
#elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) \
|| (CONFIG_KEYPAD == IPOD_3G_PAD) \
- || (CONFIG_KEYPAD == IPOD_4G_PAD) \
- || (CONFIG_KEYPAD == MPIO_HD300_PAD)
+ || (CONFIG_KEYPAD == IPOD_4G_PAD)
+ {PF_MENU, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU},
+ {PF_QUIT, BUTTON_MENU|BUTTON_REL, BUTTON_MENU},
+ {PF_SORTING_NEXT, BUTTON_SELECT|BUTTON_MENU, BUTTON_NONE},
+ {PF_SORTING_PREV, BUTTON_SELECT|BUTTON_PLAY, BUTTON_NONE},
+#elif CONFIG_KEYPAD == MPIO_HD300_PAD
{PF_QUIT, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU},
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
{PF_QUIT, BUTTON_RC_REC, BUTTON_NONE},
@@ -534,6 +540,7 @@ static PFreal offsetX;
static PFreal offsetY;
static int number_of_slides;
static bool is_initial_slide = true;
+static bool show_tracks_while_browsing = false;
static struct pf_slide_cache pf_sldcache;
@@ -554,6 +561,8 @@ static struct pf_index_t pf_idx;
static struct pf_track_t pf_tracks;
+static struct mp3entry id3;
+
void reset_track_list(void);
static bool thread_is_running;
@@ -626,7 +635,7 @@ static inline void buf_ctx_unlock(void)
buf_ctx_locked = false;
}
-static bool check_database(bool prompt)
+static bool check_database(void)
{
bool needwarn = true;
int spin = 5;
@@ -644,9 +653,7 @@ static bool check_database(bool prompt)
needwarn = false;
rb->splash(0, ID2P(LANG_TAGCACHE_BUSY));
}
- else if (!prompt)
- return false;
- else if (rb->action_userabort(HZ/5))
+ else
return false;
rb->yield();
@@ -689,7 +696,7 @@ static void config_set_defaults(struct pf_config_t *cfg)
cfg->resize = true;
cfg->cache_version = CACHE_REBUILD;
cfg->show_album_name = (LCD_HEIGHT > 100)
- ? ALBUM_NAME_TOP : ALBUM_NAME_BOTTOM;
+ ? ALBUM_AND_ARTIST_BOTTOM : ALBUM_NAME_BOTTOM;
cfg->sort_albums_by = SORT_BY_ARTIST_AND_NAME;
cfg->year_sort_order = ASCENDING;
cfg->show_year = false;
@@ -963,6 +970,7 @@ const struct custom_format format_transposed = {
static const struct button_mapping* get_context_map(int context)
{
+ context &= ~CONTEXT_LOCKED;
return pf_contexts[context & ~CONTEXT_PLUGIN];
}
@@ -1133,6 +1141,8 @@ static void write_artist_entry(struct tagcache_search *tcs,
static int get_tcs_search_res(int type, struct tagcache_search *tcs,
void **buf, size_t *bufsz)
{
+ char tcs_buf[TAGCACHE_BUFSZ];
+ const long tcs_bufsz = sizeof(tcs_buf);
int ret = SUCCESS;
unsigned int l, name_idx = 0;
void (*writefn)(struct tagcache_search *, int, unsigned int);
@@ -1148,7 +1158,7 @@ static int get_tcs_search_res(int type, struct tagcache_search *tcs,
data_size = sizeof(struct album_data);
}
- while (rb->tagcache_get_next(tcs))
+ while (rb->tagcache_get_next(tcs, tcs_buf, tcs_bufsz))
{
if (rb->button_get(false) > BUTTON_NONE)
{
@@ -1188,6 +1198,8 @@ static int get_tcs_search_res(int type, struct tagcache_search *tcs,
static int create_album_untagged(struct tagcache_search *tcs,
void **buf, size_t *bufsz)
{
+ static char tcs_buf[TAGCACHE_BUFSZ];
+ const long tcs_bufsz = sizeof(tcs_buf);
int ret = SUCCESS;
int album_count = pf_idx.album_ct; /* store existing count */
int total_count = pf_idx.album_ct + pf_idx.artist_ct * 2;
@@ -1202,7 +1214,7 @@ static int create_album_untagged(struct tagcache_search *tcs,
{
rb->tagcache_search_add_filter(tcs, tag_album, pf_idx.album_untagged_seek);
- while (rb->tagcache_get_next(tcs))
+ while (rb->tagcache_get_next(tcs, tcs_buf, tcs_bufsz))
{
if (rb->button_get(false) > BUTTON_NONE) {
if (confirm_quit())
@@ -1331,6 +1343,8 @@ static int build_artist_index(struct tagcache_search *tcs,
static int assign_album_year(void)
{
+ char tcs_buf[TAGCACHE_BUFSZ];
+ const long tcs_bufsz = sizeof(tcs_buf);
draw_progressbar(0, pf_idx.album_ct, "Assigning Album Year");
for (int album_idx = 0; album_idx < pf_idx.album_ct; album_idx++)
{
@@ -1359,7 +1373,7 @@ static int assign_album_year(void)
rb->tagcache_search_add_filter(&tcs, tag_albumartist,
pf_idx.album_index[album_idx].artist_seek);
- while (rb->tagcache_get_next(&tcs)) {
+ while (rb->tagcache_get_next(&tcs, tcs_buf, tcs_bufsz)) {
int track_year = rb->tagcache_get_numeric(&tcs, tag_year);
if (track_year > album_year)
album_year = track_year;
@@ -1378,6 +1392,8 @@ static int assign_album_year(void)
*/
static int create_album_index(void)
{
+ static char tcs_buf[TAGCACHE_BUFSZ];
+ const long tcs_bufsz = sizeof(tcs_buf);
void *buf = pf_idx.buf;
size_t buf_size = pf_idx.buf_sz;
@@ -1455,7 +1471,7 @@ static int create_album_index(void)
last = 0;
final = pf_idx.artist_ct;
retry = 0;
- if (rb->tagcache_get_next(&tcs))
+ if (rb->tagcache_get_next(&tcs, tcs_buf, tcs_bufsz))
{
retry_artist_lookup:
@@ -1927,17 +1943,10 @@ static int pf_tcs_retrieve_track_title(int string_index, int disc_num, int track
if (rb->strcmp(UNTAGGED, tcs.result) == 0)
{
/* show filename instead of <untaggged> */
- if (!rb->tagcache_retrieve(&tcs, tcs.idx_id, tag_filename,
+ if (!rb->tagcache_retrieve(&tcs, tcs.idx_id, tag_virt_basename,
file_name, MAX_PATH))
return 0;
track_title = file_name;
- if (track_title)
- {
- /* if filename remove the '/' */
- track_title = rb->strrchr(track_title, PATH_SEPCH);
- if (track_title)
- track_title++;
- }
}
if (!track_title)
@@ -1980,6 +1989,8 @@ static int pf_tcs_retrieve_file_name(int fn_idx)
*/
static void create_track_index(const int slide_index)
{
+ char tcs_buf[TAGCACHE_BUFSZ];
+ const long tcs_bufsz = sizeof(tcs_buf);
buf_ctx_lock();
if ( slide_index == pf_tracks.cur_idx )
return;
@@ -1997,7 +2008,7 @@ static void create_track_index(const int slide_index)
int string_index = 0;
pf_tracks.count = 0;
- while (rb->tagcache_get_next(&tcs))
+ while (rb->tagcache_get_next(&tcs, tcs_buf, tcs_bufsz))
{
int disc_num = rb->tagcache_get_numeric(&tcs, tag_discnumber);
int track_num = rb->tagcache_get_numeric(&tcs, tag_tracknumber);
@@ -2071,15 +2082,12 @@ static inline void free_borrowed_tracks(void)
static bool get_albumart_for_index_from_db(const int slide_index, char *buf,
int buflen)
{
- if ( slide_index == -1 )
- {
- rb->strlcpy( buf, EMPTY_SLIDE, buflen );
- }
-
+ bool ret;
+ char tcs_buf[TAGCACHE_BUFSZ];
+ const long tcs_bufsz = sizeof(tcs_buf);
if (tcs.valid || !rb->tagcache_search(&tcs, tag_filename))
return false;
- bool result;
/* find the first track of the album */
rb->tagcache_search_add_filter(&tcs, tag_album,
pf_idx.album_index[slide_index].seek);
@@ -2087,36 +2095,12 @@ static bool get_albumart_for_index_from_db(const int slide_index, char *buf,
rb->tagcache_search_add_filter(&tcs, tag_albumartist,
pf_idx.album_index[slide_index].artist_seek);
- if ( rb->tagcache_get_next(&tcs) ) {
- struct mp3entry id3;
- int fd;
-
-#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
- if (rb->tagcache_fill_tags(&id3, tcs.result))
- {
- rb->strlcpy(id3.path, tcs.result, sizeof(id3.path));
- }
- else
-#endif
- {
- fd = rb->open(tcs.result, O_RDONLY);
- if (fd) {
- rb->get_metadata(&id3, fd, tcs.result);
- rb->close(fd);
- }
- }
+ ret = rb->tagcache_get_next(&tcs, tcs_buf, tcs_bufsz) &&
+ retrieve_id3(&id3, tcs.result) &&
+ search_albumart_files(&id3, ":", buf, buflen);
- if ( search_albumart_files(&id3, ":", buf, buflen) )
- result = true;
- else
- result = false;
- }
- else {
- /* did not find a matching track */
- result = false;
- }
rb->tagcache_search_finish(&tcs);
- return result;
+ return ret;
}
/**
@@ -2213,6 +2197,9 @@ static unsigned int mfnv(char *str)
const unsigned int p = 16777619;
unsigned int hash = 0x811C9DC5; // 2166136261;
+ if (!str)
+ return 0;
+
while(*str)
hash = (hash ^ *str++) * p;
hash += hash << 13;
@@ -2318,6 +2305,8 @@ aa_success:
configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS,
CONFIG_VERSION);
free_all_slide_prio(0);
+ if (pf_state == pf_idle)
+ rb->queue_post(&thread_q, EV_WAKEUP, 0);
}
if(verbose)/* direct interaction with user */
@@ -3098,7 +3087,7 @@ static void render_slide(struct slide_data *slide, const int alpha)
const pix_t *ptr = &src[column * bmp->height];
-#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
+#if LCD_STRIDEFORMAT == VERTICAL_STRIDE
#define PIXELSTEP_Y 1
#define LCDADDR(x, y) (&buffer[BUFFER_HEIGHT*(x) + (y)])
#else
@@ -3183,7 +3172,7 @@ static inline void set_current_slide(const int slide_index)
}
-static void interrupt_cover_out_animation(void);
+static void skip_animation_to_idle_state(void);
static bool sort_albums(int new_sorting, bool from_settings)
{
int i, album_idx, artist_idx;
@@ -3217,7 +3206,7 @@ static bool sort_albums(int new_sorting, bool from_settings)
if (pf_state == pf_show_tracks ||
pf_state == pf_cover_in ||
pf_state == pf_cover_out)
- interrupt_cover_out_animation();
+ skip_animation_to_idle_state();
else if (pf_state == pf_scrolling)
set_current_slide(target);
pf_state = pf_idle;
@@ -3227,6 +3216,12 @@ static bool sort_albums(int new_sorting, bool from_settings)
{
#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, sort_options[pf_cfg.sort_albums_by]);
#ifdef USEGSLIB
@@ -3257,7 +3252,10 @@ static bool sort_albums(int new_sorting, bool from_settings)
if(!rb->strcmp(pf_idx.album_names + album_idx, current_album_name) &&
!rb->strcmp(pf_idx.artist_names + artist_idx, current_album_artist))
+ {
set_current_slide(i);
+ pf_cfg.last_album = i;
+ }
}
return true;
}
@@ -3271,6 +3269,8 @@ static void start_animation(void)
pf_state = pf_scrolling;
}
+static void update_scroll_animation(void);
+
/**
Go to the previous slide
*/
@@ -3284,6 +3284,8 @@ static void show_previous_slide(void)
} else if ( step > 0 ) {
target = center_index;
step = (target <= center_slide.slide_index) ? -1 : 1;
+ if (step < 0)
+ update_scroll_animation();
} else {
target = fmax(0, center_index - 2);
}
@@ -3303,6 +3305,8 @@ static void show_next_slide(void)
} else if ( step < 0 ) {
target = center_index;
step = (target < center_slide.slide_index) ? -1 : 1;
+ if (step > 0)
+ update_scroll_animation();
} else {
target = fmin(center_index + 2, number_of_slides - 1);
}
@@ -3479,16 +3483,29 @@ static void cleanup(void)
rb->cpu_boost(false);
#endif
end_pf_thread();
-#ifdef HAVE_BACKLIGHT
+
/* Turn on backlight timeout (revert to settings) */
backlight_use_settings();
-#endif
#ifdef USEGSLIB
grey_release();
#endif
}
+static void skip_animation_to_show_tracks(void);
+static void adjust_album_display_for_setting(int old_val, int new_val)
+{
+ if (old_val == new_val)
+ return;
+
+ reset_track_list();
+ recalc_offsets();
+ reset_slides();
+
+ if (pf_state == pf_show_tracks)
+ skip_animation_to_show_tracks();
+}
+
/**
Shows the settings menu
*/
@@ -3544,11 +3561,10 @@ static int settings_menu(void)
selection=rb->do_menu(&settings_menu,&selection, NULL, false);
switch(selection) {
case 0:
+ old_val = pf_cfg.show_album_name;
rb->set_option(rb->str(LANG_SHOW_ALBUM_TITLE),
- &pf_cfg.show_album_name, INT, album_name_options, 5, NULL);
- reset_track_list();
- recalc_offsets();
- reset_slides();
+ &pf_cfg.show_album_name, RB_INT, album_name_options, 5, NULL);
+ adjust_album_display_for_setting(old_val, pf_cfg.show_album_name);
break;
case 1:
rb->set_bool(rb->str(LANG_SHOW_YEAR_IN_ALBUM_TITLE), &pf_cfg.show_year);
@@ -3556,7 +3572,7 @@ static int settings_menu(void)
case 2:
old_val = pf_cfg.sort_albums_by;
rb->set_option(rb->str(LANG_SORT_ALBUMS_BY),
- &pf_cfg.sort_albums_by, INT, sort_options, 4, NULL);
+ &pf_cfg.sort_albums_by, RB_INT, sort_options, 4, NULL);
if (old_val != pf_cfg.sort_albums_by &&
!sort_albums(pf_cfg.sort_albums_by, true))
pf_cfg.sort_albums_by = old_val;
@@ -3564,44 +3580,46 @@ static int settings_menu(void)
case 3:
old_val = pf_cfg.year_sort_order;
rb->set_option(rb->str(LANG_YEAR_SORT_ORDER),
- &pf_cfg.year_sort_order, INT, year_sort_order_options, 2, NULL);
+ &pf_cfg.year_sort_order, RB_INT, year_sort_order_options, 2, NULL);
if (old_val != pf_cfg.year_sort_order &&
!sort_albums(pf_cfg.sort_albums_by, true))
pf_cfg.year_sort_order = old_val;
break;
case 4:
+ old_val = pf_cfg.show_fps;
rb->set_bool(rb->str(LANG_DISPLAY_FPS), &pf_cfg.show_fps);
- reset_track_list();
+ if (old_val != pf_cfg.show_fps)
+ reset_track_list();
break;
case 5:
+ old_val = pf_cfg.slide_spacing;
rb->set_int(rb->str(LANG_SPACING), "", 1,
&pf_cfg.slide_spacing,
NULL, 1, 0, 100, NULL );
- recalc_offsets();
- reset_slides();
+ adjust_album_display_for_setting(old_val, pf_cfg.slide_spacing);
break;
case 6:
+ old_val = pf_cfg.center_margin;
rb->set_int(rb->str(LANG_CENTRE_MARGIN), "", 1,
&pf_cfg.center_margin,
NULL, 1, 0, 80, NULL );
- recalc_offsets();
- reset_slides();
+ adjust_album_display_for_setting(old_val, pf_cfg.center_margin);
break;
case 7:
+ old_val = pf_cfg.num_slides;
rb->set_int(rb->str(LANG_NUMBER_OF_SLIDES), "", 1,
&pf_cfg.num_slides, NULL, 1, 1, MAX_SLIDES_COUNT, NULL );
- recalc_offsets();
- reset_slides();
+ adjust_album_display_for_setting(old_val, pf_cfg.num_slides);
break;
case 8:
+ old_val = pf_cfg.zoom;
rb->set_int(rb->str(LANG_ZOOM), "", 1, &pf_cfg.zoom,
NULL, 1, 10, 300, NULL );
- recalc_offsets();
- reset_slides();
+ adjust_album_display_for_setting(old_val, pf_cfg.zoom);
break;
case 9:
@@ -3628,11 +3646,11 @@ static int settings_menu(void)
break;
case 12:
rb->set_option(rb->str(LANG_WPS_INTEGRATION),
- &pf_cfg.auto_wps, INT, wps_options, 3, NULL);
+ &pf_cfg.auto_wps, RB_INT, wps_options, 3, NULL);
break;
case 13:
rb->set_option(rb->str(LANG_BACKLIGHT),
- &pf_cfg.backlight_mode, INT, backlight_options, 2, NULL);
+ &pf_cfg.backlight_mode, RB_INT, backlight_options, 2, NULL);
break;
case MENU_ATTACHED_USB:
@@ -3646,45 +3664,67 @@ static int settings_menu(void)
Show the main menu
*/
enum {
+ PF_SHOW_TRACKS_WHILE_BROWSING,
+ PF_GOTO_LAST_ALBUM,
PF_GOTO_WPS,
#if PF_PLAYBACK_CAPABLE
- PF_MENU_CLEAR_PLAYLIST,
PF_MENU_PLAYBACK_CONTROL,
#endif
PF_MENU_SETTINGS,
- PF_MENU_RETURN,
PF_MENU_QUIT,
};
static int main_menu(void)
{
int selection = 0;
- int result;
+ int result, curr_album;
#if LCD_DEPTH > 1
rb->lcd_set_foreground(N_BRIGHT(255));
#endif
MENUITEM_STRINGLIST(main_menu, "PictureFlow Main Menu", NULL,
+ ID2P(LANG_SHOW_TRACKS_WHILE_BROWSING),
+ ID2P(LANG_GOTO_LAST_ALBUM),
ID2P(LANG_GOTO_WPS),
#if PF_PLAYBACK_CAPABLE
- ID2P(LANG_CLEAR_PLAYLIST),
ID2P(LANG_PLAYBACK_CONTROL),
#endif
ID2P(LANG_SETTINGS),
- ID2P(LANG_RETURN),
ID2P(LANG_MENU_QUIT));
while (1) {
switch (rb->do_menu(&main_menu,&selection, NULL, false)) {
+ case PF_SHOW_TRACKS_WHILE_BROWSING:
+ if (pf_state != pf_show_tracks)
+ {
+ if (pf_state == pf_scrolling)
+ set_current_slide(target);
+
+ skip_animation_to_show_tracks();
+ }
+ show_tracks_while_browsing = true;
+ return 0;
+ case PF_GOTO_LAST_ALBUM:
+ if (pf_state == pf_scrolling)
+ curr_album = target;
+ else
+ curr_album = center_index;
+
+ if (pf_state == pf_show_tracks)
+ free_borrowed_tracks();
+ if (pf_state == pf_show_tracks ||
+ pf_state == pf_cover_in ||
+ pf_state == pf_cover_out)
+ skip_animation_to_idle_state();
+
+ set_current_slide(pf_cfg.last_album);
+ pf_cfg.last_album = curr_album;
+
+ pf_state = pf_idle;
+ return 0;
case PF_GOTO_WPS: /* WPS */
return -2;
#if PF_PLAYBACK_CAPABLE
- case PF_MENU_CLEAR_PLAYLIST:
- if(rb->warn_on_pl_erase() && rb->playlist_remove_all_tracks(NULL) == 0) {
- rb->playlist_create(NULL, NULL);
- rb->splash(HZ*2, ID2P(LANG_PLAYLIST_CLEARED));
- }
- break;
case PF_MENU_PLAYBACK_CONTROL: /* Playback Control */
playback_control(NULL);
break;
@@ -3693,8 +3733,6 @@ static int main_menu(void)
result = settings_menu();
if ( result != 0 ) return result;
break;
- case PF_MENU_RETURN:
- return 0;
case PF_MENU_QUIT:
return -1;
@@ -3707,21 +3745,33 @@ static int main_menu(void)
}
}
+#define ZOOMIN_FRAME_COUNT 19
+#define ZOOMIN_FRAME_DIST -5
+#define ZOOMIN_FRAME_ANGLE 1
+#define ZOOMIN_FRAME_FADE 13
+
+#define ROTATE_FRAME_COUNT 15
+#define ROTATE_FRAME_ANGLE 16
+
+#define KEYFRAME_COUNT ZOOMIN_FRAME_COUNT + ROTATE_FRAME_COUNT
+
/**
Animation step for zooming into the current cover
*/
static void update_cover_in_animation(void)
{
cover_animation_keyframe++;
- if( cover_animation_keyframe < 20 ) {
- center_slide.distance-=5;
- center_slide.angle+=1;
- extra_fade += 13;
- }
- else if( cover_animation_keyframe < 35 ) {
- center_slide.angle+=16;
+
+ if(cover_animation_keyframe <= ZOOMIN_FRAME_COUNT)
+ {
+ center_slide.distance += ZOOMIN_FRAME_DIST;
+ center_slide.angle += ZOOMIN_FRAME_ANGLE;
+ extra_fade += ZOOMIN_FRAME_FADE;
}
- else {
+ else if(cover_animation_keyframe <= KEYFRAME_COUNT)
+ center_slide.angle += ROTATE_FRAME_ANGLE;
+ else
+ {
cover_animation_keyframe = 0;
pf_state = pf_show_tracks;
}
@@ -3733,36 +3783,40 @@ static void update_cover_in_animation(void)
static void update_cover_out_animation(void)
{
cover_animation_keyframe++;
- if( cover_animation_keyframe <= 15 ) {
- center_slide.angle-=16;
- }
- else if( cover_animation_keyframe < 35 ) {
- center_slide.distance+=5;
- center_slide.angle-=1;
- extra_fade -= 13;
+
+ if(cover_animation_keyframe <= ROTATE_FRAME_COUNT)
+ center_slide.angle -= ROTATE_FRAME_ANGLE;
+ else if(cover_animation_keyframe <= KEYFRAME_COUNT)
+ {
+ center_slide.distance -= ZOOMIN_FRAME_DIST;
+ center_slide.angle -= ZOOMIN_FRAME_ANGLE;
+ extra_fade -= ZOOMIN_FRAME_FADE;
}
- else {
+ else
+ {
cover_animation_keyframe = 0;
pf_state = pf_idle;
}
}
/**
- Skip steps for zooming into the current cover
+ Immediately show tracks and skip any animation frames
*/
-static void interrupt_cover_in_animation(void)
+static void skip_animation_to_show_tracks(void)
{
pf_state = pf_show_tracks;
cover_animation_keyframe = 0;
- extra_fade = 13 * 19;
- center_slide.distance = -5 * 19;
- center_slide.angle = 19 + (15 * 16);
+
+ extra_fade = ZOOMIN_FRAME_COUNT * ZOOMIN_FRAME_FADE;
+ center_slide.distance = ZOOMIN_FRAME_COUNT * ZOOMIN_FRAME_DIST;
+ center_slide.angle = (ZOOMIN_FRAME_COUNT * ZOOMIN_FRAME_ANGLE) +
+ (ROTATE_FRAME_COUNT * ROTATE_FRAME_ANGLE);
}
/**
- Skip steps for zooming out the current cover
+ Immediately transition to idle state and skip any animation frames
*/
-static void interrupt_cover_out_animation(void)
+static void skip_animation_to_idle_state(void)
{
pf_state = pf_idle;
cover_animation_keyframe = 0;
@@ -3771,21 +3825,12 @@ static void interrupt_cover_out_animation(void)
}
/**
- Stop zooming out the current cover and start zooming in
-*/
-static void revert_cover_out_animation(void)
-{
- pf_state = pf_cover_in;
- cover_animation_keyframe = 34 - cover_animation_keyframe;
-}
-
-/**
- Stop zooming into the current cover and start zooming out
+ Change direction during cover in/out animation
*/
-static void revert_cover_in_animation(void)
+static void reverse_animation(void)
{
- pf_state = pf_cover_out;
- cover_animation_keyframe = 34 - cover_animation_keyframe;
+ pf_state = pf_state == pf_cover_out ? pf_cover_in : pf_cover_out;
+ cover_animation_keyframe = KEYFRAME_COUNT - cover_animation_keyframe;
}
/**
@@ -3892,7 +3937,10 @@ static void show_track_list(void)
{
mylcd_clear_display();
if ( center_slide.slide_index != pf_tracks.cur_idx ) {
- show_track_list_loading();
+#ifdef HAVE_TC_RAMCACHE
+ if (!rb->tagcache_is_in_ram())
+#endif
+ show_track_list_loading();
create_track_index(center_slide.slide_index);
if (pf_tracks.count == 0)
{
@@ -3913,7 +3961,7 @@ static void show_track_list(void)
for (; track_i < pf_tracks.list_visible + pf_tracks.list_start; track_i++)
{
char *trackname = get_track_name(track_i);
- if ( track_i == pf_tracks.sel ) {
+ if (track_i == pf_tracks.sel && !show_tracks_while_browsing) {
if (pf_tracks.sel != pf_tracks.last_sel) {
set_scroll_line(trackname, PF_SCROLL_TRACK);
pf_tracks.last_sel = pf_tracks.sel;
@@ -3965,7 +4013,7 @@ static void select_next_album(void)
free_borrowed_tracks();
target = center_index + 1;
set_current_slide(target);
- interrupt_cover_in_animation();
+ skip_animation_to_show_tracks();
}
}
@@ -3975,13 +4023,50 @@ static void select_prev_album(void)
free_borrowed_tracks();
target = center_index - 1;
set_current_slide(target);
- interrupt_cover_in_animation();
+ skip_animation_to_show_tracks();
}
}
#if PF_PLAYBACK_CAPABLE
+static int show_id3_info(const char *selected_file)
+{
+ int i;
+ unsigned long last_tick;
+ const char *file_name;
+ bool is_multiple_tracks = insert_whole_album && pf_tracks.count > 1;
+
+ last_tick = *(rb->current_tick) + HZ/2;
+ rb->splash_progress_set_delay(HZ / 2); /* wait 1/2 sec before progress */
+ i = 0;
+ do {
+ file_name = i == 0 ? selected_file : get_track_filename(i);
+ if (rb->mp3info(&id3, file_name))
+ return 0;
-static bool playlist_insert(int position, bool queue, bool create_new)
+ if (is_multiple_tracks)
+ {
+ rb->splash_progress(i, pf_tracks.count,
+ "%s (%s)", rb->str(LANG_WAIT), rb->str(LANG_OFF_ABORT));
+ if (TIME_AFTER(*(rb->current_tick), last_tick + HZ/4))
+ {
+ if (rb->action_userabort(TIMEOUT_NOBLOCK))
+ return 0;
+ last_tick = *(rb->current_tick);
+ }
+
+ collect_id3(&id3, i == 0);
+ rb->yield();
+ }
+ } while (++i < pf_tracks.count && is_multiple_tracks);
+
+ if (is_multiple_tracks)
+ finalize_id3(&id3);
+
+ return rb->browse_id3(&id3, 0, 0, NULL, i) ? PLUGIN_USB_CONNECTED : 0;
+}
+
+
+static bool pf_current_playlist_insert(int position, bool queue, bool create_new)
{
if (position == PLAYLIST_REPLACE)
{
@@ -4012,11 +4097,52 @@ static bool playlist_insert(int position, bool queue, bool create_new)
return true;
}
+
+static int pf_add_to_playlist(const char* playlist, bool new_playlist)
+{
+ int fd;
+ int result = 0;
+
+ if (new_playlist)
+ fd = rb->open_utf8(playlist, O_CREAT|O_WRONLY|O_TRUNC);
+ else
+ fd = rb->open(playlist, O_CREAT|O_WRONLY|O_APPEND, 0666);
+
+ if(fd < 0)
+ return -1;
+
+ rb->reload_directory();
+
+ if (!insert_whole_album)
+ {
+ if (rb->fdprintf(fd, "%s\n", get_track_filename(pf_tracks.sel)) <= 0)
+ result = -1;
+ }
+ else
+ {
+ int i = 0;
+ do {
+ if (rb->fdprintf(fd, "%s\n", get_track_filename(i)) <= 0)
+ {
+ result = -1;
+ break;
+ }
+ rb->yield();
+ } while(++i < pf_tracks.count);
+ }
+ rb->close(fd);
+ return result;
+}
+
+
static bool track_list_ready(void)
{
if (pf_state != pf_show_tracks)
{
- rb->splash(0, ID2P(LANG_WAIT));
+#ifdef HAVE_TC_RAMCACHE
+ if (!rb->tagcache_is_in_ram())
+#endif
+ rb->splash(0, ID2P(LANG_WAIT));
create_track_index(center_slide.slide_index);
if (pf_tracks.count == 0)
{
@@ -4028,14 +4154,8 @@ static bool track_list_ready(void)
return true;
}
-/**
- 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)
+static bool context_menu_ready(void)
{
#ifdef USEGSLIB
grey_show(false);
@@ -4047,16 +4167,26 @@ static void show_current_playlist_menu(void)
#ifdef USEGSLIB
grey_show(true);
#endif
- return;
+ return false;
}
- insert_whole_album = pf_state != pf_show_tracks;
+#if LCD_DEPTH > 1
+#ifdef USEGSLIB
+ rb->lcd_set_foreground(N_BRIGHT(0));
+ rb->lcd_set_background(N_BRIGHT(255));
+#endif
+#endif
+ insert_whole_album = (pf_state != pf_show_tracks) || show_tracks_while_browsing;
FOR_NB_SCREENS(i)
rb->viewportmanager_theme_enable(i, true, NULL);
- rb->onplay_show_playlist_menu(get_track_filename(pf_tracks.sel),
- &playlist_insert);
+
+ return true;
+}
+
+static void context_menu_cleanup(void)
+{
FOR_NB_SCREENS(i)
rb->viewportmanager_theme_undo(i, false);
- if (insert_whole_album)
+ if (pf_state != pf_show_tracks)
free_borrowed_tracks();
#ifdef USEGSLIB
grey_show(true);
@@ -4065,6 +4195,60 @@ static void show_current_playlist_menu(void)
}
+static int context_menu(void)
+{
+ char album_name[MAX_PATH];
+ char *file_name = get_track_filename(show_tracks_while_browsing ? 0 : pf_tracks.sel);
+ int attr = FILE_ATTR_AUDIO;
+
+ enum {
+ PF_CURRENT_PLAYLIST = 0,
+ PF_CATALOG,
+ PF_ID3_INFO
+ };
+ MENUITEM_STRINGLIST(context_menu, ID2P(LANG_ONPLAY_MENU_TITLE), NULL,
+ ID2P(LANG_PLAYING_NEXT),
+ ID2P(LANG_ADD_TO_PL),
+ ID2P(LANG_MENU_SHOW_ID3_INFO));
+
+ while (1) {
+ switch (rb->do_menu(&context_menu,
+ NULL, NULL, false)) {
+
+ case PF_CURRENT_PLAYLIST:
+ if (insert_whole_album && pf_tracks.count > 1)
+ {
+ attr = ATTR_DIRECTORY;
+ file_name = NULL;
+ }
+ rb->onplay_show_playlist_menu(file_name, attr, &pf_current_playlist_insert);
+ return 0;
+ case PF_CATALOG:
+ if (insert_whole_album)
+ {
+ /* add a leading slash so that catalog_add_to_a_playlist
+ later prefills the name when creating a new playlist */
+ rb->snprintf(album_name, MAX_PATH, "/%s", get_album_name(center_index));
+ rb->fix_path_part(album_name, 1, sizeof(album_name) - 2);
+ file_name = album_name;
+ attr = ATTR_DIRECTORY;
+ }
+
+ rb->onplay_show_playlist_cat_menu(file_name, attr, &pf_add_to_playlist);
+ return 0;
+ case PF_ID3_INFO:
+ return show_id3_info(file_name);
+ case MENU_ATTACHED_USB:
+ return PLUGIN_USB_CONNECTED;
+ default:
+ return 0;
+
+ }
+ }
+}
+
+
+
/*
* Puts selected album's tracks into a newly created playlist and starts playing
*/
@@ -4097,7 +4281,7 @@ static bool start_playback(bool return_to_WPS)
if (shuffle || center_slide.slide_index != old_playlist
|| (old_shuffle != shuffle))
{
- if (!playlist_insert(PLAYLIST_REPLACE, false, true))
+ if (!pf_current_playlist_insert(PLAYLIST_REPLACE, false, true))
{
#ifdef USEGSLIB
grey_show(true);
@@ -4108,7 +4292,6 @@ static bool start_playback(bool return_to_WPS)
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;
#ifdef USEGSLIB
if (!return_to_WPS)
@@ -4208,32 +4391,15 @@ static void draw_album_text(void)
static void set_initial_slide(const char* selected_file)
{
- if (selected_file == NULL)
+ if (selected_file)
+ set_current_slide(retrieve_id3(&id3, selected_file) ?
+ id3_get_index(&id3) :
+ pf_cfg.last_album);
+ else
set_current_slide(rb->audio_status() ?
id3_get_index(rb->audio_current_track()) :
pf_cfg.last_album);
- else
- {
- struct mp3entry id3;
-#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
- if (rb->tagcache_fill_tags(&id3, selected_file))
- set_current_slide(id3_get_index(&id3));
- else
-#endif
- {
- int fd = rb->open(selected_file, O_RDONLY);
- if (fd >= 0)
- {
- if (rb->get_metadata(&id3, fd, selected_file))
- set_current_slide(id3_get_index(&id3));
- else
- set_current_slide(pf_cfg.last_album);
- rb->close(fd);
- }
- else
- set_current_slide(pf_cfg.last_album);
- }
- }
+
}
/**
@@ -4268,14 +4434,11 @@ static int pictureflow_main(const char* selected_file)
config_set_defaults(&pf_cfg);
configfile_load(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION);
- if(pf_cfg.auto_wps == 0)
- draw_splashscreen(pf_idx.buf, pf_idx.buf_sz);
- if(pf_cfg.backlight_mode == 0) {
- /* Turn off backlight timeout */
+
#ifdef HAVE_BACKLIGHT
+ if(pf_cfg.backlight_mode == 0)
backlight_ignore_timeout();
#endif
- }
rb->mutex_init(&buf_ctx_mutex);
@@ -4411,6 +4574,7 @@ static int pictureflow_main(const char* selected_file)
instant_update = true;
break;
case pf_cover_out:
+ show_tracks_while_browsing = false;
update_cover_out_animation();
render_all_slides();
instant_update = true;
@@ -4419,6 +4583,7 @@ static int pictureflow_main(const char* selected_file)
show_track_list();
break;
case pf_idle:
+ show_tracks_while_browsing = false;
render_all_slides();
if (aa_cache.inspected < pf_idx.album_ct)
{
@@ -4451,7 +4616,8 @@ static int pictureflow_main(const char* selected_file)
rb->snprintf(fpstxt, sizeof(fpstxt), "%d %%", progress_pct);
}
- if (pf_cfg.show_album_name == ALBUM_NAME_TOP)
+ if (pf_cfg.show_album_name == ALBUM_NAME_TOP ||
+ pf_cfg.show_album_name == ALBUM_AND_ARTIST_TOP)
fpstxt_y = LCD_HEIGHT -
rb->screens[SCREEN_MAIN]->getcharheight();
else
@@ -4480,15 +4646,17 @@ static int pictureflow_main(const char* selected_file)
case PF_WPS:
return PLUGIN_GOTO_WPS;
case PF_BACK:
- if ( pf_state == pf_show_tracks )
+ if (show_tracks_while_browsing)
+ show_tracks_while_browsing = false;
+ else if (pf_state == pf_show_tracks)
{
pf_state = pf_cover_out;
free_borrowed_tracks();
}
else if (pf_state == pf_cover_in)
- revert_cover_in_animation();
+ reverse_animation();
else if (pf_state == pf_cover_out)
- interrupt_cover_out_animation();
+ skip_animation_to_idle_state();
else if (pf_state == pf_idle || pf_state == pf_scrolling)
return PLUGIN_OK;
break;
@@ -4513,11 +4681,16 @@ static int pictureflow_main(const char* selected_file)
case PF_NEXT:
case PF_NEXT_REPEAT:
if ( pf_state == pf_show_tracks )
- select_next_track();
+ {
+ if (show_tracks_while_browsing)
+ select_next_album();
+ else
+ select_next_track();
+ }
else if (pf_state == pf_cover_in)
- interrupt_cover_in_animation();
+ skip_animation_to_show_tracks();
else if (pf_state == pf_cover_out)
- interrupt_cover_out_animation();
+ skip_animation_to_idle_state();
if ( pf_state == pf_idle || pf_state == pf_scrolling )
show_next_slide();
@@ -4526,11 +4699,16 @@ static int pictureflow_main(const char* selected_file)
case PF_PREV:
case PF_PREV_REPEAT:
if ( pf_state == pf_show_tracks )
- select_prev_track();
+ {
+ if (show_tracks_while_browsing)
+ select_prev_album();
+ else
+ select_prev_track();
+ }
else if (pf_state == pf_cover_in)
- interrupt_cover_in_animation();
+ skip_animation_to_show_tracks();
else if (pf_state == pf_cover_out)
- interrupt_cover_out_animation();
+ skip_animation_to_idle_state();
if ( pf_state == pf_idle || pf_state == pf_scrolling )
show_previous_slide();
@@ -4566,21 +4744,30 @@ static int pictureflow_main(const char* selected_file)
}
else if ( pf_state == pf_show_tracks )
select_prev_album();
+ else if (pf_state == pf_cover_in)
+ reverse_animation();
+ else if (pf_state == pf_cover_out)
+ skip_animation_to_idle_state();
break;
#if PF_PLAYBACK_CAPABLE
case PF_CONTEXT:
- if (pf_cfg.auto_wps != 0 &&
- (pf_state == pf_idle || pf_state == pf_scrolling ||
- pf_state == pf_show_tracks || pf_state == pf_cover_out)) {
-
+ if (pf_state == pf_idle || pf_state == pf_scrolling ||
+ pf_state == pf_show_tracks || pf_state == pf_cover_out)
+ {
if ( pf_state == pf_scrolling)
{
set_current_slide(target);
pf_state = pf_idle;
- } else if (pf_state == pf_cover_out)
- interrupt_cover_out_animation();
+ }
+ else if (pf_state == pf_cover_out)
+ skip_animation_to_idle_state();
- show_current_playlist_menu();
+ if (context_menu_ready())
+ {
+ ret = context_menu();
+ context_menu_cleanup();
+ if ( ret != 0 ) return ret;
+ }
}
break;
#endif
@@ -4603,19 +4790,22 @@ static int pictureflow_main(const char* selected_file)
pf_state = pf_cover_in;
}
else if (pf_state == pf_cover_out)
- revert_cover_out_animation();
+ reverse_animation();
else if (pf_state == pf_cover_in)
- interrupt_cover_in_animation();
+ skip_animation_to_show_tracks();
+ else if (pf_state == pf_show_tracks)
+ {
+ if (show_tracks_while_browsing)
+ show_tracks_while_browsing = false;
#if PF_PLAYBACK_CAPABLE
- else if (pf_state == pf_show_tracks) {
- if(pf_cfg.auto_wps != 0) {
+ else if(pf_cfg.auto_wps != 0) {
if (start_playback(true))
return PLUGIN_GOTO_WPS;
}
else
start_playback(false);
- }
#endif
+ }
break;
default:
exit_on_usb(button);
@@ -4636,17 +4826,12 @@ enum plugin_status plugin_start(const void *parameter)
void * buf;
size_t buf_size;
- bool prompt = (parameter && (((char *) parameter)[0] == ACTIVITY_MAINMENU));
bool file_id3 = (parameter && (((char *) parameter)[0] == '/'));
- if (!check_database(prompt))
+ if (!check_database())
{
- if (prompt)
- return PLUGIN_OK;
- else
- error_wait("Please enable database");
-
- return PLUGIN_ERROR;
+ error_wait("Please enable database");
+ return PLUGIN_OK;
}
atexit(cleanup);
@@ -4686,7 +4871,10 @@ enum plugin_status plugin_start(const void *parameter)
ret = file_id3 ? pictureflow_main(file) : pictureflow_main(NULL);
if ( ret == PLUGIN_OK || ret == PLUGIN_GOTO_WPS) {
- pf_cfg.last_album = center_index;
+ if (pf_state == pf_scrolling)
+ pf_cfg.last_album = target;
+ else
+ pf_cfg.last_album = center_index;
if (configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS,
CONFIG_VERSION))
{