diff --git a/hui/src/layout.rs b/hui/src/layout.rs index bcd3376..1aaadb6 100644 --- a/hui/src/layout.rs +++ b/hui/src/layout.rs @@ -46,6 +46,7 @@ pub struct Alignment2d { } impl Alignment2d { + /// Create a new `Alignment2d` with the same alignment for both axes #[inline] pub const fn all(alignment: Alignment) -> Self { Self { @@ -76,6 +77,9 @@ impl From for Alignment2d { } } +/// Represents a single size dimension of an UI element.\ +/// Can be either a static size in pixels, a fraction the parent size or auto-calculated\ +/// (Meaning of `auto` is entirely dependent on the element). #[derive(Default, Debug, Clone, Copy, PartialEq)] pub enum UiSize { #[default] @@ -83,6 +87,9 @@ pub enum UiSize { Auto, /// Size as a ratio of parent size\ /// Valid range: 0.0-1.0 (0-100%) + /// + /// Out of range values are allowed, but are not guaranteed to work as expected\ + /// (especially with negative values) Fraction(f32), /// Static size in pixels Static(f32), @@ -121,31 +128,61 @@ impl From for UiSize2d { //TODO?: add `UiSize2d` from `(Into, Into)` or Into conversion -/// Create a `UiSize` or `UiSize2d` from a literal +/// Constructs a `UiSize` or `UiSize2d` from a literal or expression +/// /// # Syntax: /// - `auto` - `UiSize::Auto` /// - `x` - `UiSize::Static(x)` -/// - `x%` - `UiSize::Fraction(x / 100.)` +/// - `x%` - `UiSize::Fraction(x / 100.)` *(literal only)* +/// - `x/` - `UiSize::Fraction(x)` /// -/// If two values are provided, it creates a `UiSize2d` with the first value as width and the second as height +/// ...where `x` is a literal, identifier or an expression wrapped in parentheses +/// +/// # Note: +/// - If a single argument is provided, it creates a `UiSize` using the rules specified above\ +/// - If two arguments are provided, it creates a `UiSize2d` with the first value as width and the second as height\ +/// Example: `size!(100, 50%)` creates a `UiSize2d` with width `100` (`UiSize::Static(100.)`) and height `50%` (`UiSize::Fraction(0.5)`) +/// - `%` syntax is only valid for literals (`50%`), not expressions or identidiers.\ +/// Use `/` instead (`(0.5 * x)/`, `x/`), but be aware of the different range (0.0-1.0) \ +/// - Expressions must be wrapped in parentheses (for example: `(x + 5)`).\ +/// This does not apply to single identifiers (`x`) or literals (`5`) #[macro_export] macro_rules! size { (auto) => { $crate::layout::UiSize::Auto }; + ($x:literal) => { $crate::layout::UiSize::Static($x as f32) }; ($x:literal %) => { $crate::layout::UiSize::Fraction($x as f32 / 100.) }; - ($x:literal , $y:tt $($ys:tt)?) => { + ($x:literal /) => { + $crate::layout::UiSize::Fraction($x as f32) + }; + + ($x:ident) => { + $crate::layout::UiSize::Static($x as f32) + }; + ($x:ident /) => { + $crate::layout::UiSize::Fraction($x as f32) + }; + + (($x:expr)) => { + $crate::layout::UiSize::Static(($x) as f32) + }; + (($x:expr) /) => { + $crate::layout::UiSize::Fraction(($x) as f32) + }; + + ($x:tt , $y:tt $($ys:tt)?) => { $crate::layout::UiSize2d { width: $crate::layout::size!($x), height: $crate::layout::size!($y $($ys)?), } }; - ($x:literal $($xs:tt)? , $y:tt $($ys:tt)?) => { + ($x:tt $($xs:tt)? , $y:tt $($ys:tt)?) => { $crate::layout::UiSize2d { width: $crate::layout::size!($x $($xs)?), height: $crate::layout::size!($y $($ys)?), @@ -154,16 +191,33 @@ macro_rules! size { } pub use size; +/// Represents the direction of the layout\ +/// (for example, the direction of a container's children)\ +/// +/// - `Vertical` - Children are laid out from top to bottom\ +/// - `Horizontal` - Children are laid out from left to right #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum UiDirection { + /// Children are laid out from top to bottom #[default] Vertical, + /// Children are laid out from left to right Horizontal, } +/// Represents the layout information required to measure, layout and render an element.\ +/// Includes the position, maximum size, direction of the layout and other information pub struct LayoutInfo { - ///Not availabe during measuring step + /// Screen-space coordinates of the top-left corner of the element.\ + /// Use this value during the layout step to render the element + /// + /// Not available during the measure step (will be set to zero) pub position: Vec2, + + /// Maximum size the element is allowed to take up pub max_size: Vec2, + + /// Current direction of the layout\ + /// (Usually matches direction of the parent container) pub direction: UiDirection, }