WrappedTMPInputField.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #if UNITY_2018_2_OR_NEWER
  2. #define TMP_WEBGL_SUPPORT
  3. #endif
  4. #if TMP_WEBGL_SUPPORT
  5. using UnityEngine;
  6. using TMPro;
  7. using WebGLSupport.Detail;
  8. using UnityEngine.UI;
  9. using System;
  10. namespace WebGLSupport
  11. {
  12. /// <summary>
  13. /// Wrapper for TMPro.TMP_InputField
  14. /// </summary>
  15. class WrappedTMPInputField : IInputField
  16. {
  17. TMP_InputField input;
  18. RebuildChecker checker;
  19. Coroutine delayedGraphicRebuild;
  20. public bool ReadOnly { get { return input.readOnly; } }
  21. public string text
  22. {
  23. get { return input.text; }
  24. set { input.text = FixContentTypeByInputField(value); }
  25. }
  26. /// <summary>
  27. /// workaround!!
  28. /// when use TMP_InputField.text = "xxx"; is will set the text directly.
  29. /// so, use InputField for match the ContentType!
  30. /// </summary>
  31. /// <param name="inText"></param>
  32. /// <returns></returns>
  33. private string FixContentTypeByInputField(string inText)
  34. {
  35. var go = new GameObject("FixContentTypeByInputField for WebGLInput");
  36. go.SetActive(false);
  37. var i = go.AddComponent<InputField>();
  38. i.contentType = (InputField.ContentType)Enum.Parse(typeof(InputField.ContentType), input.contentType.ToString());
  39. i.lineType = (InputField.LineType)Enum.Parse(typeof(InputField.LineType), input.lineType.ToString());
  40. i.inputType = (InputField.InputType)Enum.Parse(typeof(InputField.InputType), input.inputType.ToString());
  41. i.keyboardType = input.keyboardType;
  42. i.characterValidation = (InputField.CharacterValidation)Enum.Parse(typeof(InputField.CharacterValidation), input.characterValidation.ToString());
  43. i.characterLimit = input.characterLimit;
  44. i.text = inText;
  45. var res = i.text;
  46. GameObject.Destroy(go);
  47. return res;
  48. }
  49. public string placeholder
  50. {
  51. get
  52. {
  53. if (!input.placeholder) return "";
  54. var text = input.placeholder.GetComponent<TMP_Text>();
  55. return text ? text.text : "";
  56. }
  57. }
  58. public int fontSize
  59. {
  60. get { return (int)input.textComponent.fontSize; }
  61. }
  62. public ContentType contentType
  63. {
  64. get { return (ContentType)input.contentType; }
  65. }
  66. public LineType lineType
  67. {
  68. get { return (LineType)input.lineType; }
  69. }
  70. public int characterLimit
  71. {
  72. get { return input.characterLimit; }
  73. }
  74. public int caretPosition
  75. {
  76. get { return input.caretPosition; }
  77. }
  78. public bool isFocused
  79. {
  80. get { return input.isFocused; }
  81. }
  82. public int selectionFocusPosition
  83. {
  84. get { return input.selectionStringFocusPosition; }
  85. set { input.selectionStringFocusPosition = value; }
  86. }
  87. public int selectionAnchorPosition
  88. {
  89. get { return input.selectionStringAnchorPosition; }
  90. set { input.selectionStringAnchorPosition = value; }
  91. }
  92. public bool OnFocusSelectAll
  93. {
  94. get { return input.onFocusSelectAll; }
  95. }
  96. public bool EnableMobileSupport
  97. {
  98. get
  99. {
  100. // [2023.2] Latest Development on TextMesh Pro
  101. // https://forum.unity.com/threads/2023-2-latest-development-on-textmesh-pro.1434757/
  102. // As of 2023.2, the TextMesh Pro package (com.unity.textmeshpro) has been merged into the uGUI package (com.unity.ugui) and the TextMesh Pro package has been deprecated.
  103. // In this version, TextMeshPro is default support mobile input. so disable WebGLInput mobile support
  104. #if UNITY_2023_2_OR_NEWER
  105. // return false to use unity mobile keyboard support
  106. return false;
  107. #else
  108. return true;
  109. #endif
  110. }
  111. }
  112. public WrappedTMPInputField(TMP_InputField input)
  113. {
  114. this.input = input;
  115. checker = new RebuildChecker(this);
  116. }
  117. public Rect GetScreenCoordinates()
  118. {
  119. // 表示範囲
  120. // MEMO :
  121. // TMP では textComponent を移動させてクリッピングするため、
  122. // 表示範囲外になる場合があるので、自分の範囲を返す
  123. return Support.GetScreenCoordinates(input.GetComponent<RectTransform>());
  124. }
  125. public void ActivateInputField()
  126. {
  127. input.ActivateInputField();
  128. }
  129. public void DeactivateInputField()
  130. {
  131. input.DeactivateInputField();
  132. }
  133. public void Rebuild()
  134. {
  135. #if UNITY_2020_1_OR_NEWER
  136. if (checker.NeedRebuild())
  137. {
  138. input.textComponent.SetVerticesDirty();
  139. input.textComponent.SetLayoutDirty();
  140. input.Rebuild(CanvasUpdate.LatePreRender);
  141. }
  142. #else
  143. if (input.textComponent.enabled && checker.NeedRebuild())
  144. {
  145. //================================
  146. // fix bug for tmp
  147. // TMPの不具合で、正しく座標を設定されてなかったため、試しに対応する
  148. var rt = input.textComponent.GetComponent<RectTransform>();
  149. var size = input.textComponent.GetPreferredValues();
  150. if (size.x < rt.rect.xMax)
  151. {
  152. // textComponent の座標を更新
  153. var pos = rt.anchoredPosition;
  154. pos.x = 0;
  155. rt.anchoredPosition = pos;
  156. // caret の座標更新
  157. var caret = input.GetComponentInChildren<TMP_SelectionCaret>();
  158. var caretRect = caret.GetComponent<RectTransform>();
  159. caretRect.anchoredPosition = rt.anchoredPosition;
  160. }
  161. //==============================
  162. // HACK : 1フレーム無効にする
  163. // MEMO : 他にいい方法Rebuildがあれば対応する
  164. // LayoutRebuilder.ForceRebuildLayoutImmediate(); で試してダメでした
  165. input.textComponent.enabled = rectOverlaps(input.textComponent.rectTransform, input.textViewport);
  166. input.textComponent.SetAllDirty();
  167. input.Rebuild(CanvasUpdate.LatePreRender);
  168. //Debug.Log(input.textComponent.enabled);
  169. }
  170. else
  171. {
  172. input.textComponent.enabled = true;
  173. }
  174. #endif
  175. }
  176. bool rectOverlaps(RectTransform rectTrans1, RectTransform rectTrans2)
  177. {
  178. Rect rect1 = new Rect(rectTrans1.localPosition.x, rectTrans1.localPosition.y, rectTrans1.rect.width, rectTrans1.rect.height);
  179. Rect rect2 = new Rect(rectTrans2.localPosition.x, rectTrans2.localPosition.y, rectTrans2.rect.width, rectTrans2.rect.height);
  180. return rect1.Overlaps(rect2);
  181. }
  182. }
  183. }
  184. #endif // TMP_WEBGL_SUPPORT