diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-14 07:24:32 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-14 07:24:32 +0300 |
commit | fe59111e9671fba8d1c64def9831716860ea5e44 (patch) | |
tree | fdb44222af394b4924ade2715205a813f1db2f1b /src/ui/widget.c | |
parent | 713dcca5da21897fd8f5d7519112429273d7233e (diff) |
InputWidget: Fixed cursor moving; scroll the dialog
Up/down movement sometimes ended up in the wrong cursor position.
Now the nearest overflow-scrollable parent scrolls to keep the cursor visible.
Diffstat (limited to 'src/ui/widget.c')
-rw-r--r-- | src/ui/widget.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/src/ui/widget.c b/src/ui/widget.c index fa05e8d1..18f98050 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -927,7 +927,7 @@ iBool dispatchEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
927 | return iFalse; | 927 | return iFalse; |
928 | } | 928 | } |
929 | 929 | ||
930 | static iBool scrollOverflow_Widget_(iWidget *d, int delta) { | 930 | iBool scrollOverflow_Widget(iWidget *d, int delta) { |
931 | iRect bounds = bounds_Widget(d); | 931 | iRect bounds = bounds_Widget(d); |
932 | const iInt2 rootSize = size_Root(d->root); | 932 | const iInt2 rootSize = size_Root(d->root); |
933 | const iRect winRect = safeRect_Root(d->root); | 933 | const iRect winRect = safeRect_Root(d->root); |
@@ -980,7 +980,7 @@ iBool processEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
980 | if (!isPerPixel_MouseWheelEvent(&ev->wheel)) { | 980 | if (!isPerPixel_MouseWheelEvent(&ev->wheel)) { |
981 | step *= lineHeight_Text(uiLabel_FontId); | 981 | step *= lineHeight_Text(uiLabel_FontId); |
982 | } | 982 | } |
983 | if (scrollOverflow_Widget_(d, step)) { | 983 | if (scrollOverflow_Widget(d, step)) { |
984 | return iTrue; | 984 | return iTrue; |
985 | } | 985 | } |
986 | } | 986 | } |
@@ -989,7 +989,7 @@ iBool processEvent_Widget(iWidget *d, const SDL_Event *ev) { | |||
989 | if (d->flags & overflowScrollable_WidgetFlag && | 989 | if (d->flags & overflowScrollable_WidgetFlag && |
990 | ~d->flags & visualOffset_WidgetFlag && | 990 | ~d->flags & visualOffset_WidgetFlag && |
991 | isCommand_UserEvent(ev, "widget.overflow")) { | 991 | isCommand_UserEvent(ev, "widget.overflow")) { |
992 | scrollOverflow_Widget_(d, 0); /* check bounds */ | 992 | scrollOverflow_Widget(d, 0); /* check bounds */ |
993 | } | 993 | } |
994 | if (ev->user.code == command_UserEventCode && d->commandHandler && | 994 | if (ev->user.code == command_UserEventCode && d->commandHandler && |
995 | d->commandHandler(d, ev->user.data1)) { | 995 | d->commandHandler(d, ev->user.data1)) { |
@@ -1321,6 +1321,22 @@ iAny *findParentClass_Widget(const iWidget *d, const iAnyClass *class) { | |||
1321 | return i; | 1321 | return i; |
1322 | } | 1322 | } |
1323 | 1323 | ||
1324 | iAny *findOverflowScrollable_Widget(iWidget *d) { | ||
1325 | const iRect rootRect = rect_Root(d->root); | ||
1326 | for (iWidget *w = d; w; w = parent_Widget(w)) { | ||
1327 | if (flags_Widget(w) & overflowScrollable_WidgetFlag) { | ||
1328 | const iRect bounds = boundsWithoutVisualOffset_Widget(w); | ||
1329 | if ((bottom_Rect(bounds) > bottom_Rect(rootRect) || | ||
1330 | top_Rect(bounds) < top_Rect(rootRect)) && | ||
1331 | !hasVisibleChildOnTop_Widget(w)) { | ||
1332 | return w; | ||
1333 | } | ||
1334 | return NULL; | ||
1335 | } | ||
1336 | } | ||
1337 | return NULL; | ||
1338 | } | ||
1339 | |||
1324 | size_t childCount_Widget(const iWidget *d) { | 1340 | size_t childCount_Widget(const iWidget *d) { |
1325 | if (!d->children) return 0; | 1341 | if (!d->children) return 0; |
1326 | return size_ObjectList(d->children); | 1342 | return size_ObjectList(d->children); |