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}