diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 6d7f37f137fd..c5c459ab98f0 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -19,6 +19,7 @@ iphone_lib = [ "godot_view_renderer.mm", "godot_view_gesture_recognizer.mm", "device_metrics.m", + "keyboard_input_view.mm", "native_video_view.m", ] diff --git a/platform/iphone/godot_view.h b/platform/iphone/godot_view.h index bfc1484c1cc4..cf502e74ddfa 100644 --- a/platform/iphone/godot_view.h +++ b/platform/iphone/godot_view.h @@ -40,7 +40,7 @@ class String; @protocol DisplayLayer; @protocol GodotViewRendererProtocol; -@interface GodotView : UIView +@interface GodotView : UIView @property(assign, nonatomic) id renderer; @@ -55,8 +55,6 @@ class String; - (void)stopRendering; - (void)startRendering; -- (BOOL)becomeFirstResponderWithString:(String)p_existing; - @property(nonatomic, assign) BOOL useCADisplayLink; @end diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm index d2f7bebdd195..bbe0937bcab7 100644 --- a/platform/iphone/godot_view.mm +++ b/platform/iphone/godot_view.mm @@ -30,7 +30,6 @@ #import "godot_view.h" -#include "core/os/keyboard.h" #include "core/project_settings.h" #include "os_iphone.h" #include "servers/audio_server.h" @@ -275,40 +274,6 @@ - (void)layoutSubviews { // MARK: - Input -// MARK: Keyboard - -- (BOOL)canBecomeFirstResponder { - return YES; -} - -- (BOOL)becomeFirstResponderWithString:(String)p_existing { - keyboard_text = p_existing; - return [self becomeFirstResponder]; -} - -- (BOOL)resignFirstResponder { - keyboard_text = String(); - return [super resignFirstResponder]; -} - -- (void)deleteBackward { - if (keyboard_text.length()) { - keyboard_text.erase(keyboard_text.length() - 1, 1); - } - OSIPhone::get_singleton()->key(KEY_BACKSPACE, true); -} - -- (BOOL)hasText { - return keyboard_text.length() > 0; -} - -- (void)insertText:(NSString *)p_text { - String character; - character.parse_utf8([p_text UTF8String]); - keyboard_text = keyboard_text + character; - OSIPhone::get_singleton()->key(character[0] == 10 ? KEY_ENTER : character[0], true); -} - // MARK: Touches - (void)initTouches { diff --git a/platform/iphone/keyboard_input_view.h b/platform/iphone/keyboard_input_view.h new file mode 100644 index 000000000000..63ecc420d380 --- /dev/null +++ b/platform/iphone/keyboard_input_view.h @@ -0,0 +1,37 @@ +/*************************************************************************/ +/* keyboard_input_view.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#import + +@interface GodotKeyboardInputView : UITextView + +- (BOOL)becomeFirstResponderWithString:(NSString *)existingString; + +@end diff --git a/platform/iphone/keyboard_input_view.mm b/platform/iphone/keyboard_input_view.mm new file mode 100644 index 000000000000..8696ed89abcb --- /dev/null +++ b/platform/iphone/keyboard_input_view.mm @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* keyboard_input_view.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#import "keyboard_input_view.h" + +#include "core/os/keyboard.h" +#include "os_iphone.h" + +@interface GodotKeyboardInputView () + +@end + +@implementation GodotKeyboardInputView + +- (instancetype)initWithCoder:(NSCoder *)coder { + self = [super initWithCoder:coder]; + + if (self) { + [self godot_commonInit]; + } + + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame textContainer:(NSTextContainer *)textContainer { + self = [super initWithFrame:frame textContainer:textContainer]; + + if (self) { + [self godot_commonInit]; + } + + return self; +} + +- (void)godot_commonInit { + self.hidden = YES; + self.delegate = self; +} + +- (void)dealloc { + self.delegate = nil; +} + +// MARK: Keyboard + +- (BOOL)canBecomeFirstResponder { + return YES; +} + +- (BOOL)becomeFirstResponderWithString:(NSString *)existingString { + self.text = existingString; + return [self becomeFirstResponder]; +} + +- (BOOL)resignFirstResponder { + self.text = nil; + return [super resignFirstResponder]; +} + +// MARK: Delegate + +- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { + if (textView != self) { + return NO; + } + + if (text.length == 0) { + for (int i = 0; i < range.length; i++) { + OSIPhone::get_singleton()->key(KEY_BACKSPACE, true); + } + } else { + String characters; + characters.parse_utf8([text UTF8String]); + + for (int i = 0; i < characters.size(); i++) { + int character = characters[i]; + OSIPhone::get_singleton()->key(character == 10 ? KEY_ENTER : character, true); + } + } + + return YES; +} + +@end diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index ecb52ba3a3bc..f52de794c021 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -50,6 +50,7 @@ #import "app_delegate.h" #import "device_metrics.h" #import "godot_view.h" +#import "keyboard_input_view.h" #import "native_video_view.h" #import "view_controller.h" @@ -453,11 +454,12 @@ void register_dynamic_symbol(char *name, void *address) { }; void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { - [AppDelegate.viewController.godotView becomeFirstResponderWithString:p_existing_text]; + NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()]; + [AppDelegate.viewController.keyboardView becomeFirstResponderWithString:existingString]; }; void OSIPhone::hide_virtual_keyboard() { - [AppDelegate.viewController.godotView resignFirstResponder]; + [AppDelegate.viewController.keyboardView resignFirstResponder]; } void OSIPhone::set_virtual_keyboard_height(int p_height) { diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h index b0b31ae377c7..c246973e7efa 100644 --- a/platform/iphone/view_controller.h +++ b/platform/iphone/view_controller.h @@ -33,11 +33,13 @@ @class GodotView; @class GodotNativeVideoView; +@class GodotKeyboardInputView; @interface ViewController : UIViewController @property(nonatomic, readonly, strong) GodotView *godotView; @property(nonatomic, readonly, strong) GodotNativeVideoView *videoView; +@property(nonatomic, readonly, strong) GodotKeyboardInputView *keyboardView; // MARK: Native Video Player diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index 830bc394058a..e068c3698db9 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -33,6 +33,7 @@ #include "core/project_settings.h" #import "godot_view.h" #import "godot_view_renderer.h" +#import "keyboard_input_view.h" #import "native_video_view.h" #include "os_iphone.h" @@ -40,6 +41,7 @@ @interface ViewController () @property(strong, nonatomic) GodotViewRenderer *renderer; @property(strong, nonatomic) GodotNativeVideoView *videoView; +@property(strong, nonatomic) GodotKeyboardInputView *keyboardView; @end @@ -101,6 +103,10 @@ - (void)viewDidLoad { } - (void)observeKeyboard { + printf("******** setting up keyboard input view\n"); + self.keyboardView = [GodotKeyboardInputView new]; + [self.view addSubview:self.keyboardView]; + printf("******** adding observer for keyboard show/hide\n"); [[NSNotificationCenter defaultCenter] addObserver:self @@ -118,7 +124,8 @@ - (void)dealloc { [self.videoView stopVideo]; self.videoView = nil; - self.videoView = nil; + self.keyboardView = nil; + self.renderer = nil; [[NSNotificationCenter defaultCenter] removeObserver:self];