iced_core/
padding.rs

1//! Space stuff around the perimeter.
2use crate::{Pixels, Size};
3
4/// An amount of space to pad for each side of a box
5///
6/// You can leverage the `From` trait to build [`Padding`] conveniently:
7///
8/// ```
9/// # use iced_core::Padding;
10/// #
11/// let padding = Padding::from(20);              // 20px on all sides
12/// let padding = Padding::from([10, 20]);        // top/bottom, left/right
13/// ```
14///
15/// Normally, the `padding` method of a widget will ask for an `Into<Padding>`,
16/// so you can easily write:
17///
18/// ```
19/// # use iced_core::Padding;
20/// #
21/// # struct Widget;
22/// #
23/// impl Widget {
24///     # pub fn new() -> Self { Self }
25///     #
26///     pub fn padding(mut self, padding: impl Into<Padding>) -> Self {
27///         // ...
28///         self
29///     }
30/// }
31///
32/// let widget = Widget::new().padding(20);              // 20px on all sides
33/// let widget = Widget::new().padding([10, 20]);        // top/bottom, left/right
34/// ```
35#[derive(Debug, Copy, Clone, PartialEq, Default)]
36pub struct Padding {
37    /// Top padding
38    pub top: f32,
39    /// Right padding
40    pub right: f32,
41    /// Bottom padding
42    pub bottom: f32,
43    /// Left padding
44    pub left: f32,
45}
46
47/// Create a [`Padding`] that is equal on all sides.
48pub fn all(padding: impl Into<Pixels>) -> Padding {
49    Padding::new(padding.into().0)
50}
51
52/// Create some top [`Padding`].
53pub fn top(padding: impl Into<Pixels>) -> Padding {
54    Padding::default().top(padding)
55}
56
57/// Create some bottom [`Padding`].
58pub fn bottom(padding: impl Into<Pixels>) -> Padding {
59    Padding::default().bottom(padding)
60}
61
62/// Create some left [`Padding`].
63pub fn left(padding: impl Into<Pixels>) -> Padding {
64    Padding::default().left(padding)
65}
66
67/// Create some right [`Padding`].
68pub fn right(padding: impl Into<Pixels>) -> Padding {
69    Padding::default().right(padding)
70}
71
72/// Create some [`Padding`] with equal left and right sides.
73pub fn horizontal(padding: impl Into<Pixels>) -> Padding {
74    Padding::default().horizontal(padding)
75}
76
77/// Create some [`Padding`] with equal top and bottom sides.
78pub fn vertical(padding: impl Into<Pixels>) -> Padding {
79    Padding::default().vertical(padding)
80}
81
82impl Padding {
83    /// Padding of zero
84    pub const ZERO: Padding = Padding {
85        top: 0.0,
86        right: 0.0,
87        bottom: 0.0,
88        left: 0.0,
89    };
90
91    /// Create a [`Padding`] that is equal on all sides.
92    pub const fn new(padding: f32) -> Padding {
93        Padding {
94            top: padding,
95            right: padding,
96            bottom: padding,
97            left: padding,
98        }
99    }
100
101    /// Sets the [`top`] of the [`Padding`].
102    ///
103    /// [`top`]: Self::top
104    pub fn top(self, top: impl Into<Pixels>) -> Self {
105        Self {
106            top: top.into().0,
107            ..self
108        }
109    }
110
111    /// Sets the [`bottom`] of the [`Padding`].
112    ///
113    /// [`bottom`]: Self::bottom
114    pub fn bottom(self, bottom: impl Into<Pixels>) -> Self {
115        Self {
116            bottom: bottom.into().0,
117            ..self
118        }
119    }
120
121    /// Sets the [`left`] of the [`Padding`].
122    ///
123    /// [`left`]: Self::left
124    pub fn left(self, left: impl Into<Pixels>) -> Self {
125        Self {
126            left: left.into().0,
127            ..self
128        }
129    }
130
131    /// Sets the [`right`] of the [`Padding`].
132    ///
133    /// [`right`]: Self::right
134    pub fn right(self, right: impl Into<Pixels>) -> Self {
135        Self {
136            right: right.into().0,
137            ..self
138        }
139    }
140
141    /// Sets the [`left`] and [`right`] of the [`Padding`].
142    ///
143    /// [`left`]: Self::left
144    /// [`right`]: Self::right
145    pub fn horizontal(self, horizontal: impl Into<Pixels>) -> Self {
146        let horizontal = horizontal.into();
147
148        Self {
149            left: horizontal.0,
150            right: horizontal.0,
151            ..self
152        }
153    }
154
155    /// Sets the [`top`] and [`bottom`] of the [`Padding`].
156    ///
157    /// [`top`]: Self::top
158    /// [`bottom`]: Self::bottom
159    pub fn vertical(self, vertical: impl Into<Pixels>) -> Self {
160        let vertical = vertical.into();
161
162        Self {
163            top: vertical.0,
164            bottom: vertical.0,
165            ..self
166        }
167    }
168
169    /// Returns the total amount of horizontal [`Padding`].
170    pub fn x(self) -> f32 {
171        self.left + self.right
172    }
173
174    /// Returns the total amount of vertical [`Padding`].
175    pub fn y(self) -> f32 {
176        self.top + self.bottom
177    }
178
179    /// Fits the [`Padding`] between the provided `inner` and `outer` [`Size`].
180    pub fn fit(self, inner: Size, outer: Size) -> Self {
181        let available = (outer - inner).max(Size::ZERO);
182        let new_top = self.top.min(available.height);
183        let new_left = self.left.min(available.width);
184
185        Padding {
186            top: new_top,
187            bottom: self.bottom.min(available.height - new_top),
188            left: new_left,
189            right: self.right.min(available.width - new_left),
190        }
191    }
192}
193
194impl From<u16> for Padding {
195    fn from(p: u16) -> Self {
196        Padding {
197            top: f32::from(p),
198            right: f32::from(p),
199            bottom: f32::from(p),
200            left: f32::from(p),
201        }
202    }
203}
204
205impl From<[u16; 2]> for Padding {
206    fn from(p: [u16; 2]) -> Self {
207        Padding {
208            top: f32::from(p[0]),
209            right: f32::from(p[1]),
210            bottom: f32::from(p[0]),
211            left: f32::from(p[1]),
212        }
213    }
214}
215
216impl From<f32> for Padding {
217    fn from(p: f32) -> Self {
218        Padding {
219            top: p,
220            right: p,
221            bottom: p,
222            left: p,
223        }
224    }
225}
226
227impl From<[f32; 2]> for Padding {
228    fn from(p: [f32; 2]) -> Self {
229        Padding {
230            top: p[0],
231            right: p[1],
232            bottom: p[0],
233            left: p[1],
234        }
235    }
236}
237
238impl From<Padding> for Size {
239    fn from(padding: Padding) -> Self {
240        Self::new(padding.x(), padding.y())
241    }
242}
243
244impl From<Pixels> for Padding {
245    fn from(pixels: Pixels) -> Self {
246        Self::from(pixels.0)
247    }
248}