172 lines
3.9 KiB
C#
172 lines
3.9 KiB
C#
using System.Numerics;
|
|
using Voile.Rendering;
|
|
using Voile.Resources;
|
|
using Voile.UI.Containers;
|
|
|
|
namespace Voile.UI.Widgets;
|
|
|
|
public enum ButtonState
|
|
{
|
|
Disabled,
|
|
Hovered,
|
|
Pressed,
|
|
Normal
|
|
}
|
|
|
|
/// <summary>
|
|
/// A clickable button with a label.
|
|
/// </summary>
|
|
public class Button : Widget
|
|
{
|
|
public string Text
|
|
{
|
|
get => _text; set
|
|
{
|
|
_text = value;
|
|
MarkDirty();
|
|
}
|
|
}
|
|
|
|
public ButtonState CurrentState { get; private set; } = ButtonState.Normal;
|
|
|
|
public override Rect MinimumSize => Padding + _textSize;
|
|
|
|
/// <summary>
|
|
/// <see cref="FontSet"/> to use with this button.
|
|
/// </summary>
|
|
public FontSet FontSet { get; set; } = new();
|
|
public Size Padding
|
|
{
|
|
get => _padding; set
|
|
{
|
|
_padding = value;
|
|
}
|
|
}
|
|
|
|
public override string? StyleElementName => nameof(Button);
|
|
public override string[]? StyleModifiers =>
|
|
[
|
|
CurrentState.ToString()
|
|
];
|
|
|
|
public Button(string text, ResourceRef<Font> fontOverride, Action pressedAction)
|
|
{
|
|
_text = text;
|
|
_pressedAction = pressedAction;
|
|
|
|
FontSet.AddFont(fontOverride);
|
|
|
|
MarkDirty();
|
|
Update();
|
|
}
|
|
|
|
public Button(string text, FontSet fontSet)
|
|
{
|
|
_text = text;
|
|
|
|
FontSet = fontSet;
|
|
|
|
MarkDirty();
|
|
Update();
|
|
}
|
|
|
|
public Button(string text, FontSet fontSet, Action pressedAction)
|
|
{
|
|
_text = text;
|
|
_pressedAction = pressedAction;
|
|
|
|
FontSet = fontSet;
|
|
|
|
MarkDirty();
|
|
Update();
|
|
}
|
|
|
|
public override void Render(RenderSystem renderer, Style style)
|
|
{
|
|
if (_padding != style.Padding)
|
|
{
|
|
MarkDirty();
|
|
}
|
|
|
|
_padding = style.Padding;
|
|
var textColor = style.TextColor ?? Color.Black;
|
|
|
|
// renderer.SetTransform(GlobalPosition, Vector2.Zero);
|
|
// renderer.DrawRectangle(new Vector2(Size.Width, Size.Height), backgroundColor);
|
|
|
|
RenderStyleBox(renderer, style);
|
|
|
|
var textPosition = new Vector2(GlobalPosition.X + Padding.Left, GlobalPosition.Y + Padding.Top);
|
|
renderer.SetTransform(textPosition, Vector2.Zero);
|
|
renderer.DrawText(_suitableFont, _text, textColor);
|
|
}
|
|
|
|
protected override void OnInput(UIInputContext action)
|
|
{
|
|
bool isHovering = ContainsPoint(action.MousePosition);
|
|
|
|
if (action.MousePressed && isHovering)
|
|
{
|
|
_isHeldDown = true;
|
|
CurrentState = ButtonState.Pressed;
|
|
}
|
|
else if (action.MouseReleased)
|
|
{
|
|
if (_isHeldDown && isHovering)
|
|
{
|
|
_pressedAction?.Invoke();
|
|
}
|
|
|
|
_isHeldDown = false;
|
|
CurrentState = isHovering ? ButtonState.Hovered : ButtonState.Normal;
|
|
}
|
|
else
|
|
{
|
|
if (_isHeldDown)
|
|
{
|
|
CurrentState = ButtonState.Pressed; // keep showing as pressed
|
|
}
|
|
else if (isHovering)
|
|
{
|
|
CurrentState = ButtonState.Hovered;
|
|
}
|
|
else
|
|
{
|
|
CurrentState = ButtonState.Normal;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnUpdate()
|
|
{
|
|
ResourceRef<Font> fontRef = ResourceRef<Font>.Empty();
|
|
foreach (var c in _text)
|
|
{
|
|
if (FontSet.TryGetFontFor(c, out var fallbackFont))
|
|
{
|
|
if (fallbackFont != fontRef)
|
|
{
|
|
fontRef = fallbackFont;
|
|
}
|
|
}
|
|
}
|
|
|
|
_suitableFont = fontRef;
|
|
|
|
var font = _suitableFont.Value;
|
|
_textSize = font.Measure(_text);
|
|
|
|
Size = _padding + _textSize;
|
|
}
|
|
|
|
private Action? _pressedAction;
|
|
|
|
private ResourceRef<Font> _suitableFont = ResourceRef<Font>.Empty();
|
|
|
|
private string _text = "Hello, World!";
|
|
private Rect _textSize = Rect.Zero;
|
|
|
|
private Size _padding;
|
|
|
|
private bool _isHeldDown;
|
|
} |