diff --git a/Android~/plugin/src/main/java/com/mopsicus/umi/MobileInput.java b/Android~/plugin/src/main/java/com/mopsicus/umi/MobileInput.java index 01a05dd..29af154 100644 --- a/Android~/plugin/src/main/java/com/mopsicus/umi/MobileInput.java +++ b/Android~/plugin/src/main/java/com/mopsicus/umi/MobileInput.java @@ -1,9 +1,15 @@ package com.mopsicus.umi; import android.content.Context; +import android.content.res.Resources; import android.graphics.Color; +import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Typeface; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.InsetDrawable; +import android.os.Build; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -18,10 +24,13 @@ import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; +import android.widget.TextView; import org.json.JSONException; import org.json.JSONObject; +import java.lang.reflect.Field; + public class MobileInput { private static final String CREATE = "CREATE_EDIT"; @@ -68,6 +77,16 @@ public class MobileInput { */ private int editInputType = 0; + /** + * Cached caret color + */ + private int caretColor = Color.GRAY; + + /** + * Cached flag to change caret to custom color or not + */ + private boolean isCaretChange = false; + /** * List of inputs */ @@ -255,6 +274,10 @@ private void Create(int id, JSONObject data) { int placeHolderColor_g = (int) (255.0f * data.getDouble("placeholder_color_g")); int placeHolderColor_b = (int) (255.0f * data.getDouble("placeholder_color_b")); int placeHolderColor_a = (int) (255.0f * data.getDouble("placeholder_color_a")); + int caretColor_r = (int) (255.0f * data.getDouble("caret_color_r")); + int caretColor_g = (int) (255.0f * data.getDouble("caret_color_g")); + int caretColor_b = (int) (255.0f * data.getDouble("caret_color_b")); + int caretColor_a = (int) (255.0f * data.getDouble("caret_color_a")); String contentType = data.getString("content_type"); String inputType = data.optString("input_type"); String keyboardType = data.optString("keyboard_type"); @@ -262,6 +285,8 @@ private void Create(int id, JSONObject data) { String alignment = data.getString("align"); String customFont = data.getString("font"); boolean multiline = data.getBoolean("multiline"); + caretColor = Color.argb(caretColor_a, caretColor_r, caretColor_g, caretColor_b); + isCaretChange = data.getBoolean("caret_color"); edit = new EditText(Plugin.activity.getApplicationContext()); edit.setSingleLine(!multiline); edit.setId(this.id); @@ -476,6 +501,74 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { } } + /*** + * Set cursor/caret/handles color + * + * @param color Color value + */ + void setCaretColor(int color) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + if (edit.getTextCursorDrawable() instanceof InsetDrawable) { + InsetDrawable insetDrawable = (InsetDrawable) edit.getTextCursorDrawable(); + insetDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + edit.setTextCursorDrawable(insetDrawable); + Log.d("[UMI]", String.format("set caret cursor: %s", color)); + } + if (edit.getTextSelectHandle() instanceof BitmapDrawable) { + BitmapDrawable insetDrawable = (BitmapDrawable) edit.getTextSelectHandle(); + insetDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + edit.setTextSelectHandle(insetDrawable); + Log.d("[UMI]", String.format("set caret handle: %s", color)); + } + if (edit.getTextSelectHandleRight() instanceof BitmapDrawable) { + BitmapDrawable insetDrawable = (BitmapDrawable) edit.getTextSelectHandleRight(); + insetDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + edit.setTextSelectHandleRight(insetDrawable); + Log.d("[UMI]", String.format("set caret handle right: %s", color)); + } + if (edit.getTextSelectHandleLeft() instanceof BitmapDrawable) { + BitmapDrawable insetDrawable = (BitmapDrawable) edit.getTextSelectHandleLeft(); + insetDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + edit.setTextSelectHandleLeft(insetDrawable); + Log.d("[UMI]", String.format("set caret handle left: %s", color)); + } + } else { + try { + Resources res = edit.getContext().getResources(); + Field field = TextView.class.getDeclaredField("mEditor"); + field.setAccessible(true); + Object editor = field.get(edit); + field = TextView.class.getDeclaredField("mCursorDrawableRes"); + field.setAccessible(true); + int cursorDrawableRes = field.getInt(edit); + Drawable cursorDrawable = res.getDrawable(cursorDrawableRes).mutate(); + cursorDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); + Drawable[] drawables = {cursorDrawable, cursorDrawable}; + field = editor.getClass().getDeclaredField("mCursorDrawable"); + field.setAccessible(true); + field.set(editor, drawables); + String[] resFieldNames = {"mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"}; + String[] drawableFieldNames = {"mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"}; + for (int i = 0; i < resFieldNames.length; i++) { + String resFieldName = resFieldNames[i]; + String drawableFieldName = drawableFieldNames[i]; + field = TextView.class.getDeclaredField(resFieldName); + field.setAccessible(true); + int selectHandleRes = field.getInt(edit); + Drawable selectHandleDrawable = res.getDrawable(selectHandleRes).mutate(); + selectHandleDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); + field = editor.getClass().getDeclaredField(drawableFieldName); + field.setAccessible(true); + field.set(editor, selectHandleDrawable); + } + } catch (Exception e) { + if (Plugin.bridge.isDebug) { + Log.e("[UMI]", String.format("set caret error: %s", e)); + } + } + } + } + /** * Remove MobileInput */ @@ -534,6 +627,11 @@ private void SetFocus(boolean isFocus) { } if (isFocus) { edit.requestFocus(); + if (isCaretChange) { + setCaretColor(caretColor); + } else { + setCaretColor(Color.GRAY); + } } else { edit.clearFocus(); } diff --git a/Plugins/Android/MobileInput.aar.meta b/Plugins/Android/MobileInput.aar.meta index 7f60eb1..30030be 100644 --- a/Plugins/Android/MobileInput.aar.meta +++ b/Plugins/Android/MobileInput.aar.meta @@ -7,7 +7,7 @@ PluginImporter: executionOrder: {} defineConstraints: [] isPreloaded: 0 - isOverridable: 0 + isOverridable: 1 isExplicitlyReferenced: 0 validateReferences: 1 platformData: diff --git a/Plugins/Android/Mobileinput.aar b/Plugins/Android/Mobileinput.aar index ecf170e..c7ca327 100644 Binary files a/Plugins/Android/Mobileinput.aar and b/Plugins/Android/Mobileinput.aar differ diff --git a/Plugins/iOS/MobileInput.mm b/Plugins/iOS/MobileInput.mm index 59423ab..9624c2d 100644 --- a/Plugins/iOS/MobileInput.mm +++ b/Plugins/iOS/MobileInput.mm @@ -509,12 +509,18 @@ - (void)create:(NSDictionary *)data { float placeHolderColor_b = [[data valueForKey:@"placeholder_color_b"] floatValue]; float placeHolderColor_a = [[data valueForKey:@"placeholder_color_a"] floatValue]; UIColor *placeHolderColor = [UIColor colorWithRed:placeHolderColor_r green:placeHolderColor_g blue:placeHolderColor_b alpha:placeHolderColor_a]; + float caretColor_r = [[data valueForKey:@"caret_color_r"] floatValue]; + float caretColor_g = [[data valueForKey:@"caret_color_g"] floatValue]; + float caretColor_b = [[data valueForKey:@"caret_color_b"] floatValue]; + float caretColor_a = [[data valueForKey:@"caret_color_a"] floatValue]; + UIColor *caretColor = [UIColor colorWithRed:caretColor_r green:caretColor_g blue:caretColor_b alpha:caretColor_a]; NSString *contentType = [data valueForKey:@"content_type"]; NSString *alignment = [data valueForKey:@"align"]; NSString *customFont = [data valueForKey:@"font"]; BOOL withDoneButton = [[data valueForKey:@"with_done_button"] boolValue]; BOOL withClearButton = [[data valueForKey:@"with_clear_button"] boolValue]; isMultiline = [[data valueForKey:@"multiline"] boolValue]; + BOOL isChangeCaret = [[data valueForKey:@"caret_color"] boolValue]; BOOL autoCorrection = NO; BOOL password = NO; NSString *inputType = [data valueForKey:@"input_type"]; @@ -656,6 +662,9 @@ - (void)create:(NSDictionary *)data { textView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f); textView.placeholder = placeholder; textView.placeholderColor = placeHolderColor; + if (isChangeCaret) { + textView.tintColor = caretColor; + } textView.delegate = self; if (keyType == UIKeyboardTypeEmailAddress) { textView.autocapitalizationType = UITextAutocapitalizationTypeNone; @@ -674,6 +683,9 @@ - (void)create:(NSDictionary *)data { textField.text = @""; textField.textColor = textColor; textField.backgroundColor = backgroundColor; + if (isChangeCaret) { + textField.tintColor = caretColor; + } textField.returnKeyType = returnKeyType; textField.autocorrectionType = autoCorrection ? UITextAutocorrectionTypeYes : UITextAutocorrectionTypeNo; textField.contentVerticalAlignment = valign; diff --git a/Runtime/MobileInputField.cs b/Runtime/MobileInputField.cs index e4721ee..f075f54 100644 --- a/Runtime/MobileInputField.cs +++ b/Runtime/MobileInputField.cs @@ -37,6 +37,8 @@ struct MobileInputConfig { public bool Multiline; public Color TextColor; public Color BackgroundColor; + public bool ChangeCaret; + public Color CaretColor; public string ContentType; public string InputType; public string KeyboardType; @@ -306,6 +308,7 @@ protected override void OnDestroy() { base.OnDestroy(); } +#if UNITY_ANDROID /// /// Handler for app focus lost /// @@ -325,6 +328,7 @@ void OnApplicationPause(bool hasPause) { } SetVisible(!hasPause); } +#endif /// /// Current InputField for external access @@ -420,6 +424,8 @@ void PrepareNativeEdit() { var placeHolder = _inputObject.placeholder.GetComponent(); _config.Placeholder = placeHolder.text; _config.PlaceholderColor = placeHolder.color; + _config.CaretColor = _inputObject.caretColor; + _config.ChangeCaret = _inputObject.customCaretColor; _config.CharacterLimit = _inputObject.characterLimit; var rect = GetScreenRectFromRectTransform(_inputObjectText.rectTransform); var ratio = rect.height / _inputObjectText.rectTransform.rect.height; @@ -573,6 +579,11 @@ void CreateNativeEdit() { data["placeholder_color_g"] = InvariantCultureString(_config.PlaceholderColor.g); data["placeholder_color_b"] = InvariantCultureString(_config.PlaceholderColor.b); data["placeholder_color_a"] = InvariantCultureString(_config.PlaceholderColor.a); + data["caret_color_r"] = InvariantCultureString(_config.CaretColor.r); + data["caret_color_g"] = InvariantCultureString(_config.CaretColor.g); + data["caret_color_b"] = InvariantCultureString(_config.CaretColor.b); + data["caret_color_a"] = InvariantCultureString(_config.CaretColor.a); + data["caret_color"] = _config.ChangeCaret; data["multiline"] = _config.Multiline; data["input_type"] = _config.InputType; data["keyboard_type"] = _config.KeyboardType;