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