//! In-game UI system — widget tree, layout, styling, text, input routing.
//!
//! Stage 8 builds the engine's **in-game** UI — what an exported game uses
//! to draw its menus, HUDs, and tools. This is intentionally distinct from
//! the editor's `egui` (which stays editor-only): a shipped game cannot pull
//! in `egui`, so the runtime owns its own widget tree, lays it out, batches
//! it through the Stage-5 render pipeline, and routes input through the
//! Stage-7 model.
//!
//! Stage 8 is shipped in pieces:
//!
//! 1. **Piece 1 — widget tree + layout (this module, right now).** A flat
//!    [`Widget`] data structure, three layout modes ([`Stack`], [`Grid`],
//!    [`AnchorGroup`]), and a pure-logic [`layout`] function that turns a
//!    tree into a [`LayoutTree`] of resolved screen rects. No rendering,
//!    no input, fully testable headlessly.
//! 2. Piece 2 — styling & theming (`Style` / `Theme` + RON dual-edit).
//! 3. Piece 3 — text shaping & glyph atlas.
//! 4. Piece 4 — 2D overlay render pass.
//! 5. Piece 5 — input routing (hit-test, hover/focus/press).
//! 6. Piece 6 — events + data binding.
//! 7. Pieces 7–9 — GUI tail (`examples/ui_menu`, `examples/ui_hud`, editor
//!    UI canvas).
//!
//! # Worked example
//!
//! ```
//! use glam::Vec2;
//! use oxide_engine::math::Rect;
//! use oxide_engine::ui::{layout, Insets, LayoutStyle, Sizing, Widget};
//!
//! // A toolbar with two buttons and a stretching spacer between them.
//! let toolbar = Widget::row()
//!     .with_id("toolbar")
//!     .with_gap(8.0)
//!     .with_style(LayoutStyle {
//!         width: Sizing::Grow(1.0),
//!         height: Sizing::Fixed(32.0),
//!         padding: Insets::all(4.0),
//!         ..Default::default()
//!     })
//!     .with_child(Widget::leaf(Vec2::new(64.0, 24.0)).with_id("file"))
//!     .with_child(
//!         Widget::default()
//!             .with_id("spacer")
//!             .with_style(LayoutStyle {
//!                 width: Sizing::Grow(1.0),
//!                 height: Sizing::Grow(1.0),
//!                 ..Default::default()
//!             }),
//!     )
//!     .with_child(Widget::leaf(Vec2::new(64.0, 24.0)).with_id("help"));
//!
//! let viewport = Rect::from_min_size(Vec2::ZERO, Vec2::new(800.0, 600.0));
//! let tree = layout(&toolbar, viewport, 1.0);
//! let toolbar_rect = tree.root().unwrap().rect;
//! assert_eq!(toolbar_rect.height(), 32.0);
//! let help_rect = tree.find(&"help".into()).unwrap().rect;
//! assert_eq!(help_rect.max.x, 800.0 - 4.0); // padding on the right
//! ```

mod layout;
pub mod paint;
mod panel;
pub mod routing;
mod style;
pub mod text;
mod theme;
mod value;
mod visual;
mod widget;

pub use layout::{layout, LayoutNode, LayoutTree};
pub use paint::{paint, DrawCommand, PaintedFrame};
pub use panel::UiPanel;
pub use routing::{hit_test, Router, RouterEvent, RouterFrame};
pub use style::{Align, Anchor, Insets, LayoutStyle, Sizing};
pub use text::{
    shape, shape_runs, AtlasEntry, Font, FontError, FontId, FontLoader, FontStore, GlyphAtlas,
    GlyphId, GlyphKey, RasterizedGlyph, ShapeParams, ShapedGlyph, ShapedLine, ShapedText,
    TextAlign, TextRun, TextStyle,
};
pub use theme::Theme;
pub use value::WidgetValue;
pub use visual::{Border, FontRef, FontWeight, VisualStyle};
pub use widget::{
    AnchorGroup, Grid, Stack, StackDirection, Widget, WidgetId, WidgetKind, WidgetPath,
};
