cranpose_ui/widgets/padding_values.rs
1//! Compose's `PaddingValues`: four edge insets in reading order.
2
3use cranpose_ui_graphics::EdgeInsets;
4
5use crate::{
6 Modifier,
7 layout_direction::{LayoutDirection, layout_direction},
8};
9
10/// Padding on four edges, in reading order, such as a scaffold's insets for
11/// its content slot or a lazy list's content padding.
12///
13/// `start` and `end` are the reading-order edges: in a left-to-right layout
14/// `start` is the left edge, in a right-to-left layout it is the right one.
15#[derive(Clone, Copy, Debug, Default, PartialEq)]
16pub struct PaddingValues {
17 /// Padding on the reading-order start edge, in logical pixels.
18 pub start: f32,
19 /// Padding on the top edge, in logical pixels.
20 pub top: f32,
21 /// Padding on the reading-order end edge, in logical pixels.
22 pub end: f32,
23 /// Padding on the bottom edge, in logical pixels.
24 pub bottom: f32,
25}
26
27impl PaddingValues {
28 /// Creates padding values from the four edges, in logical pixels and reading order.
29 pub const fn new(start: f32, top: f32, end: f32, bottom: f32) -> Self {
30 Self {
31 start,
32 top,
33 end,
34 bottom,
35 }
36 }
37
38 /// The same padding on every edge.
39 pub const fn all(value: f32) -> Self {
40 Self::new(value, value, value, value)
41 }
42
43 /// `horizontal` on the start and end edges, `vertical` on the top and
44 /// bottom ones: Compose's `PaddingValues(horizontal, vertical)`.
45 pub const fn symmetric(horizontal: f32, vertical: f32) -> Self {
46 Self::new(horizontal, vertical, horizontal, vertical)
47 }
48
49 /// Applies these values in the composition's current reading order.
50 pub fn apply_to(self, modifier: Modifier) -> Modifier {
51 self.apply_to_in(modifier, layout_direction())
52 }
53
54 /// Applies these values against an explicit reading order.
55 pub fn apply_to_in(self, modifier: Modifier, direction: LayoutDirection) -> Modifier {
56 modifier.padding_relative_in(direction, self.start, self.top, self.end, self.bottom)
57 }
58
59 /// The physical left/top/right/bottom edges in `direction`.
60 pub fn physical(self, direction: LayoutDirection) -> EdgeInsets {
61 let (left, right) = direction.resolve(self.start, self.end);
62 EdgeInsets::from_components(left, self.top, right, self.bottom)
63 }
64
65 /// The larger of each edge, used to merge bar heights with window insets.
66 pub fn max(self, other: Self) -> Self {
67 Self::new(
68 self.start.max(other.start),
69 self.top.max(other.top),
70 self.end.max(other.end),
71 self.bottom.max(other.bottom),
72 )
73 }
74}