Skip to main content

cranpose_ui/widgets/
flow_row.rs

1//! FlowRow widget implementation
2
3use cranpose_core::NodeId;
4
5use super::layout::Layout;
6use crate::{composable, layout::policies::FlowRowMeasurePolicy, modifier::Modifier};
7
8/// Specification for FlowRow layout behavior.
9#[derive(Clone, Copy, Debug, PartialEq)]
10pub struct FlowRowSpec {
11    /// Horizontal gap between adjacent children on the same line, in dp
12    /// (Compose: `horizontalArrangement = Arrangement.spacedBy(..)`).
13    pub main_axis_spacing: f32,
14    /// Vertical gap between consecutive lines, in dp
15    /// (Compose: `verticalArrangement = Arrangement.spacedBy(..)`).
16    pub cross_axis_spacing: f32,
17}
18
19impl FlowRowSpec {
20    /// Creates a spec with no gaps between children or between rows.
21    pub fn new() -> Self {
22        Self::default()
23    }
24
25    /// Sets the horizontal gap between adjacent children on one row, in logical pixels.
26    pub fn main_axis_spacing(mut self, spacing: f32) -> Self {
27        self.main_axis_spacing = spacing;
28        self
29    }
30
31    /// Sets the vertical gap between consecutive rows, in logical pixels.
32    pub fn cross_axis_spacing(mut self, spacing: f32) -> Self {
33        self.cross_axis_spacing = spacing;
34        self
35    }
36}
37
38impl Default for FlowRowSpec {
39    fn default() -> Self {
40        Self {
41            main_axis_spacing: 0.0,
42            cross_axis_spacing: 0.0,
43        }
44    }
45}
46
47/// Places children across a row and starts a new row when the available width is full.
48/// The spec sets the space between children and between rows.
49///
50/// # Example
51///
52/// ```rust
53/// use cranpose_ui::{
54///     widgets::{FlowRow, FlowRowSpec},
55///     *,
56/// };
57///
58/// #[composable]
59/// fn Topics() {
60///     FlowRow(
61///         Modifier::empty().fill_max_width(),
62///         FlowRowSpec::new()
63///             .main_axis_spacing(8.0)
64///             .cross_axis_spacing(4.0),
65///         || {
66///             for label in ["Rust", "Compose", "Android"] {
67///                 Text(label, Modifier::empty().padding(8.0), TextStyle::default());
68///             }
69///         },
70///     );
71/// }
72/// ```
73#[composable]
74pub fn FlowRow<F>(modifier: Modifier, spec: FlowRowSpec, content: F) -> NodeId
75where
76    F: FnMut() + 'static,
77{
78    let mut policy = FlowRowMeasurePolicy::new(spec.main_axis_spacing, spec.cross_axis_spacing);
79    policy.layout_direction = crate::layout_direction();
80    Layout(modifier, policy, content)
81}