Skip to main content

cranpose_ui/modifier/
resolved_modifiers.rs

1use cranpose_ui_layout::{Alignment, HorizontalAlignment, IntrinsicSize, VerticalAlignment};
2
3use super::{Color, EdgeInsets, Point, RoundedCornerShape};
4
5/// A background fill: its color and, when the corners are rounded, their shape.
6#[derive(Clone, Copy, Debug, PartialEq)]
7pub struct ResolvedBackground {
8    pub(super) color: Color,
9    pub(super) shape: Option<RoundedCornerShape>,
10}
11
12impl ResolvedBackground {
13    /// Creates a background of `color` with the corner `shape`, or square corners when `shape` is
14    /// `None`.
15    pub fn new(color: Color, shape: Option<RoundedCornerShape>) -> Self {
16        Self { color, shape }
17    }
18
19    /// Returns the fill color.
20    pub fn color(&self) -> Color {
21        self.color
22    }
23
24    /// Returns the corner shape, or `None` for square corners.
25    pub fn shape(&self) -> Option<RoundedCornerShape> {
26        self.shape
27    }
28
29    /// Replaces the corner shape. `None` gives square corners.
30    pub fn set_shape(&mut self, shape: Option<RoundedCornerShape>) {
31        self.shape = shape;
32    }
33}
34
35/// The padding, layout properties and offset that a modifier chain resolves to.
36#[derive(Clone, Copy, Debug, PartialEq, Default)]
37pub struct ResolvedModifiers {
38    pub(super) padding: EdgeInsets,
39    pub(super) layout: LayoutProperties,
40    pub(super) offset: Point,
41}
42
43impl ResolvedModifiers {
44    /// Returns the padding on each edge, in logical pixels.
45    pub fn padding(&self) -> EdgeInsets {
46        self.padding
47    }
48
49    /// Returns the size, alignment and weight settings of the chain.
50    pub fn layout_properties(&self) -> LayoutProperties {
51        self.layout
52    }
53
54    /// Returns the offset of the content, in logical pixels.
55    pub fn offset(&self) -> Point {
56        self.offset
57    }
58
59    pub(crate) fn set_padding(&mut self, padding: EdgeInsets) {
60        self.padding = padding;
61    }
62
63    pub(crate) fn set_layout_properties(&mut self, layout: LayoutProperties) {
64        self.layout = layout;
65    }
66
67    pub(crate) fn set_offset(&mut self, offset: Point) {
68        self.offset = offset;
69    }
70
71    /// These modifiers with every length on a whole device pixel of
72    /// `density`, as Compose's `roundToPx` puts padding, sizes and offsets.
73    pub(crate) fn on_device_grid(&self, density: f32) -> Self {
74        use cranpose_ui_layout::round_to_px;
75
76        let round = |value: Option<f32>| value.map(|value| round_to_px(value, density));
77        let dimension = |dimension: DimensionConstraint| match dimension {
78            DimensionConstraint::Points(value) => {
79                DimensionConstraint::Points(round_to_px(value, density))
80            }
81            other => other,
82        };
83        Self {
84            padding: crate::modifier_nodes::device_padding(self.padding, density),
85            layout: LayoutProperties {
86                padding: crate::modifier_nodes::device_padding(self.layout.padding, density),
87                width: dimension(self.layout.width),
88                height: dimension(self.layout.height),
89                min_width: round(self.layout.min_width),
90                min_height: round(self.layout.min_height),
91                max_width: round(self.layout.max_width),
92                max_height: round(self.layout.max_height),
93                ..self.layout
94            },
95            offset: Point {
96                x: round_to_px(self.offset.x, density),
97                y: round_to_px(self.offset.y, density),
98            },
99        }
100    }
101}
102
103#[derive(Clone, Copy, Debug, Default, PartialEq)]
104pub enum DimensionConstraint {
105    #[default]
106    Unspecified,
107    Points(f32),
108    Fraction(f32),
109    Intrinsic(IntrinsicSize),
110}
111
112#[derive(Clone, Copy, Debug, Default, PartialEq)]
113pub struct LayoutWeight {
114    pub weight: f32,
115    pub fill: bool,
116}
117
118#[derive(Clone, Copy, Debug, Default, PartialEq)]
119pub struct LayoutProperties {
120    pub(super) padding: EdgeInsets,
121    pub(super) width: DimensionConstraint,
122    pub(super) height: DimensionConstraint,
123    pub(super) min_width: Option<f32>,
124    pub(super) min_height: Option<f32>,
125    pub(super) max_width: Option<f32>,
126    pub(super) max_height: Option<f32>,
127    pub(super) weight: Option<LayoutWeight>,
128    pub(super) box_alignment: Option<Alignment>,
129    pub(super) column_alignment: Option<HorizontalAlignment>,
130    pub(super) row_alignment: Option<VerticalAlignment>,
131    pub(super) row_baseline: bool,
132}
133
134impl LayoutProperties {
135    pub fn padding(&self) -> EdgeInsets {
136        self.padding
137    }
138
139    pub fn width(&self) -> DimensionConstraint {
140        self.width
141    }
142
143    pub fn height(&self) -> DimensionConstraint {
144        self.height
145    }
146
147    pub fn min_width(&self) -> Option<f32> {
148        self.min_width
149    }
150
151    pub fn min_height(&self) -> Option<f32> {
152        self.min_height
153    }
154
155    pub fn max_width(&self) -> Option<f32> {
156        self.max_width
157    }
158
159    pub fn max_height(&self) -> Option<f32> {
160        self.max_height
161    }
162
163    pub fn weight(&self) -> Option<LayoutWeight> {
164        self.weight
165    }
166
167    pub fn box_alignment(&self) -> Option<Alignment> {
168        self.box_alignment
169    }
170
171    pub fn column_alignment(&self) -> Option<HorizontalAlignment> {
172        self.column_alignment
173    }
174
175    pub fn row_alignment(&self) -> Option<VerticalAlignment> {
176        self.row_alignment
177    }
178
179    /// Whether the parent Row aligns this child's first baseline with its siblings.
180    pub fn row_baseline(&self) -> bool {
181        self.row_baseline
182    }
183}