diff --git a/Unity/Assets/Plugins/iOS/MobileInput.mm b/Unity/Assets/Plugins/iOS/MobileInput.mm
index 4acb1d9..b3e5434 100644
--- a/Unity/Assets/Plugins/iOS/MobileInput.mm
+++ b/Unity/Assets/Plugins/iOS/MobileInput.mm
@@ -15,6 +15,8 @@
#define SET_TEXT @"SET_TEXT"
#define GET_TEXT @"GET_TEXT"
#define SET_RECT @"SET_RECT"
+#define ON_FOCUS @"ON_FOCUS"
+#define ON_UNFOCUS @"ON_UNFOCUS"
#define SET_FOCUS @"SET_FOCUS"
#define SET_VISIBLE @"SET_VISIBLE"
#define TEXT_CHANGE @"TEXT_CHANGE"
@@ -192,6 +194,19 @@ -(void) tapAction:(id)sender{
}
}
+-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
+{
+ // Allow buttons to receive press events. All other views will get ignored
+ for( id foundView in self.subviews )
+ {
+ if( [foundView isKindOfClass:[MobileInput class]] )
+ {
+ return YES;
+ }
+ }
+ return NO;
+}
+
-(void) setObserverForOrientationChanging {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
@@ -238,10 +253,6 @@ @implementation MobileInput
+(void) init:(UIViewController *)viewController {
unityViewController = viewController;
mapMobileInput = [[NSMutableDictionary alloc] init];
- CGRect frameView = unityViewController.view.frame;
- frameView.origin = CGPointMake(0.0f, 0.0f);
- viewPlugin = [[MobileInputHoldView alloc] initHoldView:frameView];
- [unityViewController.view addSubview:viewPlugin];
}
+(void) processMessage:(int)inputId data:(NSString *)data {
@@ -321,6 +332,8 @@ -(void) setRect:(NSDictionary *)data {
editView.frame = CGRectMake(x, y, width, height);
}
+BOOL multiline;
+
-(void) create:(NSDictionary *)data {
NSString *placeholder = [data valueForKey:@"placeholder"];
NSString *font = [data valueForKey:@"font"];
@@ -352,7 +365,8 @@ -(void) create:(NSDictionary *)data {
NSString *contentType = [data valueForKey:@"content_type"];
NSString *alignment = [data valueForKey:@"align"];
BOOL withDoneButton = [[data valueForKey:@"with_done_button"] boolValue];
- BOOL multiline = [[data valueForKey:@"multiline"] boolValue];
+ BOOL withClearButton = [[data valueForKey:@"with_clear_button"] boolValue];
+ multiline = [[data valueForKey:@"multiline"] boolValue];
BOOL autoCorr = NO;
BOOL password = NO;
@@ -494,17 +508,22 @@ -(void) create:(NSDictionary *)data {
textField.contentVerticalAlignment = valign;
textField.contentHorizontalAlignment = halign;
textField.textAlignment = textAlign;
+ if (withClearButton)
+ textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName: placeHolderColor}];
textField.delegate = self;
if (keyType == UIKeyboardTypeEmailAddress)
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
+ [textField addTarget:self action:@selector(textFieldActive:) forControlEvents:UIControlEventEditingDidBegin];
+ [textField addTarget:self action:@selector(textFieldInActive:) forControlEvents:UIControlEventEditingDidEnd];
[textField setSecureTextEntry:password];
if (keyboardDoneButtonView != nil)
textField.inputAccessoryView = keyboardDoneButtonView;
editView = textField;
}
- [viewPlugin addSubview:editView];
+ [unityViewController.view addSubview:editView];
+
NSMutableDictionary *msg = [[NSMutableDictionary alloc] init];
[msg setValue:READY forKey:@"msg"];
[self sendData:msg];
@@ -533,7 +552,6 @@ -(int) getLineCount {
return 0;
}
-
-(void) remove {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[editView resignFirstResponder];
@@ -578,7 +596,21 @@ -(void) textViewDidChange:(UITextView *)textView {
[self onTextChange:textView.text];
}
+- (void) textViewDidBeginEditing:(UITextView *)textView
+{
+ if (multiline) {
+ NSMutableDictionary *msg = [[NSMutableDictionary alloc] init];
+ [msg setValue:ON_FOCUS forKey:@"msg"];
+ [self sendData:msg];
+ }
+}
+
-(void) textViewDidEndEditing:(UITextView *)textView {
+ if (multiline) {
+ NSMutableDictionary *msg = [[NSMutableDictionary alloc] init];
+ [msg setValue:ON_UNFOCUS forKey:@"msg"];
+ [self sendData:msg];
+ }
[self onTextEditEnd:textView.text];
}
@@ -602,6 +634,18 @@ - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRang
return YES;
}
+-(void) textFieldActive:(UITextField *)theTextField {
+ NSMutableDictionary *msg = [[NSMutableDictionary alloc] init];
+ [msg setValue:ON_FOCUS forKey:@"msg"];
+ [self sendData:msg];
+}
+
+-(void) textFieldInActive:(UITextField *)theTextField {
+ NSMutableDictionary *msg = [[NSMutableDictionary alloc] init];
+ [msg setValue:ON_UNFOCUS forKey:@"msg"];
+ [self sendData:msg];
+}
+
-(void) textFieldDidChange:(UITextField *)theTextField {
[self onTextChange:theTextField.text];
}
diff --git a/Unity/Assets/Scripts/UnityMobileInput/MobileInput.cs b/Unity/Assets/Scripts/UnityMobileInput/MobileInput.cs
index 88e3dee..a5e2614 100644
--- a/Unity/Assets/Scripts/UnityMobileInput/MobileInput.cs
+++ b/Unity/Assets/Scripts/UnityMobileInput/MobileInput.cs
@@ -9,225 +9,256 @@
using UnityEngine;
using UnityEngine.UI;
-namespace Mopsicus.Plugins.MobileInput {
-
- ///
- /// Wrapper for Unity InputField
- /// Add this component on your InputField
- ///
- [RequireComponent (typeof (InputField))]
- public class MobileInput : MobileInputReceiver {
-
- ///
- /// Config structure
- ///
- private struct MobileInputConfig {
- public bool Multiline;
- public Color TextColor;
- public Color BackgroundColor;
- public string ContentType;
- public string Font;
- public float FontSize;
- public string Align;
- public string Placeholder;
- public Color PlaceholderColor;
- public int CharacterLimit;
-
- }
-
- ///
- /// Button type
- ///
- public enum ReturnKeyType {
- Default,
- Next,
- Done,
- Search
- }
-
- ///
- /// Input type
- ///
- public enum InputType {
- AutoCorrect,
- Password
- }
-
- ///
- /// Keyboard type
- ///
- public enum KeyboardType {
- ASCIICapable,
- NumbersAndPunctuation,
- URL,
- NumberPad,
- PhonePad,
- NamePhonePad,
- EmailAddress
- }
-
- ///
- /// "Done" button visible (for iOS)
- ///
- public bool IsWithDoneButton = true;
- ///
- /// button type
- ///
- public ReturnKeyType ReturnKey;
- ///
- /// input type
- ///
- public InputType Type;
- ///
- /// keyboard type
- ///
- public KeyboardType Keyboard;
- ///
- /// action when Return pressed
- ///
- public event Action ReturnPressed;
- ///
- /// event when Return pressed
- ///
- public UnityEngine.Events.UnityEvent OnReturnPressed;
- ///
- /// mobile input creation flag
- ///
- private bool _isMobileInputCreated = false;
- ///
- /// InputField object
- ///
- private InputField _inputObject;
- ///
- /// Text object from _inputObject
- ///
- private Text _inputObjectText;
- ///
- /// set focus on create
- ///
- private bool _isFocusOnCreate;
- ///
- /// set visible on create
- ///
- private bool _isVisibleOnCreate = true;
- ///
- /// last inputfield position
- ///
- private Rect _lastRect;
- ///
- /// config
- ///
- private MobileInputConfig _config;
-
- // event for plugin communication
-
- private const string CREATE = "CREATE_EDIT";
- private const string REMOVE = "REMOVE_EDIT";
- private const string SET_TEXT = "SET_TEXT";
- private const string SET_RECT = "SET_RECT";
- private const string SET_FOCUS = "SET_FOCUS";
- private const string SET_VISIBLE = "SET_VISIBLE";
- private const string TEXT_CHANGE = "TEXT_CHANGE";
- private const string TEXT_END_EDIT = "TEXT_END_EDIT";
- private const string ANDROID_KEY_DOWN = "ANDROID_KEY_DOWN";
- private const string RETURN_PRESSED = "RETURN_PRESSED";
- private const string READY = "READY";
-
- ///
- /// Constructor
- ///
- private void Awake () {
- _inputObject = this.GetComponent ();
- if (_inputObject == null) {
+namespace Mopsicus.Plugins.MobileInput
+{
+
+ ///
+ /// Wrapper for Unity InputField
+ /// Add this component on your InputField
+ ///
+ [RequireComponent(typeof(InputField))]
+ public class MobileInput : MobileInputReceiver
+ {
+
+ ///
+ /// Config structure
+ ///
+ private struct MobileInputConfig
+ {
+ public bool Multiline;
+ public Color TextColor;
+ public Color BackgroundColor;
+ public string ContentType;
+ public string Font;
+ public float FontSize;
+ public string Align;
+ public string Placeholder;
+ public Color PlaceholderColor;
+ public int CharacterLimit;
+
+ }
+
+ ///
+ /// Button type
+ ///
+ public enum ReturnKeyType
+ {
+ Default,
+ Next,
+ Done,
+ Search
+ }
+
+ ///
+ /// Input type
+ ///
+ public enum InputType
+ {
+ AutoCorrect,
+ Password
+ }
+
+ ///
+ /// Keyboard type
+ ///
+ public enum KeyboardType
+ {
+ ASCIICapable,
+ NumbersAndPunctuation,
+ URL,
+ NumberPad,
+ PhonePad,
+ NamePhonePad,
+ EmailAddress
+ }
+
+ ///
+ /// "Done" button visible (for iOS)
+ ///
+ public bool IsWithDoneButton = true;
+ ///
+ /// "(x)" button visible (for iOS)
+ ///
+ public bool IsWithClearButton = true;
+ ///
+ /// button type
+ ///
+ public ReturnKeyType ReturnKey;
+ ///
+ /// input type
+ ///
+ public InputType Type;
+ ///
+ /// keyboard type
+ ///
+ public KeyboardType Keyboard;
+ ///
+ /// action when Return pressed
+ ///
+ public event Action ReturnPressed;
+ ///
+ /// action when Focus changed
+ ///
+ public event Action FocusChanged = (b) => { };
+ ///
+ /// event when Return pressed
+ ///
+ public UnityEngine.Events.UnityEvent OnReturnPressed;
+ ///
+ /// mobile input creation flag
+ ///
+ private bool _isMobileInputCreated = false;
+ ///
+ /// InputField object
+ ///
+ private InputField _inputObject;
+ ///
+ /// Text object from _inputObject
+ ///
+ private Text _inputObjectText;
+ ///
+ /// set focus on create
+ ///
+ private bool _isFocusOnCreate;
+ ///
+ /// set visible on create
+ ///
+ private bool _isVisibleOnCreate = true;
+ ///
+ /// last inputfield position
+ ///
+ private Rect _lastRect;
+ ///
+ /// config
+ ///
+ private MobileInputConfig _config;
+
+ // event for plugin communication
+
+ private const string CREATE = "CREATE_EDIT";
+ private const string REMOVE = "REMOVE_EDIT";
+ private const string SET_TEXT = "SET_TEXT";
+ private const string SET_RECT = "SET_RECT";
+ private const string SET_FOCUS = "SET_FOCUS";
+ private const string ON_FOCUS = "ON_FOCUS";
+ private const string ON_UNFOCUS = "ON_UNFOCUS";
+ private const string SET_VISIBLE = "SET_VISIBLE";
+ private const string TEXT_CHANGE = "TEXT_CHANGE";
+ private const string TEXT_END_EDIT = "TEXT_END_EDIT";
+ private const string ANDROID_KEY_DOWN = "ANDROID_KEY_DOWN";
+ private const string RETURN_PRESSED = "RETURN_PRESSED";
+ private const string READY = "READY";
+
+ ///
+ /// Constructor
+ ///
+ private void Awake()
+ {
+ _inputObject = this.GetComponent();
+ if (_inputObject == null)
+ {
#if DEBUG
- Debug.LogErrorFormat ("No InputField found {0} MobileInput Error", this.name);
+ Debug.LogErrorFormat("No InputField found {0} MobileInput Error", this.name);
#endif
- throw new MissingComponentException ();
- }
- _inputObjectText = _inputObject.textComponent;
- }
-
- ///
- /// Create mobile input on Start with coroutine
- ///
- protected override void Start () {
- base.Start ();
- StartCoroutine (InitialzieOnNextFrame ());
- }
-
- ///
- /// Show on enable
- ///
- private void OnEnable () {
- if (_isMobileInputCreated)
- this.SetVisible (true);
- }
-
- ///
- /// Hide on disable
- ///
- private void OnDisable () {
- if (_isMobileInputCreated) {
- this.SetFocus (false);
- this.SetVisible (false);
- }
- }
-
- ///
- /// Destructor
- ///
- protected override void OnDestroy () {
- RemoveNative ();
- base.OnDestroy ();
- }
-
- ///
- /// Handler for app focus lost
- ///
- ///
- private void OnApplicationFocus (bool hasFocus) {
- if (!_isMobileInputCreated || !this.Visible)
- return;
- this.SetVisible (hasFocus);
- }
-
- ///
- /// Current InputField for external access
- ///
- public InputField InputField {
- get {
- return _inputObject;
- }
- }
-
- ///
- /// Mobile input visible
- ///
- /// true | false
- public bool Visible {
- get;
- private set;
- }
-
- ///
- /// Mobile input text
- ///
- public string Text {
- get {
- return _inputObject.text;
- }
- set {
- _inputObject.text = value;
- SetTextNative (value);
- }
- }
-
- ///
- /// Initialization coroutine
- ///
- private IEnumerator InitialzieOnNextFrame () {
- yield return null;
- this.PrepareNativeEdit ();
+ throw new MissingComponentException();
+ }
+ _inputObjectText = _inputObject.textComponent;
+ }
+
+ ///
+ /// Create mobile input on Start with coroutine
+ ///
+ protected override void Start()
+ {
+ base.Start();
+ StartCoroutine(InitialzieOnNextFrame());
+ }
+
+ ///
+ /// Show on enable
+ ///
+ private void OnEnable()
+ {
+ if (_isMobileInputCreated)
+ this.SetVisible(true);
+ }
+
+ ///
+ /// Hide on disable
+ ///
+ private void OnDisable()
+ {
+ if (_isMobileInputCreated)
+ {
+ this.SetFocus(false);
+ this.SetVisible(false);
+ }
+ }
+
+ ///
+ /// Destructor
+ ///
+ protected override void OnDestroy()
+ {
+ RemoveNative();
+ base.OnDestroy();
+ }
+
+ ///
+ /// Handler for app focus lost
+ ///
+ ///
+ private void OnApplicationFocus(bool hasFocus)
+ {
+ if (!_isMobileInputCreated || !this.Visible)
+ return;
+ this.SetVisible(hasFocus);
+ }
+
+ ///
+ /// Current InputField for external access
+ ///
+ public InputField InputField
+ {
+ get
+ {
+ return _inputObject;
+ }
+ }
+
+ ///
+ /// Mobile input visible
+ ///
+ /// true | false
+ public bool Visible
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Mobile input text
+ ///
+ public string Text
+ {
+ get
+ {
+ return _inputObject.text;
+ }
+ set
+ {
+ _inputObject.text = value;
+ SetTextNative(value);
+ }
+ }
+
+ ///
+ /// Initialization coroutine
+ ///
+ private IEnumerator InitialzieOnNextFrame()
+ {
+ yield return null;
+ this.PrepareNativeEdit();
#if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR
this.CreateNativeEdit ();
this.SetTextNative (this._inputObjectText.text);
@@ -235,28 +266,37 @@ private IEnumerator InitialzieOnNextFrame () {
_inputObjectText.enabled = false;
_inputObject.enabled = false;
#endif
- }
-
- ///
- /// Check position on each frame
- /// If changed - send to plugin
- /// It's need when app rotate on input field chage position
- ///
- private void Update () {
+ }
+
+ ///
+ /// Check position on each frame
+ /// If changed - send to plugin
+ /// It's need when app rotate on input field chage position
+ ///
+ private void Update()
+ {
#if UNITY_ANDROID && !UNITY_EDITOR
- this.UpdateForceKeyeventForAndroid ();
+ this.UpdateForceKeyeventForAndroid ();
#endif
- if (this._inputObject != null && _isMobileInputCreated) {
- SetRectNative (this._inputObjectText.rectTransform);
- }
- }
-
- ///
- /// Get bounds and calc for current screen size
- ///
- /// recttranform
- /// rect
- Rect GetScreenRectFromRectTransform (RectTransform rect) {
+ if (this._inputObject != null && _isMobileInputCreated)
+ {
+#if UNITY_IOS
+ if (Input.GetMouseButtonDown(0) && !this._inputObjectText.rectTransform.rect.Contains(Input.mousePosition))
+ {
+ Hide();
+ return;
+ }
+#endif
+ SetRectNative(this._inputObjectText.rectTransform);
+ }
+ }
+
+ ///
+ /// Get bounds and calc for current screen size
+ ///
+ /// recttranform
+ /// rect
+ Rect GetScreenRectFromRectTransform (RectTransform rect) {
Vector3[] corners = new Vector3[4];
rect.GetWorldCorners (corners);
float xMin = float.PositiveInfinity;
@@ -349,12 +389,19 @@ public override void Hide () {
private IEnumerator PluginsMessageRoutine (JsonObject data) {
yield return null;
string msg = data["msg"];
- if (msg.Equals (TEXT_CHANGE)) {
- string text = data["text"];
- this.onTextChange (text);
- } else if (msg.Equals (READY)) {
- this.Ready ();
- } else if (msg.Equals (TEXT_END_EDIT)) {
+ if (msg.Equals(TEXT_CHANGE)) {
+ string text = data["text"];
+ this.onTextChange(text);
+ }
+ else if (msg.Equals(READY)) {
+ this.Ready();
+ }
+ else if (msg.Equals(ON_FOCUS)) {
+ FocusChanged(true);
+ }
+ else if (msg.Equals(ON_UNFOCUS)){
+ FocusChanged(false);
+ } else if (msg.Equals (TEXT_END_EDIT)) {
string text = data["text"];
this.onTextEditEnd (text);
} else if (msg.Equals (RETURN_PRESSED)) {
@@ -389,7 +436,8 @@ private void CreateNativeEdit () {
data["font_size"] = _config.FontSize;
data["content_type"] = _config.ContentType;
data["align"] = _config.Align;
- data["with_done_button"] = this.IsWithDoneButton;
+ data["with_done_button"] = this.IsWithDoneButton;
+ data["with_clear_button"] = this.IsWithClearButton;
data["placeholder"] = _config.Placeholder;
data["placeholder_color_r"] = _config.PlaceholderColor.r;
data["placeholder_color_g"] = _config.PlaceholderColor.g;