101 lines
2.6 KiB
C#
101 lines
2.6 KiB
C#
using System.Numerics;
|
|
using Voile.Rendering;
|
|
|
|
namespace Voile.UI.Containers;
|
|
|
|
/// <summary>
|
|
/// A base class for all UI containers, used to position and rendering child <see cref="IElement">s.
|
|
/// </summary>
|
|
public abstract class Container : IElement, IParentableElement, IUpdatableElement, IResizeableElement, IRenderableElement
|
|
{
|
|
public IReadOnlyList<IElement> Children => _children;
|
|
public Vector2 Position { get; set; }
|
|
public Rect MinimumRect { get; set; } = Rect.Zero;
|
|
public Rect Size { get; set; } = Rect.Zero;
|
|
public bool Visible { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
|
|
|
public Container()
|
|
{
|
|
|
|
}
|
|
|
|
public Container(Rect minimumSize)
|
|
{
|
|
MinimumRect = minimumSize;
|
|
}
|
|
|
|
public Container(Rect minimumSize, List<IElement> children)
|
|
{
|
|
MinimumRect = minimumSize;
|
|
_children = children;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
Arrange();
|
|
CalculateMinimumSize();
|
|
|
|
foreach (var child in _children)
|
|
{
|
|
if (child is not IUpdatableElement updatable) continue;
|
|
updatable.Update();
|
|
}
|
|
}
|
|
public abstract void Arrange();
|
|
|
|
public void CalculateMinimumSize()
|
|
{
|
|
if (Children.Count == 0)
|
|
{
|
|
Size = MinimumRect;
|
|
return;
|
|
}
|
|
|
|
float minX = float.MaxValue;
|
|
float minY = float.MaxValue;
|
|
float maxX = float.MinValue;
|
|
float maxY = float.MinValue;
|
|
|
|
foreach (var child in Children)
|
|
{
|
|
var pos = child.Position;
|
|
var size = child.Size;
|
|
|
|
minX = MathF.Min(minX, pos.X);
|
|
minY = MathF.Min(minY, pos.Y);
|
|
maxX = MathF.Max(maxX, pos.X + size.Width);
|
|
maxY = MathF.Max(maxY, pos.Y + size.Height);
|
|
}
|
|
|
|
// Optionally apply padding
|
|
float padding = 0f; // or make this configurable
|
|
|
|
Size = new Rect(
|
|
maxX - minX + padding * 2,
|
|
maxY - minY + padding * 2
|
|
);
|
|
}
|
|
|
|
public void AddChild(IElement child)
|
|
{
|
|
_children.Add(child);
|
|
Update();
|
|
}
|
|
|
|
public void Render(RenderSystem renderer, Style style)
|
|
{
|
|
foreach (var child in Children)
|
|
{
|
|
if (child is not IRenderableElement renderable) continue;
|
|
renderable.Render(renderer, style);
|
|
}
|
|
}
|
|
|
|
public void DrawSize(RenderSystem renderer)
|
|
{
|
|
renderer.SetTransform(Position, Vector2.Zero);
|
|
renderer.DrawRectangleOutline(new Vector2(Size.Width, Size.Height), Color.Red, 2.0f);
|
|
}
|
|
|
|
private List<IElement> _children = new();
|
|
} |