diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/inputwidget.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 65710373..3572d043 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -241,6 +241,7 @@ struct Impl_InputWidget { | |||
241 | int backupTimer; | 241 | int backupTimer; |
242 | iString oldText; /* for restoring if edits cancelled */ | 242 | iString oldText; /* for restoring if edits cancelled */ |
243 | int lastUpdateWidth; | 243 | int lastUpdateWidth; |
244 | uint32_t lastOverflowScrollTime; /* scrolling to show focused widget */ | ||
244 | iSystemTextInput *sysCtrl; | 245 | iSystemTextInput *sysCtrl; |
245 | #if LAGRANGE_USE_SYSTEM_TEXT_INPUT | 246 | #if LAGRANGE_USE_SYSTEM_TEXT_INPUT |
246 | iString text; | 247 | iString text; |
@@ -2065,6 +2066,30 @@ static void clampWheelAccum_InputWidget_(iInputWidget *d, int wheel) { | |||
2065 | } | 2066 | } |
2066 | #endif | 2067 | #endif |
2067 | 2068 | ||
2069 | static void overflowScrollToKeepVisible_InputWidget_(iAny *widget) { | ||
2070 | iInputWidget *d = widget; | ||
2071 | iWidget *w = as_Widget(d); | ||
2072 | if (!isFocused_Widget(w) || isAffectedByVisualOffset_Widget(w)) { | ||
2073 | return; | ||
2074 | } | ||
2075 | iRect rect = boundsWithoutVisualOffset_Widget(w); | ||
2076 | iRect visible = visibleRect_Root(w->root); | ||
2077 | const uint32_t nowTime = SDL_GetTicks(); | ||
2078 | const double elapsed = (nowTime - d->lastOverflowScrollTime) / 1000.0; | ||
2079 | int dist = bottom_Rect(rect) + gap_UI - bottom_Rect(visible); | ||
2080 | const int step = iRound(10 * dist * elapsed); | ||
2081 | if (step > 0) { | ||
2082 | iWidget *scrollable = findOverflowScrollable_Widget(w); | ||
2083 | if (scrollable) { | ||
2084 | scrollOverflow_Widget(scrollable, -iClamp(step, 1, dist)); | ||
2085 | d->lastOverflowScrollTime = nowTime; | ||
2086 | } | ||
2087 | } | ||
2088 | if (dist > 0) { | ||
2089 | addTicker_App(overflowScrollToKeepVisible_InputWidget_, widget); | ||
2090 | } | ||
2091 | } | ||
2092 | |||
2068 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | 2093 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { |
2069 | iWidget *w = as_Widget(d); | 2094 | iWidget *w = as_Widget(d); |
2070 | /* Resize according to width immediately. */ | 2095 | /* Resize according to width immediately. */ |
@@ -2077,6 +2102,13 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
2077 | updateAllLinesAndResizeHeight_InputWidget_(d); | 2102 | updateAllLinesAndResizeHeight_InputWidget_(d); |
2078 | d->lastUpdateWidth = w->rect.size.x; | 2103 | d->lastUpdateWidth = w->rect.size.x; |
2079 | } | 2104 | } |
2105 | #if LAGRANGE_USE_SYSTEM_TEXT_INPUT | ||
2106 | if (isResize_UserEvent(ev)) { | ||
2107 | if (d->sysCtrl) { | ||
2108 | updateAfterVisualOffsetChange_InputWidget_(d, w->root); | ||
2109 | } | ||
2110 | } | ||
2111 | #endif | ||
2080 | if (isCommand_Widget(w, ev, "focus.gained")) { | 2112 | if (isCommand_Widget(w, ev, "focus.gained")) { |
2081 | begin_InputWidget(d); | 2113 | begin_InputWidget(d); |
2082 | return iFalse; | 2114 | return iFalse; |
@@ -2139,18 +2171,19 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
2139 | } | 2171 | } |
2140 | return iFalse; | 2172 | return iFalse; |
2141 | } | 2173 | } |
2142 | /* TODO: Scroll to keep widget visible when keyboard appears. */ | 2174 | else if (isCommand_UserEvent(ev, "keyboard.changed")) { |
2143 | // else if (isCommand_UserEvent(ev, "keyboard.changed")) { | 2175 | /* Scroll to keep widget visible when keyboard appears. */ |
2144 | // if (isFocused_Widget(d) && arg_Command(command_UserEvent(ev))) { | 2176 | if (isFocused_Widget(d) && arg_Command(command_UserEvent(ev))) { |
2145 | // iRect rect = bounds_Widget(w); | 2177 | d->lastOverflowScrollTime = SDL_GetTicks(); |
2178 | overflowScrollToKeepVisible_InputWidget_(d); | ||
2146 | // rect.pos.y -= value_Anim(&get_Window()->rootOffset); | 2179 | // rect.pos.y -= value_Anim(&get_Window()->rootOffset); |
2147 | // const iInt2 visRoot = visibleSize_Root(w->root); | 2180 | //const iInt2 visRoot = visibleSize_Root(w->root); |
2148 | // if (bottom_Rect(rect) > visRoot.y) { | 2181 | //if (bottom_Rect(rect) > visRoot.y) { |
2149 | // setValue_Anim(&get_Window()->rootOffset, -(bottom_Rect(rect) - visRoot.y), 250); | 2182 | //setValue_Anim(&get_Window()->rootOffset, -(bottom_Rect(rect) - visRoot.y), 250); |
2150 | // } | 2183 | //} |
2151 | // } | 2184 | } |
2152 | // return iFalse; | 2185 | return iFalse; |
2153 | // } | 2186 | } |
2154 | else if (isCommand_Widget(w, ev, "input.backup")) { | 2187 | else if (isCommand_Widget(w, ev, "input.backup")) { |
2155 | if (d->inFlags & needBackup_InputWidgetFlag) { | 2188 | if (d->inFlags & needBackup_InputWidgetFlag) { |
2156 | saveBackup_InputWidget_(d); | 2189 | saveBackup_InputWidget_(d); |