Add dirty UI element visualization to UISystem, fix Frame being constantly updated.

This commit is contained in:
2025-06-24 23:29:26 +02:00
parent b2f3e1c351
commit d44341974f
5 changed files with 60 additions and 31 deletions

View File

@@ -127,22 +127,22 @@ public class TestGame : Game
private ResourceRef<Sound> _sound; private ResourceRef<Sound> _sound;
private ResourceRef<Texture2d> _icon; private ResourceRef<Texture2d> _icon;
private FlexContainer _container = new(minimumSize: new Rect(64.0f, 64.0f), new()) // private FlexContainer _container = new(minimumSize: new Rect(64.0f, 64.0f), new())
{ // {
Anchor = Anchor.Center, // Anchor = Anchor.Center,
Size = new Rect(500, 300), // Size = new Rect(500, 300),
Direction = FlexDirection.Column, // Direction = FlexDirection.Column,
Justify = JustifyContent.Start, // Justify = JustifyContent.Start,
Align = AlignItems.Center, // Align = AlignItems.Center,
Wrap = true, // Wrap = true,
Gap = 10f // Gap = 10f
}; // };
private Frame _frame = new(); private Frame _frame = new();
// private VerticalContainer _container = new(new Rect(128.0f, 64.0f), new(), 16) private VerticalContainer _container = new(new Rect(128.0f, 64.0f), new(), 16)
// { {
// ConfineToContents = true, ConfineToContents = true,
// Anchor = Anchor.CenterLeft, Anchor = Anchor.CenterLeft,
// AnchorOffset = new Vector2(0.5f, 0.0f) AnchorOffset = new Vector2(0.5f, 0.0f)
// }; };
} }

View File

@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using Voile.Resources; using Voile.Resources;
namespace Voile namespace Voile
@@ -32,7 +33,7 @@ namespace Voile
/// </summary> /// </summary>
/// <param name="value">An instance of a retrieved <see cref="Resource"/>.</param> /// <param name="value">An instance of a retrieved <see cref="Resource"/>.</param>
/// <returns><c>true</c> if the resource was successfully retrieved, otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the resource was successfully retrieved, otherwise <c>false</c>.</returns>
public bool TryGetValue(out T? value) public bool TryGetValue([NotNullWhen(true)] out T? value)
{ {
value = ResourceManager.GetResource<T>(Guid); value = ResourceManager.GetResource<T>(Guid);
return value != null; return value != null;

View File

@@ -44,7 +44,6 @@ public abstract class Container : UIElement, IParentableElement
{ {
if (child is not IUpdatableElement updatable) continue; if (child is not IUpdatableElement updatable) continue;
updatable.MarkDirty();
updatable.Update(); updatable.Update();
if (child is IAnchorableElement anchorable) if (child is IAnchorableElement anchorable)

View File

@@ -50,7 +50,12 @@ public class Frame : Container
protected override void OnUpdate() protected override void OnUpdate()
{ {
base.OnUpdate(); base.OnUpdate();
if (Size == _lastParentSize) return;
Size = _lastParentSize; Size = _lastParentSize;
Console.WriteLine("Updating");
} }
private Rect _lastParentSize = Rect.Zero; private Rect _lastParentSize = Rect.Zero;

View File

@@ -9,6 +9,8 @@ public class UISystem : IUpdatableSystem, IRenderableSystem
public IReadOnlyList<IElement> Elements => _elements; public IReadOnlyList<IElement> Elements => _elements;
public bool RenderDebugRects { get; set; } public bool RenderDebugRects { get; set; }
public Color DebugSizeRectColor { get; set; } = Color.Red;
public Color DebugDirtyRectColor { get; set; } = new Color(1.0f, 1.0f, 0.0f, 0.5f);
public UISystem(InputSystem inputSystem) public UISystem(InputSystem inputSystem)
{ {
@@ -50,22 +52,44 @@ public class UISystem : IUpdatableSystem, IRenderableSystem
{ {
if (element is IRenderableElement renderable) if (element is IRenderableElement renderable)
{ {
renderable.Render(renderer, _style.Value); // TODO: normally you'd load a default style if the one supplied is empty,
// but for now this will do.
if (!RenderDebugRects) return; if (!_style.TryGetValue(out var value))
renderable.DrawSize(renderer); {
value = new Style(string.Empty);
} }
if (element is IParentableElement parentable) renderable.Render(renderer, value);
{ }
foreach (var child in parentable.Children) }
{
if (child is not IRenderableElement renderableChild) continue;
if (!RenderDebugRects) return; if (!RenderDebugRects) return;
renderableChild.DrawSize(renderer);
foreach (var element in _elements)
{
if (element is not UIElement uiElement) continue;
DrawDebugForElement(renderer, uiElement);
} }
} }
private void DrawDebugForElement(RenderSystem renderer, UIElement element)
{
var size = new Vector2(element.Size.Width, element.Size.Height);
renderer.SetTransform(element.GlobalPosition, Vector2.Zero);
renderer.DrawRectangleOutline(size, DebugSizeRectColor);
if (element.Dirty)
{
renderer.DrawRectangle(size, DebugDirtyRectColor);
}
if (element is IParentableElement parentableElement)
{
foreach (var child in parentableElement.Children)
{
if (child is not UIElement childElement) continue;
DrawDebugForElement(renderer, childElement);
}
} }
} }