using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Theriapolis.Game.CodexUI.Core; /// /// Base class for every CodexUI widget. Layout is two-pass: /// 1. — child reports a desired size given an /// available size envelope. /// 2. — parent places the child by writing into /// ; the child propagates to its own children. /// /// Update + Draw run after layout. Hit-testing uses screen-space /// directly via . /// public abstract class CodexWidget { public Rectangle Bounds { get; protected set; } public bool Visible { get; set; } = true; public bool Enabled { get; set; } = true; public CodexWidget? Parent { get; internal set; } public Point DesiredSize { get; protected set; } /// Child reports its preferred size; parent decides whether to honour it. public Point Measure(Point available) { DesiredSize = MeasureCore(available); return DesiredSize; } /// Parent commits a final rectangle; child propagates to grandchildren. public void Arrange(Rectangle bounds) { Bounds = bounds; ArrangeCore(bounds); } protected abstract Point MeasureCore(Point available); protected abstract void ArrangeCore(Rectangle bounds); public virtual void Update(GameTime gt, CodexInput input) { } public virtual void Draw(SpriteBatch sb, GameTime gt) { } /// True if a screen-space point lies inside our bounds. Hover-/click-test helper. public bool ContainsPoint(Point p) => Bounds.Contains(p); }