Skip to main content

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