Skip to main content

cranpose_ui/widgets/
row.rs

1//! Row widget implementation
2
3use cranpose_core::NodeId;
4use cranpose_ui_layout::{LinearArrangement, VerticalAlignment};
5
6use super::layout::compose_layout;
7use crate::{composable, layout::policies::FlexMeasurePolicy, modifier::Modifier};
8
9/// Specification for Row layout behavior.
10#[derive(Clone, Copy, Debug, PartialEq)]
11pub struct RowSpec {
12    /// How children are spaced along the horizontal axis. Defaults to `Start`.
13    pub horizontal_arrangement: LinearArrangement,
14    /// How children align on the vertical axis. Defaults to `Top`.
15    pub vertical_alignment: VerticalAlignment,
16}
17
18impl RowSpec {
19    /// Creates a spec with start arrangement and top alignment.
20    pub fn new() -> Self {
21        Self::default()
22    }
23
24    /// Sets how children are spaced along the horizontal axis.
25    pub fn horizontal_arrangement(mut self, arrangement: LinearArrangement) -> Self {
26        self.horizontal_arrangement = arrangement;
27        self
28    }
29
30    /// Sets how children align on the vertical axis.
31    pub fn vertical_alignment(mut self, alignment: VerticalAlignment) -> Self {
32        self.vertical_alignment = alignment;
33        self
34    }
35}
36
37impl Default for RowSpec {
38    fn default() -> Self {
39        Self {
40            horizontal_arrangement: LinearArrangement::Start,
41            vertical_alignment: VerticalAlignment::Top,
42        }
43    }
44}
45
46/// Places children from left to right, or right to left for an RTL layout.
47/// `spec` sets horizontal space and vertical alignment.
48///
49/// # Example
50///
51/// ```rust
52/// use cranpose_ui::*;
53///
54/// #[composable]
55/// fn Summary() {
56///     Row(
57///         Modifier::empty().fill_max_width(),
58///         RowSpec::default().horizontal_arrangement(LinearArrangement::SpaceBetween),
59///         || {
60///             Text("Name", Modifier::empty(), TextStyle::default());
61///             Text("Value", Modifier::empty(), TextStyle::default());
62///         },
63///     );
64/// }
65/// ```
66#[composable]
67pub fn Row<F>(modifier: Modifier, spec: RowSpec, content: F) -> NodeId
68where
69    F: FnMut() + 'static,
70{
71    let density = crate::density::density();
72    let mut policy = FlexMeasurePolicy::row(
73        spec.horizontal_arrangement,
74        spec.vertical_alignment,
75        density.density(),
76    );
77    policy.layout_direction = crate::layout_direction();
78    compose_layout(modifier, policy, density, content)
79}