Update arrangement logic for containers, remove position property from Rect, add Size property to IElement.
This commit is contained in:
@@ -67,9 +67,9 @@ public class TestGame : Game
|
||||
_particleSystem!.RestartEmitter(_emitterId);
|
||||
}
|
||||
|
||||
if (Input.KeyboardKeyJustPressed(KeyboardKey.One))
|
||||
if (Input.IsActionPressed("accept"))
|
||||
{
|
||||
_container.AddChild(new RectangleWidget(new Rect(Vector2.Zero, 32.0f, 32.0f), MathUtils.RandomColor()));
|
||||
_container.AddChild(new RectangleWidget(new Rect(32.0f, 32.0f), MathUtils.RandomColor()));
|
||||
}
|
||||
|
||||
if (Input.IsMouseButtonDown(MouseButton.Left))
|
||||
@@ -117,5 +117,5 @@ public class TestGame : Game
|
||||
private ResourceRef<Sound> _sound;
|
||||
private ResourceRef<Texture2d> _icon;
|
||||
|
||||
private HorizontalContainer _container = new(spacing: 64.0f);
|
||||
private HorizontalContainer _container = new(spacing: 8.0f);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user