Skip to main content

cranpose_ui/modifier/
size.rs

1//! Size modifier implementations following Jetpack Compose's layout/Size.kt
2//!
3//! Reference: /media/huge/composerepo/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt
4
5use super::{inspector_metadata, DimensionConstraint, Modifier, Size};
6use crate::modifier_nodes::{IntrinsicSizeElement, SizeElement};
7use cranpose_ui_layout::IntrinsicSize;
8
9impl Modifier {
10    /// Declare the preferred size of the content to be exactly [size].
11    ///
12    /// The incoming measurement constraints may override this value, forcing the content
13    /// to be either smaller or larger.
14    ///
15    /// Matches Kotlin: `Modifier.size(size: Dp)`
16    ///
17    /// Example: `Modifier::empty().size(Size { width: 100.0, height: 200.0 })`
18    pub fn size(self, size: Size) -> Self {
19        let width = size.width;
20        let height = size.height;
21        let modifier = Self::with_element(SizeElement::new(Some(width), Some(height)))
22            .with_inspector_metadata(inspector_metadata("size", move |info| {
23                info.add_dimension("width", DimensionConstraint::Points(width));
24                info.add_dimension("height", DimensionConstraint::Points(height));
25            }));
26        self.then(modifier)
27    }
28
29    /// Declare the preferred size of the content to be exactly [width]dp by [height]dp.
30    ///
31    /// Convenience method for `size(Size { width, height })`.
32    ///
33    /// Example: `Modifier::empty().size_points(100.0, 200.0)`
34    pub fn size_points(self, width: f32, height: f32) -> Self {
35        self.size(Size { width, height })
36    }
37
38    /// Declare the preferred width of the content to be exactly [width]dp.
39    ///
40    /// The incoming measurement constraints may override this value, forcing the content
41    /// to be either smaller or larger.
42    ///
43    /// Matches Kotlin: `Modifier.width(width: Dp)`
44    ///
45    /// Example: `Modifier::empty().width(100.0).height(200.0)`
46    pub fn width(self, width: f32) -> Self {
47        let modifier = Self::with_element(SizeElement::new(Some(width), None))
48            .with_inspector_metadata(inspector_metadata("width", move |info| {
49                info.add_dimension("width", DimensionConstraint::Points(width));
50            }));
51        self.then(modifier)
52    }
53
54    /// Declare the preferred height of the content to be exactly [height]dp.
55    ///
56    /// The incoming measurement constraints may override this value, forcing the content
57    /// to be either smaller or larger.
58    ///
59    /// Matches Kotlin: `Modifier.height(height: Dp)`
60    ///
61    /// Example: `Modifier::empty().width(100.0).height(200.0)`
62    pub fn height(self, height: f32) -> Self {
63        let modifier = Self::with_element(SizeElement::new(None, Some(height)))
64            .with_inspector_metadata(inspector_metadata("height", move |info| {
65                info.add_dimension("height", DimensionConstraint::Points(height));
66            }));
67        self.then(modifier)
68    }
69
70    /// Declare the width of the content based on its intrinsic size.
71    ///
72    /// Matches Kotlin: `Modifier.width(IntrinsicSize)`
73    pub fn width_intrinsic(self, intrinsic: IntrinsicSize) -> Self {
74        let modifier = Self::with_element(IntrinsicSizeElement::width(intrinsic))
75            .with_inspector_metadata(inspector_metadata("widthIntrinsic", move |info| {
76                info.add_dimension("width", DimensionConstraint::Intrinsic(intrinsic));
77            }));
78        self.then(modifier)
79    }
80
81    /// Declare the height of the content based on its intrinsic size.
82    ///
83    /// Matches Kotlin: `Modifier.height(IntrinsicSize)`
84    pub fn height_intrinsic(self, intrinsic: IntrinsicSize) -> Self {
85        let modifier = Self::with_element(IntrinsicSizeElement::height(intrinsic))
86            .with_inspector_metadata(inspector_metadata("heightIntrinsic", move |info| {
87                info.add_dimension("height", DimensionConstraint::Intrinsic(intrinsic));
88            }));
89        self.then(modifier)
90    }
91
92    /// Declare the size of the content to be exactly [size], ignoring incoming constraints.
93    ///
94    /// The incoming measurement constraints will not override this value. If the content
95    /// chooses a size that does not satisfy the incoming constraints, the parent layout
96    /// will be reported a size coerced in the constraints.
97    ///
98    /// Matches Kotlin: `Modifier.requiredSize(size: Dp)`
99    pub fn required_size(self, size: Size) -> Self {
100        let modifier = Self::with_element(SizeElement::with_constraints(
101            Some(size.width),
102            Some(size.width),
103            Some(size.height),
104            Some(size.height),
105            false,
106        ));
107        self.then(modifier)
108    }
109}