summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-04-10 13:43:41 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-04-10 13:43:41 +0300
commit22f1d02ff1d9c7ee89a80969f2122968b9b5e1fe (patch)
treeccf0174fbd9b2a57589731ac0e30765b445b6032 /src/ui
parent4e8977f5734663956613caac058849273c4e5ac0 (diff)
Touch: Improved hover behavior
Scrolling must prevent the hover state from being updated both in documents and lists.
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/documentwidget.c6
-rw-r--r--src/ui/listwidget.c34
-rw-r--r--src/ui/touch.c1
3 files changed, 29 insertions, 12 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index c3a6d40d..e18d5283 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -2585,7 +2585,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
2585 return iTrue; 2585 return iTrue;
2586 } 2586 }
2587 else if (ev->type == SDL_MOUSEMOTION) { 2587 else if (ev->type == SDL_MOUSEMOTION) {
2588 if (deviceType_App() == desktop_AppDeviceType) { 2588 if (ev->motion.which != SDL_TOUCH_MOUSEID) {
2589 iChangeFlags(d->flags, noHoverWhileScrolling_DocumentWidgetFlag, iFalse); 2589 iChangeFlags(d->flags, noHoverWhileScrolling_DocumentWidgetFlag, iFalse);
2590 } 2590 }
2591 const iInt2 mpos = init_I2(ev->motion.x, ev->motion.y); 2591 const iInt2 mpos = init_I2(ev->motion.x, ev->motion.y);
@@ -2763,6 +2763,10 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
2763 if (d->grabbedPlayer) { 2763 if (d->grabbedPlayer) {
2764 return iTrue; 2764 return iTrue;
2765 } 2765 }
2766 if (d->flags & noHoverWhileScrolling_DocumentWidgetFlag) {
2767 d->flags &= ~noHoverWhileScrolling_DocumentWidgetFlag;
2768 updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window()));
2769 }
2766 iChangeFlags(d->flags, selecting_DocumentWidgetFlag, iFalse); 2770 iChangeFlags(d->flags, selecting_DocumentWidgetFlag, iFalse);
2767 iChangeFlags(d->flags, selectWords_DocumentWidgetFlag, d->click.count == 2); 2771 iChangeFlags(d->flags, selectWords_DocumentWidgetFlag, d->click.count == 2);
2768 iChangeFlags(d->flags, selectLines_DocumentWidgetFlag, d->click.count >= 3); 2772 iChangeFlags(d->flags, selectLines_DocumentWidgetFlag, d->click.count >= 3);
diff --git a/src/ui/listwidget.c b/src/ui/listwidget.c
index dbd8e540..daf22bda 100644
--- a/src/ui/listwidget.c
+++ b/src/ui/listwidget.c
@@ -57,6 +57,7 @@ struct Impl_ListWidget {
57 iClick click; 57 iClick click;
58 iIntSet invalidItems; 58 iIntSet invalidItems;
59 iVisBuf *visBuf; 59 iVisBuf *visBuf;
60 iBool noHoverWhileScrolling;
60}; 61};
61 62
62void init_ListWidget(iListWidget *d) { 63void init_ListWidget(iListWidget *d) {
@@ -69,6 +70,7 @@ void init_ListWidget(iListWidget *d) {
69 setThumb_ScrollWidget(d->scroll, 0, 0); 70 setThumb_ScrollWidget(d->scroll, 0, 0);
70 d->scrollY = 0; 71 d->scrollY = 0;
71 d->itemHeight = 0; 72 d->itemHeight = 0;
73 d->noHoverWhileScrolling = iFalse;
72 init_PtrArray(&d->items); 74 init_PtrArray(&d->items);
73 d->hoverItem = iInvalidPos; 75 d->hoverItem = iInvalidPos;
74 init_Click(&d->click, d, SDL_BUTTON_LEFT); 76 init_Click(&d->click, d, SDL_BUTTON_LEFT);
@@ -173,6 +175,7 @@ iBool scrollOffset_ListWidget(iListWidget *d, int offset) {
173 } 175 }
174 const int scrollMax = scrollMax_ListWidget_(d); 176 const int scrollMax = scrollMax_ListWidget_(d);
175 d->scrollY = iMin(d->scrollY, scrollMax); 177 d->scrollY = iMin(d->scrollY, scrollMax);
178 d->noHoverWhileScrolling = iTrue;
176 if (oldScroll != d->scrollY) { 179 if (oldScroll != d->scrollY) {
177 if (d->hoverItem != iInvalidPos) { 180 if (d->hoverItem != iInvalidPos) {
178 invalidateItem_ListWidget(d, d->hoverItem); 181 invalidateItem_ListWidget(d, d->hoverItem);
@@ -256,10 +259,8 @@ static void setHoverItem_ListWidget_(iListWidget *d, size_t index) {
256 } 259 }
257 } 260 }
258 if (d->hoverItem != index) { 261 if (d->hoverItem != index) {
259 if (deviceType_App() == desktop_AppDeviceType || numFingers_Touch()) { 262 insert_IntSet(&d->invalidItems, d->hoverItem);
260 insert_IntSet(&d->invalidItems, d->hoverItem); 263 insert_IntSet(&d->invalidItems, index);
261 insert_IntSet(&d->invalidItems, index);
262 }
263 d->hoverItem = index; 264 d->hoverItem = index;
264 refresh_Widget(as_Widget(d)); 265 refresh_Widget(as_Widget(d));
265 } 266 }
@@ -284,6 +285,16 @@ static void sizeChanged_ListWidget_(iListWidget *d) {
284 invalidate_ListWidget(d); 285 invalidate_ListWidget(d);
285} 286}
286 287
288static void updateHover_ListWidget_(iListWidget *d, const iInt2 mouse) {
289 size_t hover = iInvalidPos;
290 if (!d->noHoverWhileScrolling &&
291 !contains_Widget(constAs_Widget(d->scroll), mouse) &&
292 contains_Widget(constAs_Widget(d), mouse)) {
293 hover = itemIndex_ListWidget(d, mouse);
294 }
295 setHoverItem_ListWidget_(d, hover);
296}
297
287static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) { 298static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) {
288 iWidget *w = as_Widget(d); 299 iWidget *w = as_Widget(d);
289 if (isMetricsChange_UserEvent(ev)) { 300 if (isMetricsChange_UserEvent(ev)) {
@@ -299,14 +310,14 @@ static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) {
299 return iTrue; 310 return iTrue;
300 } 311 }
301 } 312 }
313 else if (ev->type == SDL_USEREVENT && ev->user.code == widgetTapBegins_UserEventCode) {
314 d->noHoverWhileScrolling = iFalse;
315 }
302 if (ev->type == SDL_MOUSEMOTION) { 316 if (ev->type == SDL_MOUSEMOTION) {
303 const iInt2 mouse = init_I2(ev->motion.x, ev->motion.y); 317 if (ev->motion.which != SDL_TOUCH_MOUSEID) {
304 size_t hover = iInvalidPos; 318 d->noHoverWhileScrolling = iFalse;
305 if (!contains_Widget(constAs_Widget(d->scroll), mouse) &&
306 contains_Widget(w, mouse)) {
307 hover = itemIndex_ListWidget(d, mouse);
308 } 319 }
309 setHoverItem_ListWidget_(d, hover); 320 updateHover_ListWidget_(d, init_I2(ev->motion.x, ev->motion.y));
310 } 321 }
311 if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { 322 if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) {
312 int amount = -ev->wheel.y; 323 int amount = -ev->wheel.y;
@@ -318,13 +329,14 @@ static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) {
318 } 329 }
319 switch (processEvent_Click(&d->click, ev)) { 330 switch (processEvent_Click(&d->click, ev)) {
320 case started_ClickResult: 331 case started_ClickResult:
332 d->noHoverWhileScrolling = iFalse;
333 updateHover_ListWidget_(d, mouseCoord_Window(get_Window()));
321 redrawHoverItem_ListWidget_(d); 334 redrawHoverItem_ListWidget_(d);
322 return iTrue; 335 return iTrue;
323 case aborted_ClickResult: 336 case aborted_ClickResult:
324 redrawHoverItem_ListWidget_(d); 337 redrawHoverItem_ListWidget_(d);
325 break; 338 break;
326 case finished_ClickResult: 339 case finished_ClickResult:
327// case double_ClickResult:
328 redrawHoverItem_ListWidget_(d); 340 redrawHoverItem_ListWidget_(d);
329 if (contains_Rect(innerBounds_Widget(w), pos_Click(&d->click)) && 341 if (contains_Rect(innerBounds_Widget(w), pos_Click(&d->click)) &&
330 d->hoverItem != iInvalidSize) { 342 d->hoverItem != iInvalidSize) {
diff --git a/src/ui/touch.c b/src/ui/touch.c
index bf217301..87bb7478 100644
--- a/src/ui/touch.c
+++ b/src/ui/touch.c
@@ -234,6 +234,7 @@ static void update_TouchState_(void *ptr) {
234 const int elapsed = nowTime - touch->startTime; 234 const int elapsed = nowTime - touch->startTime;
235 if (elapsed > 25) { 235 if (elapsed > 25) {
236 clearWidgetMomentum_TouchState_(d, touch->affinity); 236 clearWidgetMomentum_TouchState_(d, touch->affinity);
237 clear_Array(d->moms); /* stop all ongoing momentum */
237 } 238 }
238 if (elapsed > 50 && !touch->isTapBegun) { 239 if (elapsed > 50 && !touch->isTapBegun) {
239 /* Looks like a possible tap. */ 240 /* Looks like a possible tap. */