summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-03-12 22:25:48 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-03-12 22:25:48 +0200
commit3e56e0f1ca20d7d0489036ce0f0bca97d596f0d5 (patch)
tree0f8b96c30ea47e7a7df631310570f15f04008b98
parent9060a1cde043fe75d28b4dc620b5e62d8baff14f (diff)
Touch: Drag behavior for input fields
Allow long-pressing in touchDrag widgets.
-rw-r--r--src/ui/touch.c61
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
256static 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
255static void dispatchButtonUp_Touch_(iFloat3 pos) { 269static 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 }