Update arrangement logic for containers, remove position property from Rect, add Size property to IElement.

This commit is contained in:
2025-06-19 15:08:23 +02:00
parent e499691714
commit 6affded730
9 changed files with 56 additions and 23 deletions

View File

@@ -134,6 +134,9 @@ namespace Voile.Input
new KeyInputAction(KeyboardKey.D),
new KeyInputAction(KeyboardKey.Right),
]);
AddInputMapping("accept", [
new KeyInputAction(KeyboardKey.Enter),
]);
}
protected bool TryGetInputMappings(string forAction, [NotNullWhen(true)] out List<IInputAction>? inputActions)

View File

@@ -9,6 +9,7 @@ public abstract class Container : IElement, IParentableElement, IUpdatableElemen
{
public IReadOnlyList<IElement> Children => _children;
public Vector2 Position { get; set; }
public Rect Size { get; set; } = Rect.Zero;
public Container()
{

View File

@@ -1,3 +1,4 @@
using System.Numerics;
using Voile.Rendering;
namespace Voile.UI.Containers;
@@ -19,15 +20,20 @@ public class HorizontalContainer : Container, IRenderableElement
public override void Arrange()
{
int i = 0;
foreach (var child in Children)
{
var pos = Position;
pos.X += i * Spacing;
float currentX = Position.X;
for (int i = 0; i < Children.Count; i++)
{
var child = Children[i];
var pos = new Vector2(currentX, Position.Y);
child.Position = pos;
i++;
currentX += child.Size.Width;
if (i < Children.Count - 1)
{
currentX += Spacing;
}
}
}

View File

@@ -1,3 +1,4 @@
using System.Numerics;
using Voile.Rendering;
namespace Voile.UI.Containers;
@@ -19,15 +20,20 @@ public class VerticalContainer : Container, IRenderableElement
public override void Arrange()
{
int i = 0;
foreach (var child in Children)
{
var pos = Position;
pos.Y += i * Spacing;
float currentY = Position.Y;
for (int i = 0; i < Children.Count; i++)
{
var child = Children[i];
var pos = new Vector2(Position.X, currentY);
child.Position = pos;
i++;
currentY += child.Size.Height;
if (i < Children.Count - 1)
{
currentY += Spacing;
}
}
}

View File

@@ -7,6 +7,7 @@ namespace Voile.UI;
public interface IElement
{
public Vector2 Position { get; set; }
public Rect Size { get; set; }
}
public interface IParentableElement
@@ -15,6 +16,14 @@ public interface IParentableElement
public void AddChild(IElement child);
}
public interface IResizeableElement
{
/// <summary>
/// Get a minimum rectangle size for this element.
/// </summary>
public abstract Rect MinimumRect { get; }
}
public interface IUpdatableElement
{
void Update();

View File

@@ -1,8 +1,9 @@
using System.Numerics;
namespace Voile.UI;
/// <summary>
/// Represents a rectangle. Used to determine widget confines for UI layout.
/// </summary>
public record Rect(Vector2 Position, float Width, float Height);
public record Rect(float Width = 0.0f, float Height = 0.0f)
{
public static Rect Zero => new Rect(0.0f, 0.0f);
}

View File

@@ -18,7 +18,7 @@ public enum ButtonState
public class Button : Widget
{
public string Label { get; set; } = "Button";
public override Rect MinimumRect => new Rect(Position, Width: 128.0f, Height: 64.0f);
public override Rect MinimumRect => new Rect(Width: 128.0f, Height: 64.0f);
public Button(string label, Action pressedAction)
{

View File

@@ -7,11 +7,12 @@ namespace Voile.UI.Widgets;
/// <summary>
/// A base class for all UI widgets.
/// </summary>
public abstract class Widget : IElement, IRenderableElement, IInputElement
public abstract class Widget : IElement, IRenderableElement, IInputElement, IResizeableElement, IUpdatableElement
{
public bool Visible { get; set; } = true;
public bool IgnoreInput { get; set; }
public Vector2 Position { get; set; } = Vector2.Zero;
public Rect Size { get; set; } = new();
public Widget()
{
@@ -23,9 +24,7 @@ public abstract class Widget : IElement, IRenderableElement, IInputElement
Position = position;
}
/// <summary>
/// Get a minimum rectangle size for this widget.
/// </summary>
/// </inheritdoc>
public abstract Rect MinimumRect { get; }
/// <summary>
@@ -38,4 +37,12 @@ public abstract class Widget : IElement, IRenderableElement, IInputElement
/// </summary>
/// <param name="action">An input action this widget received.</param>
public abstract void Input(IInputAction action);
public void Update()
{
if (Size == Rect.Zero)
{
Size = MinimumRect;
}
}
}