Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
LegacyTextBoxWidget.cs
浏览该文件的文档.
1using Engine;
3using Engine.Input;
4using Engine.Media;
5
6namespace Game {
7 [Obsolete($"LegacyTextBoxWidget is obsolete, please use {nameof(LegacyTextBoxWidget)} instead.")]
8 public class LegacyTextBoxWidget : Widget {
10
11 public string m_text = string.Empty;
12
13 public int m_maximumLength = 512;
14
15 public bool m_hasFocus;
16
17 public int m_caretPosition;
18
19 public double m_focusStartTime;
20
21 public float m_scroll;
22
23 public Vector2? m_size;
24
25 public Vector2 Size {
26 get {
27 if (!m_size.HasValue) {
28 return Vector2.Zero;
29 }
30 return m_size.Value;
31 }
32 set => m_size = value;
33 }
34
35 public string Title { get; set; }
36
37 public string Description { get; set; }
38
39 public string Text {
40 get => m_text;
41 set {
42 string text = value.Length > MaximumLength ? value.Substring(0, MaximumLength) : value;
43 if (text != m_text) {
44 m_text = text;
46 TextChanged?.Invoke(this);
47 }
48 }
49 }
50
51 public int MaximumLength {
52 get => m_maximumLength;
53 set {
54 m_maximumLength = MathUtils.Max(value, 0);
55 if (Text.Length > m_maximumLength) {
56 Text = Text.Substring(0, m_maximumLength);
57 }
58 }
59 }
60
61 public bool OverwriteMode { get; set; }
62
63 public bool HasFocus {
64 get { return m_hasFocus; }
65 set {
66 if (value != m_hasFocus) {
67 m_hasFocus = value;
68 if (value) {
69#if !ANDROID
70 if (m_hasFocus && Text == string.Empty) {
71 //清空之前的输入
73 }
74#endif
75 CaretPosition = m_text.Length;
77 Title,
79 Text,
80 false,
81 delegate(string text) {
82 Text = text;
83 HasFocus = false;
84 },
85 null
86 );
87 }
88 else {
89 FocusLost?.Invoke(this);
90 }
91 }
92 }
93 }
94
96 get => m_font;
97 set => m_font = value;
98 }
99
100 public float FontScale { get; set; }
101
102 public Vector2 FontSpacing { get; set; }
103
104 public Color Color { get; set; }
105
106 public bool TextureLinearFilter { get; set; }
107
108 public int CaretPosition {
109 get => m_caretPosition;
110 set {
111 m_caretPosition = Math.Clamp(value, 0, Text.Length);
113 }
114 }
115
116 public event Action<LegacyTextBoxWidget> TextChanged;
117
118 public event Action<LegacyTextBoxWidget> Enter;
119
120 public event Action<LegacyTextBoxWidget> Escape;
121
122 public event Action<LegacyTextBoxWidget> FocusLost;
123
124 public bool MoveNextFlag;
125
126 public bool JustOpened;
127
129 ClampToBounds = true;
130 Color = Color.White;
131 TextureLinearFilter = true;
132 Font = ContentManager.Get<BitmapFont>("Fonts/Pericles");
133 FontScale = 1f;
134 Title = string.Empty;
135 Description = string.Empty;
136 JustOpened = true;
137 }
138
139 public override void Update() {
140 if (HasFocus) {
141#if ANDROID
142 if (Input.LastChar.HasValue
143 && !Input.IsKeyDown(Key.Control)
144 && !char.IsControl(Input.LastChar.Value)) {
145 EnterText(new string(Input.LastChar.Value, 1));
146 Input.Clear();
147 }
148 if (Input.LastKey.HasValue) {
149 bool flag = false;
150 Key value = Input.LastKey.Value;
151 if (value == Key.V
152 && Input.IsKeyDown(Key.Control)) {
154 flag = true;
155 }
156 else if (value == Key.BackSpace
157 && CaretPosition > 0) {
159 Text = Text.Remove(CaretPosition, 1);
160 flag = true;
161 }
162 else {
163 switch (value) {
164 case Key.Delete:
165 if (CaretPosition < m_text.Length) {
166 Text = Text.Remove(CaretPosition, 1);
167 flag = true;
168 }
169 break;
170 case Key.LeftArrow:
172 flag = true;
173 break;
174 case Key.RightArrow:
176 flag = true;
177 break;
178 case Key.Home:
179 CaretPosition = 0;
180 flag = true;
181 break;
182 case Key.End:
183 CaretPosition = m_text.Length;
184 flag = true;
185 break;
186 case Key.Enter:
187 flag = true;
188 HasFocus = false;
189 Enter?.Invoke(this);
190 break;
191 case Key.Escape:
192 flag = true;
193 HasFocus = false;
194 Escape?.Invoke(this);
195 break;
196 }
197 }
198 if (flag) {
199 Input.Clear();
200 }
201 }
202#else
203 //处理文字删除
205 if (CaretPosition != 0) {
207 CaretPosition = Math.Max(0, CaretPosition);
208 if (Text.Length > 0) {
209 Text = Text.Remove(CaretPosition, 1);
210 }
211 float num = Font.CalculateCharacterPosition(Text, 0, new Vector2(FontScale), FontSpacing);
212 m_scroll = num - ActualSize.X;
214 }
215 }
216 //处理文字输入
217 string inputString = KeyboardInput.GetInput();
218 if (JustOpened) {
219 inputString = string.Empty;
220 JustOpened = false;
221 }
222 if (!string.IsNullOrEmpty(inputString)) {
223 EnterText(inputString);
224 }
225#endif
226 }
227 if (Input.Click.HasValue) {
228 //处理电脑键盘输入时会处理成游戏输入
229 HasFocus = HitTestGlobal(Input.Click.Value.Start) == this && HitTestGlobal(Input.Click.Value.End) == this;
230 }
231 if (HasFocus) { //处理复制粘贴事件
232 if (Input.IsKeyDown(Key.Control)) {
233 if (Input.IsKeyDownOnce(Key.V)) {
235 }
236 else if (Input.IsKeyDownOnce(Key.C)) {
238 }
239 else if (Input.IsKeyDownOnce(Key.X)) {
241 Text = string.Empty;
242 }
243 }
244 if (Input.IsKeyDownOnce(Key.Tab)) {
246 }
247 if (Input.IsKeyDownRepeat(Key.LeftArrow)) {
249 }
250 if (Input.IsKeyDownRepeat(Key.RightArrow)) {
252 }
253 if (Input.IsKeyDownRepeat(Key.UpArrow)) {
254 CaretPosition = 0;
255 }
256 if (Input.IsKeyDownRepeat(Key.DownArrow)) {
257 CaretPosition = Text.Length;
258 }
259 if (Input.IsKeyDownRepeat(Key.Enter)) {
260 Enter?.Invoke(this);
261 }
262 if (Input.IsKeyDownRepeat(Key.Escape)) {
263 Escape?.Invoke(this);
264 }
265 }
266 }
267
268 public void MoveNext(WidgetsList widgets) {
269 foreach (Widget widget in widgets) {
270 if (widget is TextBoxWidget textBox) {
271 if (!MoveNextFlag
272 && widget == this) {
273 MoveNextFlag = true;
274 }
275 else if (MoveNextFlag) {
276 textBox.HasFocus = true;
277 HasFocus = false;
278 MoveNextFlag = false;
279 }
280 }
281 if (widget is ContainerWidget container) {
282 MoveNext(container.Children);
283 }
284 }
285 }
286
287 public override void MeasureOverride(Vector2 parentAvailableSize) {
288 IsDrawRequired = true;
289 if (m_size.HasValue) {
290 DesiredSize = m_size.Value;
291 return;
292 }
293 DesiredSize = Font.MeasureText(Text.Length == 0 ? " " : Text, new Vector2(FontScale), FontSpacing);
294 DesiredSize += new Vector2(1f * FontScale * Font.Scale, 0f);
295 }
296
297 public override void Draw(DrawContext dc) {
299 if (!string.IsNullOrEmpty(m_text)) {
300 Vector2 position = new(0f - m_scroll, ActualSize.Y / 2f);
302 FontBatch2D fontBatch2D = dc.PrimitivesRenderer2D.FontBatch(Font, 1, DepthStencilState.None, null, null, samplerState);
303 int count = fontBatch2D.TriangleVertices.Count;
304 fontBatch2D.QueueText(
305 Text,
306 position,
307 0f,
308 color,
309 TextAnchor.VerticalCenter,
310 new Vector2(FontScale),
312 );
313 fontBatch2D.TransformTriangles(GlobalTransform, count);
314 }
315 if (!m_hasFocus
316 || !(MathUtils.Remainder(Time.RealTime - m_focusStartTime, 0.5) < 0.25)) {
317 return;
318 }
319 float caretPosition = Font.CalculateCharacterPosition(Text, CaretPosition, new Vector2(FontScale), FontSpacing);
320 Vector2 caretCenter = new Vector2(0f, ActualSize.Y / 2f) + new Vector2(caretPosition - m_scroll, 0f);
321 if (m_hasFocus) {
322 if (caretCenter.X < 0f) {
323 m_scroll = MathUtils.Max(m_scroll + caretCenter.X, 0f);
324 }
325 if (caretCenter.X > ActualSize.X) {
326 m_scroll += caretCenter.X - ActualSize.X + 1f;
327 }
328 }
330 int count2 = flatBatch2D.TriangleVertices.Count;
331 flatBatch2D.QueueQuad(
332 caretCenter - new Vector2(0f, Font.GlyphHeight / 2f * FontScale * Font.Scale),
333 caretCenter + new Vector2(1f, Font.GlyphHeight / 2f * FontScale * Font.Scale),
334 0f,
335 color
336 );
337 flatBatch2D.TransformTriangles(GlobalTransform, count2);
338 }
339
340 public void EnterText(string s) {
341 if (OverwriteMode) {
342 if (CaretPosition + s.Length <= MaximumLength) {
343 if (CaretPosition < m_text.Length) {
344 Text = Text.Remove(CaretPosition, s.Length).Insert(CaretPosition, s);
345 }
346 else {
347 Text = m_text + s;
348 }
349 CaretPosition += s.Length;
350 }
351 }
352 else if (m_text.Length + s.Length <= MaximumLength) {
353 if (CaretPosition < m_text.Length) {
354 Text = Text.Insert(CaretPosition, s);
355 }
356 else {
357 Text = m_text + s;
358 }
359 CaretPosition += s.Length;
360 }
361 }
362 }
363}
readonly DynamicArray< VertexPositionColor > TriangleVertices
void TransformTriangles(Matrix matrix, int start=0, int end=-1)
void TransformTriangles(Matrix matrix, int start=0, int end=-1)
readonly DynamicArray< VertexPositionColorTexture > TriangleVertices
static readonly DepthStencilState None
void QueueQuad(Vector2 corner1, Vector2 corner2, float depth, Color color)
void QueueText(string text, Vector2 position, float depth, Color color, TextAnchor anchor=TextAnchor.Default)
FlatBatch2D FlatBatch(int layer=0, DepthStencilState depthStencilState=null, RasterizerState rasterizerState=null, BlendState blendState=null)
FontBatch2D FontBatch(BitmapFont font=null, int layer=0, DepthStencilState depthStencilState=null, RasterizerState rasterizerState=null, BlendState blendState=null, SamplerState samplerState=null)
static void ShowKeyboard(string title, string description, string defaultText, bool passwordMode, Action< string > enter, Action cancel)
static float Remainder(float x, float y)
static int Min(int x1, int x2)
static int Max(int x1, int x2)
static double RealTime
定义 Time.cs:38
readonly WidgetsList Children
static object Get(Type type, string name)
Action< LegacyTextBoxWidget > Enter
Action< LegacyTextBoxWidget > Escape
Action< LegacyTextBoxWidget > TextChanged
Action< LegacyTextBoxWidget > FocusLost
override void MeasureOverride(Vector2 parentAvailableSize)
override void Draw(DrawContext dc)
void MoveNext(WidgetsList widgets)
readonly PrimitivesRenderer2D PrimitivesRenderer2D
virtual Widget HitTestGlobal(Vector2 point, Func< Widget, bool > predicate=null)
WidgetInput Input
Color GlobalColorTransform
Vector2 DesiredSize
bool IsDrawRequired
Vector2 ActualSize
Matrix GlobalTransform
static readonly Vector2 Zero