1use emath::{Rect, Vec2, vec2};
2
3use crate::Margin;
4
5#[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 #[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 #[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 #[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 #[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
128impl 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
143impl 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
158impl 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
169impl 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
184impl 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
195impl 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
210impl 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
221impl 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
236impl 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
251impl 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
262impl 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
275impl std::ops::AddAssign<MarginF32> for Rect {
277 #[inline]
278 fn add_assign(&mut self, margin: MarginF32) {
279 *self = *self + margin;
280 }
281}
282
283impl 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
296impl std::ops::SubAssign<MarginF32> for Rect {
298 #[inline]
299 fn sub_assign(&mut self, margin: MarginF32) {
300 *self = *self - margin;
301 }
302}