Compare commits

..

2 Commits

11 changed files with 18 additions and 177 deletions

View File

@@ -90,14 +90,14 @@ public class TestGame : Game
protected override void Render(double deltaTime) protected override void Render(double deltaTime)
{ {
Renderer.ClearBackground(Color.Black); Renderer.ClearBackground(Color.CadetBlue);
foreach (var emitter in _particleSystem!.Emitters) // foreach (var emitter in _particleSystem!.Emitters)
{ // {
DrawEmitter(emitter); // DrawEmitter(emitter);
} // }
Renderer.ResetTransform(); // Renderer.ResetTransform();
_uiSystem.Render(Renderer); // _uiSystem.Render(Renderer);
} }
private void DrawEmitter(ParticleEmitter emitter) private void DrawEmitter(ParticleEmitter emitter)

View File

@@ -108,7 +108,7 @@ namespace Voile
if (Renderer is null) if (Renderer is null)
{ {
Renderer = new RaylibRenderSystem(); Renderer = new StandardRenderSystem();
} }
if (Input is null) if (Input is null)

View File

@@ -81,7 +81,7 @@ namespace Voile.Rendering
Raylib.InitWindow((int)_windowSize.X, (int)_windowSize.Y, windowSettings.Title); Raylib.InitWindow((int)_windowSize.X, (int)_windowSize.Y, windowSettings.Title);
} }
Raylib.SetWindowState(windowFlags); // Raylib.SetWindowState(windowFlags);
} }
// TODO // TODO

View File

