summaryrefslogtreecommitdiffstats
path: root/apps/gui/skin_engine/skin_tokens.c
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2010-10-10 23:46:15 +0000
committerFrank Gevaerts <frank@gevaerts.be>2010-10-10 23:46:15 +0000
commit1f0ab7c9e636ba3e88700b1b6fb75e876a0f0a44 (patch)
tree4b030482b9f788e673a4b74cbbb7e83f67118615 /apps/gui/skin_engine/skin_tokens.c
parent5462ef728fd41a6db4d1d784c478416ceeebf588 (diff)
downloadrockbox-1f0ab7c9e636ba3e88700b1b6fb75e876a0f0a44.tar.gz
rockbox-1f0ab7c9e636ba3e88700b1b6fb75e876a0f0a44.zip
Fix charcell %pb and %pf tags, FS#11592
This also moves draw_player_fullbar() and draw_player_progress() from skin_display.c to skin_tokens.c. Charcell is a bit different from bitmap here because drawing a progress bar is a combination of setting up the LCD controller (custom characters) and providing a format string. The custom character definition might fit in skin_display.c, but the format strings are needed in skin_tokens.c. Putting these functions in skin_tokens.c seemed to fit better. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28241 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/skin_engine/skin_tokens.c')
-rw-r--r--apps/gui/skin_engine/skin_tokens.c148
1 files changed, 147 insertions, 1 deletions
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 11200e448c..78d141e743 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -554,6 +554,148 @@ static struct mp3entry* get_mp3entry_from_offset(int offset, char **filename)
return pid3;
}
+#ifdef HAVE_LCD_CHARCELLS
+void format_player_progress(struct gui_wps *gwps)
+{
+ struct wps_state *state = skin_get_global_state();
+ struct screen *display = gwps->display;
+ unsigned char progress_pattern[7];
+ int pos = 0;
+ int i;
+
+ int elapsed, length;
+ if (LIKELY(state->id3))
+ {
+ elapsed = state->id3->elapsed;
+ length = state->id3->length;
+ }
+ else
+ {
+ elapsed = 0;
+ length = 0;
+ }
+
+ if (length)
+ pos = 36 * (elapsed + state->ff_rewind_count) / length;
+
+ for (i = 0; i < 7; i++, pos -= 5)
+ {
+ if (pos <= 0)
+ progress_pattern[i] = 0x1fu;
+ else if (pos >= 5)
+ progress_pattern[i] = 0x00u;
+ else
+ progress_pattern[i] = 0x1fu >> pos;
+ }
+
+ display->define_pattern(gwps->data->wps_progress_pat[0], progress_pattern);
+}
+
+void format_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
+{
+ static const unsigned char numbers[10][4] = {
+ {0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */
+ {0x04, 0x0c, 0x04, 0x04}, /* 1 */
+ {0x0e, 0x02, 0x04, 0x0e}, /* 2 */
+ {0x0e, 0x02, 0x06, 0x0e}, /* 3 */
+ {0x08, 0x0c, 0x0e, 0x04}, /* 4 */
+ {0x0e, 0x0c, 0x02, 0x0c}, /* 5 */
+ {0x0e, 0x08, 0x0e, 0x0e}, /* 6 */
+ {0x0e, 0x02, 0x04, 0x08}, /* 7 */
+ {0x0e, 0x0e, 0x0a, 0x0e}, /* 8 */
+ {0x0e, 0x0e, 0x02, 0x0e}, /* 9 */
+ };
+
+ struct wps_state *state = skin_get_global_state();
+ struct screen *display = gwps->display;
+ struct wps_data *data = gwps->data;
+ unsigned char progress_pattern[7];
+ char timestr[10];
+ int time;
+ int time_idx = 0;
+ int pos = 0;
+ int pat_idx = 1;
+ int digit, i, j;
+ bool softchar;
+
+ int elapsed, length;
+ if (LIKELY(state->id3))
+ {
+ elapsed = state->id3->elapsed;
+ length = state->id3->length;
+ }
+ else
+ {
+ elapsed = 0;
+ length = 0;
+ }
+
+ if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
+ return;
+
+ time = elapsed + state->ff_rewind_count;
+ if (length)
+ pos = 55 * time / length;
+
+ memset(timestr, 0, sizeof(timestr));
+ format_time(timestr, sizeof(timestr)-2, time);
+ timestr[strlen(timestr)] = ':'; /* always safe */
+
+ for (i = 0; i < 11; i++, pos -= 5)
+ {
+ softchar = false;
+ memset(progress_pattern, 0, sizeof(progress_pattern));
+
+ if ((digit = timestr[time_idx]))
+ {
+ softchar = true;
+ digit -= '0';
+
+ if (timestr[time_idx + 1] == ':') /* ones, left aligned */
+ {
+ memcpy(progress_pattern, numbers[digit], 4);
+ time_idx += 2;
+ }
+ else /* tens, shifted right */
+ {
+ for (j = 0; j < 4; j++)
+ progress_pattern[j] = numbers[digit][j] >> 1;
+
+ if (time_idx > 0) /* not the first group, add colon in front */
+ {
+ progress_pattern[1] |= 0x10u;
+ progress_pattern[3] |= 0x10u;
+ }
+ time_idx++;
+ }
+
+ if (pos >= 5)
+ progress_pattern[5] = progress_pattern[6] = 0x1fu;
+ }
+
+ if (pos > 0 && pos < 5)
+ {
+ softchar = true;
+ progress_pattern[5] = progress_pattern[6] = (~0x1fu >> pos) & 0x1fu;
+ }
+
+ if (softchar && pat_idx < 8)
+ {
+ display->define_pattern(data->wps_progress_pat[pat_idx],
+ progress_pattern);
+ buf = utf8encode(data->wps_progress_pat[pat_idx], buf);
+ pat_idx++;
+ }
+ else if (pos <= 0)
+ buf = utf8encode(' ', buf);
+ else
+ buf = utf8encode(0xe115, buf); /* 2/7 _ */
+ }
+ *buf = '\0';
+}
+
+#endif /* HAVE_LCD_CHARCELLS */
+
/* Don't inline this; it was broken out of get_token_value to reduce stack
* usage.
*/
@@ -1075,7 +1217,9 @@ const char *get_token_value(struct gui_wps *gwps,
#ifdef HAVE_LCD_CHARCELLS
case SKIN_TOKEN_PROGRESSBAR:
{
- char *end = utf8encode(data->wps_progress_pat[0], buf);
+ char *end;
+ format_player_progress(gwps);
+ end = utf8encode(data->wps_progress_pat[0], buf);
*end = '\0';
return buf;
}
@@ -1086,6 +1230,8 @@ const char *get_token_value(struct gui_wps *gwps,
/* we need 11 characters (full line) for
progress-bar */
strlcpy(buf, " ", buf_size);
+ format_player_fullbar(gwps,buf,buf_size);
+ DEBUGF("bar='%s'\n",buf);
}
else
{