summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-02-19 10:50:41 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-02-19 10:50:41 +0200
commit63dc07ddbecfdf0be7c0bd98c53e492628dda98b (patch)
tree5757cbf586f8220a929f7341234c771ee982463a /src
parent4cb785e2b175424316a5795b1e5dcf012a69b134 (diff)
Touch: Scrollbars can be dragged via touch
Widgets can be flagged as being touch-draggable, which makes them receive finger down/motion/up events directly, and no momentum scrolling is applied.
Diffstat (limited to 'src')
-rw-r--r--src/ui/inputwidget.c2
-rw-r--r--src/ui/scrollwidget.c2
-rw-r--r--src/ui/touch.c41
-rw-r--r--src/ui/widget.h1
4 files changed, 43 insertions, 3 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index b51bd3ef..2f0fa064 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -108,7 +108,7 @@ static void showCursor_InputWidget_(iInputWidget *d) {
108void init_InputWidget(iInputWidget *d, size_t maxLen) { 108void init_InputWidget(iInputWidget *d, size_t maxLen) {
109 iWidget *w = &d->widget; 109 iWidget *w = &d->widget;
110 init_Widget(w); 110 init_Widget(w);
111 setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag, iTrue); 111 setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag | touchDrag_WidgetFlag, iTrue);
112 init_Array(&d->text, sizeof(iChar)); 112 init_Array(&d->text, sizeof(iChar));
113 init_Array(&d->oldText, sizeof(iChar)); 113 init_Array(&d->oldText, sizeof(iChar));
114 init_String(&d->hint); 114 init_String(&d->hint);
diff --git a/src/ui/scrollwidget.c b/src/ui/scrollwidget.c
index 649d0575..34efba67 100644
--- a/src/ui/scrollwidget.c
+++ b/src/ui/scrollwidget.c
@@ -41,7 +41,7 @@ void init_ScrollWidget(iScrollWidget *d) {
41 setId_Widget(w, "scroll"); 41 setId_Widget(w, "scroll");
42 setFlags_Widget(w, 42 setFlags_Widget(w,
43 fixedWidth_WidgetFlag | resizeToParentHeight_WidgetFlag | 43 fixedWidth_WidgetFlag | resizeToParentHeight_WidgetFlag |
44 moveToParentRightEdge_WidgetFlag, 44 moveToParentRightEdge_WidgetFlag | touchDrag_WidgetFlag,
45 iTrue); 45 iTrue);
46 w->rect.size.x = gap_UI * 3; 46 w->rect.size.x = gap_UI * 3;
47 init_Click(&d->click, d, SDL_BUTTON_LEFT); 47 init_Click(&d->click, d, SDL_BUTTON_LEFT);
diff --git a/src/ui/touch.c b/src/ui/touch.c
index dbb16bd5..9b47d0fe 100644
--- a/src/ui/touch.c
+++ b/src/ui/touch.c
@@ -212,9 +212,23 @@ iBool processEvent_Touch(const SDL_Event *ev) {
212 edge = right_TouchEdge; 212 edge = right_TouchEdge;
213 } 213 }
214 iWidget *aff = hitChild_Widget(window->root, init_I2(iRound(x), iRound(y_F3(pos)))); 214 iWidget *aff = hitChild_Widget(window->root, init_I2(iRound(x), iRound(y_F3(pos))));
215 if (flags_Widget(aff) & touchDrag_WidgetFlag) {
216 dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){
217 .type = SDL_MOUSEBUTTONDOWN,
218 .timestamp = fing->timestamp,
219 .clicks = 1,
220 .state = SDL_PRESSED,
221 .which = SDL_TOUCH_MOUSEID,
222 .button = SDL_BUTTON_LEFT,
223 .x = x_F3(pos),
224 .y = y_F3(pos)
225 });
226 edge = none_TouchEdge;
227 }
215 pushBack_Array(d->touches, &(iTouch){ 228 pushBack_Array(d->touches, &(iTouch){
216 .id = fing->fingerId, 229 .id = fing->fingerId,
217 .affinity = aff, 230 .affinity = aff,
231 .hasMoved = (flags_Widget(aff) & touchDrag_WidgetFlag) != 0,
218 .edge = edge, 232 .edge = edge,
219 .startTime = nowTime, 233 .startTime = nowTime,
220 .startPos = pos, 234 .startPos = pos,
@@ -223,7 +237,7 @@ iBool processEvent_Touch(const SDL_Event *ev) {
223 /* Some widgets rely on hover state. */ 237 /* Some widgets rely on hover state. */
224 dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseMotionEvent){ 238 dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseMotionEvent){
225 .type = SDL_MOUSEMOTION, 239 .type = SDL_MOUSEMOTION,
226 .timestamp = SDL_GetTicks(), 240 .timestamp = fing->timestamp,
227 .which = SDL_TOUCH_MOUSEID, 241 .which = SDL_TOUCH_MOUSEID,
228 .x = x_F3(pos), 242 .x = x_F3(pos),
229 .y = y_F3(pos) 243 .y = y_F3(pos)
@@ -233,6 +247,17 @@ iBool processEvent_Touch(const SDL_Event *ev) {
233 else if (ev->type == SDL_FINGERMOTION) { 247 else if (ev->type == SDL_FINGERMOTION) {
234 iTouch *touch = find_TouchState_(d, fing->fingerId); 248 iTouch *touch = find_TouchState_(d, fing->fingerId);
235 if (touch && touch->affinity) { 249 if (touch && touch->affinity) {
250 if (flags_Widget(touch->affinity) & touchDrag_WidgetFlag) {
251 dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseMotionEvent){
252 .type = SDL_MOUSEMOTION,
253 .timestamp = fing->timestamp,
254 .which = SDL_TOUCH_MOUSEID,
255 .state = SDL_BUTTON_LMASK,
256 .x = x_F3(pos),
257 .y = y_F3(pos)
258 });
259 return iTrue;
260 }
236 /* Update touch position. */ 261 /* Update touch position. */
237 pushPos_Touch_(touch, pos, nowTime); 262 pushPos_Touch_(touch, pos, nowTime);
238 const iFloat3 amount = add_F3(touch->remainder, 263 const iFloat3 amount = add_F3(touch->remainder,
@@ -278,6 +303,20 @@ iBool processEvent_Touch(const SDL_Event *ev) {
278 if (touch->id != fing->fingerId) { 303 if (touch->id != fing->fingerId) {
279 continue; 304 continue;
280 } 305 }
306 if (flags_Widget(touch->affinity) & touchDrag_WidgetFlag) {
307 dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){
308 .type = SDL_MOUSEBUTTONUP,
309 .timestamp = fing->timestamp,
310 .clicks = 1,
311 .state = SDL_RELEASED,
312 .which = SDL_TOUCH_MOUSEID,
313 .button = SDL_BUTTON_LEFT,
314 .x = x_F3(pos),
315 .y = y_F3(pos)
316 });
317 remove_ArrayIterator(&i);
318 continue;
319 }
281 /* Edge swipes do not generate momentum. */ 320 /* Edge swipes do not generate momentum. */
282 const uint32_t duration = nowTime - touch->startTime; 321 const uint32_t duration = nowTime - touch->startTime;
283 const iFloat3 gestureVector = sub_F3(pos, touch->startPos); 322 const iFloat3 gestureVector = sub_F3(pos, touch->startPos);
diff --git a/src/ui/widget.h b/src/ui/widget.h
index a9756793..0b7a76e1 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -92,6 +92,7 @@ enum iWidgetFlag {
92#define overflowScrollable_WidgetFlag iBit64(38) 92#define overflowScrollable_WidgetFlag iBit64(38)
93#define focusRoot_WidgetFlag iBit64(39) 93#define focusRoot_WidgetFlag iBit64(39)
94#define unhittable_WidgetFlag iBit64(40) 94#define unhittable_WidgetFlag iBit64(40)
95#define touchDrag_WidgetFlag iBit64(41) /* touch event behavior: immediate drag */
95 96
96enum iWidgetAddPos { 97enum iWidgetAddPos {
97 back_WidgetAddPos, 98 back_WidgetAddPos,