diff --git a/TestGame/TestGame.cs b/TestGame/TestGame.cs
index fa70522..0cc5832 100644
--- a/TestGame/TestGame.cs
+++ b/TestGame/TestGame.cs
@@ -56,7 +56,8 @@ public class TestGame : Game
Input.AddInputMapping("reload", new IInputAction[] { new KeyInputAction(KeyboardKey.R) });
_emitterId = _particleSystem.CreateEmitter(Renderer.WindowSize / 2, _fireEffect);
- _fillContainer.AddChild(_container);
+ _fillContainer.AddChild(_marginContainer);
+ _marginContainer.AddChild(_container);
_uiSystem.AddElement(_fillContainer);
}
@@ -129,21 +130,20 @@ public class TestGame : Game
private FlexContainer _container = new(minimumSize: new Rect(64.0f, 64.0f), new())
{
- ConfineToContents = true,
Anchor = Anchor.Center,
- Size = new Rect(500, 300),
Direction = FlexDirection.Column,
Justify = JustifyContent.Start,
Align = AlignItems.Center,
Wrap = true,
- Gap = 10f
+ Gap = 8.0f
};
private FillContainer _fillContainer = new();
+ private MarginContainer _marginContainer = new(new Margin(32.0f))
+ {
+ };
// private HorizontalContainer _container = new(new Rect(128.0f, 64.0f), new(), 16)
// {
// ConfineToContents = true,
- // Anchor = Anchor.CenterRight,
- // AnchorOffset = new Vector2(0.5f, 0.0f)
// };
}
\ No newline at end of file
diff --git a/Voile/Source/UI/Containers/Container.cs b/Voile/Source/UI/Containers/Container.cs
index c9112ca..b5db935 100644
--- a/Voile/Source/UI/Containers/Container.cs
+++ b/Voile/Source/UI/Containers/Container.cs
@@ -60,6 +60,18 @@ public abstract class Container : UIElement, IParentableElement
}
}
+ public override void MarkDirty()
+ {
+ base.MarkDirty();
+
+ foreach (var child in _children)
+ {
+ if (child is not IUpdatableElement updatable) continue;
+
+ updatable.MarkDirty();
+ }
+ }
+
///
/// Called when this has to rearrange its children.
///
diff --git a/Voile/Source/UI/Containers/FillContainer.cs b/Voile/Source/UI/Containers/FillContainer.cs
index 15b0897..1a08b85 100644
--- a/Voile/Source/UI/Containers/FillContainer.cs
+++ b/Voile/Source/UI/Containers/FillContainer.cs
@@ -51,9 +51,6 @@ public class FillContainer : Container
protected override void OnUpdate()
{
base.OnUpdate();
-
- if (Size == _lastParentSize) return;
-
Size = _lastParentSize;
}
diff --git a/Voile/Source/UI/Containers/MarginContainer.cs b/Voile/Source/UI/Containers/MarginContainer.cs
new file mode 100644
index 0000000..bf3d586
--- /dev/null
+++ b/Voile/Source/UI/Containers/MarginContainer.cs
@@ -0,0 +1,78 @@
+using System.Numerics;
+
+namespace Voile.UI.Containers;
+
+///
+/// Represents the margin offsets applied around an element.
+///
+public struct Margin
+{
+ public float Left;
+ public float Right;
+ public float Top;
+ public float Bottom;
+
+ public Margin(float uniform)
+ {
+ Left = Right = Top = Bottom = uniform;
+ }
+
+ public Margin(float horizontal, float vertical)
+ {
+ Left = Right = horizontal;
+ Top = Bottom = vertical;
+ }
+
+ public Margin(float left, float right, float top, float bottom)
+ {
+ Left = left;
+ Right = right;
+ Top = top;
+ Bottom = bottom;
+ }
+
+ public static Margin Zero => new Margin(0);
+}
+
+public class MarginContainer : Container
+{
+ ///
+ /// The margin to apply around the contents of this container.
+ ///
+ public Margin Margin { get; set; }
+
+ ///
+ /// Specifies if this will fill to parent size.
+ ///
+ public bool Fill { get; set; } = true;
+
+ public MarginContainer() : this(new Margin()) { }
+
+ public MarginContainer(Margin margin)
+ {
+ Margin = margin;
+ }
+
+ protected override void OnUpdate()
+ {
+ base.OnUpdate();
+ if (Parent == null) return;
+
+ Size = Parent.Size;
+ }
+
+ public override void Arrange()
+ {
+ foreach (var child in Children)
+ {
+ var newPosition = new Vector2(Margin.Left, Margin.Top);
+ var newSize = new Rect(
+ Size.Width - Margin.Left - Margin.Right,
+ Size.Height - Margin.Top - Margin.Bottom
+ );
+
+ child.Size = newSize;
+ child.LocalPosition = newPosition;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Voile/Source/UI/UIElement.cs b/Voile/Source/UI/UIElement.cs
index 4a2a894..0b7fc09 100644
--- a/Voile/Source/UI/UIElement.cs
+++ b/Voile/Source/UI/UIElement.cs
@@ -23,8 +23,6 @@ public abstract class UIElement : IElement, IRenderableElement, IResizeableEleme
get => _size;
set
{
- _size = value;
-
if (value.Width < MinimumSize.Width)
{
_size.Width = MinimumSize.Width;
@@ -35,7 +33,12 @@ public abstract class UIElement : IElement, IRenderableElement, IResizeableEleme
_size.Height = MinimumSize.Height;
}
- MarkDirty();
+ if (_size != value)
+ {
+ MarkDirty();
+ }
+
+ _size = value;
}
}
public Vector2 AnchorOffset { get; set; } = Vector2.Zero;
@@ -44,7 +47,15 @@ public abstract class UIElement : IElement, IRenderableElement, IResizeableEleme
public abstract Rect MinimumSize { get; }
public bool Dirty => _dirty;
- public virtual void MarkDirty() => _dirty = true;
+ public virtual void MarkDirty()
+ {
+ if (Parent != null && !Parent.Dirty)
+ {
+ Parent.MarkDirty();
+ }
+
+ _dirty = true;
+ }
///
/// Sets a parent element for this .