1use emath::{vec2, Rect, 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 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 #[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 #[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 #[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 #[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
125impl 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
140impl 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
155impl 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
166impl 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
181impl 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
192impl 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
207impl 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
218impl 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
233impl 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
248impl 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
259impl 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
272impl std::ops::AddAssign<Marginf> for Rect {
274 #[inline]
275 fn add_assign(&mut self, margin: Marginf) {
276 *self = *self + margin;
277 }
278}
279
280impl 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
293impl std::ops::SubAssign<Marginf> for Rect {
295 #[inline]
296 fn sub_assign(&mut self, margin: Marginf) {
297 *self = *self - margin;
298 }
299}