summaryrefslogtreecommitdiffstats
path: root/apps/screens.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/screens.c')
-rw-r--r--apps/screens.c184
1 files changed, 152 insertions, 32 deletions
diff --git a/apps/screens.c b/apps/screens.c
index 24d1fed915..c11e052bce 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -20,7 +20,7 @@
****************************************************************************/
#include <stdbool.h>
-#include <string.h>
+#include <string-extra.h>
#include <stdio.h>
#include <stdlib.h>
#include "backlight.h"
@@ -233,12 +233,10 @@ bool set_time_screen(const char* title, struct tm *tm, bool set_date)
else
prev_line_height = 0;
- screen->getstringsize(SEPARATOR, &separator_width, NULL);
-
/* weekday */
- screen->getstringsize(str(LANG_WEEKDAY_SUNDAY + tm->tm_wday),
- &weekday_width, NULL);
- screen->getstringsize(" ", &separator_width, NULL);
+ weekday_width = screen->getstringsize(str(LANG_WEEKDAY_SUNDAY + tm->tm_wday),
+ NULL, NULL);
+ separator_width = screen->getstringsize(SEPARATOR, NULL, NULL);
for(i=0, j=0; i < 6; i++)
{
@@ -247,7 +245,7 @@ bool set_time_screen(const char* title, struct tm *tm, bool set_date)
j = weekday_width + separator_width;
prev_line_height *= 2;
}
- screen->getstringsize(ptr[i], &width, NULL);
+ width = screen->getstringsize(ptr[i], NULL, NULL);
cursor[i][INDEX_Y] = prev_line_height;
cursor[i][INDEX_X] = j;
j += width + separator_width;
@@ -369,6 +367,7 @@ bool set_time_screen(const char* title, struct tm *tm, bool set_date)
static const int id3_headers[]=
{
+ LANG_TAGNAVI_ALL_TRACKS,
LANG_ID3_TITLE,
LANG_ID3_ARTIST,
LANG_ID3_COMPOSER,
@@ -389,11 +388,16 @@ static const int id3_headers[]=
LANG_ID3_ALBUM_GAIN,
LANG_FILESIZE,
LANG_ID3_PATH,
+ LANG_DATE,
+ LANG_TIME,
};
struct id3view_info {
struct mp3entry* id3;
+ struct tm *modified;
+ int track_ct;
int count;
+ struct playlist_info *playlist;
int playlist_display_index;
int playlist_amount;
int info_id[ARRAYLEN(id3_headers)];
@@ -490,13 +494,19 @@ static const char * id3_get_or_speak_info(int selected_item, void* data,
{
struct id3view_info *info = (struct id3view_info*)data;
struct mp3entry* id3 =info->id3;
+ const unsigned char * const *unit;
+ unsigned int unit_ct;
+ unsigned long length;
+ bool pl_modified;
+ struct tm *tm = info->modified;
int info_no=selected_item/2;
if(!(selected_item%2))
{/* header */
if(say_it)
talk_id(id3_headers[info->info_id[info_no]], false);
snprintf(buffer, buffer_len,
- "[%s]", str(id3_headers[info->info_id[info_no]]));
+ info->info_id[info_no] > 0 ? "[%s]" : "%s",
+ str(id3_headers[info->info_id[info_no]]));
return buffer;
}
else
@@ -505,6 +515,14 @@ static const char * id3_get_or_speak_info(int selected_item, void* data,
char * val=NULL;
switch(id3_headers[info->info_id[info_no]])
{
+ case LANG_TAGNAVI_ALL_TRACKS:
+ if (info->track_ct <= 1)
+ return NULL;
+ snprintf(buffer, buffer_len, "%d", info->track_ct);
+ val = buffer;
+ if(say_it)
+ talk_number(info->track_ct, true);
+ break;
case LANG_ID3_TITLE:
val=id3->title;
if(say_it && val)
@@ -563,7 +581,9 @@ static const char * id3_get_or_speak_info(int selected_item, void* data,
case LANG_ID3_COMMENT:
if (!id3->comment)
return NULL;
- snprintf(buffer, buffer_len, "%s", id3->comment);
+
+ strmemccpy(buffer, id3->comment, buffer_len);
+
val=buffer;
if(say_it && val)
talk_spell(val, true);
@@ -589,33 +609,65 @@ static const char * id3_get_or_speak_info(int selected_item, void* data,
}
break;
case LANG_ID3_LENGTH:
- format_time(buffer, buffer_len, id3->length);
+ length = info->track_ct > 1 ? id3->length : id3->length / 1000;
+
+ format_time_auto(buffer, buffer_len,
+ length, UNIT_SEC | UNIT_TRIM_ZERO, true);
val=buffer;
if(say_it)
- talk_value(id3->length /1000, UNIT_TIME, true);
+ talk_value(length, UNIT_TIME, true);
break;
case LANG_ID3_PLAYLIST:
if (info->playlist_display_index == 0 || info->playlist_amount == 0 )
return NULL;
- snprintf(buffer, buffer_len, "%d/%d",
- info->playlist_display_index, info->playlist_amount);
- val=buffer;
+
+ pl_modified = playlist_modified(info->playlist);
+
+ snprintf(buffer, buffer_len, "%d/%d%s",
+ info->playlist_display_index, info->playlist_amount,
+ pl_modified ? "* " :" ");
+ val = buffer;
+ size_t prefix_len = strlen(buffer);
+ buffer += prefix_len;
+ buffer_len -= prefix_len;
+
+ if (info->playlist)
+ playlist_name(info->playlist, buffer, buffer_len);
+ else
+ {
+ if (playlist_allow_dirplay(NULL))
+ strmemccpy(buffer, "(Folder)", buffer_len);
+ else if (playlist_dynamic_only())
+ strmemccpy(buffer, "(Dynamic)", buffer_len);
+ else
+ playlist_name(NULL, buffer, buffer_len);
+ }
+
if(say_it)
{
talk_number(info->playlist_display_index, true);
talk_id(VOICE_OF, true);
talk_number(info->playlist_amount, true);
+
+ if (pl_modified)
+ talk_spell("Modified", true);
+ if (buffer) /* playlist name */
+ talk_spell(buffer, true);
}
break;
case LANG_FORMAT:
if (id3->codectype >= AFMT_NUM_CODECS)
return NULL;
- snprintf(buffer, buffer_len, "%s", audio_formats[id3->codectype].label);
+
+ strmemccpy(buffer, audio_formats[id3->codectype].label, buffer_len);
+
val=buffer;
if(say_it)
talk_spell(val, true);
break;
case LANG_ID3_BITRATE:
+ if (!id3->bitrate)
+ return NULL;
snprintf(buffer, buffer_len, "%d kbps%s", id3->bitrate,
id3->vbr ? str(LANG_ID3_VBR) : (const unsigned char*) "");
val=buffer;
@@ -627,6 +679,8 @@ static const char * id3_get_or_speak_info(int selected_item, void* data,
}
break;
case LANG_ID3_FREQUENCY:
+ if (!id3->frequency)
+ return NULL;
snprintf(buffer, buffer_len, "%ld Hz", id3->frequency);
val=buffer;
if(say_it)
@@ -655,10 +709,44 @@ static const char * id3_get_or_speak_info(int selected_item, void* data,
talk_spell(val, true);
break;
case LANG_FILESIZE: /* not LANG_ID3_FILESIZE because the string is shared */
- output_dyn_value(buffer, buffer_len, id3->filesize, byte_units, 4, true);
+ if (!id3->filesize)
+ return NULL;
+ if (info->track_ct > 1)
+ {
+ unit = kibyte_units;
+ unit_ct = 3;
+ }
+ else
+ {
+ unit = byte_units;
+ unit_ct = 4;
+ }
+ output_dyn_value(buffer, buffer_len, id3->filesize, unit, unit_ct, true);
val=buffer;
if(say_it && val)
- output_dyn_value(NULL, 0, id3->filesize, byte_units, 4, true);
+ output_dyn_value(NULL, 0, id3->filesize, unit, unit_ct, true);
+ break;
+ case LANG_DATE:
+ if (!tm)
+ return NULL;
+
+ snprintf(buffer, buffer_len, "%04d/%02d/%02d",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
+
+ val = buffer;
+ if (say_it)
+ talk_date(tm, true);
+ break;
+ case LANG_TIME:
+ if (!tm)
+ return NULL;
+
+ snprintf(buffer, buffer_len, "%02d:%02d:%02d",
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ val = buffer;
+ if (say_it)
+ talk_time(tm, true);
break;
}
if((!val || !*val) && say_it)
@@ -668,11 +756,11 @@ static const char * id3_get_or_speak_info(int selected_item, void* data,
}
/* gui_synclist callback */
-static const char* id3_get_info(int selected_item, void* data,
- char *buffer, size_t buffer_len)
+static const char* id3_get_name_cb(int selected_item, void* data,
+ char *buffer, size_t buffer_len)
{
return id3_get_or_speak_info(selected_item, data, buffer,
- buffer_len, false);
+ buffer_len, false) ? : "";
}
static int id3_speak_item(int selected_item, void* data)
@@ -686,27 +774,40 @@ static int id3_speak_item(int selected_item, void* data)
return 0;
}
-bool browse_id3(struct mp3entry *id3, int playlist_display_index, int playlist_amount)
+/* Note: If track_ct > 1, filesize value will be treated as
+ * KiB (instead of Bytes), and length as s instead of ms.
+ */
+bool browse_id3_ex(struct mp3entry *id3, struct playlist_info *playlist,
+ int playlist_display_index, int playlist_amount,
+ struct tm *modified, int track_ct)
{
struct gui_synclist id3_lists;
int key;
unsigned int i;
struct id3view_info info;
- info.count = 0;
info.id3 = id3;
- info.playlist_display_index = playlist_display_index;
+ info.modified = modified;
+ info.track_ct = track_ct;
+ info.playlist = playlist;
info.playlist_amount = playlist_amount;
bool ret = false;
- push_current_activity(ACTIVITY_ID3SCREEN);
+ int curr_activity = get_current_activity();
+ bool is_curr_track_info = curr_activity != ACTIVITY_PLUGIN &&
+ curr_activity != ACTIVITY_PLAYLISTVIEWER;
+ if (is_curr_track_info)
+ push_current_activity(ACTIVITY_ID3SCREEN);
+refresh_info:
+ info.count = 0;
+ info.playlist_display_index = playlist_display_index;
for (i = 0; i < ARRAYLEN(id3_headers); i++)
{
char temp[8];
info.info_id[i] = i;
- if (id3_get_info((i*2)+1, &info, temp, 8) != NULL)
+ if (id3_get_or_speak_info((i*2)+1, &info, temp, 8, false) != NULL)
info.info_id[info.count++] = i;
}
- gui_synclist_init(&id3_lists, &id3_get_info, &info, true, 2, NULL);
+ gui_synclist_init(&id3_lists, &id3_get_name_cb, &info, true, 2, NULL);
if(global_settings.talk_menu)
gui_synclist_set_voice_callback(&id3_lists, id3_speak_item);
gui_synclist_set_nb_items(&id3_lists, info.count*2);
@@ -714,8 +815,7 @@ bool browse_id3(struct mp3entry *id3, int playlist_display_index, int playlist_a
gui_synclist_draw(&id3_lists);
gui_synclist_speak_item(&id3_lists);
while (true) {
- if(!list_do_action(CONTEXT_LIST,HZ/2,
- &id3_lists, &key,LIST_WRAP_UNLESS_HELD)
+ if(!list_do_action(CONTEXT_LIST,HZ/2, &id3_lists, &key)
&& key!=ACTION_NONE && key!=ACTION_UNKNOWN)
{
if (key == ACTION_STD_OK || key == ACTION_STD_CANCEL)
@@ -729,13 +829,34 @@ bool browse_id3(struct mp3entry *id3, int playlist_display_index, int playlist_a
ret = true;
break;
}
+ }
+ else if (is_curr_track_info)
+ {
+ if (!audio_status())
+ {
+ ret = false;
+ break;
+ }
+ else
+ {
+ playlist_display_index = playlist_get_display_index();
+ if (playlist_display_index != info.playlist_display_index)
+ goto refresh_info;
+ }
}
}
-
- pop_current_activity();
+ if (is_curr_track_info)
+ pop_current_activity();
return ret;
}
+bool browse_id3(struct mp3entry *id3, int playlist_display_index, int playlist_amount,
+ struct tm *modified, int track_ct)
+{
+ return browse_id3_ex(id3, NULL, playlist_display_index, playlist_amount,
+ modified, track_ct);
+}
+
static const char* runtime_get_data(int selected_item, void* data,
char* buffer, size_t buffer_len)
{
@@ -793,8 +914,7 @@ int view_runtime(void)
say_runtime = false;
}
gui_synclist_draw(&lists);
- list_do_action(CONTEXT_STD, HZ,
- &lists, &action, LIST_WRAP_UNLESS_HELD);
+ list_do_action(CONTEXT_STD, HZ, &lists, &action);
if(action == ACTION_STD_CANCEL)
break;
if(action == ACTION_STD_OK) {