epaint/
marginf.rs

1use emath::{vec2, Rect, 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 Marginf {
14    pub left: f32,
15    pub right: f32,
16    pub top: f32,
17    pub bottom: f32,
18}
19
20impl From<Margin> for Marginf {
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<Marginf> for Margin {
33    #[inline]
34    fn from(marginf: Marginf) -> 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 Marginf {
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    #[deprecated = "Use `rect + margin` instead"]
99    #[inline]
100    pub fn expand_rect(&self, rect: Rect) -> Rect {
101        Rect::from_min_max(rect.min - self.left_top(), rect.max + self.right_bottom())
102    }
103
104    #[deprecated = "Use `rect - margin` instead"]
105    #[inline]
106    pub fn shrink_rect(&self, rect: Rect) -> Rect {
107        Rect::from_min_max(rect.min + self.left_top(), rect.max - self.right_bottom())
108    }
109}
110
111impl From<f32> for Marginf {
112    #[inline]
113    fn from(v: f32) -> Self {
114        Self::same(v)
115    }
116}
117
118impl From<Vec2> for Marginf {
119    #[inline]
120    fn from(v: Vec2) -> Self {
121        Self::symmetric(v.x, v.y)
122    }
123}
124
125/// `Marginf + Marginf`
126impl std::ops::Add for Marginf {
127    type Output = Self;
128
129    #[inline]
130    fn add(self, other: Self) -> Self {
131        Self {
132            left: self.left + other.left,
133            right: self.right + other.right,
134            top: self.top + other.top,
135            bottom: self.bottom + other.bottom,
136        }
137    }
138}
139
140/// `Marginf + f32`
141impl std::ops::Add<f32> for Marginf {
142    type Output = Self;
143
144    #[inline]
145    fn add(self, v: f32) -> Self {
146        Self {
147            left: self.left + v,
148            right: self.right + v,
149            top: self.top + v,
150            bottom: self.bottom + v,
151        }
152    }
153}
154
155/// `Margind += f32`
156impl std::ops::AddAssign<f32> for Marginf {
157    #[inline]
158    fn add_assign(&mut self, v: f32) {
159        self.left += v;
160        self.right += v;
161        self.top += v;
162        self.bottom += v;
163    }
164}
165
166/// `Marginf * f32`
167impl std::ops::Mul<f32> for Marginf {
168    type Output = Self;
169
170    #[inline]
171    fn mul(self, v: f32) -> Self {
172        Self {
173            left: self.left * v,
174            right: self.right * v,
175            top: self.top * v,
176            bottom: self.bottom * v,
177        }
178    }
179}
180
181/// `Marginf *= f32`
182impl std::ops::MulAssign<f32> for Marginf {
183    #[inline]
184    fn mul_assign(&mut self, v: f32) {
185        self.left *= v;
186        self.right *= v;
187        self.top *= v;
188        self.bottom *= v;
189    }
190}
191
192/// `Marginf / f32`
193impl std::ops::Div<f32> for Marginf {
194    type Output = Self;
195
196    #[inline]
197    fn div(self, v: f32) -> Self {
198        Self {
199            left: self.left / v,
200            right: self.right / v,
201            top: self.top / v,
202            bottom: self.bottom / v,
203        }
204    }
205}
206
207/// `Marginf /= f32`
208impl std::ops::DivAssign<f32> for Marginf {
209    #[inline]
210    fn div_assign(&mut self, v: f32) {
211        self.left /= v;
212        self.right /= v;
213        self.top /= v;
214        self.bottom /= v;
215    }
216}
217
218/// `Marginf - Marginf`
219impl std::ops::Sub for Marginf {
220    type Output = Self;
221
222    #[inline]
223    fn sub(self, other: Self) -> Self {
224        Self {
225            left: self.left - other.left,
226            right: self.right - other.right,
227            top: self.top - other.top,
228            bottom: self.bottom - other.bottom,
229        }
230    }
231}
232
233/// `Marginf - f32`
234impl std::ops::Sub<f32> for Marginf {
235    type Output = Self;
236
237    #[inline]
238    fn sub(self, v: f32) -> Self {
239        Self {
240            left: self.left - v,
241            right: self.right - v,
242            top: self.top - v,
243            bottom: self.bottom - v,
244        }
245    }
246}
247
248/// `Marginf -= f32`
249impl std::ops::SubAssign<f32> for Marginf {
250    #[inline]
251    fn sub_assign(&mut self, v: f32) {
252        self.left -= v;
253        self.right -= v;
254        self.top -= v;
255        self.bottom -= v;
256    }
257}
258
259/// `Rect + Marginf`
260impl std::ops::Add<Marginf> for Rect {
261    type Output = Self;
262
263    #[inline]
264    fn add(self, margin: Marginf) -> Self {
265        Self::from_min_max(
266            self.min - margin.left_top(),
267            self.max + margin.right_bottom(),
268        )
269    }
270}
271
272/// `Rect += Marginf`
273impl std::ops::AddAssign<Marginf> for Rect {
274    #[inline]
275    fn add_assign(&mut self, margin: Marginf) {
276        *self = *self + margin;
277    }
278}
279
280/// `Rect - Marginf`
281impl std::ops::Sub<Marginf> for Rect {
282    type Output = Self;
283
284    #[inline]
285    fn sub(self, margin: Marginf) -> Self {
286        Self::from_min_max(
287            self.min + margin.left_top(),
288            self.max - margin.right_bottom(),
289        )
290    }
291}
292
293/// `Rect -= Marginf`
294impl std::ops::SubAssign<Marginf> for Rect {
295    #[inline]
296    fn sub_assign(&mut self, margin: Marginf) {
297        *self = *self - margin;
298    }
299}