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
This commit is contained in:
Jonathan Gordon 2011-12-14 12:53:19 +00:00
parent b3caa01062
commit 13f1b08388
2 changed files with 59 additions and 36 deletions

View file

@ -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++;

View file

@ -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)