summaryrefslogtreecommitdiff
path: root/src/ui/inputwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-12-04 17:55:38 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-12-04 17:55:38 +0200
commit368eddea42200ec95faa4f4767a72b2b3cf7bdff (patch)
tree5de42312f4ff697d7a141e926be41731e957d043 /src/ui/inputwidget.c
parentf8c0c817c2ce1919f71ef333439c9f4742fc6a12 (diff)
iOS: Setting up a system-provided text input control
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r--src/ui/inputwidget.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index bd9b63b5..bb3851df 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -40,6 +40,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
40# include "macos.h" 40# include "macos.h"
41#endif 41#endif
42 42
43#if defined (iPlatformAppleMobile)
44# include "ios.h"
45# define LAGRANGE_ENABLE_SYSTEM_INPUT 1
46#endif
47
43static const int refreshInterval_InputWidget_ = 512; 48static const int refreshInterval_InputWidget_ = 512;
44static const size_t maxUndo_InputWidget_ = 64; 49static const size_t maxUndo_InputWidget_ = 64;
45static const int unlimitedWidth_InputWidget_ = 1000000; /* TODO: WrapText disables some functionality if maxWidth==0 */ 50static const int unlimitedWidth_InputWidget_ = 1000000; /* TODO: WrapText disables some functionality if maxWidth==0 */
@@ -233,6 +238,7 @@ struct Impl_InputWidget {
233 void * validatorContext; 238 void * validatorContext;
234 iString * backupPath; 239 iString * backupPath;
235 int backupTimer; 240 int backupTimer;
241 iSystemTextInput *sysCtrl;
236}; 242};
237 243
238iDefineObjectConstructionArgs(InputWidget, (size_t maxLen), maxLen) 244iDefineObjectConstructionArgs(InputWidget, (size_t maxLen), maxLen)
@@ -721,10 +727,12 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) {
721 d->buffered = NULL; 727 d->buffered = NULL;
722 d->backupPath = NULL; 728 d->backupPath = NULL;
723 d->backupTimer = 0; 729 d->backupTimer = 0;
730 d->sysCtrl = NULL;
724 updateMetrics_InputWidget_(d); 731 updateMetrics_InputWidget_(d);
725} 732}
726 733
727void deinit_InputWidget(iInputWidget *d) { 734void deinit_InputWidget(iInputWidget *d) {
735 delete_SystemTextInput(d->sysCtrl);
728 if (d->backupTimer) { 736 if (d->backupTimer) {
729 SDL_RemoveTimer(d->backupTimer); 737 SDL_RemoveTimer(d->backupTimer);
730 } 738 }
@@ -953,6 +961,9 @@ void setText_InputWidget(iInputWidget *d, const iString *text) {
953 iString *nfcText = collect_String(copy_String(text)); 961 iString *nfcText = collect_String(copy_String(text));
954 normalize_String(nfcText); 962 normalize_String(nfcText);
955 splitToLines_(nfcText, &d->lines); 963 splitToLines_(nfcText, &d->lines);
964 if (d->sysCtrl) {
965 setText_SystemTextInput(d->sysCtrl, nfcText);
966 }
956 iAssert(!isEmpty_Array(&d->lines)); 967 iAssert(!isEmpty_Array(&d->lines));
957 iForEach(Array, i, &d->lines) { 968 iForEach(Array, i, &d->lines) {
958 updateLine_InputWidget_(d, i.value); /* count number of visible lines */ 969 updateLine_InputWidget_(d, i.value); /* count number of visible lines */
@@ -1008,6 +1019,16 @@ iLocalDef iBool isEditing_InputWidget_(const iInputWidget *d) {
1008 return (flags_Widget(constAs_Widget(d)) & selected_WidgetFlag) != 0; 1019 return (flags_Widget(constAs_Widget(d)) & selected_WidgetFlag) != 0;
1009} 1020}
1010 1021
1022static void contentsWereChanged_InputWidget_(iInputWidget *);
1023
1024#if defined (LAGRANGE_ENABLE_SYSTEM_INPUT)
1025void systemInputChanged_InputWidget_(iSystemTextInput *sysCtrl, void *widget) {
1026 iInputWidget *d = widget;
1027 splitToLines_(text_SystemTextInput(sysCtrl), &d->lines);
1028 contentsWereChanged_InputWidget_(d);
1029}
1030#endif
1031
1011void begin_InputWidget(iInputWidget *d) { 1032void begin_InputWidget(iInputWidget *d) {
1012 iWidget *w = as_Widget(d); 1033 iWidget *w = as_Widget(d);
1013 if (isEditing_InputWidget_(d)) { 1034 if (isEditing_InputWidget_(d)) {
@@ -1016,7 +1037,18 @@ void begin_InputWidget(iInputWidget *d) {
1016 } 1037 }
1017 invalidateBuffered_InputWidget_(d); 1038 invalidateBuffered_InputWidget_(d);
1018 setFlags_Widget(w, hidden_WidgetFlag | disabled_WidgetFlag, iFalse); 1039 setFlags_Widget(w, hidden_WidgetFlag | disabled_WidgetFlag, iFalse);
1040 setFlags_Widget(w, selected_WidgetFlag, iTrue);
1019 mergeLines_(&d->lines, &d->oldText); 1041 mergeLines_(&d->lines, &d->oldText);
1042#if defined (LAGRANGE_ENABLE_SYSTEM_INPUT)
1043 d->sysCtrl = new_SystemTextInput((d->inFlags & isUrl_InputWidgetFlag ? disableAutocorrect_SystemTextInputFlag : 0) |
1044 (!cmp_String(id_Widget(w), "url") ? returnGo_SystemTextInputFlags : 0) );
1045// (flags_Widget(w) & alignRight_WidgetFlag ? alignRight_SystemTextInputFlag : 0));
1046 setFont_SystemTextInput(d->sysCtrl, d->font);
1047 setRect_SystemTextInput(d->sysCtrl, contentBounds_InputWidget_(d));
1048 setText_SystemTextInput(d->sysCtrl, &d->oldText);
1049 setTextChangedFunc_SystemTextInput(d->sysCtrl, systemInputChanged_InputWidget_, d);
1050 return;
1051#endif
1020 if (d->mode == overwrite_InputMode) { 1052 if (d->mode == overwrite_InputMode) {
1021 d->cursor = zero_I2(); 1053 d->cursor = zero_I2();
1022 } 1054 }
@@ -1025,7 +1057,6 @@ void begin_InputWidget(iInputWidget *d) {
1025 d->cursor.x = iMin(d->cursor.x, cursorLine_InputWidget_(d)->range.end); 1057 d->cursor.x = iMin(d->cursor.x, cursorLine_InputWidget_(d)->range.end);
1026 } 1058 }
1027 SDL_StartTextInput(); 1059 SDL_StartTextInput();
1028 setFlags_Widget(w, selected_WidgetFlag, iTrue);
1029 showCursor_InputWidget_(d); 1060 showCursor_InputWidget_(d);
1030 refresh_Widget(w); 1061 refresh_Widget(w);
1031 startOrStopCursorTimer_InputWidget_(d, iTrue); 1062 startOrStopCursorTimer_InputWidget_(d, iTrue);
@@ -1048,15 +1079,22 @@ void end_InputWidget(iInputWidget *d, iBool accept) {
1048 /* Was not active. */ 1079 /* Was not active. */
1049 return; 1080 return;
1050 } 1081 }
1051 enableEditorKeysInMenus_(iTrue); 1082 if (d->sysCtrl) {
1052 if (!accept) { 1083 if (accept) {
1084 splitToLines_(text_SystemTextInput(d->sysCtrl), &d->lines);
1085 }
1086 delete_SystemTextInput(d->sysCtrl);
1087 d->sysCtrl = NULL;
1088 }
1089 else if (!accept) {
1053 /* Overwrite the edited lines. */ 1090 /* Overwrite the edited lines. */
1054 splitToLines_(&d->oldText, &d->lines); 1091 splitToLines_(&d->oldText, &d->lines);
1092 SDL_StopTextInput();
1055 } 1093 }
1094 enableEditorKeysInMenus_(iTrue);
1056 d->inFlags |= needUpdateBuffer_InputWidgetFlag; 1095 d->inFlags |= needUpdateBuffer_InputWidgetFlag;
1057 d->inFlags &= ~isMarking_InputWidgetFlag; 1096 d->inFlags &= ~isMarking_InputWidgetFlag;
1058 startOrStopCursorTimer_InputWidget_(d, iFalse); 1097 startOrStopCursorTimer_InputWidget_(d, iFalse);
1059 SDL_StopTextInput();
1060 setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag | touchDrag_WidgetFlag, iFalse); 1098 setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag | touchDrag_WidgetFlag, iFalse);
1061 const char *id = cstr_String(id_Widget(as_Widget(d))); 1099 const char *id = cstr_String(id_Widget(as_Widget(d)));
1062 if (!*id) id = "_"; 1100 if (!*id) id = "_";
@@ -2324,6 +2362,10 @@ static void draw_InputWidget_(const iInputWidget *d) {
2324 isFocused ? gap_UI / 4 : 1, 2362 isFocused ? gap_UI / 4 : 1,
2325 isFocused ? uiInputFrameFocused_ColorId 2363 isFocused ? uiInputFrameFocused_ColorId
2326 : isHover ? uiInputFrameHover_ColorId : uiInputFrame_ColorId); 2364 : isHover ? uiInputFrameHover_ColorId : uiInputFrame_ColorId);
2365 if (d->sysCtrl) {
2366 drawChildren_Widget(w);
2367 return;
2368 }
2327 setClip_Paint(&p, adjusted_Rect(bounds, init_I2(d->leftPadding, 0), 2369 setClip_Paint(&p, adjusted_Rect(bounds, init_I2(d->leftPadding, 0),
2328 init_I2(-d->rightPadding, w->flags & extraPadding_WidgetFlag ? -gap_UI / 2 : 0))); 2370 init_I2(-d->rightPadding, w->flags & extraPadding_WidgetFlag ? -gap_UI / 2 : 0)));
2329 const iRect contentBounds = contentBounds_InputWidget_(d); 2371 const iRect contentBounds = contentBounds_InputWidget_(d);