diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-12 22:25:48 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-12 22:25:48 +0200 |
commit | 3e56e0f1ca20d7d0489036ce0f0bca97d596f0d5 (patch) | |
tree | 0f8b96c30ea47e7a7df631310570f15f04008b98 /src/ui/touch.c | |
parent | 9060a1cde043fe75d28b4dc620b5e62d8baff14f (diff) |
Touch: Drag behavior for input fields
Allow long-pressing in touchDrag widgets.
Diffstat (limited to 'src/ui/touch.c')
-rw-r--r-- | src/ui/touch.c | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/src/ui/touch.c b/src/ui/touch.c index df457b27..416819a0 100644 --- a/src/ui/touch.c +++ b/src/ui/touch.c | |||
@@ -56,6 +56,7 @@ struct Impl_Touch { | |||
56 | iWidget *affinity; /* widget on which the touch started */ | 56 | iWidget *affinity; /* widget on which the touch started */ |
57 | iWidget *edgeDragging; | 57 | iWidget *edgeDragging; |
58 | iBool hasMoved; | 58 | iBool hasMoved; |
59 | iBool isTouchDrag; | ||
59 | iBool isTapAndHold; | 60 | iBool isTapAndHold; |
60 | enum iTouchEdge edge; | 61 | enum iTouchEdge edge; |
61 | uint32_t startTime; | 62 | uint32_t startTime; |
@@ -252,6 +253,19 @@ void widgetDestroyed_Touch(iWidget *widget) { | |||
252 | } | 253 | } |
253 | } | 254 | } |
254 | 255 | ||
256 | static void dispatchButtonDown_Touch_(iFloat3 pos) { | ||
257 | dispatchEvent_Widget(get_Window()->root, (SDL_Event *) &(SDL_MouseButtonEvent){ | ||
258 | .type = SDL_MOUSEBUTTONDOWN, | ||
259 | .timestamp = SDL_GetTicks(), | ||
260 | .clicks = 1, | ||
261 | .state = SDL_PRESSED, | ||
262 | .which = SDL_TOUCH_MOUSEID, | ||
263 | .button = SDL_BUTTON_LEFT, | ||
264 | .x = x_F3(pos), | ||
265 | .y = y_F3(pos) | ||
266 | }); | ||
267 | } | ||
268 | |||
255 | static void dispatchButtonUp_Touch_(iFloat3 pos) { | 269 | static void dispatchButtonUp_Touch_(iFloat3 pos) { |
256 | dispatchEvent_Widget(get_Window()->root, (SDL_Event *) &(SDL_MouseButtonEvent){ | 270 | dispatchEvent_Widget(get_Window()->root, (SDL_Event *) &(SDL_MouseButtonEvent){ |
257 | .type = SDL_MOUSEBUTTONUP, | 271 | .type = SDL_MOUSEBUTTONUP, |
@@ -327,24 +341,11 @@ iBool processEvent_Touch(const SDL_Event *ev) { | |||
327 | // cstr_String(id_Widget(aff))); | 341 | // cstr_String(id_Widget(aff))); |
328 | // printf("drg:[%p] %s:'%s'\n", dragging, dragging ? class_Widget(dragging)->name : "-", | 342 | // printf("drg:[%p] %s:'%s'\n", dragging, dragging ? class_Widget(dragging)->name : "-", |
329 | // cstr_String(id_Widget(dragging))); | 343 | // cstr_String(id_Widget(dragging))); |
330 | if (flags_Widget(aff) & touchDrag_WidgetFlag) { | ||
331 | dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){ | ||
332 | .type = SDL_MOUSEBUTTONDOWN, | ||
333 | .timestamp = fing->timestamp, | ||
334 | .clicks = 1, | ||
335 | .state = SDL_PRESSED, | ||
336 | .which = SDL_TOUCH_MOUSEID, | ||
337 | .button = SDL_BUTTON_LEFT, | ||
338 | .x = x_F3(pos), | ||
339 | .y = y_F3(pos) | ||
340 | }); | ||
341 | edge = none_TouchEdge; | ||
342 | } | ||
343 | iTouch newTouch = { | 344 | iTouch newTouch = { |
344 | .id = fing->fingerId, | 345 | .id = fing->fingerId, |
345 | .affinity = aff, | 346 | .affinity = aff, |
346 | .edgeDragging = dragging, | 347 | .edgeDragging = dragging, |
347 | .hasMoved = (flags_Widget(aff) & touchDrag_WidgetFlag) != 0, | 348 | // .hasMoved = (flags_Widget(aff) & touchDrag_WidgetFlag) != 0, |
348 | .edge = edge, | 349 | .edge = edge, |
349 | .startTime = nowTime, | 350 | .startTime = nowTime, |
350 | .startPos = pos, | 351 | .startPos = pos, |
@@ -352,7 +353,7 @@ iBool processEvent_Touch(const SDL_Event *ev) { | |||
352 | pushPos_Touch_(&newTouch, pos, fing->timestamp); | 353 | pushPos_Touch_(&newTouch, pos, fing->timestamp); |
353 | pushBack_Array(d->touches, &newTouch); | 354 | pushBack_Array(d->touches, &newTouch); |
354 | /* Some widgets rely on hover state for scrolling. */ | 355 | /* Some widgets rely on hover state for scrolling. */ |
355 | if (flags_Widget(aff) & hover_WidgetFlag) { | 356 | if (flags_Widget(aff) & hover_WidgetFlag && ~flags_Widget(aff) & touchDrag_WidgetFlag) { |
356 | setHover_Widget(aff); | 357 | setHover_Widget(aff); |
357 | } | 358 | } |
358 | addTicker_App(update_TouchState_, d); | 359 | addTicker_App(update_TouchState_, d); |
@@ -360,6 +361,10 @@ iBool processEvent_Touch(const SDL_Event *ev) { | |||
360 | else if (ev->type == SDL_FINGERMOTION) { | 361 | else if (ev->type == SDL_FINGERMOTION) { |
361 | iTouch *touch = find_TouchState_(d, fing->fingerId); | 362 | iTouch *touch = find_TouchState_(d, fing->fingerId); |
362 | if (touch && touch->affinity) { | 363 | if (touch && touch->affinity) { |
364 | if (touch->isTouchDrag) { | ||
365 | dispatchMotion_Touch_(pos, SDL_BUTTON_LMASK); | ||
366 | return iTrue; | ||
367 | } | ||
363 | if (touch->isTapAndHold) { | 368 | if (touch->isTapAndHold) { |
364 | pushPos_Touch_(touch, pos, fing->timestamp); | 369 | pushPos_Touch_(touch, pos, fing->timestamp); |
365 | if (!touch->hasMoved && !isStationary_Touch_(touch)) { | 370 | if (!touch->hasMoved && !isStationary_Touch_(touch)) { |
@@ -368,12 +373,27 @@ iBool processEvent_Touch(const SDL_Event *ev) { | |||
368 | dispatchMotion_Touch_(pos, 0); | 373 | dispatchMotion_Touch_(pos, 0); |
369 | return iTrue; | 374 | return iTrue; |
370 | } | 375 | } |
371 | if (flags_Widget(touch->affinity) & touchDrag_WidgetFlag) { | 376 | /* Update touch position. */ |
377 | pushPos_Touch_(touch, pos, nowTime); | ||
378 | if (!touch->isTouchDrag && !isStationary_Touch_(touch) && | ||
379 | flags_Widget(touch->affinity) & touchDrag_WidgetFlag) { | ||
380 | touch->hasMoved = iTrue; | ||
381 | touch->isTouchDrag = iTrue; | ||
382 | touch->edge = none_TouchEdge; | ||
383 | pushPos_Touch_(touch, pos, fing->timestamp); | ||
384 | dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){ | ||
385 | .type = SDL_MOUSEBUTTONDOWN, | ||
386 | .timestamp = fing->timestamp, | ||
387 | .clicks = 1, | ||
388 | .state = SDL_PRESSED, | ||
389 | .which = SDL_TOUCH_MOUSEID, | ||
390 | .button = SDL_BUTTON_LEFT, | ||
391 | .x = x_F3(touch->startPos), | ||
392 | .y = y_F3(touch->startPos) | ||
393 | }); | ||
372 | dispatchMotion_Touch_(pos, SDL_BUTTON_LMASK); | 394 | dispatchMotion_Touch_(pos, SDL_BUTTON_LMASK); |
373 | return iTrue; | 395 | return iTrue; |
374 | } | 396 | } |
375 | /* Update touch position. */ | ||
376 | pushPos_Touch_(touch, pos, nowTime); | ||
377 | const iFloat3 amount = mul_F3(init_F3(fing->dx, fing->dy, 0), | 397 | const iFloat3 amount = mul_F3(init_F3(fing->dx, fing->dy, 0), |
378 | init_F3(rootSize.x, rootSize.y, 0)); | 398 | init_F3(rootSize.x, rootSize.y, 0)); |
379 | addv_F3(&touch->accum, amount); | 399 | addv_F3(&touch->accum, amount); |
@@ -473,8 +493,11 @@ iBool processEvent_Touch(const SDL_Event *ev) { | |||
473 | continue; | 493 | continue; |
474 | } | 494 | } |
475 | if (flags_Widget(touch->affinity) & touchDrag_WidgetFlag) { | 495 | if (flags_Widget(touch->affinity) & touchDrag_WidgetFlag) { |
496 | if (!touch->isTouchDrag) { | ||
497 | dispatchButtonDown_Touch_(touch->startPos); | ||
498 | } | ||
476 | dispatchButtonUp_Touch_(pos); | 499 | dispatchButtonUp_Touch_(pos); |
477 | setHover_Widget(NULL); | 500 | // setHover_Widget(NULL); |
478 | remove_ArrayIterator(&i); | 501 | remove_ArrayIterator(&i); |
479 | continue; | 502 | continue; |
480 | } | 503 | } |