Tanoda
WrappedTMPInputField.cs
Go to the documentation of this file.
1#if UNITY_2018_2_OR_NEWER
2#define TMP_WEBGL_SUPPORT
3#endif
4
5#if TMP_WEBGL_SUPPORT
6using UnityEngine;
7using TMPro;
9using UnityEngine.UI;
10
11namespace WebGLSupport
12{
16 class WrappedTMPInputField : IInputField
17 {
18 TMP_InputField input;
19 RebuildChecker checker;
20 Coroutine delayedGraphicRebuild;
21
22 public bool ReadOnly { get { return input.readOnly; } }
23
24 public string text
25 {
26 get { return input.text; }
27 set { input.text = value; }
28 }
29 public string placeholder
30 {
31 get
32 {
33 if (!input.placeholder) return "";
34 var text = input.placeholder.GetComponent<TMP_Text>();
35 return text ? text.text : "";
36 }
37 }
38
39 public int fontSize
40 {
41 get { return (int)input.textComponent.fontSize; }
42 }
43
44 public ContentType contentType
45 {
46 get { return (ContentType)input.contentType; }
47 }
48
49 public LineType lineType
50 {
51 get { return (LineType)input.lineType; }
52 }
53
54 public int characterLimit
55 {
56 get { return input.characterLimit; }
57 }
58
59 public int caretPosition
60 {
61 get { return input.caretPosition; }
62 }
63
64 public bool isFocused
65 {
66 get { return input.isFocused; }
67 }
68
69 public int selectionFocusPosition
70 {
71 get { return input.selectionStringFocusPosition; }
72 set { input.selectionStringFocusPosition = value; }
73 }
74
75 public int selectionAnchorPosition
76 {
77 get { return input.selectionStringAnchorPosition; }
78 set { input.selectionStringAnchorPosition = value; }
79 }
80
81 public bool OnFocusSelectAll
82 {
83 get { return input.onFocusSelectAll; }
84 }
85
86 public WrappedTMPInputField(TMP_InputField input)
87 {
88 this.input = input;
89 checker = new RebuildChecker(this);
90 }
91
92 public RectTransform RectTransform()
93 {
94 // 表示範囲
95 // MEMO :
96 // TMP では textComponent を移動させてクリッピングするため、
97 // 表示範囲外になる場合があるので、自分の範囲を返す
98 return input.GetComponent<RectTransform>();
99 }
100
101 public void ActivateInputField()
102 {
103 input.ActivateInputField();
104 }
105
106 public void DeactivateInputField()
107 {
108 input.DeactivateInputField();
109 }
110
111 public void Rebuild()
112 {
113#if UNITY_2020_1_OR_NEWER
114 if (checker.NeedRebuild())
115 {
116 input.textComponent.SetVerticesDirty();
117 input.textComponent.SetLayoutDirty();
118 input.Rebuild(CanvasUpdate.LatePreRender);
119 }
120#else
121 if (input.textComponent.enabled && checker.NeedRebuild())
122 {
123 //================================
124 // fix bug for tmp
125 // TMPの不具合で、正しく座標を設定されてなかったため、試しに対応する
126 var rt = input.textComponent.GetComponent<RectTransform>();
127 var size = input.textComponent.GetPreferredValues();
128 if (size.x < rt.rect.xMax)
129 {
130 // textComponent の座標を更新
131 var pos = rt.anchoredPosition;
132 pos.x = 0;
133 rt.anchoredPosition = pos;
134
135 // caret の座標更新
136 var caret = input.GetComponentInChildren<TMP_SelectionCaret>();
137 var caretRect = caret.GetComponent<RectTransform>();
138 caretRect.anchoredPosition = rt.anchoredPosition;
139 }
140 //==============================
141
142 // HACK : 1フレーム無効にする
143 // MEMO : 他にいい方法Rebuildがあれば対応する
144 // LayoutRebuilder.ForceRebuildLayoutImmediate(); で試してダメでした
145 input.textComponent.enabled = rectOverlaps(input.textComponent.rectTransform, input.textViewport);
146 input.textComponent.SetAllDirty();
147 input.Rebuild(CanvasUpdate.LatePreRender);
148 //Debug.Log(input.textComponent.enabled);
149 }
150 else
151 {
152 input.textComponent.enabled = true;
153 }
154#endif
155 }
156
157 bool rectOverlaps(RectTransform rectTrans1, RectTransform rectTrans2)
158 {
159 Rect rect1 = new Rect(rectTrans1.localPosition.x, rectTrans1.localPosition.y, rectTrans1.rect.width, rectTrans1.rect.height);
160 Rect rect2 = new Rect(rectTrans2.localPosition.x, rectTrans2.localPosition.y, rectTrans2.rect.width, rectTrans2.rect.height);
161
162 return rect1.Overlaps(rect2);
163 }
164 }
165}
166
167#endif // TMP_WEBGL_SUPPORT