summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/inputwidget.c55
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
2069static 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
2068static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { 2093static 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);