From 63dc07ddbecfdf0be7c0bd98c53e492628dda98b Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Fri, 19 Feb 2021 10:50:41 +0200 Subject: 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. --- src/ui/inputwidget.c | 2 +- src/ui/scrollwidget.c | 2 +- src/ui/touch.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/ui/widget.h | 1 + 4 files changed, 43 insertions(+), 3 deletions(-) (limited to 'src') 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) { void init_InputWidget(iInputWidget *d, size_t maxLen) { iWidget *w = &d->widget; init_Widget(w); - setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag, iTrue); + setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag | touchDrag_WidgetFlag, iTrue); init_Array(&d->text, sizeof(iChar)); init_Array(&d->oldText, sizeof(iChar)); 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) { setId_Widget(w, "scroll"); setFlags_Widget(w, fixedWidth_WidgetFlag | resizeToParentHeight_WidgetFlag | - moveToParentRightEdge_WidgetFlag, + moveToParentRightEdge_WidgetFlag | touchDrag_WidgetFlag, iTrue); w->rect.size.x = gap_UI * 3; 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) { edge = right_TouchEdge; } iWidget *aff = hitChild_Widget(window->root, init_I2(iRound(x), iRound(y_F3(pos)))); + if (flags_Widget(aff) & touchDrag_WidgetFlag) { + dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){ + .type = SDL_MOUSEBUTTONDOWN, + .timestamp = fing->timestamp, + .clicks = 1, + .state = SDL_PRESSED, + .which = SDL_TOUCH_MOUSEID, + .button = SDL_BUTTON_LEFT, + .x = x_F3(pos), + .y = y_F3(pos) + }); + edge = none_TouchEdge; + } pushBack_Array(d->touches, &(iTouch){ .id = fing->fingerId, .affinity = aff, + .hasMoved = (flags_Widget(aff) & touchDrag_WidgetFlag) != 0, .edge = edge, .startTime = nowTime, .startPos = pos, @@ -223,7 +237,7 @@ iBool processEvent_Touch(const SDL_Event *ev) { /* Some widgets rely on hover state. */ dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseMotionEvent){ .type = SDL_MOUSEMOTION, - .timestamp = SDL_GetTicks(), + .timestamp = fing->timestamp, .which = SDL_TOUCH_MOUSEID, .x = x_F3(pos), .y = y_F3(pos) @@ -233,6 +247,17 @@ iBool processEvent_Touch(const SDL_Event *ev) { else if (ev->type == SDL_FINGERMOTION) { iTouch *touch = find_TouchState_(d, fing->fingerId); if (touch && touch->affinity) { + if (flags_Widget(touch->affinity) & touchDrag_WidgetFlag) { + dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseMotionEvent){ + .type = SDL_MOUSEMOTION, + .timestamp = fing->timestamp, + .which = SDL_TOUCH_MOUSEID, + .state = SDL_BUTTON_LMASK, + .x = x_F3(pos), + .y = y_F3(pos) + }); + return iTrue; + } /* Update touch position. */ pushPos_Touch_(touch, pos, nowTime); const iFloat3 amount = add_F3(touch->remainder, @@ -278,6 +303,20 @@ iBool processEvent_Touch(const SDL_Event *ev) { if (touch->id != fing->fingerId) { continue; } + if (flags_Widget(touch->affinity) & touchDrag_WidgetFlag) { + dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){ + .type = SDL_MOUSEBUTTONUP, + .timestamp = fing->timestamp, + .clicks = 1, + .state = SDL_RELEASED, + .which = SDL_TOUCH_MOUSEID, + .button = SDL_BUTTON_LEFT, + .x = x_F3(pos), + .y = y_F3(pos) + }); + remove_ArrayIterator(&i); + continue; + } /* Edge swipes do not generate momentum. */ const uint32_t duration = nowTime - touch->startTime; 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 { #define overflowScrollable_WidgetFlag iBit64(38) #define focusRoot_WidgetFlag iBit64(39) #define unhittable_WidgetFlag iBit64(40) +#define touchDrag_WidgetFlag iBit64(41) /* touch event behavior: immediate drag */ enum iWidgetAddPos { back_WidgetAddPos, -- cgit v1.2.3