epaint/
margin_f32.rs

1use emath::{Rect, Vec2, vec2};
2
3use crate::Margin;
4
5/// A value for all four sides of a rectangle,
6/// often used to express padding or spacing.
7///
8/// Can be added and subtracted to/from [`Rect`]s.
9///
10/// For storage, use [`crate::Margin`] instead.
11#[derive(Clone, Copy, Debug, Default, PartialEq)]
12#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
13pub struct MarginF32 {
14    pub left: f32,
15    pub right: f32,
16    pub top: f32,
17    pub bottom: f32,
18}
19
20#[deprecated = "Renamed to MarginF32"]
21pub type Marginf = MarginF32;
22
23impl From<Margin> for MarginF32 {
24    #[inline]
25    fn from(margin: Margin) -> Self {
26        Self {
27            left: margin.left as _,
28            right: margin.right as _,
29            top: margin.top as _,
30            bottom: margin.bottom as _,
31        }
32    }
33}
34
35impl From<MarginF32> for Margin {
36    #[inline]
37    fn from(marginf: MarginF32) -> Self {
38        Self {
39            left: marginf.left as _,
40            right: marginf.right as _,
41            top: marginf.top as _,
42            bottom: marginf.bottom as _,
43        }
44    }
45}
46
47impl MarginF32 {
48    pub const ZERO: Self = Self {
49        left: 0.0,
50        right: 0.0,
51        top: 0.0,
52        bottom: 0.0,
53    };
54
55    /// The same margin on every side.
56    #[doc(alias = "symmetric")]
57    #[inline]
58    pub const fn same(margin: f32) -> Self {
59        Self {
60            left: margin,
61            right: margin,
62            top: margin,
63            bottom: margin,
64        }
65    }
66
67    /// Margins with the same size on opposing sides
68    #[inline]
69    pub const fn symmetric(x: f32, y: f32) -> Self {
70        Self {
71            left: x,
72            right: x,
73            top: y,
74            bottom: y,
75        }
76    }
77
78    /// Total margins on both sides
79    #[inline]
80    pub fn sum(&self) -> Vec2 {
81        vec2(self.left + self.right, self.top + self.bottom)
82    }
83
84    #[inline]
85    pub const fn left_top(&self) -> Vec2 {
86        vec2(self.left, self.top)
87    }
88
89    #[inline]
90    pub const fn right_bottom(&self) -> Vec2 {
91        vec2(self.right, self.bottom)
92    }
93
94    /// Are the margin on every side the same?
95    #[doc(alias = "symmetric")]
96    #[inline]
97    pub fn is_same(&self) -> bool {
98        self.left == self.right && self.left == self.top && self.left == self.bottom
99    }
100
101    #[deprecated = "Use `rect + margin` instead"]
102    #[inline]
103    pub fn expand_rect(&self, rect: Rect) -> Rect {
104        Rect::from_min_max(rect.min - self.left_top(), rect.max + self.right_bottom())
105    }
106
107    #[deprecated = "Use `rect - margin` instead"]
108    #[inline]
109    pub fn shrink_rect(&self, rect: Rect) -> Rect {
110        Rect::from_min_max(rect.min + self.left_top(), rect.max - self.right_bottom())
111    }
112}
113
114impl From<f32> for MarginF32 {
115    #[inline]
116    fn from(v: f32) -> Self {
117        Self::same(v)
118    }
119}
120
121impl From<Vec2> for MarginF32 {
122    #[inline]
123    fn from(v: Vec2) -> Self {
124        Self::symmetric(v.x, v.y)
125    }
126}
127
128/// `MarginF32 + MarginF32`
129impl std::ops::Add for MarginF32 {
130    type Output = Self;
131
132    #[inline]
133    fn add(self, other: Self) -> Self {
134        Self {
135            left: self.left + other.left,
136            right: self.right + other.right,
137            top: self.top + other.top,
138            bottom: self.bottom + other.bottom,
139        }
140    }
141}
142
143/// `MarginF32 + f32`
144impl std::ops::Add<f32> for MarginF32 {
145    type Output = Self;
146
147    #[inline]
148    fn add(self, v: f32) -> Self {
149        Self {
150            left: self.left + v,
151            right: self.right + v,
152            top: self.top + v,
153            bottom: self.bottom + v,
154        }
155    }
156}
157
158/// `Margind += f32`
159impl std::ops::AddAssign<f32> for MarginF32 {
160    #[inline]
161    fn add_assign(&mut self, v: f32) {
162        self.left += v;
163        self.right += v;
164        self.top += v;
165        self.bottom += v;
166    }
167}
168
169/// `MarginF32 * f32`
170impl std::ops::Mul<f32> for MarginF32 {
171    type Output = Self;
172
173    #[inline]
174    fn mul(self, v: f32) -> Self {
175        Self {
176            left: self.left * v,
177            right: self.right * v,
178            top: self.top * v,
179            bottom: self.bottom * v,
180        }
181    }
182}
183
184/// `MarginF32 *= f32`
185impl std::ops::MulAssign<f32> for MarginF32 {
186    #[inline]
187    fn mul_assign(&mut self, v: f32) {
188        self.left *= v;
189        self.right *= v;
190        self.top *= v;
191        self.bottom *= v;
192    }
193}
194
195/// `MarginF32 / f32`
196impl std::ops::Div<f32> for MarginF32 {
197    type Output = Self;
198
199    #[inline]
200    fn div(self, v: f32) -> Self {
201        Self {
202            left: self.left / v,
203            right: self.right / v,
204            top: self.top / v,
205            bottom: self.bottom / v,
206        }
207    }
208}
209
210/// `MarginF32 /= f32`
211impl std::ops::DivAssign<f32> for MarginF32 {
212    #[inline]
213    fn div_assign(&mut self, v: f32) {
214        self.left /= v;
215        self.right /= v;
216        self.top /= v;
217        self.bottom /= v;
218    }
219}
220
221/// `MarginF32 - MarginF32`
222impl std::ops::Sub for MarginF32 {
223    type Output = Self;
224
225    #[inline]
226    fn sub(self, other: Self) -> Self {
227        Self {
228            left: self.left - other.left,
229            right: self.right - other.right,
230            top: self.top - other.top,
231            bottom: self.bottom - other.bottom,
232        }
233    }
234}
235
236/// `MarginF32 - f32`
237impl std::ops::Sub<f32> for MarginF32 {
238    type Output = Self;
239
240    #[inline]
241    fn sub(self, v: f32) -> Self {
242        Self {
243            left: self.left - v,
244            right: self.right - v,
245            top: self.top - v,
246            bottom: self.bottom - v,
247        }
248    }
249}
250
251/// `MarginF32 -= f32`
252impl std::ops::SubAssign<f32> for MarginF32 {
253    #[inline]
254    fn sub_assign(&mut self, v: f32) {
255        self.left -= v;
256        self.right -= v;
257        self.top -= v;
258        self.bottom -= v;
259    }
260}
261
262/// `Rect + MarginF32`
263impl std::ops::Add<MarginF32> for Rect {
264    type Output = Self;
265
266    #[inline]
267    fn add(self, margin: MarginF32) -> Self {
268        Self::from_min_max(
269            self.min - margin.left_top(),
270            self.max + margin.right_bottom(),
271        )
272    }
273}
274
275/// `Rect += MarginF32`
276impl std::ops::AddAssign<MarginF32> for Rect {
277    #[inline]
278    fn add_assign(&mut self, margin: MarginF32) {
279        *self = *self + margin;
280    }
281}
282
283/// `Rect - MarginF32`
284impl std::ops::Sub<MarginF32> for Rect {
285    type Output = Self;
286
287    #[inline]
288    fn sub(self, margin: MarginF32) -> Self {
289        Self::from_min_max(
290            self.min + margin.left_top(),
291            self.max - margin.right_bottom(),
292        )
293    }
294}
295
296/// `Rect -= MarginF32`
297impl std::ops::SubAssign<MarginF32> for Rect {
298    #[inline]
299    fn sub_assign(&mut self, margin: MarginF32) {
300        *self = *self - margin;
301    }
302}