summaryrefslogtreecommitdiff
path: root/src/ios.m
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/ios.m
parentf8c0c817c2ce1919f71ef333439c9f4742fc6a12 (diff)
iOS: Setting up a system-provided text input control
Diffstat (limited to 'src/ios.m')
-rw-r--r--src/ios.m111
1 files changed, 110 insertions, 1 deletions
diff --git a/src/ios.m b/src/ios.m
index b46fb8dc..be1e644f 100644
--- a/src/ios.m
+++ b/src/ios.m
@@ -60,6 +60,8 @@ static UIViewController *viewController_(iWindow *window) {
60 return NULL; 60 return NULL;
61} 61}
62 62
63static void notifyChange_SystemTextInput_(iSystemTextInput *);
64
63/*----------------------------------------------------------------------------------------------*/ 65/*----------------------------------------------------------------------------------------------*/
64 66
65API_AVAILABLE(ios(13.0)) 67API_AVAILABLE(ios(13.0))
@@ -159,9 +161,10 @@ API_AVAILABLE(ios(13.0))
159 161
160/*----------------------------------------------------------------------------------------------*/ 162/*----------------------------------------------------------------------------------------------*/
161 163
162@interface AppState : NSObject<UIDocumentPickerDelegate> { 164@interface AppState : NSObject<UIDocumentPickerDelegate, UITextFieldDelegate> {
163 iString *fileBeingSaved; 165 iString *fileBeingSaved;
164 iString *pickFileCommand; 166 iString *pickFileCommand;
167 iSystemTextInput *sysCtrl;
165} 168}
166@property (nonatomic, assign) BOOL isHapticsAvailable; 169@property (nonatomic, assign) BOOL isHapticsAvailable;
167@property (nonatomic, strong) NSObject *haptic; 170@property (nonatomic, strong) NSObject *haptic;
@@ -175,9 +178,18 @@ static AppState *appState_;
175 self = [super init]; 178 self = [super init];
176 fileBeingSaved = NULL; 179 fileBeingSaved = NULL;
177 pickFileCommand = NULL; 180 pickFileCommand = NULL;
181 sysCtrl = NULL;
178 return self; 182 return self;
179} 183}
180 184
185-(void)setSystemTextInput:(iSystemTextInput *)sys {
186 sysCtrl = sys;
187}
188
189-(iSystemTextInput *)systemTextInput {
190 return sysCtrl;
191}
192
181-(void)setPickFileCommand:(const char *)command { 193-(void)setPickFileCommand:(const char *)command {
182 if (!pickFileCommand) { 194 if (!pickFileCommand) {
183 pickFileCommand = new_String(); 195 pickFileCommand = new_String();
@@ -256,6 +268,21 @@ didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
256-(void)keyboardOffScreen:(NSNotification *)notification { 268-(void)keyboardOffScreen:(NSNotification *)notification {
257 setKeyboardHeight_MainWindow(get_MainWindow(), 0); 269 setKeyboardHeight_MainWindow(get_MainWindow(), 0);
258} 270}
271
272- (BOOL)textFieldShouldReturn:(UITextField *)textField {
273 SDL_Event ev = { .type = SDL_KEYDOWN };
274 ev.key.keysym.sym = SDLK_RETURN;
275 SDL_PushEvent(&ev);
276 printf("Return pressed\n");
277 return NO;
278}
279
280- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
281 iSystemTextInput *sysCtrl = [appState_ systemTextInput];
282 notifyChange_SystemTextInput_(sysCtrl);
283 return YES;
284}
285
259@end 286@end
260 287
261static void enableMouse_(iBool yes) { 288static void enableMouse_(iBool yes) {
@@ -607,3 +634,85 @@ iBool isStarted_AVFAudioPlayer(const iAVFAudioPlayer *d) {
607iBool isPaused_AVFAudioPlayer(const iAVFAudioPlayer *d) { 634iBool isPaused_AVFAudioPlayer(const iAVFAudioPlayer *d) {
608 return d->state == paused_AVFAudioPlayerState; 635 return d->state == paused_AVFAudioPlayerState;
609} 636}
637
638/*----------------------------------------------------------------------------------------------*/
639
640struct Impl_SystemTextInput {
641 void *ctrl;
642 void (*textChangedFunc)(iSystemTextInput *, void *);
643 void *textChangedContext;
644};
645
646iDefineTypeConstructionArgs(SystemTextInput, (int flags), flags)
647
648#define REF_d_ctrl (__bridge UITextField *)d->ctrl
649
650void init_SystemTextInput(iSystemTextInput *d, int flags) {
651 d->ctrl = (void *) CFBridgingRetain([[UITextField alloc] init]);
652 UITextField *field = REF_d_ctrl;
653 // TODO: Use the right font: https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app?language=objc
654 [[viewController_(get_Window()) view] addSubview:REF_d_ctrl];
655 if (flags & returnGo_SystemTextInputFlags) {
656 [field setReturnKeyType:UIReturnKeyGo];
657 }
658 if (flags & returnSend_SystemTextInputFlags) {
659 [field setReturnKeyType:UIReturnKeySend];
660 }
661 if (flags & disableAutocorrect_SystemTextInputFlag) {
662 [field setAutocorrectionType:UITextAutocorrectionTypeNo];
663 [field setAutocapitalizationType:UITextAutocapitalizationTypeNone];
664 [field setSpellCheckingType:UITextSpellCheckingTypeNo];
665 }
666 if (flags & alignRight_WidgetFlag) {
667 [field setTextAlignment:NSTextAlignmentRight];
668 }
669 [field setDelegate:appState_];
670 [field becomeFirstResponder];
671 d->textChangedFunc = NULL;
672 d->textChangedContext = NULL;
673 [appState_ setSystemTextInput:d];
674}
675
676void deinit_SystemTextInput(iSystemTextInput *d) {
677 [appState_ setSystemTextInput:nil];
678 [REF_d_ctrl removeFromSuperview];
679 d->ctrl = nil; // TODO: Does this need to be released??
680}
681
682void setText_SystemTextInput(iSystemTextInput *d, const iString *text) {
683 [REF_d_ctrl setText:[NSString stringWithUTF8String:cstr_String(text)]];
684 [REF_d_ctrl selectAll:nil];
685}
686
687void setFont_SystemTextInput(iSystemTextInput *d, int fontId) {
688 int height = lineHeight_Text(fontId);
689 UIFont *font = [UIFont systemFontOfSize:0.65f * height / get_Window()->pixelRatio];
690 [REF_d_ctrl setFont:font];
691}
692
693const iString *text_SystemTextInput(const iSystemTextInput *d) {
694 return collectNewCStr_String([[REF_d_ctrl text] cStringUsingEncoding:NSUTF8StringEncoding]);;
695}
696
697void setRect_SystemTextInput(iSystemTextInput *d, iRect rect) {
698 const iWindow *win = get_Window();
699 CGRect frame;
700 frame.origin.x = rect.pos.x / win->pixelRatio;
701 frame.origin.y = (rect.pos.y - gap_UI + 2) / win->pixelRatio;
702 frame.size.width = rect.size.x / win->pixelRatio;
703 frame.size.height = rect.size.y / win->pixelRatio;
704 [REF_d_ctrl setFrame:frame];
705}
706
707void setTextChangedFunc_SystemTextInput(iSystemTextInput *d,
708 void (*textChangedFunc)(iSystemTextInput *, void *),
709 void *context) {
710 d->textChangedFunc = textChangedFunc;
711 d->textChangedContext = context;
712}
713
714static void notifyChange_SystemTextInput_(iSystemTextInput *d) {
715 if (d && d->textChangedFunc) {
716 d->textChangedFunc(d, d->textChangedContext);
717 }
718}