From 7bbfab83596d25592d235f8478fbdb187c8e8aeb Mon Sep 17 00:00:00 2001 From: dnesov Date: Mon, 1 Jun 2026 22:30:54 +0200 Subject: [PATCH] Use enums for ActionTypes in InputField, use ReadOnlySpan for Font measurements, only measure placeholderSize if the input is empty. --- Voile/Source/Resources/Font.cs | 18 ++++++++++--- Voile/Source/UI/Widgets/InputField.cs | 38 +++++++++++++++------------ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Voile/Source/Resources/Font.cs b/Voile/Source/Resources/Font.cs index 47df04e..bd7dc87 100644 --- a/Voile/Source/Resources/Font.cs +++ b/Voile/Source/Resources/Font.cs @@ -83,16 +83,26 @@ public class Font : Resource, IUpdatableResource, IDisposable /// A with the sizes of a given text using this font. public Rect Measure(string text) { - if (string.IsNullOrEmpty(text)) + return Measure(text.AsSpan()); + } + + /// + /// Measures a given of characters. + /// + /// + /// A with the sizes of a given text using this font. + public Rect Measure(ReadOnlySpan chars) + { + if (chars.Length == 0) return Rect.Zero; float totalWidth = 0; float maxAscent = 0; float maxDescent = 0; - for (int i = 0; i < text.Length; i++) + for (int i = 0; i < chars.Length; i++) { - char c = text[i]; + char c = chars[i]; Glyph glyph = GetGlyph(c); totalWidth += glyph.Advance * SpacingScale + LetterSpacing; @@ -107,7 +117,7 @@ public class Font : Resource, IUpdatableResource, IDisposable if (i > 0) { - char prevChar = text[i - 1]; + char prevChar = chars[i - 1]; totalWidth += GetKerning(prevChar, c); } } diff --git a/Voile/Source/UI/Widgets/InputField.cs b/Voile/Source/UI/Widgets/InputField.cs index 536ae42..886cc85 100644 --- a/Voile/Source/UI/Widgets/InputField.cs +++ b/Voile/Source/UI/Widgets/InputField.cs @@ -7,6 +7,8 @@ namespace Voile.UI.Widgets; public class InputField : Widget, ITickableElement { + enum ActionType { None, Backspace, Left, Right } + public override Rect MinimumSize => _placeholderSize + _padding; public override string? StyleElementName => nameof(InputField); @@ -58,7 +60,7 @@ public class InputField : Widget, ITickableElement if (!_isFocused) { - _lastActiveAction = string.Empty; + _lastActiveAction = ActionType.None; _repeatTimer = 0.0f; return; } @@ -100,15 +102,15 @@ public class InputField : Widget, ITickableElement private void HandleRepeatingActions(float dt, InputSystem input) { - string currentAction = string.Empty; + ActionType currentAction = ActionType.None; - if (input.IsKeyboardKeyDown(KeyboardKey.Backspace)) currentAction = "backspace"; - else if (input.IsKeyboardKeyDown(KeyboardKey.Left)) currentAction = "left"; - else if (input.IsKeyboardKeyDown(KeyboardKey.Right)) currentAction = "right"; + if (input.IsKeyboardKeyDown(KeyboardKey.Backspace)) currentAction = ActionType.Backspace; + else if (input.IsKeyboardKeyDown(KeyboardKey.Left)) currentAction = ActionType.Left; + else if (input.IsKeyboardKeyDown(KeyboardKey.Right)) currentAction = ActionType.Right; - if (string.IsNullOrEmpty(currentAction)) + if (currentAction == ActionType.None) { - _lastActiveAction = string.Empty; + _lastActiveAction = ActionType.None; _repeatTimer = 0.0f; return; } @@ -138,11 +140,11 @@ public class InputField : Widget, ITickableElement } } - private void ExecuteAction(string actionName) + private void ExecuteAction(ActionType action) { - switch (actionName) + switch (action) { - case "backspace": + case ActionType.Backspace: if (_cursor > 0 && _input.Length > 0) { _input = _input.Remove(_cursor - 1, 1); @@ -151,7 +153,7 @@ public class InputField : Widget, ITickableElement } break; - case "left": + case ActionType.Left: if (_cursor > 0) { _cursor--; @@ -159,7 +161,7 @@ public class InputField : Widget, ITickableElement } break; - case "right": + case ActionType.Right: if (_cursor < _input.Length) { _cursor++; @@ -211,7 +213,7 @@ public class InputField : Widget, ITickableElement // Caret if (_isFocused && _blink) { - var caretX = MeasureTextWidth(_input.Substring(0, _cursor)); + var caretX = MeasureTextWidth(_input.AsSpan(0, _cursor)); renderer.SetTransform( new Vector2(GlobalPosition.X + caretX + _padding.Left, GlobalPosition.Y + _padding.Top), @@ -247,7 +249,9 @@ public class InputField : Widget, ITickableElement var font = _suitableFont.Value; _textSize = font.Measure(_input); - _placeholderSize = font.Measure(PlaceholderText); + + if (string.IsNullOrEmpty(_input)) + _placeholderSize = font.Measure(PlaceholderText); } var size = Rect.MaxWidth(_placeholderSize, _textSize); @@ -255,18 +259,18 @@ public class InputField : Widget, ITickableElement Size = _padding + size; } - private float MeasureTextWidth(string text) + private float MeasureTextWidth(ReadOnlySpan chars) { if (!_suitableFont.HasValue) { return 0.0f; } - return _suitableFont.Value.Measure(text).Width; + return _suitableFont.Value.Measure(chars).Width; } private float _repeatTimer = 0.0f; - private string _lastActiveAction = string.Empty; + private ActionType _lastActiveAction = ActionType.None; private const float INITIAL_DELAY = 0.5f; private const float REPEAT_RATE = 0.05f;