cranpose_ui/widgets/box_widget.rs
1//! Box widget implementation
2
3use cranpose_core::NodeId;
4use cranpose_ui_layout::Alignment;
5
6use super::layout::compose_layout;
7use crate::{composable, layout::policies::BoxMeasurePolicy, modifier::Modifier};
8
9/// Specification for Box layout behavior.
10#[derive(Clone, Copy, Debug, PartialEq)]
11pub struct BoxSpec {
12 /// Where children sit inside the box. Defaults to top start.
13 pub content_alignment: Alignment,
14 /// Whether the box's minimum constraints pass on to its children. Defaults to `false`.
15 pub propagate_min_constraints: bool,
16}
17
18impl BoxSpec {
19 /// Creates a spec with top start alignment and no minimum constraint propagation.
20 pub fn new() -> Self {
21 Self::default()
22 }
23
24 /// Sets where children sit inside the box.
25 pub fn content_alignment(mut self, alignment: Alignment) -> Self {
26 self.content_alignment = alignment;
27 self
28 }
29
30 /// Sets whether the box's minimum constraints pass on to its children.
31 pub fn propagate_min_constraints(mut self, propagate: bool) -> Self {
32 self.propagate_min_constraints = propagate;
33 self
34 }
35}
36
37impl Default for BoxSpec {
38 fn default() -> Self {
39 Self {
40 content_alignment: Alignment::TOP_START,
41 propagate_min_constraints: false,
42 }
43 }
44}
45
46/// Places children over the same area. `content_alignment` selects each child's
47/// position within the box; later children draw above earlier children.
48///
49/// # Example
50///
51/// ```rust
52/// use cranpose_ui::*;
53///
54/// #[composable]
55/// fn Badge() {
56/// Box(
57/// Modifier::empty()
58/// .size_points(100.0, 100.0)
59/// .background(Color(0.1, 0.3, 0.9, 1.0)),
60/// BoxSpec::default().content_alignment(Alignment::CENTER),
61/// || {
62/// Text("Centered", Modifier::empty(), TextStyle::default());
63/// },
64/// );
65/// }
66/// ```
67#[composable]
68pub fn Box<F>(modifier: Modifier, spec: BoxSpec, content: F) -> NodeId
69where
70 F: FnMut() + 'static,
71{
72 let mut policy = BoxMeasurePolicy::new(spec.content_alignment, spec.propagate_min_constraints);
73 policy.layout_direction = crate::layout_direction();
74 compose_layout(modifier, policy, crate::density::density(), content)
75}