diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index e408caa..1e5ba4e 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -735,10 +735,9 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, { 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); + if (!info.force_redraw) + info.text_style |= STYLE_NOSCROLL_RESTART; + write_line(display, align, info.line_number, true, info.text_style); } else write_line(display, align, info.line_number, false, info.text_style); @@ -911,8 +910,8 @@ void skin_render_playlistviewer(struct playlistviewer* viewer, { /* 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); + // if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw) + write_line(display, align, info.line_number, true, info.text_style&STYLE_NOSCROLL_RESTART); } else write_line(display, align, info.line_number, false, info.text_style); diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 3806bb0..c83616f 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; iy == line) + 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,48 @@ 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 || ((style&STYLE_NOSCROLL_RESTART) == 0)) + 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; + s->style = style & ~STYLE_NOSCROLL_RESTART; + } 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 +441,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 +450,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) diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 2d0123c..b0ac820 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -130,6 +130,10 @@ enum screen_type { * of a char. Remove this hack when the whole LCD api goes to fully * pixel based positioning - jdgordon */ #define STYLE_XY_PIXELS 0x00010000 +/* HACK: This might not even be needed... don't restart scrolling + * when we update the lines text - jdgordon */ +#define STYLE_NOSCROLL_RESTART 0x00020000 + #define STYLE_COLOR_MASK 0x0000FFFF #ifdef HAVE_LCD_COLOR #define STYLE_CURLN_MASK 0x0000FF00