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