1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
diff --git a/apps/action.c b/apps/action.c
index fc10c92..fbf520c 100644
--- a/apps/action.c
+++ b/apps/action.c
@@ -37,6 +37,7 @@
 #if defined(HAVE_LCD_BITMAP) && !defined(BOOTLOADER)
 #include "language.h"
 #endif
+#include "viewport.h"

 static int last_button = BUTTON_NONE|BUTTON_REL; /* allow the ipod wheel to
                                                     work on startup */
@@ -353,7 +354,7 @@ int get_action_statuscode(int *button)
 }

 #ifdef HAVE_TOUCHSCREEN
-/* return BUTTON_NONE               on error
+/* return ACTION_NONE               on error
  *        BUTTON_REPEAT             if repeated press
  *        BUTTON_REPEAT|BUTTON_REL  if release after repeated press
  *        BUTTON_REL                if its a short press = release after press
@@ -386,6 +387,29 @@ int action_get_touchscreen_press(short *x, short *y)
         return BUTTON_REPEAT|BUTTON_REL;
     return BUTTON_TOUCHSCREEN;
 }
+
+/* wrapper to filter the touchscreen coordinates through a viewport
+ * returns the action and x1, y1 relative to the viewport if
+ * the press was within the viewport,
+ * ACTION_UNKNOWN (and x1, y1 untouched) if the press was outside
+ * BUTTON_NONE else */
+int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp)
+{
+    short x, y;
+    int ret;
+
+    ret = action_get_touchscreen_press(&x, &y);
+
+    if (ret != BUTTON_NONE && viewport_point_within_vp(vp, x, y))
+    {
+        *x1 = x - vp->x;
+        *y1 = y - vp->y;
+        return ret;
+    }
+    if (ret & BUTTON_TOUCHSCREEN)
+        return ACTION_UNKNOWN;
+    return BUTTON_NONE;
+}
 #endif

 /* Don't let get_action*() return any ACTION_* values untill the current buttons
diff --git a/apps/action.h b/apps/action.h
index 24250ef..545994d 100644
--- a/apps/action.h
+++ b/apps/action.h
@@ -22,6 +22,7 @@

 #include "stdbool.h"
 #include "button.h"
+#include "viewport.h"

 #define TIMEOUT_BLOCK   -1
 #define TIMEOUT_NOBLOCK  0
@@ -327,12 +328,20 @@ int get_action_statuscode(int *button);
 intptr_t get_action_data(void);

 #ifdef HAVE_TOUCHSCREEN
-/* return BUTTON_NONE on error
-          BUTTON_REPEAT if repeated press
-          BUTTON_REL    if its a short press
-          BUTTON_TOUCHSCREEN   otherwise
-*/
+/* return ACTION_NONE               on error
+ *        BUTTON_REPEAT             if repeated press
+ *        BUTTON_REPEAT|BUTTON_REL  if release after repeated press
+ *        BUTTON_REL                if its a short press = release after press
+ *        BUTTON_TOUCHSCREEN        if press
+ */
 int action_get_touchscreen_press(short *x, short *y);
+
+/* wrapper for action_get_touchscreen_press
+ * to filter the touchscreen coordinates through a viewport,
+ * returns the action and x1, y1 relative to the viewport if
+ * the press was within the viewport,
+ * ACTION_NONE (and x1, y1 untouched) if the press was outside */
+int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp);
 #endif

 /* Don't let get_action*() return any ACTION_* values untill the current buttons
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c
index d70b98c..75c0612 100644
--- a/apps/gui/color_picker.c
+++ b/apps/gui/color_picker.c
@@ -335,7 +335,7 @@ static int touchscreen_slider(struct screen *display,
 {
     short     x,y;
     int       text_top, slider_x, slider_width, title_height;
-    unsigned  button = action_get_touchscreen_press(&x, &y);
+    int       button;
     bool      display_three_rows;
     int       max_label_width;
     int      pressed_slider;
@@ -344,16 +344,15 @@ static int touchscreen_slider(struct screen *display,

     viewport_set_defaults(&vp, display->screen_type);

-    if (button == BUTTON_NONE)
-        return ACTION_NONE;
-
     max_label_width =  label_get_max_width(display);
     display->getstringsize(title, NULL, &title_height);
-
+    button = action_get_touchscreen_press_in_vp(&x, &y, &vp);
+    if (button == ACTION_UNKNOWN || button == BUTTON_NONE)
+        return ACTION_NONE;
     /* Get slider positions and top starting position
      * need vp.y here, because of the statusbar, since touchscreen
      * coordinates are absolute */
-    text_top     = vp.y + MARGIN_TOP + title_height + TITLE_MARGIN_BOTTOM +
+    text_top     = MARGIN_TOP + title_height + TITLE_MARGIN_BOTTOM +
                    SELECTOR_TB_MARGIN;
     slider_x     = SELECTOR_WIDTH + max_label_width + SLIDER_TEXT_MARGIN;
     slider_width = vp.width - slider_x*2 - max_label_width;
@@ -376,12 +375,15 @@ static int touchscreen_slider(struct screen *display,
             return ACTION_STD_CANCEL;
     }

-    pressed_slider = (y - text_top)/line_height;
-    if (pressed_slider > (display_three_rows?2:0))
-    {
+    vp.y += text_top;
+    vp.height = line_height * (display_three_rows ? 3:1);
+    if (!viewport_point_within_vp(&vp, x, y))
+    {   /* touching the color area means accept */
         if (button == BUTTON_REL)
             return ACTION_STD_OK;
     }
+    /* y is relative to the original viewport */
+    pressed_slider = (y - text_top)/line_height;
     if (pressed_slider != *selected_slider)
         *selected_slider = pressed_slider;
     /* add max_label_width to overcome integer division limits,