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
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 #[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
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
113impl 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
128impl 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
143impl 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
154impl 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
169impl 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
180impl 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
195impl 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
206impl 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
221impl 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
236impl 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
247impl 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
260impl core::ops::AddAssign<MarginF32> for Rect {
262 #[inline]
263 fn add_assign(&mut self, margin: MarginF32) {
264 *self = *self + margin;
265 }
266}
267
268impl 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
281impl core::ops::SubAssign<MarginF32> for Rect {
283 #[inline]
284 fn sub_assign(&mut self, margin: MarginF32) {
285 *self = *self - margin;
286 }
287}