diff options
Diffstat (limited to 'apps/screens.c')
-rw-r--r-- | apps/screens.c | 184 |
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) { |