waterui_layout/
stack.rs

1//! Stack-based layout primitives.
2//!
3//! The submodules implement horizontal, vertical, and overlay stacks. These
4//! views arrange child content according to alignments and spacing and are the
5//! backbone of most declarative layouts in `WaterUI`.
6//!
7//! ![Stack](https://raw.githubusercontent.com/water-rs/waterui/dev/docs/illustrations/stack.svg)
8
9mod vstack;
10pub use vstack::*;
11mod hstack;
12pub use hstack::*;
13mod zstack;
14pub use zstack::*;
15
16/// Defines the axis of a stack.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18#[non_exhaustive]
19pub enum Axis {
20    /// Horizontal axis is the x-axis (`HStack`)
21    Horizontal,
22    /// Vertical axis is the y-axis (`VStack`)
23    Vertical,
24}
25
26impl Axis {
27    /// Returns true if this axis is horizontal.
28    #[must_use]
29    pub const fn is_horizontal(&self) -> bool {
30        matches!(self, Self::Horizontal)
31    }
32
33    /// Returns true if this axis is vertical.
34    #[must_use]
35    pub const fn is_vertical(&self) -> bool {
36        matches!(self, Self::Vertical)
37    }
38}
39
40/// Defines vertical alignment options for layout components.
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
42pub enum VerticalAlignment {
43    /// Pin the child to the top edge.
44    Top,
45    /// Center the child along the vertical axis.
46    #[default]
47    Center,
48    /// Pin the child to the bottom edge.
49    Bottom,
50}
51
52/// Defines horizontal alignment options for layout components.
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
54pub enum HorizontalAlignment {
55    /// Pin the child to the leading edge (left in LTR locales).
56    Leading,
57    /// Center the child along the horizontal axis.
58    #[default]
59    Center,
60    /// Pin the child to the trailing edge (right in LTR locales).
61    Trailing,
62}
63
64/// Combined two-dimensional alignment used by overlay stacks.
65#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Default)]
66pub enum Alignment {
67    /// Place the child in the top centre.
68    Top,
69    /// Place the child in the top-left corner.
70    TopLeading,
71    /// Place the child in the top-right corner.
72    TopTrailing,
73    #[default]
74    /// Place the child exactly in the centre.
75    Center,
76    /// Place the child in the bottom centre.
77    Bottom,
78    /// Place the child in the bottom-left corner.
79    BottomLeading,
80    /// Place the child in the bottom-right corner.
81    BottomTrailing,
82    /// Place the child in the vertical centre along the leading edge.
83    Leading,
84    /// Place the child in the vertical centre along the trailing edge.
85    Trailing,
86}
87
88impl Alignment {
89    /// Returns the horizontal alignment component of this alignment.
90    #[must_use]
91    pub const fn horizontal(&self) -> HorizontalAlignment {
92        match self {
93            Self::TopLeading | Self::Leading | Self::BottomLeading => HorizontalAlignment::Leading,
94            Self::TopTrailing | Self::Trailing | Self::BottomTrailing => {
95                HorizontalAlignment::Trailing
96            }
97            _ => HorizontalAlignment::Center,
98        }
99    }
100
101    /// Returns the vertical alignment component of this alignment.
102    #[must_use]
103    pub const fn vertical(&self) -> VerticalAlignment {
104        match self {
105            Self::TopLeading | Self::Top | Self::TopTrailing => VerticalAlignment::Top,
106            Self::BottomLeading | Self::Bottom | Self::BottomTrailing => VerticalAlignment::Bottom,
107            _ => VerticalAlignment::Center,
108        }
109    }
110}