summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-12-05 10:25:44 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-12-05 10:25:44 +0200
commitbe8fcebadb4a12844dd367d1f7da03bbe920ea0a (patch)
tree1e1b0614b660adfc593052aa262dc97c9ac64949
parent6b4d15c83232d3af564157afdc32dfb5573c2aef (diff)
iOS: Custom editor font and adjusted positioning
-rw-r--r--CMakeLists.txt8
-rw-r--r--res/iOSBundleInfo.plist.in4
-rw-r--r--src/ios.h4
-rw-r--r--src/ios.m81
-rw-r--r--src/ui/inputwidget.c16
5 files changed, 90 insertions, 23 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4200c7c5..2d11e43e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,6 +104,12 @@ endif ()
104set (EMB_BIN ${CMAKE_CURRENT_BINARY_DIR}/resources.lgr) 104set (EMB_BIN ${CMAKE_CURRENT_BINARY_DIR}/resources.lgr)
105make_resources (${EMB_BIN} ${RESOURCES}) 105make_resources (${EMB_BIN} ${RESOURCES})
106set_source_files_properties (${EMB_BIN} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) 106set_source_files_properties (${EMB_BIN} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
107if (IOS)
108 set (EMB_FONTS res/fonts/SourceSans3-Regular.ttf)
109 set_source_files_properties (${EMB_FONTS}
110 PROPERTIES MACOSX_PACKAGE_LOCATION Resources
111 )
112endif ()
107 113
108# Source files. 114# Source files.
109set (SOURCES 115set (SOURCES
@@ -287,7 +293,7 @@ else ()
287endif () 293endif ()
288 294
289# Target. 295# Target.
290add_executable (app ${SOURCES} ${RESOURCES}) 296add_executable (app ${SOURCES} ${RESOURCES} ${EMB_FONTS})
291set_property (TARGET app PROPERTY C_STANDARD 11) 297set_property (TARGET app PROPERTY C_STANDARD 11)
292if (TARGET ext-deps) 298if (TARGET ext-deps)
293 add_dependencies (app ext-deps) 299 add_dependencies (app ext-deps)
diff --git a/res/iOSBundleInfo.plist.in b/res/iOSBundleInfo.plist.in
index 09af4abf..5a02ed68 100644
--- a/res/iOSBundleInfo.plist.in
+++ b/res/iOSBundleInfo.plist.in
@@ -49,6 +49,10 @@
49 </array> 49 </array>
50 <key>UILaunchStoryboardName</key> 50 <key>UILaunchStoryboardName</key>
51 <string>LaunchScreen</string> 51 <string>LaunchScreen</string>
52 <key>UIAppFonts</key>
53 <array>
54 <string>SourceSans3-Regular.ttf</string>
55 </array>
52 <key>UIBackgroundModes</key> 56 <key>UIBackgroundModes</key>
53 <array> 57 <array>
54 <string>audio</string> 58 <string>audio</string>
diff --git a/src/ios.h b/src/ios.h
index ff07b2e8..6c5ec8d5 100644
--- a/src/ios.h
+++ b/src/ios.h
@@ -70,7 +70,9 @@ enum iSystemTextInputFlags {
70 returnGo_SystemTextInputFlags = iBit(3), 70 returnGo_SystemTextInputFlags = iBit(3),
71 returnSend_SystemTextInputFlags = iBit(4), 71 returnSend_SystemTextInputFlags = iBit(4),
72 disableAutocorrect_SystemTextInputFlag = iBit(5), 72 disableAutocorrect_SystemTextInputFlag = iBit(5),
73 alignRight_SystemTextInputFlag = iBit(6), 73 disableAutocapitalize_SystemTextInputFlag = iBit(6),
74 alignRight_SystemTextInputFlag = iBit(7),
75 insertNewlines_SystemTextInputFlag = iBit(8),
74}; 76};
75 77
76iDeclareType(SystemTextInput) 78iDeclareType(SystemTextInput)
diff --git a/src/ios.m b/src/ios.m
index 290d4804..47303b7f 100644
--- a/src/ios.m
+++ b/src/ios.m
@@ -61,6 +61,7 @@ static UIViewController *viewController_(iWindow *window) {
61} 61}
62 62
63static void notifyChange_SystemTextInput_(iSystemTextInput *); 63static void notifyChange_SystemTextInput_(iSystemTextInput *);
64static BOOL isNewlineAllowed_SystemTextInput_(const iSystemTextInput *);
64 65
65/*----------------------------------------------------------------------------------------------*/ 66/*----------------------------------------------------------------------------------------------*/
66 67
@@ -269,10 +270,19 @@ didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
269 setKeyboardHeight_MainWindow(get_MainWindow(), 0); 270 setKeyboardHeight_MainWindow(get_MainWindow(), 0);
270} 271}
271 272
272- (BOOL)textFieldShouldReturn:(UITextField *)textField { 273static void sendReturnKeyPress_(void) {
273 SDL_Event ev = { .type = SDL_KEYDOWN }; 274 SDL_Event ev = { .type = SDL_KEYDOWN };
275 ev.key.timestamp = SDL_GetTicks();
274 ev.key.keysym.sym = SDLK_RETURN; 276 ev.key.keysym.sym = SDLK_RETURN;
277 ev.key.state = SDL_PRESSED;
278 SDL_PushEvent(&ev);
279 ev.type = SDL_KEYUP;
280 ev.key.state = SDL_RELEASED;
275 SDL_PushEvent(&ev); 281 SDL_PushEvent(&ev);
282}
283
284- (BOOL)textFieldShouldReturn:(UITextField *)textField {
285 sendReturnKeyPress_();
276 return NO; 286 return NO;
277} 287}
278 288
@@ -283,6 +293,17 @@ replacementString:(NSString *)string {
283 return YES; 293 return YES;
284} 294}
285 295
296- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
297 replacementText:(NSString *)text {
298 if ([text isEqualToString:@"\n"]) {
299 if (!isNewlineAllowed_SystemTextInput_([appState_ systemTextInput])) {
300 sendReturnKeyPress_();
301 return NO;
302 }
303 }
304 return YES;
305}
306
286- (void)textViewDidChange:(UITextView *)textView { 307- (void)textViewDidChange:(UITextView *)textView {
287 iSystemTextInput *sysCtrl = [appState_ systemTextInput]; 308 iSystemTextInput *sysCtrl = [appState_ systemTextInput];
288 notifyChange_SystemTextInput_(sysCtrl); 309 notifyChange_SystemTextInput_(sysCtrl);
@@ -659,14 +680,23 @@ iDefineTypeConstructionArgs(SystemTextInput, (iRect rect, int flags), rect, flag
659#define REF_d_field (__bridge UITextField *)d->field 680#define REF_d_field (__bridge UITextField *)d->field
660#define REF_d_view (__bridge UITextView *)d->view 681#define REF_d_view (__bridge UITextView *)d->view
661 682
662static CGRect convertToCGRect_(const iRect *rect) { 683static CGRect convertToCGRect_(const iRect *rect, iBool expanded) {
663 const iWindow *win = get_Window(); 684 const iWindow *win = get_Window();
664 CGRect frame; 685 CGRect frame;
665 // TODO: Convert coordinates properly! 686 // TODO: Convert coordinates properly!
666 frame.origin.x = rect->pos.x / win->pixelRatio; 687 frame.origin.x = rect->pos.x / win->pixelRatio;
667 frame.origin.y = (rect->pos.y - gap_UI + 2) / win->pixelRatio; 688 frame.origin.y = (rect->pos.y - gap_UI + 1) / win->pixelRatio;
668 frame.size.width = rect->size.x / win->pixelRatio; 689 frame.size.width = rect->size.x / win->pixelRatio;
669 frame.size.height = rect->size.y / win->pixelRatio; 690 frame.size.height = rect->size.y / win->pixelRatio;
691 /* Some padding to account for insets. If we just zero out the insets, the insertion point
692 may be clipped at the edges. */
693 if (expanded) {
694 const float inset = gap_UI / get_Window()->pixelRatio;
695 frame.origin.x -= inset + 1;
696 frame.origin.y -= inset + 1;
697 frame.size.width += 2 * inset + 2;
698 frame.size.height += inset + 1;
699 }
670 return frame; 700 return frame;
671} 701}
672 702
@@ -682,7 +712,7 @@ void init_SystemTextInput(iSystemTextInput *d, iRect rect, int flags) {
682 d->flags = flags; 712 d->flags = flags;
683 d->field = NULL; 713 d->field = NULL;
684 d->view = NULL; 714 d->view = NULL;
685 CGRect frame = convertToCGRect_(&rect); 715 CGRect frame = convertToCGRect_(&rect, (flags & multiLine_SystemTextInputFlags) != 0);
686 if (flags & multiLine_SystemTextInputFlags) { 716 if (flags & multiLine_SystemTextInputFlags) {
687 d->view = (void *) CFBridgingRetain([[UITextView alloc] initWithFrame:frame textContainer:nil]); 717 d->view = (void *) CFBridgingRetain([[UITextView alloc] initWithFrame:frame textContainer:nil]);
688 [[viewController_(get_Window()) view] addSubview:REF_d_view]; 718 [[viewController_(get_Window()) view] addSubview:REF_d_view];
@@ -692,7 +722,9 @@ void init_SystemTextInput(iSystemTextInput *d, iRect rect, int flags) {
692 [[viewController_(get_Window()) view] addSubview:REF_d_field]; 722 [[viewController_(get_Window()) view] addSubview:REF_d_field];
693 } 723 }
694 UIControl<UITextInputTraits> *traits = (UIControl<UITextInputTraits> *) (d->view ? REF_d_view : REF_d_field); 724 UIControl<UITextInputTraits> *traits = (UIControl<UITextInputTraits> *) (d->view ? REF_d_view : REF_d_field);
695 // TODO: Use the right font: https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app?language=objc 725 if (~flags & insertNewlines_SystemTextInputFlag) {
726 [traits setReturnKeyType:UIReturnKeyDone];
727 }
696 if (flags & returnGo_SystemTextInputFlags) { 728 if (flags & returnGo_SystemTextInputFlags) {
697 [traits setReturnKeyType:UIReturnKeyGo]; 729 [traits setReturnKeyType:UIReturnKeyGo];
698 } 730 }
@@ -701,29 +733,38 @@ void init_SystemTextInput(iSystemTextInput *d, iRect rect, int flags) {
701 } 733 }
702 if (flags & disableAutocorrect_SystemTextInputFlag) { 734 if (flags & disableAutocorrect_SystemTextInputFlag) {
703 [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; 735 [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
704 [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
705 [traits setSpellCheckingType:UITextSpellCheckingTypeNo]; 736 [traits setSpellCheckingType:UITextSpellCheckingTypeNo];
706 } 737 }
738 if (flags & disableAutocapitalize_SystemTextInputFlag) {
739 [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
740 }
707 if (flags & alignRight_SystemTextInputFlag) { 741 if (flags & alignRight_SystemTextInputFlag) {
708 if (d->field) { 742 if (d->field) {
709 [REF_d_field setTextAlignment:NSTextAlignmentRight]; 743 [REF_d_field setTextAlignment:NSTextAlignmentRight];
710 } 744 }
745 if (d->view) {
746 [REF_d_view setTextAlignment:NSTextAlignmentRight];
747 }
711 } 748 }
712 UIColor *textColor = makeUIColor_(uiInputTextFocused_ColorId); 749 UIColor *textColor = makeUIColor_(uiInputTextFocused_ColorId);
713 UIColor *backgroundColor = makeUIColor_(uiInputBackgroundFocused_ColorId); 750 UIColor *backgroundColor = makeUIColor_(uiInputBackgroundFocused_ColorId);
714 [appState_ setSystemTextInput:d]; 751 [appState_ setSystemTextInput:d];
715 if (d->field) { 752 if (d->field) {
716 [REF_d_field setTextColor:textColor]; 753 UITextField *field = REF_d_field;
717 [REF_d_field setDelegate:appState_]; 754 [field setTextColor:textColor];
718 [REF_d_field becomeFirstResponder]; 755 [field setDelegate:appState_];
756 [field becomeFirstResponder];
719 } 757 }
720 else { 758 else {
721 [REF_d_view setTextColor:textColor]; 759 UITextView *view = REF_d_view;
722 [REF_d_view setBackgroundColor:backgroundColor]; 760 [view setTextColor:textColor];
723 [REF_d_view setEditable:YES]; 761 [view setBackgroundColor:backgroundColor];
762 [view setEditable:YES];
724// [REF_d_view setSelectable:YES]; 763// [REF_d_view setSelectable:YES];
725 [REF_d_view setDelegate:appState_]; 764 const float inset = gap_UI / get_Window()->pixelRatio;
726 [REF_d_view becomeFirstResponder]; 765 //[view setTextContainerInset:(UIEdgeInsets){ inset - 1, -inset - 1, 0, -inset - 1 }];
766 [view setDelegate:appState_];
767 [view becomeFirstResponder];
727 } 768 }
728 d->textChangedFunc = NULL; 769 d->textChangedFunc = NULL;
729 d->textChangedContext = NULL; 770 d->textChangedContext = NULL;
@@ -774,7 +815,11 @@ void setFont_SystemTextInput(iSystemTextInput *d, int fontId) {
774 font = [UIFont monospacedSystemFontOfSize:0.8f * height weight:UIFontWeightRegular]; 815 font = [UIFont monospacedSystemFontOfSize:0.8f * height weight:UIFontWeightRegular];
775 } 816 }
776 else { 817 else {
777 font = [UIFont systemFontOfSize:0.65f * height]; 818// font = [UIFont systemFontOfSize:0.65f * height];
819// for (NSString *name in [UIFont fontNamesForFamilyName:@"Source Sans 3"]) {
820// printf("fontname: %s\n", [name cStringUsingEncoding:NSUTF8StringEncoding]);
821// }
822 font = [UIFont fontWithName:@"SourceSans3-Regular" size:height * 0.7f];
778 } 823 }
779 if (d->field) { 824 if (d->field) {
780 [REF_d_field setFont:font]; 825 [REF_d_field setFont:font];
@@ -795,7 +840,7 @@ const iString *text_SystemTextInput(const iSystemTextInput *d) {
795} 840}
796 841
797void setRect_SystemTextInput(iSystemTextInput *d, iRect rect) { 842void setRect_SystemTextInput(iSystemTextInput *d, iRect rect) {
798 CGRect frame = convertToCGRect_(&rect); 843 CGRect frame = convertToCGRect_(&rect, (d->flags & multiLine_SystemTextInputFlags) != 0);
799 if (d->field) { 844 if (d->field) {
800 [REF_d_field setFrame:frame]; 845 [REF_d_field setFrame:frame];
801 } 846 }
@@ -816,3 +861,7 @@ static void notifyChange_SystemTextInput_(iSystemTextInput *d) {
816 d->textChangedFunc(d, d->textChangedContext); 861 d->textChangedFunc(d, d->textChangedContext);
817 } 862 }
818} 863}
864
865static BOOL isNewlineAllowed_SystemTextInput_(const iSystemTextInput *d) {
866 return (d->flags & insertNewlines_SystemTextInputFlag) != 0;
867}
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index ea7ed523..ad45ed92 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -765,6 +765,12 @@ void deinit_InputWidget(iInputWidget *d) {
765 deinit_Array(&d->lines); 765 deinit_Array(&d->lines);
766} 766}
767 767
768static iBool isAllowedToInsertNewline_InputWidget_(const iInputWidget *d) {
769 return ~d->inFlags & isSensitive_InputWidgetFlag &&
770 ~d->inFlags & isUrl_InputWidgetFlag &&
771 d->inFlags & lineBreaksEnabled_InputWidgetFlag && d->maxLen == 0;
772}
773
768#if defined (LAGRANGE_ENABLE_SYSTEM_INPUT) 774#if defined (LAGRANGE_ENABLE_SYSTEM_INPUT)
769static void updateAfterVisualOffsetChange_InputWidget_(iInputWidget *d, iRoot *root) { 775static void updateAfterVisualOffsetChange_InputWidget_(iInputWidget *d, iRoot *root) {
770 iAssert(as_Widget(d)->root == root); 776 iAssert(as_Widget(d)->root == root);
@@ -1062,9 +1068,11 @@ void begin_InputWidget(iInputWidget *d) {
1062#if defined (LAGRANGE_ENABLE_SYSTEM_INPUT) 1068#if defined (LAGRANGE_ENABLE_SYSTEM_INPUT)
1063 d->sysCtrl = new_SystemTextInput(contentBounds_InputWidget_(d), 1069 d->sysCtrl = new_SystemTextInput(contentBounds_InputWidget_(d),
1064 (d->maxWrapLines > 1 ? multiLine_SystemTextInputFlags : 0) | 1070 (d->maxWrapLines > 1 ? multiLine_SystemTextInputFlags : 0) |
1065 (d->inFlags & isUrl_InputWidgetFlag ? disableAutocorrect_SystemTextInputFlag : 0) | 1071 (d->inFlags & isUrl_InputWidgetFlag ? (disableAutocorrect_SystemTextInputFlag |
1072 disableAutocapitalize_SystemTextInputFlag) : 0) |
1066 (!cmp_String(id_Widget(w), "url") ? returnGo_SystemTextInputFlags : 0) | 1073 (!cmp_String(id_Widget(w), "url") ? returnGo_SystemTextInputFlags : 0) |
1067 (flags_Widget(w) & alignRight_WidgetFlag ? alignRight_SystemTextInputFlag : 0)); 1074 (flags_Widget(w) & alignRight_WidgetFlag ? alignRight_SystemTextInputFlag : 0) |
1075 (isAllowedToInsertNewline_InputWidget_(d) ? insertNewlines_SystemTextInputFlag : 0));
1068 setFont_SystemTextInput(d->sysCtrl, d->font); 1076 setFont_SystemTextInput(d->sysCtrl, d->font);
1069 setText_SystemTextInput(d->sysCtrl, &d->oldText); 1077 setText_SystemTextInput(d->sysCtrl, &d->oldText);
1070 setTextChangedFunc_SystemTextInput(d->sysCtrl, systemInputChanged_InputWidget_, d); 1078 setTextChangedFunc_SystemTextInput(d->sysCtrl, systemInputChanged_InputWidget_, d);
@@ -2110,9 +2118,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
2110 return iTrue; 2118 return iTrue;
2111 case SDLK_RETURN: 2119 case SDLK_RETURN:
2112 case SDLK_KP_ENTER: 2120 case SDLK_KP_ENTER:
2113 if (~d->inFlags & isSensitive_InputWidgetFlag && 2121 if (isAllowedToInsertNewline_InputWidget_(d)) {
2114 ~d->inFlags & isUrl_InputWidgetFlag &&
2115 d->inFlags & lineBreaksEnabled_InputWidgetFlag && d->maxLen == 0) {
2116 if (checkLineBreakMods_InputWidget_(d, mods)) { 2122 if (checkLineBreakMods_InputWidget_(d, mods)) {
2117 pushUndo_InputWidget_(d); 2123 pushUndo_InputWidget_(d);
2118 deleteMarked_InputWidget_(d); 2124 deleteMarked_InputWidget_(d);