Files
Voile/Voile/Source/UI/Anchor.cs

94 lines
3.1 KiB
C#

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);
var parentSize = new Vector2(parentRect.Width, parentRect.Height);
return anchor switch
{
Anchor.TopLeft => Vector2.Zero,
Anchor.TopCenter => new Vector2((parentSize.X - size.X) / 2, 0),
Anchor.TopRight => new Vector2(parentSize.X - size.X, 0),
Anchor.CenterLeft => new Vector2(0, (parentSize.Y - size.Y) / 2),
Anchor.Center => (parentSize - size) / 2,
Anchor.CenterRight => new Vector2(parentSize.X - size.X, (parentSize.Y - size.Y) / 2),
Anchor.BottomLeft => new Vector2(0, parentSize.Y - size.Y),
Anchor.BottomCenter => new Vector2((parentSize.X - size.X) / 2, parentSize.Y - size.Y),
Anchor.BottomRight => parentSize - size,
_ => Vector2.Zero
};
}
}