Compare commits
4 Commits
standard-r
...
5871e8966b
| Author | SHA1 | Date | |
|---|---|---|---|
| 5871e8966b | |||
| ed9f17e6c4 | |||
| 4362e88eab | |||
| 58efd449a8 |
@@ -81,7 +81,7 @@ namespace Voile.Rendering
|
||||
Raylib.InitWindow((int)_windowSize.X, (int)_windowSize.Y, windowSettings.Title);
|
||||
}
|
||||
|
||||
// Raylib.SetWindowState(windowFlags);
|
||||
Raylib.SetWindowState(windowFlags);
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
@@ -256,7 +256,7 @@ namespace Voile.Rendering
|
||||
{
|
||||
public string Title;
|
||||
public Vector2 Size = new Vector2(1280, 720);
|
||||
public bool Resizable { get; set; }
|
||||
public bool Resizable { get; set; } = true;
|
||||
|
||||
public WindowSettings(string title, Vector2 size)
|
||||
{
|
||||
|
||||
@@ -13,11 +13,35 @@ namespace Voile
|
||||
/// </summary>
|
||||
public readonly Guid Guid = Guid.Empty;
|
||||
public bool HasValue => Guid != Guid.Empty;
|
||||
/// <summary>
|
||||
/// Retrieve a reference.
|
||||
/// </summary>
|
||||
public T Value => ResourceManager.GetResource<T>(Guid);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a <see cref="Resource"/>.<br />
|
||||
/// 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>
|
||||
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()
|
||||
{
|
||||
return new ResourceRef<T>(Guid.Empty);
|
||||
|
||||
@@ -2,23 +2,76 @@ using System.Numerics;
|
||||
|
||||
namespace Voile.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies predefined anchor points used to position UI elements relative to their parent container.
|
||||
/// </summary>
|
||||
public enum Anchor
|
||||
{
|
||||
/// <summary>
|
||||
/// Anchors the element to the top-left corner of the parent.
|
||||
/// </summary>
|
||||
TopLeft,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the top-center of the parent.
|
||||
/// </summary>
|
||||
TopCenter,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the top-right corner of the parent.
|
||||
/// </summary>
|
||||
TopRight,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the center-left edge of the parent.
|
||||
/// </summary>
|
||||
CenterLeft,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the exact center of the parent.
|
||||
/// </summary>
|
||||
Center,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the center-right edge of the parent.
|
||||
/// </summary>
|
||||
CenterRight,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the bottom-left corner of the parent.
|
||||
/// </summary>
|
||||
BottomLeft,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the bottom-center of the parent.
|
||||
/// </summary>
|
||||
BottomCenter,
|
||||
|
||||
/// <summary>
|
||||
/// Anchors the element to the bottom-right corner of the parent.
|
||||
/// </summary>
|
||||
BottomRight,
|
||||
Fill
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for calculating anchored positions of UI elements.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
var size = new Vector2(elementRect.Width, elementRect.Height);
|
||||
|
||||
@@ -3,7 +3,6 @@ using Voile.Rendering;
|
||||
|
||||
namespace Voile.UI.Containers;
|
||||
|
||||
// TODO: make Container extend Widget, it already implements similar behaviors.
|
||||
/// <summary>
|
||||
/// A base class for all UI containers, used to position and rendering child <see cref="IElement">s.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
using Voile.Rendering;
|
||||
|
||||
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 Frame()
|
||||
@@ -9,11 +14,44 @@ public class Frame : Container
|
||||
|
||||
public Frame(Rect minimumSize) : base(minimumSize)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Arrange()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using System.Numerics;
|
||||
using Voile.Input;
|
||||
using Voile.Rendering;
|
||||
|
||||
namespace Voile.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a basic UI element with position and size information.
|
||||
/// </summary>
|
||||
public interface IElement
|
||||
{
|
||||
/// <summary>
|
||||
@@ -16,6 +18,9 @@ public interface IElement
|
||||
public Rect Size { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a UI element that can contain child elements.
|
||||
/// </summary>
|
||||
public interface IParentableElement
|
||||
{
|
||||
/// <summary>
|
||||
@@ -34,6 +39,10 @@ public interface IParentableElement
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
@@ -42,10 +51,13 @@ public interface IResizeableElement
|
||||
public abstract Rect MinimumSize { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a UI element that supports updates when its state changes.
|
||||
/// </summary>
|
||||
public interface IUpdatableElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies if this element's properties have changed, making it necessary to update it.
|
||||
/// Gets a value indicating whether the element's state has changed and needs to be updated.
|
||||
/// </summary>
|
||||
public bool Dirty { get; }
|
||||
/// <summary>
|
||||
@@ -58,6 +70,9 @@ public interface IUpdatableElement
|
||||
void MarkDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a UI element that can be rendered to the screen.
|
||||
/// </summary>
|
||||
public interface IRenderableElement
|
||||
{
|
||||
/// <summary>
|
||||
@@ -77,6 +92,9 @@ public interface IRenderableElement
|
||||
public void DrawSize(RenderSystem renderer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a UI element that can receive and process user input.
|
||||
/// </summary>
|
||||
public interface IInputElement
|
||||
{
|
||||
/// <summary>
|
||||
@@ -90,9 +108,23 @@ public interface IInputElement
|
||||
void Input(UIInputContext action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a UI element that supports positional anchoring within a parent.
|
||||
/// </summary>
|
||||
public interface IAnchorableElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the anchor point relative to the parent container.
|
||||
/// </summary>
|
||||
public Anchor Anchor { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets an additional offset to apply after anchoring, in pixels.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
@@ -3,6 +3,9 @@ using Voile.Rendering;
|
||||
|
||||
namespace Voile.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all UI elements.
|
||||
/// </summary>
|
||||
public abstract class UIElement : IElement, IRenderableElement, IResizeableElement, IUpdatableElement, IAnchorableElement
|
||||
{
|
||||
public bool Visible { get; set; } = true;
|
||||
@@ -10,6 +13,11 @@ public abstract class UIElement : IElement, IRenderableElement, IResizeableEleme
|
||||
public Vector2 LocalPosition { get; set; } = Vector2.Zero;
|
||||
public Vector2 GlobalPosition => _parent?.GlobalPosition + LocalPosition ?? LocalPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Parent <see cref="UIElement"/> of this element.
|
||||
/// </summary>
|
||||
public UIElement? Parent => _parent;
|
||||
|
||||
public Rect Size
|
||||
{
|
||||
get => _size;
|
||||
@@ -38,9 +46,14 @@ public abstract class UIElement : IElement, IRenderableElement, IResizeableEleme
|
||||
|
||||
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)
|
||||
{
|
||||
_parent = parent;
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
|
||||
Reference in New Issue
Block a user