summaryrefslogtreecommitdiff
path: root/firmware/scroll_engine.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/scroll_engine.c')
-rw-r--r--firmware/scroll_engine.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/firmware/scroll_engine.c b/firmware/scroll_engine.c
index 200695b..9607c90 100644
--- a/firmware/scroll_engine.c
+++ b/firmware/scroll_engine.c
@@ -84,6 +84,18 @@ void lcd_stop_scroll(void)
lcd_scroll_info.lines = 0;
}
+/* returns true if the 'line' in 'lines_vp' would scroll into 'othervp' */
+static bool line_overlaps_viewport(struct viewport *lines_vp, int line,
+ struct viewport *othervp)
+{
+ int y = (font_get(lines_vp->font)->height*line) + lines_vp->y;
+ if (y < othervp->y || y > othervp->y + othervp->height)
+ return false;
+ else if ((lines_vp->x + lines_vp->width < othervp->x) ||
+ (othervp->x + othervp->width < lines_vp->x))
+ return false;
+ return true;
+}
/* Stop scrolling line y in the specified viewport, or all lines if y < 0 */
void lcd_scroll_stop_line(struct viewport* current_vp, int y)
{
@@ -91,8 +103,11 @@ void lcd_scroll_stop_line(struct viewport* current_vp, int y)
while (i < lcd_scroll_info.lines)
{
- if ((lcd_scroll_info.scroll[i].vp == current_vp) &&
- ((y < 0) || (lcd_scroll_info.scroll[i].y == y)))
+ if (((lcd_scroll_info.scroll[i].vp == current_vp) &&
+ ((y < 0) || (lcd_scroll_info.scroll[i].y == y))) ||
+ ((lcd_scroll_info.scroll[i].vp != current_vp) &&
+ line_overlaps_viewport(lcd_scroll_info.scroll[i].vp,
+ lcd_scroll_info.scroll[i].y, current_vp)))
{
/* If i is not the last active line in the array, then move
the last item to position i */
@@ -102,8 +117,10 @@ void lcd_scroll_stop_line(struct viewport* current_vp, int y)
}
lcd_scroll_info.lines--;
- /* A line can only appear once, so we're done. */
- return ;
+ /* A line can only appear once, so we're done,
+ * unless we are clearing the whole viewport */
+ if (y >= 0)
+ return ;
}
else
{
@@ -165,8 +182,11 @@ void lcd_remote_scroll_stop_line(struct viewport* current_vp, int y)
while (i < lcd_remote_scroll_info.lines)
{
- if ((lcd_remote_scroll_info.scroll[i].vp == current_vp) &&
- ((y < 0) || (lcd_remote_scroll_info.scroll[i].y == y)))
+ if (((lcd_remote_scroll_info.scroll[i].vp == current_vp) &&
+ ((y < 0) || (lcd_remote_scroll_info.scroll[i].y == y))) ||
+ (((lcd_remote_scroll_info.scroll[i].vp != current_vp) &&
+ line_overlaps_viewport(lcd_scroll_info.scroll[i].vp,
+ lcd_scroll_info.scroll[i].y, current_vp))))
{
/* If i is not the last active line in the array, then move
the last item to position i */
@@ -176,8 +196,10 @@ void lcd_remote_scroll_stop_line(struct viewport* current_vp, int y)
}
lcd_remote_scroll_info.lines--;
- /* A line can only appear once, so we're done. */
- return ;
+ /* A line can only appear once, so we're done,
+ * unless we are clearing the whole viewport */
+ if (y >= 0)
+ return ;
}
else
{