Skip to main content

cranpose_ui/widgets/
column.rs

1//! Column widget implementation
2
3#![allow(non_snake_case)]
4
5use super::layout::Layout;
6use crate::composable;
7use crate::layout::policies::FlexMeasurePolicy;
8use crate::modifier::Modifier;
9use cranpose_core::NodeId;
10use cranpose_ui_layout::{HorizontalAlignment, LinearArrangement};
11
12/// Specification for Column layout behavior.
13#[derive(Clone, Copy, Debug, PartialEq)]
14pub struct ColumnSpec {
15    pub vertical_arrangement: LinearArrangement,
16    pub horizontal_alignment: HorizontalAlignment,
17}
18
19impl ColumnSpec {
20    pub fn new() -> Self {
21        Self::default()
22    }
23
24    pub fn vertical_arrangement(mut self, arrangement: LinearArrangement) -> Self {
25        self.vertical_arrangement = arrangement;
26        self
27    }
28
29    pub fn horizontal_alignment(mut self, alignment: HorizontalAlignment) -> Self {
30        self.horizontal_alignment = alignment;
31        self
32    }
33}
34
35impl Default for ColumnSpec {
36    fn default() -> Self {
37        Self {
38            vertical_arrangement: LinearArrangement::Start,
39            horizontal_alignment: HorizontalAlignment::Start,
40        }
41    }
42}
43
44/// A layout composable that places its children in a vertical sequence.
45///
46/// # When to use
47/// Use `Column` to arrange items top-to-bottom. For horizontal arrangement, use [`Row`](crate::widgets::Row).
48///
49/// # Arguments
50///
51/// * `modifier` - Modifiers to apply to the column layout.
52/// * `spec` - Configuration for vertical arrangement and horizontal alignment.
53/// * `content` - The children composables to layout.
54///
55/// # Example
56///
57/// ```rust,ignore
58/// Column(
59///     Modifier::padding(16.0),
60///     ColumnSpec::default().vertical_arrangement(LinearArrangement::spaced_by(8.0)),
61///     || {
62///         Text("Title", Modifier::empty());
63///         Text("Subtitle", Modifier::empty());
64///     }
65/// );
66/// ```
67#[composable]
68pub fn Column<F>(modifier: Modifier, spec: ColumnSpec, content: F) -> NodeId
69where
70    F: FnMut() + 'static,
71{
72    let policy = FlexMeasurePolicy::column(spec.vertical_arrangement, spec.horizontal_alignment);
73    Layout(modifier, policy, content)
74}