@@ -256,7 +256,7 @@ namespace Voile.Rendering
{ {
public string Title; public string Title;
public Vector2 Size = new Vector2(1280, 720); public Vector2 Size = new Vector2(1280, 720);
public bool Resizable { get; set; } = true; public bool Resizable { get; set; }
public WindowSettings(string title, Vector2 size) public WindowSettings(string title, Vector2 size)
{ {

View File

@@ -363,7 +363,7 @@ namespace Voile.Rendering
private Silk.NET.WebGPU.Color VoileColorToWebGPUColor(Color color) private Silk.NET.WebGPU.Color VoileColorToWebGPUColor(Color color)
{ {
return new Silk.NET.WebGPU.Color(color.R, color.G, color.B, color.A); return new Silk.NET.WebGPU.Color((double)color.R / 255, (double)color.G / 255, (double)color.B / 255, (double)color.A / 255);
} }
private unsafe RenderPassColorAttachment CreateClearColorAttachment(TextureView* view, Color clearColor) private unsafe RenderPassColorAttachment CreateClearColorAttachment(TextureView* view, Color clearColor)

View File

@@ -13,35 +13,11 @@ namespace Voile
/// </summary> /// </summary>
public readonly Guid Guid = Guid.Empty; public readonly Guid Guid = Guid.Empty;
public bool HasValue => Guid != Guid.Empty; public bool HasValue => Guid != Guid.Empty;
/// <summary> /// <summary>
/// Retrieves a <see cref="Resource"/>.<br /> /// Retrieve a reference.
/// This will throw an <see cref="InvalidOperationException"/> if the resource wasn't loaded or is invalid. <br />
/// You can check if resource was loaded with <see cref="HasValue"/>, or consider using <see cref="TryGetValue"/>.
/// </summary> /// </summary>
public T Value => ResourceManager.GetResource<T>(Guid) public T Value => ResourceManager.GetResource<T>(Guid);
?? throw new InvalidOperationException($"Resource with GUID {Guid} is not loaded or invalid.");
/// <summary>
/// Retrieves a resource or <c>null</c> if the resource wasn't loaded or is invalid.
/// </summary>
public T? ValueOrNull => ResourceManager.GetResource<T>(Guid);
/// <summary>
/// Tries to retrieve a <see cref="Resource"/>.
/// </summary>
/// <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>
public bool TryGetValue(out T? value)
{
value = ResourceManager.GetResource<T>(Guid);
return value != null;
}
/// <summary>
/// Create an empty <see cref="ResourceRef"/>.
/// </summary>
/// <returns></returns>
public static ResourceRef<T> Empty() public static ResourceRef<T> Empty()
{ {
return new ResourceRef<T>(Guid.Empty); return new ResourceRef<T>(Guid.Empty);

View File

@@ -2,76 +2,23 @@ using System.Numerics;
namespace Voile.UI; namespace Voile.UI;
/// <summary>
/// Specifies predefined anchor points used to position UI elements relative to their parent container.
/// </summary>
public enum Anchor public enum Anchor
{ {
/// <summary>
/// Anchors the element to the top-left corner of the parent.
/// </summary>
TopLeft, TopLeft,
/// <summary>
/// Anchors the element to the top-center of the parent.
/// </summary>
TopCenter, TopCenter,
/// <summary>
/// Anchors the element to the top-right corner of the parent.
/// </summary>
TopRight, TopRight,
/// <summary>
/// Anchors the element to the center-left edge of the parent.
/// </summary>
CenterLeft, CenterLeft,
/// <summary>
/// Anchors the element to the exact center of the parent.
/// </summary>
Center, Center,
/// <summary>
/// Anchors the element to the center-right edge of the parent.
/// </summary>
CenterRight, CenterRight,
/// <summary>
/// Anchors the element to the bottom-left corner of the parent.
/// </summary>
BottomLeft, BottomLeft,
/// <summary>
/// Anchors the element to the bottom-center of the parent.
/// </summary>
BottomCenter, BottomCenter,
/// <summary>
/// Anchors the element to the bottom-right corner of the parent.
/// </summary>
BottomRight, BottomRight,
Fill Fill
} }
/// <summary>
/// Provides extension methods for calculating anchored positions of UI elements.
/// </summary>
public static class AnchorExtensions public static class AnchorExtensions
{ {
/// <summary>
/// Calculates the offset position for an element based on the specified <see cref="Anchor"/>.
/// </summary>
/// <param name="anchor">The anchor mode to use.</param>
/// <param name="parentPosition">The absolute position of the parent container (top-left corner).</param>
/// <param name="parentRect">The bounding rectangle of the parent container.</param>
/// <param name="elementRect">The size of the element being anchored.</param>
/// <returns>
/// A <see cref="Vector2"/> representing the local offset position where the element should be placed inside the parent.
/// </returns>
/// <remarks>
/// The result is the relative offset from the parent's origin, not a global position.
/// </remarks>
public static Vector2 Calculate(this Anchor anchor, Vector2 parentPosition, Rect parentRect, Rect elementRect) public static Vector2 Calculate(this Anchor anchor, Vector2 parentPosition, Rect parentRect, Rect elementRect)
{ {
var size = new Vector2(elementRect.Width, elementRect.Height); var size = new Vector2(elementRect.Width, elementRect.Height);

View File

@@ -3,6 +3,7 @@ using Voile.Rendering;
namespace Voile.UI.Containers; namespace Voile.UI.Containers;
// TODO: make Container extend Widget, it already implements similar behaviors.
/// <summary> /// <summary>
/// A base class for all UI containers, used to position and rendering child <see cref="IElement">s. /// A base class for all UI containers, used to position and rendering child <see cref="IElement">s.
/// </summary> /// </summary>

View File

@@ -1,10 +1,5 @@
using Voile.Rendering;
namespace Voile.UI.Containers; namespace Voile.UI.Containers;
/// <summary>
/// A frame is a special container that occupies the entire available size of the parent.
/// </summary>
public class Frame : Container public class Frame : Container
{ {
public Frame() public Frame()
@@ -21,37 +16,4 @@ public class Frame : Container
{ {
} }
public override void Render(RenderSystem renderer, Style style)
{
base.Render(renderer, style);
Rect parentSize;
if (Parent != null)
{
parentSize = Parent.Size;
}
else
{
var windowSize = renderer.WindowSize;
var windowRect = new Rect(windowSize.X, windowSize.Y);
parentSize = windowRect;
}
if (_lastParentSize != parentSize)
{
Size = parentSize;
_lastParentSize = parentSize;
}
}
protected override void OnUpdate()
{
base.OnUpdate();
Size = _lastParentSize;
}
private Rect _lastParentSize = Rect.Zero;
} }

View File

@@ -1,11 +1,9 @@
using System.Numerics; using System.Numerics;
using Voile.Input;
using Voile.Rendering; using Voile.Rendering;
namespace Voile.UI; namespace Voile.UI;
/// <summary>
/// Represents a basic UI element with position and size information.
/// </summary>
public interface IElement public interface IElement
{ {
/// <summary> /// <summary>
@@ -18,9 +16,6 @@ public interface IElement
public Rect Size { get; set; } public Rect Size { get; set; }
} }
/// <summary>
/// Represents a UI element that can contain child elements.
/// </summary>
public interface IParentableElement public interface IParentableElement
{ {
/// <summary> /// <summary>
@@ -39,10 +34,6 @@ public interface IParentableElement
public void RemoveChild(UIElement child); public void RemoveChild(UIElement child);
} }
/// <summary>
/// Represents a UI element that can provide a minimum size constraint.<br />
/// Implement this interface if your UI element is expected to be resizeable.
/// </summary>
public interface IResizeableElement public interface IResizeableElement
{ {
/// <summary> /// <summary>
@@ -51,13 +42,10 @@ public interface IResizeableElement
public abstract Rect MinimumSize { get; } public abstract Rect MinimumSize { get; }
} }
/// <summary>
/// Represents a UI element that supports updates when its state changes.
/// </summary>
public interface IUpdatableElement public interface IUpdatableElement
{ {
/// <summary> /// <summary>
/// Gets a value indicating whether the element's state has changed and needs to be updated. /// Specifies if this element's properties have changed, making it necessary to update it.
/// </summary> /// </summary>
public bool Dirty { get; } public bool Dirty { get; }
/// <summary> /// <summary>
@@ -70,9 +58,6 @@ public interface IUpdatableElement
void MarkDirty(); void MarkDirty();
} }
/// <summary>
/// Represents a UI element that can be rendered to the screen.
/// </summary>
public interface IRenderableElement public interface IRenderableElement
{ {
/// <summary> /// <summary>
@@ -92,9 +77,6 @@ public interface IRenderableElement
public void DrawSize(RenderSystem renderer); public void DrawSize(RenderSystem renderer);
} }
/// <summary>
/// Represents a UI element that can receive and process user input.
/// </summary>
public interface IInputElement public interface IInputElement
{ {
/// <summary> /// <summary>
@@ -108,23 +90,9 @@ public interface IInputElement
void Input(UIInputContext action); void Input(UIInputContext action);
} }
/// <summary>
/// Represents a UI element that supports positional anchoring within a parent.
/// </summary>
public interface IAnchorableElement public interface IAnchorableElement
{ {
/// <summary>
/// Gets or sets the anchor point relative to the parent container.
/// </summary>
public Anchor Anchor { get; set; } public Anchor Anchor { get; set; }
/// <summary>
/// Gets or sets an additional offset to apply after anchoring, in pixels.
/// </summary>
public Vector2 AnchorOffset { get; set; } public Vector2 AnchorOffset { get; set; }
/// <summary>
/// Applies the current anchor settings based on the parent's position and size.
/// </summary>
/// <param name="parentPosition">The parent's top-left global position.</param>
/// <param name="parentRect">The bounding rectangle of the parent container.</param>
public void ApplyAnchor(Vector2 parentPosition, Rect parentRect); public void ApplyAnchor(Vector2 parentPosition, Rect parentRect);
} }

View File

@@ -3,9 +3,6 @@ using Voile.Rendering;
namespace Voile.UI; namespace Voile.UI;
/// <summary>
/// Base class for all UI elements.
/// </summary>
public abstract class UIElement : IElement, IRenderableElement, IResizeableElement, IUpdatableElement, IAnchorableElement public abstract class UIElement : IElement, IRenderableElement, IResizeableElement, IUpdatableElement, IAnchorableElement
{ {
public bool Visible { get; set; } = true; public bool Visible { get; set; } = true;
@@ -13,11 +10,6 @@ public abstract class UIElement : IElement, IRenderableElement, IResizeableEleme
public Vector2 LocalPosition { get; set; } = Vector2.Zero; public Vector2 LocalPosition { get; set; } = Vector2.Zero;
public Vector2 GlobalPosition => _parent?.GlobalPosition + LocalPosition ?? LocalPosition; public Vector2 GlobalPosition => _parent?.GlobalPosition + LocalPosition ?? LocalPosition;
/// <summary>
/// Parent <see cref="UIElement"/> of this element.
/// </summary>
public UIElement? Parent => _parent;
public Rect Size public Rect Size
{ {
get => _size; get => _size;
@@ -46,14 +38,9 @@ public abstract class UIElement : IElement, IRenderableElement, IResizeableEleme
public virtual void MarkDirty() => _dirty = true; public virtual void MarkDirty() => _dirty = true;
/// <summary>
/// Sets a parent element for this <see cref="UIElement"/>.
/// </summary>
/// <param name="parent">Element to parent this <see cref="UIElement"/> to.</param>
public void SetParent(UIElement parent) public void SetParent(UIElement parent)
{ {
_parent = parent; _parent = parent;
MarkDirty();
} }
public void Update() public void Update()