summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-12-14 12:53:19 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-12-14 12:53:19 +0000
commit13f1b08388fa2896ebdc0e52920b23a1e9703c40 (patch)
tree7ad05812359467916ea6d66a3afa98f5b49f265d
parentb3caa010624248930eaf487b5e151bbe2b9b9f27 (diff)
downloadrockbox-13f1b08388fa2896ebdc0e52920b23a1e9703c40.tar.gz
rockbox-13f1b08388fa2896ebdc0e52920b23a1e9703c40.zip
Allow scrolling lines to have their content changed without restarting the scroll line. This means skin lines with dynamic tags can be updated in realtime instead of delayed
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31247 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/skin_engine/skin_render.c26
-rw-r--r--firmware/drivers/lcd-bitmap-common.c69
2 files changed, 59 insertions, 36 deletions
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index e408caaa1e..7b80d8c7a0 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -733,15 +733,10 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
/* only update if the line needs to be, and there is something to write */
if (refresh_type && needs_update)
{
- if (info.line_scrolls)
- {
- /* if the line is a scrolling one we don't want to update
- too often, so that it has the time to scroll */
- if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw)
- write_line(display, align, info.line_number, true, info.text_style);
- }
- else
- write_line(display, align, info.line_number, false, info.text_style);
+ if (!info.force_redraw)
+ display->scroll_stop_line(&skin_viewport->vp, info.line_number);
+ write_line(display, align, info.line_number,
+ info.line_scrolls, info.text_style);
}
if (!info.no_line_break)
info.line_number++;
@@ -907,15 +902,10 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
/* only update if the line needs to be, and there is something to write */
if (refresh_type && needs_update)
{
- if (info.line_scrolls)
- {
- /* if the line is a scrolling one we don't want to update
- too often, so that it has the time to scroll */
- if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw)
- write_line(display, align, info.line_number, true, info.text_style);
- }
- else
- write_line(display, align, info.line_number, false, info.text_style);
+ if (!info.force_redraw)
+ display->scroll_stop_line(&skin_viewport->vp, info.line_number);
+ write_line(display, align, info.line_number,
+ info.line_scrolls, info.text_style);
}
info.line_number++;
info.offset++;
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index 3806bb024d..37c6bdaad7 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -365,6 +365,20 @@ void LCDFN(puts_offset)(int x, int y, const unsigned char *str, int offset)
/*** scrolling ***/
+static struct scrollinfo* find_scrolling_line(int line)
+{
+ struct scrollinfo* s = NULL;
+ int i;
+
+ for(i=0; i<LCDFN(scroll_info).lines; i++)
+ {
+ s = &LCDFN(scroll_info).scroll[i];
+ if (s->y == line && s->vp == current_vp)
+ return s;
+ }
+ return NULL;
+}
+
void LCDFN(puts_scroll_style_xyoffset)(int x, int y, const unsigned char *string,
int style, int x_offset, int y_offset)
{
@@ -372,32 +386,47 @@ void LCDFN(puts_scroll_style_xyoffset)(int x, int y, const unsigned char *string
char *end;
int w, h;
int len;
+ bool restart = false;
+ int space_width;
- if ((unsigned)y >= (unsigned)current_vp->height)
+ if (!string || ((unsigned)y >= (unsigned)current_vp->height))
return;
- /* remove any previously scrolling line at the same location */
- LCDFN(scroll_stop_line)(current_vp, y);
+ s = find_scrolling_line(y);
+ if (!s)
+ restart = true;
- if (LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) return;
- if (!string)
- return;
- LCDFN(puts_style_xyoffset)(x, y, string, style, x_offset, y_offset);
+ if (restart)
+ {
+ /* remove any previously scrolling line at the same location */
+ LCDFN(scroll_stop_line)(current_vp, y);
+
+ if (LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) return;
+ LCDFN(puts_style_xyoffset)(x, y, string, style, x_offset, y_offset);
+ }
LCDFN(getstringsize)(string, &w, &h);
if (current_vp->width - x * 8 >= w)
return;
- /* prepare scroll line */
- s = &LCDFN(scroll_info).scroll[LCDFN(scroll_info).lines];
- s->start_tick = current_tick + LCDFN(scroll_info).delay;
- s->style = style;
-
+ if (restart)
+ {
+ /* prepare scroll line */
+ s = &LCDFN(scroll_info).scroll[LCDFN(scroll_info).lines];
+ s->start_tick = current_tick + LCDFN(scroll_info).delay;
+ }
strlcpy(s->line, string, sizeof s->line);
+ space_width = LCDFN(getstringsize)(" ", NULL, NULL);
/* get width */
- s->width = LCDFN(getstringsize)(s->line, &w, &h);
+ LCDFN(getstringsize)(s->line, &w, &h);
+ if (!restart && s->width > w)
+ {
+ if (s->startx > w)
+ s->startx = w;
+ }
+ s->width = w;
/* scroll bidirectional or forward only depending on the string
width */
@@ -411,7 +440,7 @@ void LCDFN(puts_scroll_style_xyoffset)(int x, int y, const unsigned char *string
if (!s->bidir) { /* add spaces if scrolling in the round */
strlcat(s->line, " ", sizeof s->line);
/* get new width incl. spaces */
- s->width = LCDFN(getstringsize)(s->line, &w, &h);
+ s->width += space_width * 3;
}
end = strchr(s->line, '\0');
@@ -420,12 +449,16 @@ void LCDFN(puts_scroll_style_xyoffset)(int x, int y, const unsigned char *string
s->vp = current_vp;
s->y = y;
- s->offset = x_offset;
- s->startx = x * LCDFN(getstringsize)(" ", NULL, NULL);
+ if (restart)
+ {
+ s->offset = x_offset;
+ s->startx = x * space_width;
+ s->backward = false;
+ }
s->y_offset = y_offset;
- s->backward = false;
- LCDFN(scroll_info).lines++;
+ if (restart)
+ LCDFN(scroll_info).lines++;
}
void LCDFN(puts_scroll)(int x, int y, const unsigned char *string)