Modified playlist handling to allow for multiple playlists to be edited at the same time. Added support in playlist viewer for viewing/editing playlists on disk (accessed via ON+PLAY->Playlist->View on a playlist). Added menu in playlist viewer for changing a few settings and saving playlist. Added File Options menu in playlist viewer ON+PLAY menu.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4276 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
1c7a88de78
commit
107ebc5ba9
14 changed files with 1307 additions and 645 deletions
|
@ -140,7 +140,7 @@ static bool bookmark_load_menu(void)
|
|||
return false;
|
||||
else
|
||||
{
|
||||
char* name = playlist_get_name(global_temp_buffer,
|
||||
char* name = playlist_get_name(NULL, global_temp_buffer,
|
||||
sizeof(global_temp_buffer));
|
||||
if (generate_bookmark_file_name(name,
|
||||
global_bookmark_file_name,
|
||||
|
@ -306,7 +306,7 @@ static bool write_bookmark(bool create_bookmark_file)
|
|||
/* writing the bookmark */
|
||||
if (create_bookmark_file)
|
||||
{
|
||||
char* name = playlist_get_name(global_temp_buffer,
|
||||
char* name = playlist_get_name(NULL, global_temp_buffer,
|
||||
sizeof(global_temp_buffer));
|
||||
if (generate_bookmark_file_name(name,
|
||||
global_bookmark_file_name,
|
||||
|
@ -428,12 +428,13 @@ static char* create_bookmark()
|
|||
"%d;%d;%d;%d;%d;%d;%d;%s;%s",
|
||||
resume_index,
|
||||
id3->offset,
|
||||
playlist_get_seed(),
|
||||
playlist_get_seed(NULL),
|
||||
0,
|
||||
id3->elapsed,
|
||||
global_settings.repeat_mode,
|
||||
global_settings.playlist_shuffle,
|
||||
playlist_get_name(global_temp_buffer,sizeof(global_temp_buffer)),
|
||||
playlist_get_name(NULL, global_temp_buffer,
|
||||
sizeof(global_temp_buffer)),
|
||||
file+1);
|
||||
|
||||
/* checking to see if the bookmark is valid */
|
||||
|
@ -1090,7 +1091,7 @@ static bool system_check(void)
|
|||
/* something bad happened while getting the queue information */
|
||||
return false;
|
||||
}
|
||||
else if (playlist_modified())
|
||||
else if (playlist_modified(NULL))
|
||||
{
|
||||
/* can't bookmark while in the queue */
|
||||
return false;
|
||||
|
|
|
@ -1666,3 +1666,38 @@ id: LANG_CREATE_DIR
|
|||
desc: in main menu
|
||||
eng: "Create directory"
|
||||
new:
|
||||
|
||||
id: LANG_VIEW
|
||||
desc: in on+play menu
|
||||
eng: "View"
|
||||
new:
|
||||
|
||||
id: LANG_SHOW_INDICES
|
||||
desc: in playlist viewer menu
|
||||
eng: "Show Indices"
|
||||
new:
|
||||
|
||||
id: LANG_TRACK_DISPLAY
|
||||
desc: in playlist viewer on+play menu
|
||||
eng: "Track Display"
|
||||
new:
|
||||
|
||||
id: LANG_DISPLAY_TRACK_NAME_ONLY
|
||||
desc: track display options
|
||||
eng: "Track name only"
|
||||
new:
|
||||
|
||||
id: LANG_DISPLAY_FULL_PATH
|
||||
desc: track display options
|
||||
eng: "Full path"
|
||||
new:
|
||||
|
||||
id: LANG_REMOVE
|
||||
desc: in playlist viewer on+play menu
|
||||
eng: "Remove"
|
||||
new:
|
||||
|
||||
id: LANG_FILE_OPTIONS
|
||||
desc: in playlist viewer on+play menu
|
||||
eng: "File Options"
|
||||
new:
|
||||
|
|
|
@ -44,7 +44,7 @@ struct menu {
|
|||
int itemcount;
|
||||
};
|
||||
|
||||
#define MAX_MENUS 4
|
||||
#define MAX_MENUS 5
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "buffer.h"
|
||||
#include "settings.h"
|
||||
#include "status.h"
|
||||
#include "playlist_viewer.h"
|
||||
#include "onplay.h"
|
||||
|
||||
static char* selected_file = NULL;
|
||||
|
@ -60,7 +61,7 @@ static bool add_to_playlist(int position, bool queue)
|
|||
playlist_create(NULL, NULL);
|
||||
|
||||
if ((selected_file_attr & TREE_ATTR_MASK) == TREE_ATTR_MPA)
|
||||
playlist_insert_track(selected_file, position, queue);
|
||||
playlist_insert_track(NULL, selected_file, position, queue);
|
||||
else if (selected_file_attr & ATTR_DIRECTORY)
|
||||
{
|
||||
bool recurse = false;
|
||||
|
@ -99,10 +100,11 @@ static bool add_to_playlist(int position, bool queue)
|
|||
}
|
||||
}
|
||||
|
||||
playlist_insert_directory(selected_file, position, queue, recurse);
|
||||
playlist_insert_directory(NULL, selected_file, position, queue,
|
||||
recurse);
|
||||
}
|
||||
else if ((selected_file_attr & TREE_ATTR_MASK) == TREE_ATTR_M3U)
|
||||
playlist_insert_playlist(selected_file, position, queue);
|
||||
playlist_insert_playlist(NULL, selected_file, position, queue);
|
||||
|
||||
if (new_playlist && (playlist_amount() > 0))
|
||||
{
|
||||
|
@ -119,12 +121,36 @@ static bool add_to_playlist(int position, bool queue)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool view_playlist(void)
|
||||
{
|
||||
bool was_playing = mpeg_status() & MPEG_STATUS_PLAY;
|
||||
bool result;
|
||||
|
||||
result = playlist_viewer_ex(selected_file);
|
||||
|
||||
if (!was_playing && (mpeg_status() & MPEG_STATUS_PLAY) &&
|
||||
onplay_result == ONPLAY_OK)
|
||||
/* playlist was started from viewer */
|
||||
onplay_result = ONPLAY_START_PLAY;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Sub-menu for playlist options */
|
||||
static bool playlist_options(void)
|
||||
{
|
||||
struct menu_items menu[6];
|
||||
struct playlist_args args[6]; /* increase these 2 if you add entries! */
|
||||
int m, i=0, result;
|
||||
struct menu_items menu[7];
|
||||
struct playlist_args args[7]; /* increase these 2 if you add entries! */
|
||||
int m, i=0, pstart=0, result;
|
||||
bool ret = false;
|
||||
|
||||
if ((selected_file_attr & TREE_ATTR_MASK) == TREE_ATTR_M3U)
|
||||
{
|
||||
menu[i].desc = str(LANG_VIEW);
|
||||
menu[i].function = view_playlist;
|
||||
i++;
|
||||
pstart++;
|
||||
}
|
||||
|
||||
if (mpeg_status() & MPEG_STATUS_PLAY)
|
||||
{
|
||||
|
@ -169,11 +195,13 @@ static bool playlist_options(void)
|
|||
|
||||
m = menu_init( menu, i );
|
||||
result = menu_show(m);
|
||||
if (result >= 0)
|
||||
add_to_playlist(args[result].position, args[result].queue);
|
||||
if (result >= 0 && result < pstart)
|
||||
ret = menu[result].function();
|
||||
else if (result >= pstart)
|
||||
ret = add_to_playlist(args[result].position, args[result].queue);
|
||||
menu_exit(m);
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool delete_file(void)
|
||||
|
@ -489,8 +517,9 @@ int onplay(char* file, int attr)
|
|||
selected_file = file;
|
||||
selected_file_attr = attr;
|
||||
|
||||
if (((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) || (attr & ATTR_DIRECTORY) ||
|
||||
(((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U) && (mpeg_status() & MPEG_STATUS_PLAY)))
|
||||
if (((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) ||
|
||||
(attr & ATTR_DIRECTORY) ||
|
||||
((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U))
|
||||
{
|
||||
menu[i].desc = str(LANG_PLAYINDICES_PLAYLIST);
|
||||
menu[i].function = playlist_options;
|
||||
|
|
1349
apps/playlist.c
1349
apps/playlist.c
File diff suppressed because it is too large
Load diff
|
@ -28,9 +28,12 @@
|
|||
|
||||
struct playlist_info
|
||||
{
|
||||
bool current; /* current playing playlist */
|
||||
char filename[MAX_PATH]; /* path name of m3u playlist on disk */
|
||||
char control_filename[MAX_PATH]; /* full path of control file */
|
||||
int fd; /* descriptor of the open playlist file */
|
||||
int control_fd; /* descriptor of the open control file */
|
||||
bool control_created; /* has control file been created? */
|
||||
int dirlen; /* Length of the path to the playlist file */
|
||||
unsigned int *indices; /* array of indices */
|
||||
int max_playlist_size; /* Max number of files in playlist. Mirror of
|
||||
|
@ -63,33 +66,48 @@ struct playlist_track_info
|
|||
int display_index; /* index of track for display */
|
||||
};
|
||||
|
||||
/* Exported functions only for current playlist. */
|
||||
void playlist_init(void);
|
||||
int playlist_create(char *dir, char *file);
|
||||
int playlist_resume(void);
|
||||
int playlist_add(char *filename);
|
||||
int playlist_insert_track(char *filename, int position, bool queue);
|
||||
int playlist_insert_directory(char *dirname, int position, bool queue,
|
||||
bool recurse);
|
||||
int playlist_insert_playlist(char *filename, int position, bool queue);
|
||||
int playlist_delete(int index);
|
||||
int playlist_move(int index, int new_index);
|
||||
int playlist_shuffle(int random_seed, int start_index);
|
||||
int playlist_randomise(unsigned int seed, bool start_current);
|
||||
int playlist_sort(bool start_current);
|
||||
int playlist_start(int start_index, int offset);
|
||||
bool playlist_check(int steps);
|
||||
char *playlist_peek(int steps);
|
||||
int playlist_next(int steps);
|
||||
int playlist_get_resume_info(int *resume_index);
|
||||
int playlist_get_display_index(void);
|
||||
int playlist_get_first_index(void);
|
||||
int playlist_amount(void);
|
||||
char *playlist_name(char *buf, int buf_size);
|
||||
int playlist_get_track_info(int index, struct playlist_track_info* info);
|
||||
int playlist_save(char *filename);
|
||||
int playlist_get_seed(void);
|
||||
char *playlist_get_name(char *buf, int buf_size);
|
||||
bool playlist_modified(void);
|
||||
|
||||
/* Exported functions for all playlists. Pass NULL for playlist_info
|
||||
structure to work with current playlist. */
|
||||
int playlist_create_ex(struct playlist_info* playlist, char* dir, char* file,
|
||||
void* index_buffer, int index_buffer_size,
|
||||
void* temp_buffer, int temp_buffer_size);
|
||||
int playlist_set_current(struct playlist_info* playlist);
|
||||
void playlist_close(struct playlist_info* playlist);
|
||||
int playlist_insert_track(struct playlist_info* playlist, char *filename,
|
||||
int position, bool queue);
|
||||
int playlist_insert_directory(struct playlist_info* playlist, char *dirname,
|
||||
int position, bool queue, bool recurse);
|
||||
int playlist_insert_playlist(struct playlist_info* playlist, char *filename,
|
||||
int position, bool queue);
|
||||
int playlist_delete(struct playlist_info* playlist, int index);
|
||||
int playlist_move(struct playlist_info* playlist, int index, int new_index);
|
||||
int playlist_randomise(struct playlist_info* playlist, unsigned int seed,
|
||||
bool start_current);
|
||||
int playlist_sort(struct playlist_info* playlist, bool start_current);
|
||||
bool playlist_modified(struct playlist_info* playlist);
|
||||
int playlist_get_first_index(struct playlist_info* playlist);
|
||||
int playlist_get_seed(struct playlist_info* playlist);
|
||||
int playlist_amount_ex(struct playlist_info* playlist);
|
||||
char *playlist_name(struct playlist_info* playlist, char *buf, int buf_size);
|
||||
char *playlist_get_name(struct playlist_info* playlist, char *buf,
|
||||
int buf_size);
|
||||
int playlist_get_track_info(struct playlist_info* playlist, int index,
|
||||
struct playlist_track_info* info);
|
||||
int playlist_save(struct playlist_info* playlist, char *filename);
|
||||
|
||||
enum {
|
||||
PLAYLIST_PREPEND = -1,
|
||||
|
|
|
@ -39,7 +39,7 @@ static bool save_playlist(void)
|
|||
|
||||
if (!kbd_input(filename, sizeof(filename)))
|
||||
{
|
||||
playlist_save(filename);
|
||||
playlist_save(NULL, filename);
|
||||
|
||||
/* reload in case playlist was saved to cwd */
|
||||
reload_directory();
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#include "icons.h"
|
||||
#include "menu.h"
|
||||
#include "plugin.h"
|
||||
#include "keyboard.h"
|
||||
#include "tree.h"
|
||||
#include "onplay.h"
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "widgets.h"
|
||||
|
@ -35,6 +38,8 @@
|
|||
|
||||
#include "lang.h"
|
||||
|
||||
#include "playlist_viewer.h"
|
||||
|
||||
/* Defines for LCD display purposes. Taken from tree.c */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#define CURSOR_X (global_settings.scrollbar && \
|
||||
|
@ -46,7 +51,9 @@
|
|||
|
||||
#define MARGIN_X ((global_settings.scrollbar && \
|
||||
viewer.num_tracks > viewer.num_display_lines ? \
|
||||
SCROLLBAR_WIDTH : 0) + CURSOR_WIDTH + ICON_WIDTH)
|
||||
SCROLLBAR_WIDTH : 0) + CURSOR_WIDTH + \
|
||||
(global_settings.playlist_viewer_icons ? \
|
||||
ICON_WIDTH : 0))
|
||||
#define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0)
|
||||
|
||||
#define LINE_X 0
|
||||
|
@ -67,11 +74,15 @@
|
|||
/* Maximum number of tracks we can have loaded at one time */
|
||||
#define MAX_PLAYLIST_ENTRIES 200
|
||||
|
||||
/* Default playlist name for saving */
|
||||
#define DEFAULT_PLAYLIST_NAME "/viewer.m3u"
|
||||
|
||||
/* Index of track on display line _pos */
|
||||
#define INDEX(_pos) (viewer.first_display_index - viewer.first_index + (_pos))
|
||||
|
||||
/* Global playlist viewer settings */
|
||||
struct playlist_viewer_info {
|
||||
struct playlist_info* playlist; /* playlist being viewed */
|
||||
char *name_buffer; /* Buffer used to store track names */
|
||||
int buffer_size; /* Size of name buffer */
|
||||
|
||||
|
@ -103,15 +114,19 @@ struct playlist_entry {
|
|||
static struct playlist_viewer_info viewer;
|
||||
static struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES];
|
||||
|
||||
/* Used when viewing playlists on disk */
|
||||
static struct playlist_info temp_playlist;
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
extern unsigned char bitmap_icons_6x8[LastIcon][6];
|
||||
#endif
|
||||
|
||||
static bool initialize(void);
|
||||
static bool initialize(char* filename, bool reload);
|
||||
static void load_playlist_entries(int start_index);
|
||||
static void load_playlist_entries_r(int end_index);
|
||||
static int load_entry(int index, int pos, char* p, int size);
|
||||
static void format_name(char* dest, char* src);
|
||||
static void format_line(struct playlist_entry* track, char* str, int len);
|
||||
static void display_playlist(void);
|
||||
static void update_display_line(int line, bool scroll);
|
||||
static void scroll_display(int lines);
|
||||
|
@ -120,18 +135,74 @@ static bool update_playlist(bool force);
|
|||
#ifdef BUTTON_ON
|
||||
static int onplay_menu(int index);
|
||||
#endif
|
||||
static bool viewer_menu(void);
|
||||
static bool show_icons(void);
|
||||
static bool show_indices(void);
|
||||
static bool track_display(void);
|
||||
static bool save_playlist(void);
|
||||
|
||||
/* Initialize the playlist viewer */
|
||||
static bool initialize(void)
|
||||
/* Initialize the playlist viewer. */
|
||||
static bool initialize(char* filename, bool reload)
|
||||
{
|
||||
if (!(mpeg_status() & MPEG_STATUS_PLAY))
|
||||
char* buffer;
|
||||
int buffer_size;
|
||||
bool is_playing = mpeg_status() & MPEG_STATUS_PLAY;
|
||||
|
||||
if (!filename && !is_playing)
|
||||
/* Nothing is playing, exit */
|
||||
return false;
|
||||
|
||||
viewer.name_buffer = plugin_get_buffer(&viewer.buffer_size);
|
||||
if (!viewer.name_buffer)
|
||||
buffer = plugin_get_buffer(&buffer_size);
|
||||
if (!buffer)
|
||||
return false;
|
||||
|
||||
if (!filename)
|
||||
viewer.playlist = NULL;
|
||||
else
|
||||
{
|
||||
/* Viewing playlist on disk */
|
||||
char *dir, *file, *temp_ptr;
|
||||
char *index_buffer = NULL;
|
||||
int index_buffer_size = 0;
|
||||
|
||||
viewer.playlist = &temp_playlist;
|
||||
|
||||
/* Separate directory from filename */
|
||||
temp_ptr = strrchr(filename+1,'/');
|
||||
if (temp_ptr)
|
||||
{
|
||||
*temp_ptr = 0;
|
||||
dir = filename;
|
||||
file = temp_ptr + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = "/";
|
||||
file = filename+1;
|
||||
}
|
||||
|
||||
if (is_playing)
|
||||
{
|
||||
/* Something is playing, use half the plugin buffer for playlist
|
||||
indices */
|
||||
index_buffer_size = buffer_size / 2;
|
||||
index_buffer = buffer;
|
||||
}
|
||||
|
||||
playlist_create_ex(viewer.playlist, dir, file, index_buffer,
|
||||
index_buffer_size, buffer+index_buffer_size,
|
||||
buffer_size-index_buffer_size);
|
||||
|
||||
if (temp_ptr)
|
||||
*temp_ptr = '/';
|
||||
|
||||
buffer += index_buffer_size;
|
||||
buffer_size -= index_buffer_size;
|
||||
}
|
||||
|
||||
viewer.name_buffer = buffer;
|
||||
viewer.buffer_size = buffer_size;
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{
|
||||
char icon_chars[] = "MQ"; /* characters used as icons */
|
||||
|
@ -166,12 +237,20 @@ static bool initialize(void)
|
|||
viewer.line_height = 1;
|
||||
#endif
|
||||
|
||||
viewer.cursor_pos = 0;
|
||||
viewer.move_track = -1;
|
||||
|
||||
/* Start displaying at current playing track */
|
||||
viewer.first_display_index = playlist_get_display_index() - 1;
|
||||
update_first_index();
|
||||
if (!reload)
|
||||
{
|
||||
viewer.cursor_pos = 0;
|
||||
|
||||
if (!viewer.playlist)
|
||||
/* Start displaying at current playing track */
|
||||
viewer.first_display_index = playlist_get_display_index() - 1;
|
||||
else
|
||||
viewer.first_display_index = 0;
|
||||
|
||||
update_first_index();
|
||||
}
|
||||
|
||||
if (!update_playlist(true))
|
||||
return false;
|
||||
|
@ -287,21 +366,19 @@ static int load_entry(int index, int pos, char* p, int size)
|
|||
struct playlist_track_info info;
|
||||
int len;
|
||||
int result = 0;
|
||||
char name[MAX_PATH];
|
||||
|
||||
/* Playlist viewer orders songs based on display index. We need to
|
||||
convert to real playlist index to access track */
|
||||
index = (index + playlist_get_first_index()) % viewer.num_tracks;
|
||||
if (playlist_get_track_info(index, &info) < 0)
|
||||
index = (index + playlist_get_first_index(viewer.playlist)) %
|
||||
viewer.num_tracks;
|
||||
if (playlist_get_track_info(viewer.playlist, index, &info) < 0)
|
||||
return -1;
|
||||
|
||||
format_name(name, info.filename);
|
||||
|
||||
len = strlen(name) + 1;
|
||||
len = strlen(info.filename) + 1;
|
||||
|
||||
if (len <= size)
|
||||
{
|
||||
strcpy(p, name);
|
||||
strcpy(p, info.filename);
|
||||
|
||||
tracks[pos].name = p;
|
||||
tracks[pos].index = info.index;
|
||||
|
@ -319,18 +396,46 @@ static int load_entry(int index, int pos, char* p, int size)
|
|||
/* Format trackname for display purposes */
|
||||
static void format_name(char* dest, char* src)
|
||||
{
|
||||
char* p = strrchr(src, '/');
|
||||
int len;
|
||||
switch (global_settings.playlist_viewer_track_display)
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
/* Only display the mp3 filename */
|
||||
char* p = strrchr(src, '/');
|
||||
int len;
|
||||
|
||||
strcpy(dest, p+1);
|
||||
len = strlen(dest);
|
||||
|
||||
/* Remove the extension */
|
||||
if (!strcasecmp(&dest[len-4], ".mp3") ||
|
||||
!strcasecmp(&dest[len-4], ".mp2") ||
|
||||
!strcasecmp(&dest[len-4], ".mpa"))
|
||||
dest[len-4] = '\0';
|
||||
|
||||
/* Only display the mp3 filename */
|
||||
strcpy(dest, p+1);
|
||||
len = strlen(dest);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
/* Full path */
|
||||
strcpy(dest, src);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Format display line */
|
||||
static void format_line(struct playlist_entry* track, char* str, int len)
|
||||
{
|
||||
char name[MAX_PATH];
|
||||
|
||||
format_name(name, track->name);
|
||||
|
||||
if (global_settings.playlist_viewer_indices)
|
||||
/* Display playlist index */
|
||||
snprintf(str, len, "%d. %s", track->display_index, name);
|
||||
else
|
||||
snprintf(str, len, "%s", name);
|
||||
|
||||
/* Remove the extension */
|
||||
if (!strcasecmp(&dest[len-4], ".mp3") ||
|
||||
!strcasecmp(&dest[len-4], ".mp2") ||
|
||||
!strcasecmp(&dest[len-4], ".mpa"))
|
||||
dest[len-4] = '\0';
|
||||
}
|
||||
|
||||
/* Display tracks on screen */
|
||||
|
@ -349,41 +454,44 @@ static void display_playlist(void)
|
|||
|
||||
for (i=0; i<=num_display_tracks; i++)
|
||||
{
|
||||
/* Icons */
|
||||
if (tracks[INDEX(i)].index == viewer.current_playing_track)
|
||||
if (global_settings.playlist_viewer_icons)
|
||||
{
|
||||
/* Current playing track */
|
||||
/* Icons */
|
||||
if (tracks[INDEX(i)].index == viewer.current_playing_track)
|
||||
{
|
||||
/* Current playing track */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
int offset=0;
|
||||
if ( viewer.line_height > 8 )
|
||||
offset = (viewer.line_height - 8) / 2;
|
||||
lcd_bitmap(bitmap_icons_6x8[File],
|
||||
CURSOR_X * 6 + CURSOR_WIDTH,
|
||||
MARGIN_Y+(i*viewer.line_height) + offset,
|
||||
6, 8, true);
|
||||
int offset=0;
|
||||
if ( viewer.line_height > 8 )
|
||||
offset = (viewer.line_height - 8) / 2;
|
||||
lcd_bitmap(bitmap_icons_6x8[File],
|
||||
CURSOR_X * 6 + CURSOR_WIDTH,
|
||||
MARGIN_Y+(i*viewer.line_height) + offset,
|
||||
6, 8, true);
|
||||
#else
|
||||
lcd_putc(LINE_X-1, i, File);
|
||||
lcd_putc(LINE_X-1, i, File);
|
||||
#endif
|
||||
}
|
||||
else if (tracks[INDEX(i)].index == viewer.move_track)
|
||||
{
|
||||
/* Track we are moving */
|
||||
}
|
||||
else if (tracks[INDEX(i)].index == viewer.move_track)
|
||||
{
|
||||
/* Track we are moving */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH,
|
||||
MARGIN_Y+(i*viewer.line_height), "M");
|
||||
lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH,
|
||||
MARGIN_Y+(i*viewer.line_height), "M");
|
||||
#else
|
||||
lcd_putc(LINE_X-1, i, 'M');
|
||||
lcd_putc(LINE_X-1, i, 'M');
|
||||
#endif
|
||||
}
|
||||
else if (tracks[INDEX(i)].queued)
|
||||
{
|
||||
/* Queued track */
|
||||
}
|
||||
else if (tracks[INDEX(i)].queued)
|
||||
{
|
||||
/* Queued track */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH,
|
||||
MARGIN_Y+(i*viewer.line_height), "Q");
|
||||
lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH,
|
||||
MARGIN_Y+(i*viewer.line_height), "Q");
|
||||
#else
|
||||
lcd_putc(LINE_X-1, i, 'Q');
|
||||
lcd_putc(LINE_X-1, i, 'Q');
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
update_display_line(i, false);
|
||||
|
@ -494,10 +602,8 @@ static void update_display_line(int line, bool scroll)
|
|||
{
|
||||
char str[MAX_PATH + 16];
|
||||
|
||||
snprintf(str, sizeof(str), "%d. %s",
|
||||
tracks[INDEX(line)].display_index,
|
||||
tracks[INDEX(line)].name);
|
||||
|
||||
format_line(&tracks[INDEX(line)], str, sizeof(str));
|
||||
|
||||
if (scroll)
|
||||
{
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
@ -516,7 +622,7 @@ static void update_display_line(int line, bool scroll)
|
|||
static void update_first_index(void)
|
||||
{
|
||||
/* viewer.num_tracks may be invalid at this point */
|
||||
int num_tracks = playlist_amount();
|
||||
int num_tracks = playlist_amount_ex(viewer.playlist);
|
||||
|
||||
if ((num_tracks - viewer.first_display_index) < viewer.num_display_lines)
|
||||
{
|
||||
|
@ -535,14 +641,17 @@ static void update_first_index(void)
|
|||
/* Update playlist in case something has changed or forced */
|
||||
static bool update_playlist(bool force)
|
||||
{
|
||||
playlist_get_resume_info(&viewer.current_playing_track);
|
||||
if (!viewer.playlist)
|
||||
playlist_get_resume_info(&viewer.current_playing_track);
|
||||
else
|
||||
viewer.current_playing_track = -1;
|
||||
|
||||
if (force || playlist_amount() != viewer.num_tracks)
|
||||
if (force || playlist_amount_ex(viewer.playlist) != viewer.num_tracks)
|
||||
{
|
||||
int index;
|
||||
|
||||
/* Reload tracks */
|
||||
viewer.num_tracks = playlist_amount();
|
||||
viewer.num_tracks = playlist_amount_ex(viewer.playlist);
|
||||
if (viewer.num_tracks < 0)
|
||||
return false;
|
||||
|
||||
|
@ -571,16 +680,19 @@ static bool update_playlist(bool force)
|
|||
changed. */
|
||||
static int onplay_menu(int index)
|
||||
{
|
||||
struct menu_items menu[2]; /* increase this if you add entries! */
|
||||
struct menu_items menu[3]; /* increase this if you add entries! */
|
||||
int m, i=0, result, ret = 0;
|
||||
bool current = (tracks[index].index == viewer.current_playing_track);
|
||||
|
||||
menu[i].desc = str(LANG_DELETE);
|
||||
menu[i].desc = str(LANG_REMOVE);
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_MOVE);
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_FILE_OPTIONS);
|
||||
i++;
|
||||
|
||||
m = menu_init(menu, i);
|
||||
result = menu_show(m);
|
||||
if (result == MENU_ATTACHED_USB)
|
||||
|
@ -597,7 +709,7 @@ static int onplay_menu(int index)
|
|||
if (current)
|
||||
mpeg_stop();
|
||||
|
||||
playlist_delete(tracks[index].index);
|
||||
playlist_delete(viewer.playlist, tracks[index].index);
|
||||
|
||||
if (current)
|
||||
{
|
||||
|
@ -618,6 +730,17 @@ static int onplay_menu(int index)
|
|||
viewer.move_track = tracks[index].index;
|
||||
ret = 0;
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
onplay(tracks[index].name, TREE_ATTR_MPA);
|
||||
|
||||
if (!viewer.playlist)
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,17 +750,91 @@ static int onplay_menu(int index)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Main viewer function */
|
||||
/* Menu of viewer options. Invoked via F1(r) or Menu(p). */
|
||||
static bool viewer_menu(void)
|
||||
{
|
||||
int m;
|
||||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_SHOW_ICONS), show_icons },
|
||||
{ str(LANG_SHOW_INDICES), show_indices },
|
||||
{ str(LANG_TRACK_DISPLAY), track_display },
|
||||
{ str(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items) );
|
||||
result = menu_run(m);
|
||||
menu_exit(m);
|
||||
|
||||
settings_save();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Show icons in viewer? */
|
||||
static bool show_icons(void)
|
||||
{
|
||||
return set_bool(str(LANG_SHOW_ICONS),
|
||||
&global_settings.playlist_viewer_icons);
|
||||
}
|
||||
|
||||
/* Show indices of tracks? */
|
||||
static bool show_indices(void)
|
||||
{
|
||||
return set_bool(str(LANG_SHOW_INDICES),
|
||||
&global_settings.playlist_viewer_indices);
|
||||
}
|
||||
|
||||
/* How to display a track */
|
||||
static bool track_display(void)
|
||||
{
|
||||
char* names[] = {
|
||||
str(LANG_DISPLAY_TRACK_NAME_ONLY),
|
||||
str(LANG_DISPLAY_FULL_PATH)
|
||||
};
|
||||
|
||||
return set_option(str(LANG_TRACK_DISPLAY),
|
||||
&global_settings.playlist_viewer_track_display, INT, names, 2, NULL);
|
||||
}
|
||||
|
||||
/* Save playlist to disk */
|
||||
static bool save_playlist(void)
|
||||
{
|
||||
char filename[MAX_PATH+1];
|
||||
|
||||
strncpy(filename, DEFAULT_PLAYLIST_NAME, sizeof(filename));
|
||||
|
||||
if (!kbd_input(filename, sizeof(filename)))
|
||||
{
|
||||
playlist_save(viewer.playlist, filename);
|
||||
|
||||
/* reload in case playlist was saved to cwd */
|
||||
reload_directory();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* View current playlist */
|
||||
bool playlist_viewer(void)
|
||||
{
|
||||
return playlist_viewer_ex(NULL);
|
||||
}
|
||||
|
||||
/* Main viewer function. Filename identifies playlist to be viewed. If NULL,
|
||||
view current playlist. */
|
||||
bool playlist_viewer_ex(char* filename)
|
||||
{
|
||||
bool ret = false; /* return value */
|
||||
bool exit=false; /* exit viewer */
|
||||
bool update=true; /* update display */
|
||||
bool cursor_on=true; /* used for flashing cursor */
|
||||
int old_cursor_pos; /* last cursor position */
|
||||
int button;
|
||||
|
||||
if (!initialize())
|
||||
return false;
|
||||
if (!initialize(filename, false))
|
||||
goto exit;
|
||||
|
||||
old_cursor_pos = viewer.cursor_pos;
|
||||
|
||||
|
@ -648,7 +845,7 @@ bool playlist_viewer(void)
|
|||
/* Timeout so we can determine if play status has changed */
|
||||
button = button_get_w_tmo(HZ/2);
|
||||
|
||||
if (!(mpeg_status() & MPEG_STATUS_PLAY))
|
||||
if (!viewer.playlist && !(mpeg_status() & MPEG_STATUS_PLAY))
|
||||
{
|
||||
/* Play has stopped */
|
||||
#ifdef HAVE_LCD_CHARCELLS
|
||||
|
@ -657,7 +854,7 @@ bool playlist_viewer(void)
|
|||
splash(HZ, true, str(LANG_END_PLAYLIST_RECORDER));
|
||||
#endif
|
||||
status_set_playmode(STATUS_STOP);
|
||||
return false;;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (viewer.move_track != -1 || !cursor_on)
|
||||
|
@ -685,10 +882,13 @@ bool playlist_viewer(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
playlist_get_resume_info(&track);
|
||||
if (!viewer.playlist)
|
||||
playlist_get_resume_info(&track);
|
||||
else
|
||||
track = -1;
|
||||
|
||||
if (track != viewer.current_playing_track ||
|
||||
playlist_amount() != viewer.num_tracks)
|
||||
playlist_amount_ex(viewer.playlist) != viewer.num_tracks)
|
||||
{
|
||||
/* Playlist has changed (new track started?) */
|
||||
update_first_index();
|
||||
|
@ -769,7 +969,7 @@ bool playlist_viewer(void)
|
|||
/* Move track */
|
||||
int ret;
|
||||
|
||||
ret = playlist_move(viewer.move_track,
|
||||
ret = playlist_move(viewer.playlist, viewer.move_track,
|
||||
tracks[INDEX(viewer.cursor_pos)].index);
|
||||
if (ret < 0)
|
||||
splash(HZ, true, str(LANG_MOVE_FAILED));
|
||||
|
@ -777,7 +977,7 @@ bool playlist_viewer(void)
|
|||
update_playlist(true);
|
||||
viewer.move_track = -1;
|
||||
}
|
||||
else
|
||||
else if (!viewer.playlist)
|
||||
{
|
||||
/* Stop current track and play new track */
|
||||
mpeg_stop();
|
||||
|
@ -785,6 +985,22 @@ bool playlist_viewer(void)
|
|||
status_set_playmode(STATUS_PLAY);
|
||||
update_playlist(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Play track from playlist on disk */
|
||||
mpeg_stop();
|
||||
|
||||
/* New playlist */
|
||||
if (playlist_set_current(viewer.playlist) < 0)
|
||||
goto exit;
|
||||
|
||||
playlist_start(tracks[INDEX(viewer.cursor_pos)].index, 0);
|
||||
status_set_playmode(STATUS_PLAY);
|
||||
|
||||
/* Our playlist is now the current list */
|
||||
if (!initialize(NULL, true))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
display_playlist();
|
||||
update = true;
|
||||
|
@ -799,13 +1015,15 @@ bool playlist_viewer(void)
|
|||
ret = onplay_menu(INDEX(viewer.cursor_pos));
|
||||
|
||||
if (ret < 0)
|
||||
/* USB attached */
|
||||
return true;
|
||||
{
|
||||
ret = true;
|
||||
goto exit;
|
||||
}
|
||||
else if (ret > 0)
|
||||
{
|
||||
/* Playlist changed */
|
||||
update_first_index();
|
||||
update_playlist(true);
|
||||
update_playlist(false);
|
||||
if (viewer.num_tracks <= 0)
|
||||
exit = true;
|
||||
}
|
||||
|
@ -816,9 +1034,30 @@ bool playlist_viewer(void)
|
|||
break;
|
||||
}
|
||||
#endif /* BUTTON_ON */
|
||||
#ifdef HAVE_RECORDER_KEYPAD
|
||||
case BUTTON_F1:
|
||||
#else
|
||||
case BUTTON_MENU:
|
||||
#endif
|
||||
if (viewer_menu())
|
||||
{
|
||||
ret = true;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
display_playlist();
|
||||
update = true;
|
||||
break;
|
||||
|
||||
case SYS_USB_CONNECTED:
|
||||
usb_screen();
|
||||
return true;
|
||||
ret = true;
|
||||
goto exit;
|
||||
break;
|
||||
|
||||
case BUTTON_NONE:
|
||||
status_draw(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (update && !exit)
|
||||
|
@ -852,5 +1091,8 @@ bool playlist_viewer(void)
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
exit:
|
||||
if (viewer.playlist)
|
||||
playlist_close(viewer.playlist);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
#define _PLAYLIST_VIEWER_H_
|
||||
|
||||
bool playlist_viewer(void);
|
||||
bool playlist_viewer_ex(char* filename);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -512,9 +512,9 @@ bool f2_screen(void)
|
|||
if(mpeg_status() & MPEG_STATUS_PLAY)
|
||||
{
|
||||
if (global_settings.playlist_shuffle)
|
||||
playlist_randomise(current_tick, true);
|
||||
playlist_randomise(NULL, current_tick, true);
|
||||
else
|
||||
playlist_sort(true);
|
||||
playlist_sort(NULL, true);
|
||||
}
|
||||
used = true;
|
||||
break;
|
||||
|
|
|
@ -146,6 +146,9 @@ Rest of config block, only saved to disk:
|
|||
caption backlight (bit 1)
|
||||
car adapter mode (bit 2)
|
||||
line_in (Player only) (bit 3)
|
||||
playlist viewer icons (bit 4)
|
||||
playlist viewer indices (bit 5)
|
||||
playlist viewer track display (bit 6)
|
||||
0xAF <most-recent-bookmarks, auto-bookmark, autoload>
|
||||
0xB0 peak meter clip hold timeout (bit 0-4), peak meter performance (bit 7)
|
||||
0xB1 peak meter release step size, peak_meter_dbfs (bit 7)
|
||||
|
@ -421,7 +424,10 @@ int settings_save( void )
|
|||
((global_settings.fade_on_stop & 1) |
|
||||
((global_settings.caption_backlight & 1) << 1) |
|
||||
((global_settings.car_adapter_mode & 1) << 2) |
|
||||
((global_settings.line_in & 1) << 3));
|
||||
((global_settings.line_in & 1) << 3) |
|
||||
((global_settings.playlist_viewer_icons & 1) << 4) |
|
||||
((global_settings.playlist_viewer_indices & 1) << 5) |
|
||||
((global_settings.playlist_viewer_track_display & 1) << 6));
|
||||
config_block[0xaf] = ((global_settings.usemrb << 5) |
|
||||
(global_settings.autocreatebookmark << 2) |
|
||||
(global_settings.autoloadbookmark));
|
||||
|
@ -726,6 +732,12 @@ void settings_load(void)
|
|||
global_settings.caption_backlight = (config_block[0xae] >> 1) & 1;
|
||||
global_settings.car_adapter_mode = (config_block[0xae] >> 2) & 1;
|
||||
global_settings.line_in = (config_block[0xae] >> 3) & 1;
|
||||
global_settings.playlist_viewer_icons =
|
||||
(config_block[0xae] >> 4) & 1;
|
||||
global_settings.playlist_viewer_indices =
|
||||
(config_block[0xae] >> 5) & 1;
|
||||
global_settings.playlist_viewer_track_display =
|
||||
(config_block[0xae] >> 6) & 1;
|
||||
}
|
||||
|
||||
if(config_block[0xb0] != 0xff) {
|
||||
|
@ -1161,6 +1173,16 @@ bool settings_load_config(char* file)
|
|||
static char* options[] = {"off", "on", "unique only"};
|
||||
set_cfg_option(&global_settings.usemrb, value, options, 3);
|
||||
}
|
||||
else if (!strcasecmp(name, "playlist viewer icons"))
|
||||
set_cfg_bool(&global_settings.playlist_viewer_icons, value);
|
||||
else if (!strcasecmp(name, "playlist viewer indices"))
|
||||
set_cfg_bool(&global_settings.playlist_viewer_indices, value);
|
||||
else if (!strcasecmp(name, "playlist viewer track display"))
|
||||
{
|
||||
static char* options[] = {"track name", "full path"};
|
||||
set_cfg_option(&global_settings.playlist_viewer_track_display,
|
||||
value, options, 2);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
@ -1494,6 +1516,19 @@ bool settings_save_config(void)
|
|||
triopt[global_settings.recursive_dir_insert]);
|
||||
}
|
||||
|
||||
fprintf(fd, "#\r\n# Playlist viewer\r\n#\r\n");
|
||||
{
|
||||
fprintf(fd, "playlist viewer icons: %s\r\n",
|
||||
boolopt[global_settings.playlist_viewer_icons]);
|
||||
fprintf(fd, "playlist viewer indices: %s\r\n",
|
||||
boolopt[global_settings.playlist_viewer_indices]);
|
||||
{
|
||||
static char* options[] = {"track name", "full path"};
|
||||
fprintf(fd, "playlist viewer track display: %s\r\n",
|
||||
options[global_settings.playlist_viewer_track_display]);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
lcd_clear_display();
|
||||
|
@ -1596,6 +1631,9 @@ void settings_reset(void) {
|
|||
global_settings.show_icons = true;
|
||||
global_settings.recursive_dir_insert = RECURSE_OFF;
|
||||
global_settings.line_in = false;
|
||||
global_settings.playlist_viewer_icons = true;
|
||||
global_settings.playlist_viewer_indices = true;
|
||||
global_settings.playlist_viewer_track_display = 0;
|
||||
}
|
||||
|
||||
bool set_bool(char* string, bool* variable )
|
||||
|
|
|
@ -194,6 +194,11 @@ struct user_settings
|
|||
int recursive_dir_insert; /* should directories be inserted recursively */
|
||||
|
||||
bool line_in; /* false=off, true=active */
|
||||
|
||||
/* playlist viewer settings */
|
||||
bool playlist_viewer_icons; /* display icons on viewer */
|
||||
bool playlist_viewer_indices; /* display playlist indices on viewer */
|
||||
int playlist_viewer_track_display; /* how to display tracks in viewer */
|
||||
};
|
||||
|
||||
enum optiontype { INT, BOOL };
|
||||
|
|
|
@ -827,11 +827,11 @@ static bool playback_settings_menu(void)
|
|||
{
|
||||
if (global_settings.playlist_shuffle)
|
||||
{
|
||||
playlist_randomise(current_tick, true);
|
||||
playlist_randomise(NULL, current_tick, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
playlist_sort(true);
|
||||
playlist_sort(NULL, true);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -499,7 +499,7 @@ static char* get_tag(struct mp3entry* id3,
|
|||
|
||||
case 'n': /* Playlist Name (without path) */
|
||||
*flags |= WPS_REFRESH_STATIC;
|
||||
return playlist_name(buf, buf_size);
|
||||
return playlist_name(NULL, buf, buf_size);
|
||||
|
||||
case 'e': /* Playlist Total Entries */
|
||||
*flags |= WPS_REFRESH_STATIC;
|
||||
|
|
Loading…
Reference in a new issue