diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..6a6bcde --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @YousicianGit/coreapplication diff --git a/README.md b/README.md index 7e0977a..574ea5a 100644 --- a/README.md +++ b/README.md @@ -3,28 +3,21 @@ Unity Native Input Plugin for both iOS and Android (Unity UI InputField compatib This means you don't need a separate 'Unity' Input box and you can use all native text functions such as `Select`, `Copy` and `Paste` ## Usage -1. Simply copy the files in `release/NativeEditPlugin` into your existing unity project asset folder. -2. If using Unity >= 5.6 make sure that your Plugins/Android/AndroidManifest.xml defines - ``` - - ``` - instead of - ``` - - ``` - Note that there can be multiple Android manifests in a Unity project (if you have multiple Android plugins) and Unity merges them to a single manifest when building. The `activity` on the manifest closest to the root level of `Plugins/Android` directory seems to override definitions in other manifests so make sure to modify that manifest - - If another plugin you're using is overriding the `UnityPlayerActivity` and the input field appears invisible you need to modify the overriding `UnityPlayerActivity` so that it doesn't appear on top of native views, see https://github.com/YousicianGit/UnityNativeEdit/issues/34. - - You can refer to sample `AndroidManifest.xml` in `/Plugings/Android` folder. - -3. Make empty Gameobject and attach ```PluginMsgHandler``` to your new GameObject -4. Attach ```NativeEditBox``` script to your UnityUI ```InputField```object. -5. Build and run on your android or ios device! +1. Simply copy the files in `release/NativeEditPlugin` into your existing unity project asset folder. +2. Make empty Gameobject and attach ```PluginMsgHandler``` to your new GameObject +3. Attach ```NativeEditBox``` script to your UnityUI ```InputField```object. +4. Build and run on your android or ios device! ## Etc 1. NativeEditBox will work with delegate defined in your Unity UI InputField, `On Value Change` and `End Edit` 2. It's open source and free to use/redistribute! 3. Please refer to `demo` Unity project. + +## Building the Android plugin +If you want to tinker with the project yourself you need to build the Android project again in AndroidStudio (for iOS you can just modify the Objective-C code and it will get built at the same time as the Unity project). + +1. Open the `src/androidProj` directory in AndroidStudio. +2. Select View -> Tool Windows -> Gradle in AndroidStudio. +3. In Gradle run the :nativeeditplugin -> other -> makeJar task. +4. It's a bit confusing but the task seems to generate .aar files (even though it was called makeJar, not sure what's up with that) in the `src/androidProj/nativeeditplugin/build/outputs/aar` directory. +5. To test in the demo Unity project copy the `nativeeditplugin-release.aar` file (from the output directory) to the `release\NativeEditPlugin\Plugins\Android` directory. This file is symlinked to the Unity demo project. \ No newline at end of file diff --git a/demo/Assets/NativeEditPlugin/demo b/demo/Assets/NativeEditPlugin/demo deleted file mode 120000 index 6a83949..0000000 --- a/demo/Assets/NativeEditPlugin/demo +++ /dev/null @@ -1 +0,0 @@ -../../../release/NativeEditPlugin/demo/ \ No newline at end of file diff --git a/demo/Assets/Plugins.meta b/demo/Assets/Plugins.meta deleted file mode 100644 index b440888..0000000 --- a/demo/Assets/Plugins.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 43ed4bbb5a5d3413fbabfb45a14b2fc9 -folderAsset: yes -timeCreated: 1430960228 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/demo/Assets/Plugins/Android.meta b/demo/Assets/Plugins/Android.meta deleted file mode 100644 index 716eb2f..0000000 --- a/demo/Assets/Plugins/Android.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 72c849c8861e341128c79b4e08f88147 -folderAsset: yes -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/demo/Assets/Plugins/Android/AndroidManifest.xml b/demo/Assets/Plugins/Android/AndroidManifest.xml deleted file mode 100644 index a2a2049..0000000 --- a/demo/Assets/Plugins/Android/AndroidManifest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/release.meta b/release.meta new file mode 100644 index 0000000..e6dc0b6 --- /dev/null +++ b/release.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cfac1d20dbc44821b8f76ba649183eda +timeCreated: 1604320105 \ No newline at end of file diff --git a/release/NativeEditPlugin/Plugins/Android/AndroidManifest.xml b/release/NativeEditPlugin/Plugins/Android/AndroidManifest.xml deleted file mode 100644 index a2a2049..0000000 --- a/release/NativeEditPlugin/Plugins/Android/AndroidManifest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/release/NativeEditPlugin/Plugins/Android/AndroidManifest.xml.meta b/release/NativeEditPlugin/Plugins/Android/AndroidManifest.xml.meta deleted file mode 100644 index 877490b..0000000 --- a/release/NativeEditPlugin/Plugins/Android/AndroidManifest.xml.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7bfe820b46571db4dbac71c4a5ffec61 -timeCreated: 1459854746 -licenseType: Free -TextScriptImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/EditBox.java b/release/NativeEditPlugin/Plugins/Android/EditBox.java similarity index 76% rename from src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/EditBox.java rename to release/NativeEditPlugin/Plugins/Android/EditBox.java index 99661ef..c258970 100644 --- a/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/EditBox.java +++ b/release/NativeEditPlugin/Plugins/Android/EditBox.java @@ -1,5 +1,6 @@ package com.bkmin.android; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -12,6 +13,7 @@ import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; +import android.text.method.DigitsKeyListener; import android.util.Log; import android.util.SparseArray; import android.util.TypedValue; @@ -24,6 +26,12 @@ import android.widget.RelativeLayout; import android.widget.TextView; +import com.redmadrobot.inputmask.MaskedTextChangedListener; +import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy; + +import java.util.ArrayList; +import java.util.List; + public class EditBox { // Simplest way to notify the EditBox about the application lifecycle. @@ -49,19 +57,27 @@ public void onWindowFocusChanged(boolean hasWindowFocus) private final RelativeLayout layout; private int tag; private int characterLimit; + private String extractedText = ""; + private String formattedText = ""; private static SparseArray mapEditBox = null; private static final String MSG_CREATE = "CreateEdit"; private static final String MSG_REMOVE = "RemoveEdit"; private static final String MSG_SET_TEXT = "SetText"; private static final String MSG_SET_RECT = "SetRect"; + private static final String MSG_SET_TEXTSIZE = "SetTextSize"; private static final String MSG_SET_FOCUS = "SetFocus"; private static final String MSG_SET_VISIBLE = "SetVisible"; private static final String MSG_TEXT_CHANGE = "TextChange"; + private static final String MSG_TEXT_BEGIN_EDIT = "TextBeginEdit"; private static final String MSG_TEXT_END_EDIT = "TextEndEdit"; private static final String MSG_ANDROID_KEY_DOWN = "AndroidKeyDown"; private static final String MSG_RETURN_PRESSED = "ReturnPressed"; + private static final String APPLY_MASK_KEY = "applyMask"; + private static final String AFFINE_MASKS_KEY = "affineMasks"; + private static final String EXTRA_CHARACTERS_FOR_DIGITS_KEY = "extraCharactersForDigits"; + public static void processRecvJsonMsg(int nSenderId, final String strJson) { if (mapEditBox == null) mapEditBox = new SparseArray<>(); @@ -141,6 +157,9 @@ private void processJsonMsg(JSONObject jsonMsg) case MSG_SET_RECT: this.SetRect(jsonMsg); break; + case MSG_SET_TEXTSIZE: + this.SetTextSize(jsonMsg); + break; case MSG_SET_FOCUS: boolean isFocus = jsonMsg.getBoolean("isFocus"); this.SetFocus(isFocus); @@ -314,62 +333,17 @@ else if (returnKeyType.equals("Done")) { } final EditBox eb = this; - edit.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - // your action here - JSONObject msgTextEndJSON = new JSONObject(); - try - { - msgTextEndJSON.put("msg", MSG_TEXT_END_EDIT); - msgTextEndJSON.put("text", eb.GetText()); - } - catch(JSONException e) {} - eb.SendJsonToUnity(msgTextEndJSON); - } + SendTextToUnity(hasFocus ? MSG_TEXT_BEGIN_EDIT : MSG_TEXT_END_EDIT); SetFocus(hasFocus); } }); - edit.addTextChangedListener(new TextWatcher() { - - public void afterTextChanged(Editable s) - { - JSONObject jsonToUnity = new JSONObject(); - - if(characterLimit > 0 && s.length() >= characterLimit+1) - { - s.delete(s.length() - 1, - s.length()); - edit.setText(s); - edit.setSelection(s.length()); - } - - try - { - jsonToUnity.put("msg", MSG_TEXT_CHANGE); - jsonToUnity.put("text", s.toString()); - } - catch(JSONException e) {} - eb.SendJsonToUnity(jsonToUnity); - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - // TODO Auto-generated method stub - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - // TODO Auto-generated method stub - - } - }); + TextWatcher editTextWatcher = getEditTextWatcher(jsonObj, eb); + edit.addTextChangedListener(editTextWatcher); edit.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override @@ -397,6 +371,87 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { } } + private TextWatcher getEditTextWatcher(JSONObject jsonObj, final EditBox editBox) throws JSONException { + + boolean applyMask = jsonObj.has(APPLY_MASK_KEY) && jsonObj.getBoolean(APPLY_MASK_KEY); + + if (applyMask) { + String primaryMask = jsonObj.getString("primaryMask"); + JSONArray affineMasks = jsonObj.isNull(AFFINE_MASKS_KEY) ? new JSONArray() : jsonObj.getJSONArray(AFFINE_MASKS_KEY); + int affinityStrategy = jsonObj.getInt("affinityStrategy"); + boolean useCustomPlaceholder = jsonObj.getBoolean("useCustomPlaceholder"); + String customPlaceholder = jsonObj.getString("customPlaceholder"); + + boolean useExtraCharactersForDigits = + !jsonObj.isNull(EXTRA_CHARACTERS_FOR_DIGITS_KEY) && + (edit.getInputType() & InputType.TYPE_CLASS_NUMBER) == InputType.TYPE_CLASS_NUMBER; + + if (useExtraCharactersForDigits) + { + String extraCharactersForDigits = jsonObj.getString(EXTRA_CHARACTERS_FOR_DIGITS_KEY); + if (!extraCharactersForDigits.isEmpty()) + edit.setKeyListener(DigitsKeyListener.getInstance(extraCharactersForDigits)); + } + + final MaskedTextChangedListener maskedTextChangedListener = new MaskedTextChangedListener( + primaryMask, + JSONArrayToStringList(affineMasks), + GetAffinityCalculationStrategy(affinityStrategy), + true, + edit, + null, + new MaskedTextChangedListener.ValueListener() { + @Override + public void onTextChanged(boolean maskFilled, String extractedValue, String formattedValue) { + editBox.extractedText = extractedValue; + editBox.formattedText = formattedValue; + editBox.SendTextToUnity(MSG_TEXT_CHANGE); + } + }); + + String placeholder = useCustomPlaceholder ? customPlaceholder : maskedTextChangedListener.placeholder(); + edit.setHint(placeholder); + + return maskedTextChangedListener; + } + + return defaultTextWatcher(); + } + + private TextWatcher defaultTextWatcher() { + return new TextWatcher() { + public void afterTextChanged(Editable s) { + if (characterLimit > 0 && s.length() >= characterLimit + 1) { + s.delete(s.length() - 1, + s.length()); + edit.setText(s); + edit.setSelection(s.length()); + } + extractedText = s.toString(); + formattedText = extractedText; + SendTextToUnity(MSG_TEXT_CHANGE); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { } + }; + } + + private void SendTextToUnity(String messageKey) + { + JSONObject jsonToUnity = new JSONObject(); + try + { + jsonToUnity.put("msg", messageKey); + jsonToUnity.put("text", formattedText); + jsonToUnity.put("extractedText", extractedText); + } + catch(JSONException e) {} + SendJsonToUnity(jsonToUnity); + } + private void Remove() { if (edit != null) { @@ -452,6 +507,17 @@ private void SetFocus(boolean isFocus) this.showKeyboard(isFocus); } + private void SetTextSize(JSONObject jsonRect) + { + try + { + double fontSize = jsonRect.getDouble("fontSize"); + edit.setTextSize(TypedValue.COMPLEX_UNIT_PX, (float) fontSize); + } catch (JSONException e) + { + } + } + private void SetRect(JSONObject jsonRect) { try @@ -514,4 +580,32 @@ private void OnForceAndroidKeyDown(String strKey) { edit.onKeyDown(keyCode, ke); } } + + private static AffinityCalculationStrategy GetAffinityCalculationStrategy(int value) + { + switch (value) { + case 0: + return AffinityCalculationStrategy.PREFIX; + case 1: + return AffinityCalculationStrategy.WHOLE_STRING; + case 2: + return AffinityCalculationStrategy.CAPACITY; + case 3: + return AffinityCalculationStrategy.EXTRACTED_VALUE_CAPACITY; + default: + return AffinityCalculationStrategy.PREFIX; + } + } + + private List JSONArrayToStringList(JSONArray jsonArray) { + List list = new ArrayList<>(); + for (int i = 0; i < jsonArray.length(); i++) { + try { + list.add(jsonArray.getString(i)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return list; + } } diff --git a/release/NativeEditPlugin/Plugins/Android/EditBox.java.meta b/release/NativeEditPlugin/Plugins/Android/EditBox.java.meta new file mode 100644 index 0000000..a5625a3 --- /dev/null +++ b/release/NativeEditPlugin/Plugins/Android/EditBox.java.meta @@ -0,0 +1,99 @@ +fileFormatVersion: 2 +guid: 2315322cc46b5475ebacc557c43c7ccc +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 1 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: x86_64 + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + iPhone: iOS + second: + enabled: 0 + settings: + AddToEmbeddedBinaries: false + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/NativeEditPlugin.java b/release/NativeEditPlugin/Plugins/Android/NativeEditPlugin.java similarity index 100% rename from src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/NativeEditPlugin.java rename to release/NativeEditPlugin/Plugins/Android/NativeEditPlugin.java diff --git a/release/NativeEditPlugin/Plugins/Android/NativeEditPlugin.java.meta b/release/NativeEditPlugin/Plugins/Android/NativeEditPlugin.java.meta new file mode 100644 index 0000000..3d9b4f2 --- /dev/null +++ b/release/NativeEditPlugin/Plugins/Android/NativeEditPlugin.java.meta @@ -0,0 +1,29 @@ +fileFormatVersion: 2 +guid: 7ce221fdcf4e949bdb24c027829930c7 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Android: Android + second: + enabled: 1 + settings: {} + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/release/NativeEditPlugin/Plugins/Android/nativeeditplugin.jar b/release/NativeEditPlugin/Plugins/Android/nativeeditplugin.jar deleted file mode 100644 index 561ff7d..0000000 Binary files a/release/NativeEditPlugin/Plugins/Android/nativeeditplugin.jar and /dev/null differ diff --git a/release/NativeEditPlugin/Plugins/Android/nativeeditplugin.jar.meta b/release/NativeEditPlugin/Plugins/Android/nativeeditplugin.jar.meta deleted file mode 100644 index 090a9bf..0000000 --- a/release/NativeEditPlugin/Plugins/Android/nativeeditplugin.jar.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: ca56f230e8554c146818642d411d9183 -timeCreated: 1459854746 -licenseType: Free -PluginImporter: - serializedVersion: 2 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - isOverridable: 0 - platformData: - data: - first: - Android: Android - second: - enabled: 1 - settings: {} - data: - first: - Any: - second: - enabled: 0 - settings: {} - data: - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - userData: - assetBundleName: - assetBundleVariant: diff --git a/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.h b/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.h index 6c0d3ce..77569b5 100644 --- a/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.h +++ b/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.h @@ -10,9 +10,11 @@ #define MSG_SET_TEXT @"SetText" #define MSG_GET_TEXT @"GetText" #define MSG_SET_RECT @"SetRect" +#define MSG_SET_TEXTSIZE @"SetTextSize" #define MSG_SET_FOCUS @"SetFocus" #define MSG_SET_VISIBLE @"SetVisible" #define MSG_TEXT_CHANGE @"TextChange" +#define MSG_TEXT_BEGIN_EDIT @"TextBeginEdit" #define MSG_TEXT_END_EDIT @"TextEndEdit" #define MSG_RETURN_PRESSED @"ReturnPressed" @@ -35,10 +37,12 @@ int tag; } +@property (nonatomic, assign) int maxLength; + +(void) initializeEditBox:(UIViewController*) _unityViewController unityName:(const char*) unityName; +(JsonObject*) processRecvJsonMsg:(int)nSenderId msg:(JsonObject*) jsonMsg; +(void) finalizeEditBox; --(void) showKeyboard:(bool)isShow; +-(void) hideKeyboard; -(BOOL) IsFocused; @end diff --git a/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.m b/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.m index 87b5ef0..9ff5ad6 100755 --- a/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.m +++ b/release/NativeEditPlugin/Plugins/iOS/EditBox_iOS.m @@ -10,7 +10,6 @@ EditBoxHoldView* viewPlugin = nil; char g_unityName[64]; -int characterLimit; bool approxEqualFloat(float x, float y) { @@ -37,7 +36,7 @@ -(void) tapAction:(id) sender { if ([eb IsFocused]) { - [eb showKeyboard:NO]; + [eb hideKeyboard]; } } } @@ -154,6 +153,10 @@ -(JsonObject*) processJsonMsg:(NSString*) msg json:(JsonObject*) jsonMsg { [self setRect:jsonMsg]; } + else if ([msg isEqualToString:MSG_SET_TEXTSIZE]) + { + [self setTextSize:jsonMsg]; + } else if ([msg isEqualToString:MSG_SET_FOCUS]) { BOOL isFocus = [jsonMsg getBool:@"isFocus"]; @@ -191,6 +194,26 @@ -(void) setRect:(JsonObject*)json editView.frame = CGRectMake(x, y, width, height); } +-(void) setTextSize:(JsonObject*)json +{ + float fontSize = [json getFloat:@"fontSize"]; + // Conversion for retina displays + fontSize = fontSize / [UIScreen mainScreen].scale; + + if([editView isKindOfClass:[UITextField class]]) + { + UITextField *textField = ((UITextField*)editView); + UIFont *newFont = [[textField font] fontWithSize:fontSize]; + [textField setFont:newFont]; + } + else if([editView isKindOfClass:[UITextView class]]) + { + UITextView *textView = ((UITextView*)editView); + UIFont *newFont = [[textView font] fontWithSize:fontSize]; + [textView setFont:newFont]; + } +} + -(void) create:(JsonObject*)json { NSString* placeholder = [json getString:@"placeHolder"]; @@ -203,7 +226,7 @@ -(void) create:(JsonObject*)json float width = [json getFloat:@"width"] * viewController.view.bounds.size.width; float height = [json getFloat:@"height"] * viewController.view.bounds.size.height; - characterLimit = [json getInt:@"characterLimit"]; + [self setMaxLength:[json getInt:@"characterLimit"]]; float textColor_r = [json getFloat:@"textColor_r"]; float textColor_g = [json getFloat:@"textColor_g"]; @@ -224,9 +247,11 @@ -(void) create:(JsonObject*)json UIColor* placeHolderColor = [UIColor colorWithRed:placeHolderColor_r green:placeHolderColor_g blue:placeHolderColor_b alpha:placeHolderColor_a]; NSString* contentType = [json getString:@"contentType"]; + NSString* keyboardType = [json getString:@"keyboardType"]; NSString* alignment = [json getString:@"align"]; BOOL withDoneButton = [json getBool:@"withDoneButton"]; BOOL multiline = [json getBool:@"multiline"]; + NSString* contentTypeOverride = [json getString:@"iosContentTypeOverride"]; BOOL autoCorr = NO; BOOL password = NO; @@ -236,35 +261,49 @@ -(void) create:(JsonObject*)json { autoCorr = YES; } - else if ([contentType isEqualToString:@"IntegerNumber"]) + else if ([contentType isEqualToString:@"Password"]) { - keyType = UIKeyboardTypeNumberPad; + password = YES; } - else if ([contentType isEqualToString:@"DecimalNumber"]) + + // We don't need to look at the content type to determine the keyboard type, as Unity InputField will fill in the right type. + if ([keyboardType isEqualToString:@"ASCIICapable"]) + { + keyType = UIKeyboardTypeASCIICapable; + } + else if ([keyboardType isEqualToString:@"NumbersAndPunctuation"]) { - keyType = UIKeyboardTypeDecimalPad; + keyType = UIKeyboardTypeNumbersAndPunctuation; } - else if ([contentType isEqualToString:@"Alphanumeric"]) + else if ([keyboardType isEqualToString:@"URL"]) { - keyType = UIKeyboardTypeAlphabet; + keyType = UIKeyboardTypeURL; } - else if ([contentType isEqualToString:@"Name"]) + else if ([keyboardType isEqualToString:@"NumberPad"]) + { + keyType = UIKeyboardTypeNumberPad; + } + else if ([keyboardType isEqualToString:@"PhonePad"]) + { + keyType = UIKeyboardTypePhonePad; + } + else if ([keyboardType isEqualToString:@"NamePhonePad"]) { keyType = UIKeyboardTypeNamePhonePad; } - else if ([contentType isEqualToString:@"EmailAddress"]) + else if ([keyboardType isEqualToString:@"EmailAddress"]) { keyType = UIKeyboardTypeEmailAddress; } - else if ([contentType isEqualToString:@"Password"]) + else if ([keyboardType isEqualToString:@"Social"]) { - password = YES; + keyType = UIKeyboardTypeTwitter; } - else if ([contentType isEqualToString:@"Pin"]) + else if ([keyboardType isEqualToString:@"Search"]) { - keyType = UIKeyboardTypePhonePad; + keyType = UIKeyboardTypeWebSearch; } - + UIControlContentHorizontalAlignment halign = UIControlContentHorizontalAlignmentLeft; UIControlContentVerticalAlignment valign = UIControlContentVerticalAlignmentCenter; @@ -351,8 +390,25 @@ -(void) create:(JsonObject*)json else { uiFont = [UIFont systemFontOfSize:fontSize]; - } - + } + + UITextContentType overrideContentType = nil; + if (@available(iOS 12.0, *)) + { + if ([contentTypeOverride isEqualToString:@"Username"]) + { + overrideContentType = UITextContentTypeUsername; + } + else if ([contentTypeOverride isEqualToString:@"Password"]) + { + overrideContentType = UITextContentTypePassword; + } + else if ([contentTypeOverride isEqualToString:@"NewPassword"]) + { + overrideContentType = UITextContentTypeNewPassword; + } + } + if (multiline) { PlaceholderTextView* textView = [[PlaceholderTextView alloc] initWithFrame:CGRectMake(x, y, width, height)]; @@ -379,10 +435,14 @@ -(void) create:(JsonObject*)json [textView setSecureTextEntry:password]; if (keyboardDoneButtonView != nil) textView.inputAccessoryView = keyboardDoneButtonView; - - + /// Todo /// UITextView Alignment is not implemented + + if (overrideContentType != nil) + { + textView.textContentType = overrideContentType; + } editView = textView; } @@ -409,7 +469,12 @@ -(void) create:(JsonObject*)json [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; [textField setSecureTextEntry:password]; if (keyboardDoneButtonView != nil) textField.inputAccessoryView = keyboardDoneButtonView; - + + if (overrideContentType != nil) + { + textField.textContentType = overrideContentType; + } + editView = textField; } [viewPlugin addSubview:editView]; @@ -427,7 +492,7 @@ -(void) setText:(JsonObject*)json -(IBAction) doneClicked:(id)sender { - [self showKeyboard:false]; + [self hideKeyboard]; } -(int) getLineCount @@ -442,7 +507,6 @@ -(int) getLineCount return 0; } - -(void) remove { [[NSNotificationCenter defaultCenter] removeObserver:self]; @@ -482,15 +546,18 @@ -(bool) isFocused return editView.isFirstResponder; } --(void) showKeyboard:(bool)isShow +-(void) hideKeyboard { - [viewController.view endEditing:(isShow ? YES : NO)]; + [editView resignFirstResponder]; } + -(void) setVisible:(bool)isVisible { - editView.hidden = (isVisible ? NO : YES); + editView.hidden = !isVisible; } +#pragma mark - Common callbacks + -(void) onTextChange:(NSString*) text { JsonObject* jsonToUnity = [[JsonObject alloc] init]; @@ -500,6 +567,14 @@ -(void) onTextChange:(NSString*) text [self sendJsonToUnity:jsonToUnity]; } +-(void) onTextEditBegin +{ + JsonObject* jsonToUnity = [[JsonObject alloc] init]; + + [jsonToUnity setString:@"msg" value:MSG_TEXT_BEGIN_EDIT]; + [self sendJsonToUnity:jsonToUnity]; +} + -(void) onTextEditEnd:(NSString*) text { JsonObject* jsonToUnity = [[JsonObject alloc] init]; @@ -509,9 +584,11 @@ -(void) onTextEditEnd:(NSString*) text [self sendJsonToUnity:jsonToUnity]; } --(void) textViewDidChange:(UITextView *)textView +#pragma mark - UITextViewDelegate + +- (void)textViewDidBeginEditing:(UITextView *)textView { - [self onTextChange:textView.text]; + [self onTextEditBegin]; } -(void) textViewDidEndEditing:(UITextView *)textView @@ -519,6 +596,23 @@ -(void) textViewDidEndEditing:(UITextView *)textView [self onTextEditEnd:textView.text]; } +-(void) textViewDidChange:(UITextView *)textView +{ + [self onTextChange:textView.text]; +} + +#pragma mark - UITextFieldDelegate + +- (void)textFieldDidBeginEditing:(UITextField *)textField +{ + [self onTextEditBegin]; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField +{ + [self onTextEditEnd:textField.text]; +} + - (BOOL)textFieldShouldReturn:(UITextField *)textField { if (![editView isFirstResponder]) return YES; @@ -537,12 +631,14 @@ - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRang } NSUInteger newLength = [textField.text length] + [string length] - range.length; - if(characterLimit > 0) - return newLength <= characterLimit; + if([self maxLength] > 0) + return newLength <= [self maxLength]; else return YES; } +#pragma mark - Other targets + -(void) textFieldDidChange :(UITextField *)theTextField{ [self onTextChange:theTextField.text]; } @@ -554,13 +650,12 @@ -(void) keyboardWillShow:(NSNotification *)notification NSDictionary* keyboardInfo = [notification userInfo]; NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey]; rectKeyboardFrame = [keyboardFrameBegin CGRectValue]; - } -(void) keyboardWillHide:(NSNotification*)notification { - if (![editView isFirstResponder]) return; - + if (![editView isFirstResponder]) + return; } -(float) getKeyboardheight diff --git a/demo/Assets/Plugins/Android/AndroidManifest.xml.meta b/release/NativeEditPlugin/README.md.meta similarity index 61% rename from demo/Assets/Plugins/Android/AndroidManifest.xml.meta rename to release/NativeEditPlugin/README.md.meta index f622964..bcc9d70 100644 --- a/demo/Assets/Plugins/Android/AndroidManifest.xml.meta +++ b/release/NativeEditPlugin/README.md.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 -guid: 0c193a17dd00d4eafb043a79cc8e1323 +guid: 88c0a6a8da0ea4eb5841c115973dc132 TextScriptImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/release/NativeEditPlugin/demo/demo.cs b/release/NativeEditPlugin/Samples~/demo.cs similarity index 100% rename from release/NativeEditPlugin/demo/demo.cs rename to release/NativeEditPlugin/Samples~/demo.cs diff --git a/release/NativeEditPlugin/demo/demo.cs.meta b/release/NativeEditPlugin/Samples~/demo.cs.meta similarity index 100% rename from release/NativeEditPlugin/demo/demo.cs.meta rename to release/NativeEditPlugin/Samples~/demo.cs.meta diff --git a/release/NativeEditPlugin/demo/demo.unity b/release/NativeEditPlugin/Samples~/demo.unity similarity index 100% rename from release/NativeEditPlugin/demo/demo.unity rename to release/NativeEditPlugin/Samples~/demo.unity diff --git a/release/NativeEditPlugin/demo/demo.unity.meta b/release/NativeEditPlugin/Samples~/demo.unity.meta similarity index 100% rename from release/NativeEditPlugin/demo/demo.unity.meta rename to release/NativeEditPlugin/Samples~/demo.unity.meta diff --git a/release/NativeEditPlugin/demo.meta b/release/NativeEditPlugin/demo.meta deleted file mode 100644 index e0c6014..0000000 --- a/release/NativeEditPlugin/demo.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 9afd885945d234ee287edaf3288ca395 -folderAsset: yes -timeCreated: 1430955862 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/release/NativeEditPlugin/package.json b/release/NativeEditPlugin/package.json new file mode 100644 index 0000000..7c517df --- /dev/null +++ b/release/NativeEditPlugin/package.json @@ -0,0 +1,16 @@ +{ + "name": "com.yousician.nativeedit", + "displayName": "Native Edit", + "version": "1.0.0", + "unity": "2019.4", + "description": "Unity Native Input Plugin for both iOS and Android (Unity UI InputField compatible). This means you don't need a separate 'Unity' Input box and you can use all native text functions such as Select, Copy and Paste.", + "type": "library", + "samples": [ + { + + "displayName": "Sample", + "description": "", + "path": "Samples~" + } + ] +} \ No newline at end of file diff --git a/release/NativeEditPlugin/package.json.meta b/release/NativeEditPlugin/package.json.meta new file mode 100644 index 0000000..421748d --- /dev/null +++ b/release/NativeEditPlugin/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9e4e7cb3fb4064579a7d03b455e0016e +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/release/NativeEditPlugin/scripts/MaskOptions.cs b/release/NativeEditPlugin/scripts/MaskOptions.cs new file mode 100644 index 0000000..1320e85 --- /dev/null +++ b/release/NativeEditPlugin/scripts/MaskOptions.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; + +/// +/// Please see for more information about +/// the masks. +/// +public class MaskOptions +{ + /// + /// Strategy to calculate affinity value. For more information, + /// see + /// + /// + /// Integer value of this enum will be sent to the native side where it's + /// converted from int to related native enum value again. + /// On Android, EditBox.java does this conversion. + /// + public enum AffinityCalculationStrategy + { + Prefix = 0, + WholeString = 1, + Capacity = 2, + ExtractedValueCapacity = 3, + } + + public string PrimaryMask { get; } + public IReadOnlyList AffineMasks { get; } + public AffinityCalculationStrategy AffinityStrategy { get; } + public bool UseCustomPlaceholder { get; } + public string CustomPlaceholder { get; } + public string ExtraCharactersForDigits { get; } + + /// + /// Creates new mask options. + /// + /// Primary mask to use. + /// Affine masks to select depending on the given affinity strategy. + /// Strategy to follow while selecting an affine mask. + /// Will be used to overwrite the placeholder of given mask. + /// Placeholder to show instead of the default placeholder of given mask. + /// Can be used to set an extra accepted character set when + /// the content type is numbers only. + /// + /// If the content type is numbers only and there's a separation character in the mask (e.g space, dash etc.) + /// should be set to accept these characters. Otherwise an exception + /// will be thrown. + /// + public MaskOptions( + string primaryMask, + IReadOnlyList affineMasks = null, + AffinityCalculationStrategy affinityStrategy = AffinityCalculationStrategy.Prefix, + bool useCustomPlaceholder = false, + string customPlaceholder = null, + string extraCharactersForDigits = null) + { + this.PrimaryMask = primaryMask; + this.AffineMasks = affineMasks; + this.AffinityStrategy = affinityStrategy; + this.UseCustomPlaceholder = useCustomPlaceholder; + this.CustomPlaceholder = customPlaceholder; + this.ExtraCharactersForDigits = extraCharactersForDigits; + } +} \ No newline at end of file diff --git a/release/NativeEditPlugin/scripts/MaskOptions.cs.meta b/release/NativeEditPlugin/scripts/MaskOptions.cs.meta new file mode 100644 index 0000000..3754a23 --- /dev/null +++ b/release/NativeEditPlugin/scripts/MaskOptions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5fb2f4de92464e218b1fedca464eb9c3 +timeCreated: 1565179309 \ No newline at end of file diff --git a/release/NativeEditPlugin/scripts/MaskedNativeEditBox.cs b/release/NativeEditPlugin/scripts/MaskedNativeEditBox.cs new file mode 100644 index 0000000..f08f43d --- /dev/null +++ b/release/NativeEditPlugin/scripts/MaskedNativeEditBox.cs @@ -0,0 +1,86 @@ +using System; +using UnityEngine.UI; + +/// +/// Formats the value depending on the given mask options. +/// +/// +/// Works only on Android, iOS is not _yet_ supported. +/// +public class MaskedNativeEditBox : NativeEditBox +{ + private const string ApplyMaskKey = "applyMask"; + private const string PrimaryMaskKey = "primaryMask"; + private const string AffineMasksKey = "affineMasks"; + private const string AffinityStrategyKey = "affinityStrategy"; + private const string UseCustomPlaceholderKey = "useCustomPlaceholder"; + private const string CustomPlaceholderKey = "customPlaceholder"; + private const string ExtraCharactersForDigitsKey = "extraCharactersForDigits"; + + public MaskOptions MaskOptions { get; private set; } + public string ExtractedText { get; private set; } + + /// + /// Event to call whenever the value changes. Will be called with the extracted value. + /// To get formatted values, listen event. + /// + public event Action OnValueChanged; + + /// + /// Event to call when the editing has ended. Will be called with the extracted value. + /// To get formatted values, listen event. + /// + public event Action OnEndEdit; + + private bool shouldApplyMask = true; + + /// + /// Please see for more information about + /// the masks. + /// + public void SetMask(MaskOptions maskOptions) + { + this.MaskOptions = maskOptions; + } + + public void ApplyMask(bool to) + { + this.shouldApplyMask = to; + } + + protected override void AppendExtraFieldsForCreation(JsonObject jsonObject) + { + if (this.MaskOptions == null) + { + jsonObject[ApplyMaskKey] = false; + return; + } + + jsonObject[ApplyMaskKey] = this.shouldApplyMask; + jsonObject[PrimaryMaskKey] = this.MaskOptions.PrimaryMask; + jsonObject[AffineMasksKey] = this.MaskOptions.AffineMasks; + jsonObject[AffinityStrategyKey] = (int)this.MaskOptions.AffinityStrategy; + jsonObject[UseCustomPlaceholderKey] = this.MaskOptions.UseCustomPlaceholder; + jsonObject[CustomPlaceholderKey] = this.MaskOptions.CustomPlaceholder; + jsonObject[ExtraCharactersForDigitsKey] = this.MaskOptions.ExtraCharactersForDigits; + } + + protected override void HandlePluginMessage(JsonObject jsonMsg) + { + base.HandlePluginMessage(jsonMsg); + + var msg = jsonMsg.GetString("msg"); + if (msg.Equals(MSG_TEXT_CHANGE)) + { + this.ExtractedText = jsonMsg.GetString("extractedText"); + if (this.OnValueChanged != null) + this.OnValueChanged(this.ExtractedText); + } + else if (msg.Equals(MSG_TEXT_END_EDIT)) + { + this.ExtractedText = jsonMsg.GetString("extractedText"); + if (this.OnEndEdit != null) + this.OnEndEdit(this.ExtractedText); + } + } +} \ No newline at end of file diff --git a/release/NativeEditPlugin/scripts/MaskedNativeEditBox.cs.meta b/release/NativeEditPlugin/scripts/MaskedNativeEditBox.cs.meta new file mode 100644 index 0000000..32dc1b8 --- /dev/null +++ b/release/NativeEditPlugin/scripts/MaskedNativeEditBox.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e6e7a607a56e48af92ca597e1d8c068d +timeCreated: 1565162931 \ No newline at end of file diff --git a/release/NativeEditPlugin/scripts/MiniJSON.cs b/release/NativeEditPlugin/scripts/MiniJSON.cs index ec7720e..ae3fcd9 100644 --- a/release/NativeEditPlugin/scripts/MiniJSON.cs +++ b/release/NativeEditPlugin/scripts/MiniJSON.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Text; @@ -527,18 +528,22 @@ void SerializeString(string str) { } void SerializeOther(object value) { - if (value is float - || value is int - || value is uint + if (value is int || value is long - || value is double || value is sbyte - || value is byte - || value is short - || value is ushort - || value is ulong - || value is decimal) { - builder.Append(value.ToString()); + || value is short) { + builder.Append(Convert.ToInt64(value).ToString(CultureInfo.InvariantCulture)); + } + else if (value is uint + || value is byte + || value is ushort + || value is ulong) { + builder.Append(Convert.ToUInt64(value).ToString(CultureInfo.InvariantCulture)); + } + else if (value is float + || value is double + || value is decimal) { + builder.Append(Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture)); } else { SerializeString(value.ToString()); diff --git a/release/NativeEditPlugin/scripts/NativeEdit.asmdef b/release/NativeEditPlugin/scripts/NativeEdit.asmdef new file mode 100644 index 0000000..fa2530f --- /dev/null +++ b/release/NativeEditPlugin/scripts/NativeEdit.asmdef @@ -0,0 +1,14 @@ +{ + "name": "NativeEdit", + "references": [ + "Unity.TextMeshPro" + ], + "optionalUnityReferences": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [] +} \ No newline at end of file diff --git a/release/NativeEditPlugin/scripts/NativeEdit.asmdef.meta b/release/NativeEditPlugin/scripts/NativeEdit.asmdef.meta new file mode 100644 index 0000000..97fc544 --- /dev/null +++ b/release/NativeEditPlugin/scripts/NativeEdit.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 56ffed08b69974d02b19c1dcf7e3b995 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/release/NativeEditPlugin/scripts/NativeEditBox.cs b/release/NativeEditPlugin/scripts/NativeEditBox.cs index 2ed4364..6c89d7d 100644 --- a/release/NativeEditPlugin/scripts/NativeEditBox.cs +++ b/release/NativeEditPlugin/scripts/NativeEditBox.cs @@ -35,6 +35,7 @@ using UnityEngine.Events; using System; using System.Collections; +using TMPro; using UnityEngine.UI; [RequireComponent(typeof(InputField))] @@ -46,12 +47,14 @@ private struct EditBoxConfig public Color textColor; public Color backColor; public string contentType; + public string keyboardType; public string font; public float fontSize; public string align; public string placeHolder; public int characterLimit; public Color placeHolderColor; + public IosContentTypeOverride iosContentTypeOverride; } public enum ReturnKeyType @@ -60,20 +63,31 @@ public enum ReturnKeyType Next, Done } - + + // The name of these enum values has to exactly match the string check in iOS native code + private enum IosContentTypeOverride + { + None, + Username, + Password, + NewPassword, + } + public bool withDoneButton = true; public ReturnKeyType returnKeyType; + [SerializeField] private IosContentTypeOverride iosContentTypeOverride; public event Action returnPressed; public bool updateRectEveryFrame; public bool useInputFieldFont; public UnityEngine.Events.UnityEvent OnReturnPressed; + public UnityEngine.Events.UnityEvent OnBeginEditing; private bool bNativeEditCreated = false; private InputField objUnityInput; - private Text objUnityText; + private Text objUnityText => objUnityInput.textComponent; private bool focusOnCreate; private bool visibleOnCreate = true; @@ -81,24 +95,47 @@ public enum ReturnKeyType private const string MSG_REMOVE = "RemoveEdit"; private const string MSG_SET_TEXT = "SetText"; private const string MSG_SET_RECT = "SetRect"; + private const string MSG_SET_TEXTSIZE = "SetTextSize"; private const string MSG_SET_FOCUS = "SetFocus"; private const string MSG_SET_VISIBLE = "SetVisible"; - private const string MSG_TEXT_CHANGE = "TextChange"; - private const string MSG_TEXT_END_EDIT = "TextEndEdit"; + protected const string MSG_TEXT_CHANGE = "TextChange"; + private const string MSG_TEXT_BEGIN_EDIT = "TextBeginEdit"; + protected const string MSG_TEXT_END_EDIT = "TextEndEdit"; // to fix bug Some keys 'back' & 'enter' are eaten by unity and never arrive at plugin private const string MSG_ANDROID_KEY_DOWN = "AndroidKeyDown"; private const string MSG_RETURN_PRESSED = "ReturnPressed"; private const string MSG_GET_TEXT = "GetText"; - public InputField InputField { get { return objUnityInput; } } + public InputField InputField + { + get + { + if (this.objUnityInput != null) + { + return this.objUnityInput; + } + + this.objUnityInput = this.GetComponent(); + if (this.objUnityInput == null) + { + Debug.LogErrorFormat("No InputField found {0} NativeEditBox Error", this.name); + throw new MissingComponentException(); + } + + return this.objUnityInput; + } + } + public bool Visible { get; private set; } + protected virtual void AppendExtraFieldsForCreation(JsonObject jsonObject) { } + public string text { - get { return objUnityInput.text; } + get { return InputField.text; } set { - objUnityInput.text = value; + InputField.text = value; SetTextNative(value); } } @@ -135,18 +172,6 @@ public static Rect GetScreenRectFromRectTransform(RectTransform rectTransform) private EditBoxConfig mConfig; - private void Awake() - { - objUnityInput = this.GetComponent(); - if (objUnityInput == null) - { - Debug.LogErrorFormat("No InputField found {0} NativeEditBox Error", this.name); - throw new MissingComponentException(); - } - - objUnityText = objUnityInput.textComponent; - } - // Use this for initialization protected override void Start() { @@ -177,14 +202,6 @@ protected override void OnDestroy() base.OnDestroy(); } - private void OnApplicationFocus(bool hasFocus) - { - if (!bNativeEditCreated || !this.Visible) - return; - - this.SetVisible(hasFocus); - } - private IEnumerator InitializeOnNextFrame() { yield return null; @@ -192,11 +209,24 @@ private IEnumerator InitializeOnNextFrame() this.PrepareNativeEdit(); #if (UNITY_IPHONE || UNITY_ANDROID) && !UNITY_EDITOR this.CreateNativeEdit(); - this.SetTextNative(this.objUnityText.text); + this.SetTextNative(this.InputField.text); + + this.InputField.placeholder.gameObject.SetActive(false); + this.objUnityText.enabled = false; + this.InputField.enabled = false; - objUnityInput.placeholder.gameObject.SetActive(false); - objUnityText.enabled = false; - objUnityInput.enabled = false; + // For iOS autofill to work correctly, all input fields expected to be autofilled, need to exist before we set + // the native focus. Assuming all related input fields are created simultaneously, they will all be + // initialized after one frame (see above). In this case, waiting for one more frame should ensure they all + // exist before we set the focus. In more complex cases, the caller may need to further delay setting focus, + // until all related input fields are guaranteed to exist. + + yield return null; + + if (this.focusOnCreate) + { + this.SetFocus(true); + } #endif } @@ -206,7 +236,7 @@ private void Update() this.UpdateForceKeyeventForAndroid(); #endif - if (updateRectEveryFrame && this.objUnityInput != null && bNativeEditCreated) + if (updateRectEveryFrame && this.InputField != null && bNativeEditCreated) { SetRectNative(this.objUnityText.rectTransform); } @@ -214,14 +244,23 @@ private void Update() private void PrepareNativeEdit() { - var placeHolder = objUnityInput.placeholder.GetComponent(); + var tmpPlaceholder = this.InputField.placeholder.GetComponent(); + var placeHolder = this.InputField.placeholder.GetComponent(); if (useInputFieldFont) mConfig.font = objUnityText.font.fontNames.Length > 0 ? objUnityText.font.fontNames[0] : "Arial"; - mConfig.placeHolder = placeHolder.text; - mConfig.placeHolderColor = placeHolder.color; - mConfig.characterLimit = objUnityInput.characterLimit; + if (tmpPlaceholder != null) + { + mConfig.placeHolder = tmpPlaceholder.text; + mConfig.placeHolderColor = tmpPlaceholder.color; + } + else + { + mConfig.placeHolder = placeHolder.text; + mConfig.placeHolderColor = placeHolder.color; + } + mConfig.characterLimit = this.InputField.characterLimit; Rect rectScreen = GetScreenRectFromRectTransform(this.objUnityText.rectTransform); float fHeightRatio = rectScreen.height / objUnityText.rectTransform.rect.height; @@ -229,50 +268,40 @@ private void PrepareNativeEdit() mConfig.textColor = objUnityText.color; mConfig.align = objUnityText.alignment.ToString(); - mConfig.contentType = objUnityInput.contentType.ToString(); + mConfig.contentType = this.InputField.contentType.ToString(); + mConfig.keyboardType = this.InputField.keyboardType.ToString(); mConfig.backColor = new Color(1.0f, 1.0f, 1.0f, 0.0f); - mConfig.multiline = (objUnityInput.lineType == InputField.LineType.SingleLine) ? false : true; - } - - private void onTextChange(string newText) - { - // Avoid firing a delayed onValueChanged event if the text was changed from Unity with the text property in this - // class. - if (newText == this.objUnityInput.text) - return; - - this.objUnityInput.text = newText; - if (this.objUnityInput.onValueChanged != null) - this.objUnityInput.onValueChanged.Invoke(newText); - } - - private void onTextEditEnd(string newText) - { - this.objUnityInput.text = newText; - if (this.objUnityInput.onEndEdit != null) - this.objUnityInput.onEndEdit.Invoke(newText); + mConfig.multiline = this.InputField.lineType != InputField.LineType.SingleLine; + this.mConfig.iosContentTypeOverride = this.iosContentTypeOverride; } public override void OnPluginMsgDirect(JsonObject jsonMsg) { - PluginMsgHandler.getInst().StartCoroutine(PluginsMessageRoutine(jsonMsg)); + PluginMsgHandler.getInst().StartCoroutine(this.HandlePluginMessageOnNextFrame(jsonMsg)); } - private IEnumerator PluginsMessageRoutine(JsonObject jsonMsg) + private IEnumerator HandlePluginMessageOnNextFrame(JsonObject jsonMsg) { // this is to avoid a deadlock for more info when trying to get data from two separate native plugins and handling them in Unity yield return null; + this.HandlePluginMessage(jsonMsg); + } + + protected virtual void HandlePluginMessage(JsonObject jsonMsg) + { + // By the time this is called the component might be destroyed + if (this == null) + return; string msg = jsonMsg.GetString("msg"); - if (msg.Equals(MSG_TEXT_CHANGE)) + if (msg.Equals(MSG_TEXT_BEGIN_EDIT)) { - string text = jsonMsg.GetString("text"); - this.onTextChange(text); + if (this.OnBeginEditing != null) + this.OnBeginEditing.Invoke(); } - else if (msg.Equals(MSG_TEXT_END_EDIT)) + else if (msg.Equals(MSG_TEXT_CHANGE) || msg.Equals(MSG_TEXT_END_EDIT)) { - string text = jsonMsg.GetString("text"); - this.onTextEditEnd(text); + this.InputField.text = jsonMsg.GetString("text"); } else if (msg.Equals(MSG_RETURN_PRESSED)) { @@ -319,6 +348,7 @@ private void CreateNativeEdit() jsonMsg["font"] = mConfig.font; jsonMsg["fontSize"] = mConfig.fontSize; jsonMsg["contentType"] = mConfig.contentType; + jsonMsg["keyboardType"] = mConfig.keyboardType; jsonMsg["align"] = mConfig.align; jsonMsg["withDoneButton"] = this.withDoneButton; jsonMsg["placeHolder"] = mConfig.placeHolder; @@ -327,6 +357,8 @@ private void CreateNativeEdit() jsonMsg["placeHolderColor_b"] = mConfig.placeHolderColor.b; jsonMsg["placeHolderColor_a"] = mConfig.placeHolderColor.a; jsonMsg["multiline"] = mConfig.multiline; + jsonMsg["iosContentTypeOverride"] = this.mConfig.iosContentTypeOverride.ToString(); + this.AppendExtraFieldsForCreation(jsonMsg); switch (returnKeyType) { @@ -348,9 +380,6 @@ private void CreateNativeEdit() if (!visibleOnCreate) SetVisible(false); - - if (focusOnCreate) - SetFocus(true); } private void SetTextNative(string newText) @@ -373,18 +402,26 @@ private void RemoveNative() public void SetRectNative(RectTransform rectTrans) { - Rect rectScreen = GetScreenRectFromRectTransform(rectTrans); + var rectScreen = GetScreenRectFromRectTransform(rectTrans); - JsonObject jsonMsg = new JsonObject(); - + var jsonMsg = new JsonObject(); jsonMsg["msg"] = MSG_SET_RECT; - jsonMsg["x"] = rectScreen.x / Screen.width; jsonMsg["y"] = rectScreen.y / Screen.height; jsonMsg["width"] = rectScreen.width / Screen.width; jsonMsg["height"] = rectScreen.height / Screen.height; - this.SendPluginMsg(jsonMsg); + + var fontRectHeightRatio = rectScreen.height / this.objUnityText.rectTransform.rect.height; + var fontSize = this.objUnityText.fontSize * fontRectHeightRatio; + if (Math.Abs(this.mConfig.fontSize - fontSize) > 0.1f) + { + var sizeMsg = new JsonObject(); + sizeMsg["msg"] = MSG_SET_TEXTSIZE; + sizeMsg["fontSize"] = fontSize; + this.SendPluginMsg(sizeMsg); + this.mConfig.fontSize = fontSize; + } } public void SetFocus(bool bFocus) @@ -406,9 +443,9 @@ public void SetFocus(bool bFocus) if (gameObject.activeInHierarchy) { if (bFocus) - objUnityInput.ActivateInputField(); + this.InputField.ActivateInputField(); else - objUnityInput.DeactivateInputField(); + this.InputField.DeactivateInputField(); } else focusOnCreate = bFocus; diff --git a/release/NativeEditPlugin/scripts/PluginMsgHandler.cs b/release/NativeEditPlugin/scripts/PluginMsgHandler.cs index 46cdc79..3544704 100644 --- a/release/NativeEditPlugin/scripts/PluginMsgHandler.cs +++ b/release/NativeEditPlugin/scripts/PluginMsgHandler.cs @@ -27,6 +27,7 @@ using System.Runtime.InteropServices; using System; using System.IO; +using System.Reflection; using AOT; public class PluginMsgHandler : MonoBehaviour { @@ -81,7 +82,13 @@ void Awake() return; } instance = gameObject; - DontDestroyOnLoad(gameObject); + + // If instantiated in a non-root object (e.g. Zenject ProjectContext subcontainer), + // Don't use DontDestroyOnLoad + if (gameObject.transform.parent == null) + { + DontDestroyOnLoad(gameObject); + } int tempRandom = (int) UnityEngine.Random.Range(0, 10000.0f); this.name = DEFAULT_NAME + tempRandom.ToString(); @@ -99,7 +106,6 @@ void Awake() void OnDestroy() { - FileLog("Application closed"); if (fileWriter != null) fileWriter.Close(); fileWriter = null; this.FinalizeHandler(); @@ -146,6 +152,7 @@ public PluginMsgReceiver GetReceiver(int nSenderId) return m_dictReceiver[nSenderId]; } + [Obfuscation(Exclude = true)] private void OnMsgFromPlugin(string jsonPluginMsg) { if (jsonPluginMsg == null) return; diff --git a/src/androidProj/.gitignore b/src/androidProj/.gitignore deleted file mode 100644 index c858a88..0000000 --- a/src/androidProj/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -# Built application files -*.apk -*.ap_ - -# Files for the Dalvik VM -*.dex - -# Java class files -*.class - -# Generated files -bin/ -gen/ -out/ - -# Gradle files -.gradle -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log - -# Android Studio Navigation editor temp files -.navigation/ - -# Android Studio captures folder -captures/ - -# Intellij -*.iml - -# Keystore files -*.jks - -# from android studio -/.idea/workspace.xml -/.idea/libraries -.DS_Store - diff --git a/src/androidProj/.idea/compiler.xml b/src/androidProj/.idea/compiler.xml deleted file mode 100644 index 96cc43e..0000000 --- a/src/androidProj/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/androidProj/.idea/copyright/profiles_settings.xml b/src/androidProj/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/src/androidProj/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/androidProj/.idea/gradle.xml b/src/androidProj/.idea/gradle.xml deleted file mode 100644 index e0c8136..0000000 --- a/src/androidProj/.idea/gradle.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/androidProj/.idea/misc.xml b/src/androidProj/.idea/misc.xml deleted file mode 100644 index 279cf59..0000000 --- a/src/androidProj/.idea/misc.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/androidProj/.idea/modules.xml b/src/androidProj/.idea/modules.xml deleted file mode 100644 index 1c57583..0000000 --- a/src/androidProj/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/androidProj/build.gradle b/src/androidProj/build.gradle deleted file mode 100644 index d3ff69d..0000000 --- a/src/androidProj/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:1.1.0' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - jcenter() - } -} diff --git a/src/androidProj/gradle.properties b/src/androidProj/gradle.properties deleted file mode 100644 index 1d3591c..0000000 --- a/src/androidProj/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file diff --git a/src/androidProj/gradle/wrapper/gradle-wrapper.jar b/src/androidProj/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8c0fb64..0000000 Binary files a/src/androidProj/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/src/androidProj/gradle/wrapper/gradle-wrapper.properties b/src/androidProj/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 0c71e76..0000000 --- a/src/androidProj/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Apr 10 15:27:10 PDT 2013 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/src/androidProj/gradlew b/src/androidProj/gradlew deleted file mode 100755 index 91a7e26..0000000 --- a/src/androidProj/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/src/androidProj/gradlew.bat b/src/androidProj/gradlew.bat deleted file mode 100644 index aec9973..0000000 --- a/src/androidProj/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/src/androidProj/nativeeditplugin/.gitignore b/src/androidProj/nativeeditplugin/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/src/androidProj/nativeeditplugin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/src/androidProj/nativeeditplugin/build.gradle b/src/androidProj/nativeeditplugin/build.gradle deleted file mode 100644 index fa59dfa..0000000 --- a/src/androidProj/nativeeditplugin/build.gradle +++ /dev/null @@ -1,43 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" - - defaultConfig { - minSdkVersion 11 - targetSdkVersion 25 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -repositories { - maven { - url "https://maven.google.com" - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:25.1.0' -} - -task clearJar(type: Delete) { - delete 'build/outputs/nativeeditplugin.jar' -} - -task makeJar(type: Copy) { - from('build/intermediates/bundles/release/') - into('build/outputs/') - include('classes.jar') - rename ('classes.jar', 'nativeeditplugin.jar') -} - -makeJar.dependsOn(clearJar, build) \ No newline at end of file diff --git a/src/androidProj/nativeeditplugin/libs/classes.jar b/src/androidProj/nativeeditplugin/libs/classes.jar deleted file mode 100644 index bacd980..0000000 Binary files a/src/androidProj/nativeeditplugin/libs/classes.jar and /dev/null differ diff --git a/src/androidProj/nativeeditplugin/proguard-rules.pro b/src/androidProj/nativeeditplugin/proguard-rules.pro deleted file mode 100644 index e82f354..0000000 --- a/src/androidProj/nativeeditplugin/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/kyungminbang/Library/Android/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/src/androidProj/nativeeditplugin/src/androidTest/java/com/bkmin/android/ApplicationTest.java b/src/androidProj/nativeeditplugin/src/androidTest/java/com/bkmin/android/ApplicationTest.java deleted file mode 100644 index 336c6b6..0000000 --- a/src/androidProj/nativeeditplugin/src/androidTest/java/com/bkmin/android/ApplicationTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bkmin.android; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} \ No newline at end of file diff --git a/src/androidProj/nativeeditplugin/src/main/AndroidManifest.xml b/src/androidProj/nativeeditplugin/src/main/AndroidManifest.xml deleted file mode 100644 index 9889667..0000000 --- a/src/androidProj/nativeeditplugin/src/main/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/UnityPlayerNotOnTop.java b/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/UnityPlayerNotOnTop.java deleted file mode 100644 index 7beea89..0000000 --- a/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/UnityPlayerNotOnTop.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.bkmin.android; - -import com.unity3d.player.*; -import android.content.ContextWrapper; -import android.view.SurfaceView; -import android.view.View; -import android.util.Log; - -public class UnityPlayerNotOnTop - extends UnityPlayer -{ - public UnityPlayerNotOnTop(ContextWrapper contextwrapper) - { - super(contextwrapper); - } - - public void addView(View child) - { - if (child instanceof SurfaceView) { - ((SurfaceView)child).setZOrderOnTop(false); - } - super.addView(child); - } -} \ No newline at end of file diff --git a/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/UnityPlayerNotOnTopActivity.java b/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/UnityPlayerNotOnTopActivity.java deleted file mode 100644 index a2570e9..0000000 --- a/src/androidProj/nativeeditplugin/src/main/java/com/bkmin/android/UnityPlayerNotOnTopActivity.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.bkmin.android; - -import com.unity3d.player.*; -import android.os.Bundle; -import android.util.Log; - -public class UnityPlayerNotOnTopActivity - extends UnityPlayerActivity -{ - @Override - public void onCreate(Bundle bundle) - { - requestWindowFeature(1); - super.onCreate(bundle); - getWindow().setFormat(2); - mUnityPlayer = new UnityPlayerNotOnTop(this); - setContentView(mUnityPlayer); - mUnityPlayer.requestFocus(); - } -} \ No newline at end of file diff --git a/src/androidProj/nativeeditplugin/src/main/res/values/strings.xml b/src/androidProj/nativeeditplugin/src/main/res/values/strings.xml deleted file mode 100644 index 4da4064..0000000 --- a/src/androidProj/nativeeditplugin/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - nativeeditplugin - diff --git a/src/androidProj/settings.gradle b/src/androidProj/settings.gradle deleted file mode 100644 index fd94c52..0000000 --- a/src/androidProj/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':nativeeditplugin'