diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2010-05-12 10:38:00 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2010-05-12 10:38:00 +0000 |
commit | 1bd072c92d5f6d4a9a26d738a421f5a05048bb29 (patch) | |
tree | 11bf71c80cd995dad20b4316f201a63f78111383 /apps/gui/skin_engine | |
parent | f9736c0b63d90d3cda7e2c77d1cae20939ae328f (diff) |
FS#10853 - Skin support in the radio screen! Check CustomWPS for the new tags
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25964 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/skin_engine')
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 161 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_engine.h | 12 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 31 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.c | 129 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.h | 28 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_debug.c | 1 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 5 |
7 files changed, 341 insertions, 26 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 9b42a7c18b..8d4e5b58f4 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -31,6 +31,7 @@ #ifdef DEBUG #include "debug.h" #endif +#include "action.h" #include "abrepeat.h" #include "lang.h" #include "language.h" @@ -57,6 +58,9 @@ #endif #include "backdrop.h" #include "viewport.h" +#include "radio.h" +#include "tuner.h" +#include "root_menu.h" #include "wps_internals.h" @@ -78,7 +82,7 @@ bool skin_update(struct gui_wps *gwps, unsigned int update_type) struct mp3entry *id3 = gwps->state->id3; bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false); gwps->sync_data->do_full_update |= cuesheet_update; - + retval = skin_redraw(gwps, gwps->sync_data->do_full_update ? WPS_REFRESH_ALL : update_type); return retval; @@ -157,6 +161,14 @@ static void draw_progressbar(struct gui_wps *gwps, length = id3->length; elapsed = id3->elapsed + state->ff_rewind_count; } +#if CONFIG_TUNER + else if (in_radio_screen()) + { + int min = fm_region_data[global_settings.fm_region].freq_min; + elapsed = radio_current_frequency() - min; + length = fm_region_data[global_settings.fm_region].freq_max - min; + } +#endif else { length = 1; @@ -191,8 +203,8 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, struct wps_state *state = gwps->state; int lines = viewport_get_nb_lines(viewer->vp); int line_height = font_get(viewer->vp->font)->height; - int cur_playlist_pos = playlist_get_display_index(); - int start_item = MAX(0, cur_playlist_pos + viewer->start_offset); + int cur_pos, count; + int start_item; int i; struct wps_token token; int x, length, alignment = WPS_TOKEN_ALIGN_LEFT; @@ -200,39 +212,65 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, struct mp3entry *pid3; char buf[MAX_PATH*2], tempbuf[MAX_PATH]; const char *filename; + bool ismusic = true; +#if CONFIG_TUNER + if (current_screen() == GO_TO_FM) + { + cur_pos = radio_current_preset(); + count = radio_preset_count(); + ismusic = false; + } + else +#endif + { + cur_pos = playlist_get_display_index(); + count = playlist_amount()+1; + } + start_item = MAX(0, cur_pos + viewer->start_offset); gwps->display->set_viewport(viewer->vp); - for(i=start_item; (i-start_item)<lines && i<=playlist_amount(); i++) + for(i=start_item; (i-start_item)<lines && i<count; i++) { - filename = playlist_peek(i-cur_playlist_pos); - if (i == cur_playlist_pos) - { - pid3 = state->id3; - } - else if (i == cur_playlist_pos+1) + int line; +#if CONFIG_TUNER + if (current_screen() == GO_TO_FM) { - pid3 = state->nid3; + pid3 = NULL; + line = TRACK_HAS_INFO; + filename = ""; } -#if CONFIG_CODEC == SWCODEC - else if (i>cur_playlist_pos) + else +#endif { -#ifdef HAVE_TC_RAMCACHE - if (tagcache_fill_tags(&viewer->tempid3, filename)) + filename = playlist_peek(i-cur_pos); + if (i == cur_pos) { - pid3 = &viewer->tempid3; + pid3 = state->id3; } - else + else if (i == cur_pos+1) + { + pid3 = state->nid3; + } +#if CONFIG_CODEC == SWCODEC + else if (i>cur_pos) + { +#ifdef HAVE_TC_RAMCACHE + if (tagcache_fill_tags(&viewer->tempid3, filename)) + { + pid3 = &viewer->tempid3; + } + else #endif - if (!audio_peek_track(&pid3, i-cur_playlist_pos)) - pid3 = NULL; - } + if (!audio_peek_track(&pid3, i-cur_pos)) + pid3 = NULL; + } #endif - else - { - pid3 = NULL; + else + { + pid3 = NULL; + } + line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO; } - - int line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO; int j = 0, cur_string = 0; unsigned int line_len = 0; buf[0] = '\0'; @@ -243,12 +281,18 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, token.value.i = 0; token.next = false; out = get_id3_token(&token, pid3, tempbuf, sizeof(tempbuf), -1, NULL); +#if CONFIG_TUNER + if (!out) + out = get_radio_token(&token, i-cur_pos, + tempbuf, sizeof(tempbuf), -1, NULL); +#endif if (out) { line_len = strlcat(buf, out, sizeof(buf)); j++; continue; } + switch (viewer->lines[line].tokens[j]) { case WPS_TOKEN_ALIGN_CENTER: @@ -1303,3 +1347,70 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) return true; } + +bool skin_has_sbs(enum screen_type screen, struct wps_data *data) +{ + (void)screen; + bool draw = false; +#ifdef HAVE_LCD_BITMAP + if (data->wps_sb_tag) + draw = data->show_sb_on_wps; + else if (statusbar_position(screen) != STATUSBAR_OFF) + draw = true; +#endif + return draw; +} + +/* do the button loop as often as required for the peak meters to update + * with a good refresh rate. + * gwps is really gwps[NB_SCREENS]! don't wrap this if FOR_NB_SCREENS() + */ +int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout) +{ +#ifdef HAVE_LCD_BITMAP + int i; + int button = ACTION_NONE; + /* when the peak meter is enabled we want to have a + few extra updates to make it look smooth. On the + other hand we don't want to waste energy if it + isn't displayed */ + bool pm=false; + FOR_NB_SCREENS(i) + { + if(gwps[i].data->peak_meter_enabled) + pm = true; + } + + if (pm) { + long next_refresh = current_tick; + long next_big_refresh = current_tick + timeout; + button = BUTTON_NONE; + while (TIME_BEFORE(current_tick, next_big_refresh)) { + button = get_action(context,TIMEOUT_NOBLOCK); + if (button != ACTION_NONE) { + break; + } + peak_meter_peek(); + sleep(0); /* Sleep until end of current tick. */ + + if (TIME_AFTER(current_tick, next_refresh)) { + FOR_NB_SCREENS(i) + { + if(gwps[i].data->peak_meter_enabled) + skin_update(&gwps[i], WPS_REFRESH_PEAK_METER); + next_refresh += HZ / PEAK_METER_FPS; + } + } + } + + } + + /* The peak meter is disabled + -> no additional screen updates needed */ + else +#endif + { + button = get_action(context, timeout); + } + return button; +} diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h index 90f38c9920..380b854d24 100644 --- a/apps/gui/skin_engine/skin_engine.h +++ b/apps/gui/skin_engine/skin_engine.h @@ -30,6 +30,9 @@ enum skinnable_screens { CUSTOM_STATUSBAR, WPS, +#if CONFIG_TUNER + FM_SCREEN, +#endif SKINNABLE_SCREENS_COUNT @@ -53,9 +56,18 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, /* call this in statusbar toggle handlers if needed */ void skin_statusbar_changed(struct gui_wps*); +bool skin_has_sbs(enum screen_type screen, struct wps_data *data); + /* load a backdrop into the skin buffer. * reuse buffers if the file is already loaded */ char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen); void skin_backdrop_init(void); + + +/* do the button loop as often as required for the peak meters to update + * with a good refresh rate. + * gwps is really gwps[NB_SCREENS]! don't wrap this in FOR_NB_SCREENS() + */ +int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout); #endif diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 78ec26eaf9..93df300335 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -52,6 +52,7 @@ #include "skin_engine.h" #include "settings.h" #include "settings_list.h" +#include "radio.h" #include "skin_fonts.h" #ifdef HAVE_LCD_BITMAP @@ -348,6 +349,25 @@ static const struct wps_tag all_tags[] = { { WPS_TOKEN_CROSSFADE, "xf", WPS_REFRESH_DYNAMIC, NULL }, #endif + { WPS_TOKEN_HAVE_TUNER, "tp", WPS_REFRESH_STATIC, NULL }, +#if CONFIG_TUNER /* Re-uses the 't' and 'T' prefixes, be careful about doubleups */ + { WPS_TOKEN_TUNER_TUNED, "tt", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_TUNER_SCANMODE, "tm", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_TUNER_STEREO, "ts", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_TUNER_MINFREQ, "ta", WPS_REFRESH_STATIC, NULL }, + { WPS_TOKEN_TUNER_MAXFREQ, "tb", WPS_REFRESH_STATIC, NULL }, + { WPS_TOKEN_TUNER_CURFREQ, "tf", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_PRESET_ID, "Ti", WPS_REFRESH_STATIC, NULL }, + { WPS_TOKEN_PRESET_NAME, "Tn", WPS_REFRESH_STATIC, NULL }, + { WPS_TOKEN_PRESET_FREQ, "Tf", WPS_REFRESH_STATIC, NULL }, + { WPS_TOKEN_PRESET_COUNT, "Tc", WPS_REFRESH_STATIC, NULL }, + { WPS_TOKEN_HAVE_RDS, "tx", WPS_REFRESH_STATIC, NULL }, +#ifdef HAVE_RDS_CAPS + { WPS_TOKEN_RDS_NAME, "ty", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_RDS_TEXT, "tz", WPS_REFRESH_DYNAMIC, NULL }, +#endif +#endif /* CONFIG_TUNER */ + { WPS_NO_TOKEN, "s", WPS_REFRESH_SCROLL, NULL }, { WPS_TOKEN_SUBLINE_TIMEOUT, "t", 0, parse_timeout }, @@ -398,10 +418,14 @@ static const struct wps_tag all_tags[] = { /* Recording Tokens */ { WPS_TOKEN_HAVE_RECORDING, "Rp", WPS_REFRESH_STATIC, NULL }, #ifdef HAVE_RECORDING + { WPS_TOKEN_IS_RECORDING, "Rr", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_REC_FREQ, "Rf", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_REC_ENCODER, "Re", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_REC_BITRATE, "Rb", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_REC_MONO, "Rm", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_REC_SECONDS, "Rs", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_REC_MINUTES, "Rn", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_REC_HOURS, "Rh", WPS_REFRESH_DYNAMIC, NULL }, #endif { WPS_TOKEN_UNKNOWN, "", 0, NULL } /* the array MUST end with an empty string (first char is \0) */ @@ -1723,6 +1747,13 @@ static int check_feature_tag(const char *wps_bufptr, const int type) #else return find_false_branch(wps_bufptr); #endif + case WPS_TOKEN_HAVE_TUNER: +#if CONFIG_TUNER + if (radio_hardware_present()) + return 0; +#endif + return find_false_branch(wps_bufptr); + default: /* not a tag we care about, just don't skip */ return 0; } diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 20206f0114..4acf7ea840 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -61,6 +61,8 @@ #endif #include "language.h" #include "usb.h" +#include "radio.h" +#include "tuner.h" extern struct wps_state wps_state; @@ -339,6 +341,89 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, return buf; } +#if CONFIG_TUNER +/* Tokens which are really only used by the radio screen go in here */ +const char *get_radio_token(struct wps_token *token, int preset_offset, + char *buf, int buf_size, int limit, int *intval) +{ + (void)limit; + switch (token->type) + { + /* Radio/tuner tokens */ + case WPS_TOKEN_TUNER_TUNED: + if (tuner_get(RADIO_TUNED)) + return "t"; + return NULL; + case WPS_TOKEN_TUNER_SCANMODE: + if (radio_scan_mode()) + return "s"; + return NULL; + case WPS_TOKEN_TUNER_STEREO: + if (radio_is_stereo()) + return "s"; + return NULL; + case WPS_TOKEN_TUNER_MINFREQ: /* changes based on "region" */ + { + int freq = fm_region_data[global_settings.fm_region].freq_min / 10000; + snprintf(buf, buf_size, "%d.%02d", freq/100, freq%100); + return buf; + } + case WPS_TOKEN_TUNER_MAXFREQ: /* changes based on "region" */ + { + int freq = fm_region_data[global_settings.fm_region].freq_max / 10000; + snprintf(buf, buf_size, "%d.%02d", freq/100, freq%100); + return buf; + } + case WPS_TOKEN_TUNER_CURFREQ: + { + int freq = radio_current_frequency() / 10000; + snprintf(buf, buf_size, "%d.%02d", freq/100, freq%100); + return buf; + } + case WPS_TOKEN_PRESET_ID: + snprintf(buf, buf_size, "%d", radio_current_preset() + 1 + preset_offset); + return buf; + case WPS_TOKEN_PRESET_NAME: + case WPS_TOKEN_PRESET_FREQ: + { + int preset = radio_current_preset() + preset_offset; + if (radio_preset_count() == 0 || preset == -1) + return NULL; + /* make sure its in the valid range */ + while (preset < 0) + preset += radio_preset_count(); + preset %= radio_preset_count(); + if (token->type == WPS_TOKEN_PRESET_NAME) + { + snprintf(buf, buf_size, "%s", radio_get_preset(preset)->name); + } + else + { + int freq = radio_get_preset(preset)->frequency / 10000; + snprintf(buf, buf_size, "%d.%02d", freq/100, freq%100); + } + return buf; + } + case WPS_TOKEN_PRESET_COUNT: + snprintf(buf, buf_size, "%d", radio_preset_count()); + if (intval) + *intval = radio_preset_count(); + return buf; + case WPS_TOKEN_HAVE_RDS: +#ifdef HAVE_RDS_CAP + return "rds"; + case WPS_TOKEN_RDS_NAME: + return tuner_get_rds_info(RADIO_RDS_NAME); + case WPS_TOKEN_RDS_TEXT: + return tuner_get_rds_info(RADIO_RDS_TEXT); +#else + return NULL; /* end of the WPS_TOKEN_HAVE_RDS case */ +#endif /* HAVE_RDS_CAP */ + } + return NULL; +} +#endif + /* Return the tags value as text. buf should be used as temp storage if needed. intval is used with conditionals/enums: when this function is called, @@ -396,6 +481,11 @@ const char *get_token_value(struct gui_wps *gwps, out_text = get_id3_token(token, id3, buf, buf_size, limit, intval); if (out_text) return out_text; +#if CONFIG_TUNER + out_text = get_radio_token(token, 0, buf, buf_size, limit, intval); + if (out_text) + return out_text; +#endif switch (token->type) { @@ -971,6 +1061,9 @@ const char *get_token_value(struct gui_wps *gwps, * The string's emptyness discards the setting's * prefix and suffix */ *intval = ((char*)s->setting)[0]?1:2; + /* if there is a prefix we should ignore it here */ + if (s->filename_setting->prefix) + return (char*)s->setting; break; default: /* This shouldn't happen ... but you never know */ @@ -988,6 +1081,12 @@ const char *get_token_value(struct gui_wps *gwps, cfg_to_string(token->value.i,buf,buf_size); return buf; } + case WPS_TOKEN_HAVE_TUNER: +#if CONFIG_TUNER + if (radio_hardware_present()) + return "r"; +#endif + return NULL; /* Recording tokens */ case WPS_TOKEN_HAVE_RECORDING: #ifdef HAVE_RECORDING @@ -997,6 +1096,10 @@ const char *get_token_value(struct gui_wps *gwps, #endif #ifdef HAVE_RECORDING + case WPS_TOKEN_IS_RECORDING: + if (audio_status() == AUDIO_STATUS_RECORD) + return "r"; + return NULL; case WPS_TOKEN_REC_FREQ: /* order from REC_FREQ_CFG_VAL_LIST */ { #if CONFIG_CODEC == SWCODEC @@ -1179,8 +1282,34 @@ const char *get_token_value(struct gui_wps *gwps, if (!global_settings.rec_channels) return "m"; return NULL; + + case WPS_TOKEN_REC_SECONDS: + { + int time = (audio_recorded_time() / HZ) % 60; + if (intval) + *intval = time; + snprintf(buf, buf_size, "%02d", time); + return buf; + } + case WPS_TOKEN_REC_MINUTES: + { + int time = (audio_recorded_time() / HZ) / 60; + if (intval) + *intval = time; + snprintf(buf, buf_size, "%02d", time); + return buf; + } + case WPS_TOKEN_REC_HOURS: + { + int time = (audio_recorded_time() / HZ) / 3600; + if (intval) + *intval = time; + snprintf(buf, buf_size, "%02d", time); + return buf; + } #endif /* HAVE_RECORDING */ + case WPS_TOKEN_CURRENT_SCREEN: { int curr_screen = current_screen(); diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h index aefae40af9..f25b123d9d 100644 --- a/apps/gui/skin_engine/skin_tokens.h +++ b/apps/gui/skin_engine/skin_tokens.h @@ -219,10 +219,38 @@ enum wps_token_type { /* Recording Tokens */ TOKEN_MARKER_RECORDING, WPS_TOKEN_HAVE_RECORDING, + WPS_TOKEN_IS_RECORDING, WPS_TOKEN_REC_FREQ, WPS_TOKEN_REC_ENCODER, WPS_TOKEN_REC_BITRATE, /* SWCODEC: MP3 bitrate, HWCODEC: MP3 "quality" */ WPS_TOKEN_REC_MONO, + WPS_TOKEN_REC_SECONDS, + WPS_TOKEN_REC_MINUTES, + WPS_TOKEN_REC_HOURS, + + + /* Radio Tokens */ + TOKEN_MARKER_TUNER, + WPS_TOKEN_HAVE_TUNER, +#if CONFIG_TUNER + WPS_TOKEN_TUNER_TUNED, + WPS_TOKEN_TUNER_SCANMODE, + WPS_TOKEN_TUNER_STEREO, + WPS_TOKEN_TUNER_MINFREQ, /* changes based on "region" */ + WPS_TOKEN_TUNER_MAXFREQ, /* changes based on "region" */ + WPS_TOKEN_TUNER_CURFREQ, + WPS_TOKEN_PRESET_ID, /* "id" of this preset.. really the array element number */ + WPS_TOKEN_PRESET_NAME, + WPS_TOKEN_PRESET_FREQ, + WPS_TOKEN_PRESET_COUNT, + /* RDS tokens */ + WPS_TOKEN_HAVE_RDS, +#ifdef HAVE_RDS_CAP + WPS_TOKEN_RDS_NAME, + WPS_TOKEN_RDS_TEXT, +#endif +#endif /* CONFIG_TUNER */ + TOKEN_MARKER_END, /* this needs to be the last value in this enum */ }; diff --git a/apps/gui/skin_engine/wps_debug.c b/apps/gui/skin_engine/wps_debug.c index 4186e306e3..a1ebb837d0 100644 --- a/apps/gui/skin_engine/wps_debug.c +++ b/apps/gui/skin_engine/wps_debug.c @@ -60,6 +60,7 @@ struct debug_token_table tokens[] = { { X(TOKEN_MARKER_PLAYLIST) }, { X(TOKEN_MARKER_MISC) }, { X(TOKEN_MARKER_RECORDING) }, + { X(TOKEN_MARKER_TUNER) }, { X(TOKEN_MARKER_END) }, }; #undef X diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 211d9a13ee..945932a125 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -371,7 +371,10 @@ const char *get_token_value(struct gui_wps *gwps, const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, char *buf, int buf_size, int limit, int *intval); - +#if CONFIG_TUNER +const char *get_radio_token(struct wps_token *token, int preset_offset, + char *buf, int buf_size, int limit, int *intval); +#endif struct gui_img* find_image(char label, struct wps_data *data); struct skin_viewport* find_viewport(char label, struct wps_data *data); |