Skip to content

Commit

Permalink
Merge pull request #13 from kou-yeung/feature/#12
Browse files Browse the repository at this point in the history
Keep Selection
  • Loading branch information
kou-yeung authored May 23, 2019
2 parents 77f2723 + ffa1235 commit 5d2a8ef
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 18 deletions.
60 changes: 42 additions & 18 deletions Assets/WebGLSupport/WebGLInput/WebGLInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System;
using AOT;
using System.Runtime.InteropServices; // for DllImport
using System.Collections;

namespace WebGLSupport
{
Expand Down Expand Up @@ -59,6 +60,7 @@ class WebGLInputPlugin
[DllImport("__Internal")]
public static extern void WebGLInputDelete(int id);
#else

public static int WebGLInputCreate(int x, int y, int width, int height, int fontsize, string text, bool isMultiLine, bool isPassword) { return 0; }
public static void WebGLInputEnterSubmit(int id, bool flag) { }
public static void WebGLInputTab(int id, Action<int, int> cb) { }
Expand All @@ -79,10 +81,11 @@ public static void WebGLInputDelete(int id) { }

public class WebGLInput : MonoBehaviour, IComparable<WebGLInput>
{
static Dictionary<int, IInputField> instances = new Dictionary<int, IInputField>();
static Dictionary<int, WebGLInput> instances = new Dictionary<int, WebGLInput>();

int id = -1;
IInputField input;
bool blueBlock = false;

private IInputField Setup()
{
Expand Down Expand Up @@ -116,7 +119,7 @@ public void OnSelect(/*BaseEventData eventData*/)
var y = (int)(Screen.height - (rect.y));
id = WebGLInputPlugin.WebGLInputCreate(x, y, (int)rect.width, (int)1, input.fontSize, input.text, input.lineType != LineType.SingleLine, isPassword);

instances[id] = input;
instances[id] = this;
WebGLInputPlugin.WebGLInputEnterSubmit(id, input.lineType != LineType.MultiLineNewline);
WebGLInputPlugin.WebGLInputOnFocus(id, OnFocus);
WebGLInputPlugin.WebGLInputOnBlur(id, OnBlur);
Expand All @@ -126,6 +129,13 @@ public void OnSelect(/*BaseEventData eventData*/)
// default value : https://www.w3schools.com/tags/att_input_maxlength.asp
WebGLInputPlugin.WebGLInputMaxLength(id, (input.characterLimit > 0) ? input.characterLimit : 524288);
WebGLInputPlugin.WebGLInputFocus(id);

WebGLWindow.OnBlurEvent += OnWindowBlur;
}

void OnWindowBlur()
{
blueBlock = true;
}

/// <summary>
Expand Down Expand Up @@ -161,6 +171,14 @@ Rect GetScreenCoordinates(RectTransform uiElement)
return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
}

void DeactivateInputField()
{
WebGLInputPlugin.WebGLInputDelete(id);
input.DeactivateInputField();
instances.Remove(id);
WebGLWindow.OnBlurEvent -= OnWindowBlur;
}

[MonoPInvokeCallback(typeof(Action<int>))]
static void OnFocus(int id)
{
Expand All @@ -172,43 +190,50 @@ static void OnFocus(int id)
[MonoPInvokeCallback(typeof(Action<int>))]
static void OnBlur(int id)
{
WebGLInputPlugin.WebGLInputDelete(id);
instances[id].DeactivateInputField();
instances.Remove(id);
#if UNITY_WEBGL && !UNITY_EDITOR
UnityEngine.WebGLInput.captureAllKeyboardInput = true;
#endif
instances[id].StartCoroutine(Blue(id));
}
static IEnumerator Blue(int id)
{
yield return null;
var block = instances[id].blueBlock; // get blue block state
instances[id].blueBlock = false; // reset instalce block state
if (block) yield break; // if block. break it!!

instances[id].DeactivateInputField();
}

[MonoPInvokeCallback(typeof(Action<int, string>))]
static void OnValueChange(int id, string value)
{
if (!instances.ContainsKey(id)) return;

var input = instances[id];
var index = input.caretPosition;
input.text = value;
var instance = instances[id];
var index = instance.input.caretPosition;
instance.input.text = value;

// InputField.ContentType.Name が Name の場合、先頭文字が強制的大文字になるため小文字にして比べる
if (input.contentType == ContentType.Name)
if (instance.input.contentType == ContentType.Name)
{
if (string.Compare(input.text, value, true) == 0)
if (string.Compare(instance.input.text, value, true) == 0)
{
value = input.text;
value = instance.input.text;
}
}

// InputField の ContentType による整形したテキストを HTML の input に再設定します
if (value != input.text)
if (value != instance.input.text)
{
WebGLInputPlugin.WebGLInputText(id, input.text);
WebGLInputPlugin.WebGLInputText(id, instance.input.text);
WebGLInputPlugin.WebGLInputSetSelectionRange(id, index, index);
}
}
[MonoPInvokeCallback(typeof(Action<int, string>))]
static void OnEditEnd(int id, string value)
{
instances[id].text = value;
instances[id].input.text = value;
}
[MonoPInvokeCallback(typeof(Action<int, int>))]
static void OnTab(int id, int value)
Expand Down Expand Up @@ -263,10 +288,9 @@ public int CompareTo(WebGLInput other)
/// to manage tab focus
/// base on scene position
/// </summary>
public static class WebGLInputTabFocus
static class WebGLInputTabFocus
{
static List<WebGLInput> inputs = new List<WebGLInput>();
static int current = 0;

public static void Add(WebGLInput input)
{
Expand All @@ -279,10 +303,10 @@ public static void Remove(WebGLInput input)
inputs.Remove(input);
}

public static void OnTab(IInputField input, int value)
public static void OnTab(WebGLInput input, int value)
{
if (inputs.Count <= 1) return;
var index = inputs.FindIndex(v => v.input == input);
var index = inputs.IndexOf(input);
index += value;
if (index < 0) index = inputs.Count - 1;
else if (index >= inputs.Count) index = 0;
Expand Down
8 changes: 8 additions & 0 deletions Assets/WebGLSupport/WebGLWindow.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 57 additions & 0 deletions Assets/WebGLSupport/WebGLWindow/WebGLWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using AOT;
using System.Runtime.InteropServices; // for DllImport
using UnityEngine;

namespace WebGLSupport
{
static class WebGLWindowPlugin
{
#if UNITY_WEBGL && !UNITY_EDITOR
[DllImport("__Internal")]
public static extern void WebGLWindowOnFocus(Action cb);

[DllImport("__Internal")]
public static extern void WebGLWindowOnBlur(Action cb);

#else
public static void WebGLWindowOnFocus(Action cb) { }
public static void WebGLWindowOnBlur(Action cb) { }
#endif

}

public static class WebGLWindow
{
public static bool Focus { get; private set; }
public static event Action OnFocusEvent = () => { };
public static event Action OnBlurEvent = () => { };

static void Init()
{
Focus = true;
WebGLWindowPlugin.WebGLWindowOnFocus(OnWindowFocus);
WebGLWindowPlugin.WebGLWindowOnBlur(OnWindowBlur);
}

[MonoPInvokeCallback(typeof(Action))]
static void OnWindowFocus()
{
Focus = true;
OnFocusEvent();
}

[MonoPInvokeCallback(typeof(Action))]
static void OnWindowBlur()
{
Focus = false;
OnBlurEvent();
}

[RuntimeInitializeOnLoadMethod]
static void RuntimeInitializeOnLoadMethod()
{
Init();
}
}
}
11 changes: 11 additions & 0 deletions Assets/WebGLSupport/WebGLWindow/WebGLWindow.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions Assets/WebGLSupport/WebGLWindow/WebGLWindow.jslib
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var WebGLWindow = {
WebGLWindowOnFocus: function (cb) {
window.addEventListener('focus', function () {
Runtime.dynCall("v", cb, []);
});
},
WebGLWindowOnBlur: function (cb) {
window.addEventListener('blur', function () {
Runtime.dynCall("v", cb, []);
});
},
}

mergeInto(LibraryManager.library, WebGLWindow);
34 changes: 34 additions & 0 deletions Assets/WebGLSupport/WebGLWindow/WebGLWindow.jslib.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5d2a8ef

Please sign in to comment.