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; i<LCDFN(scroll_info).lines; i++)
+ {
+ s = &LCDFN(scroll_info).scroll[i];
+ if (s->y == 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