diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-10 13:43:41 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-10 13:43:41 +0300 |
commit | 22f1d02ff1d9c7ee89a80969f2122968b9b5e1fe (patch) | |
tree | ccf0174fbd9b2a57589731ac0e30765b445b6032 /src/ui/listwidget.c | |
parent | 4e8977f5734663956613caac058849273c4e5ac0 (diff) |
Touch: Improved hover behavior
Scrolling must prevent the hover state from being updated both in documents and lists.
Diffstat (limited to 'src/ui/listwidget.c')
-rw-r--r-- | src/ui/listwidget.c | 34 |
1 files changed, 23 insertions, 11 deletions
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 | ||
62 | void init_ListWidget(iListWidget *d) { | 63 | void 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 | ||
288 | static 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 | |||
287 | static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) { | 298 | static 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) { |