1use zng_unit::FactorUnits;
2
3use super::{
4 DipPoint, DipRect, DipSideOffsets, DipSize, DipVector, Factor, FactorPercent, PxPoint, PxRect, PxSideOffsets, PxSize, PxVector, Size,
5};
6use std::{fmt, ops};
7use zng_var::impl_from_and_into_var;
8
9impl ops::Mul<Factor> for Factor2d {
10 type Output = Factor2d;
11
12 fn mul(self, rhs: Factor) -> Factor2d {
13 Factor2d::new(self.x * rhs, self.y * rhs)
14 }
15}
16impl ops::Div<Factor> for Factor2d {
17 type Output = Factor2d;
18
19 fn div(self, rhs: Factor) -> Factor2d {
20 Factor2d::new(self.x / rhs, self.y / rhs)
21 }
22}
23impl ops::MulAssign<Factor> for Factor2d {
24 fn mul_assign(&mut self, rhs: Factor) {
25 *self = *self * rhs;
26 }
27}
28impl ops::DivAssign<Factor> for Factor2d {
29 fn div_assign(&mut self, rhs: Factor) {
30 *self = *self / rhs;
31 }
32}
33
34#[derive(Clone, Copy, Debug, PartialEq)]
36pub struct Factor2d {
37 pub x: Factor,
39 pub y: Factor,
41}
42impl_from_and_into_var! {
43 fn from<X: Into<Factor>, Y: Into<Factor>>((x, y): (X, Y)) -> Factor2d {
44 Factor2d { x: x.into(), y: y.into() }
45 }
46
47 fn from(xy: Factor) -> Factor2d {
48 Factor2d { x: xy, y: xy }
49 }
50
51 fn from(xy: FactorPercent) -> Factor2d {
52 xy.fct().into()
53 }
54
55 fn from(scale: Factor2d) -> Size {
57 Size {
58 width: scale.x.into(),
59 height: scale.y.into(),
60 }
61 }
62}
63impl Factor2d {
64 pub fn new(x: impl Into<Factor>, y: impl Into<Factor>) -> Self {
66 Factor2d { x: x.into(), y: y.into() }
67 }
68
69 pub fn uniform(xy: impl Into<Factor>) -> Self {
71 let xy = xy.into();
72 xy.into()
73 }
74
75 pub fn identity() -> Self {
77 Self::uniform(1.0)
78 }
79
80 pub fn is_uniform(self) -> bool {
82 self.x == self.y
83 }
84
85 pub fn abs(mut self) -> Self {
87 self.x = self.x.abs();
88 self.y = self.y.abs();
89 self
90 }
91
92 pub fn yx(self) -> Self {
94 Self::new(self.y, self.x)
95 }
96}
97impl fmt::Display for Factor2d {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 if self.is_uniform() {
100 write!(f, "{}", FactorPercent::from(self.x))
101 } else {
102 write!(f, "({}, {})", FactorPercent::from(self.x), FactorPercent::from(self.y))
103 }
104 }
105}
106impl ops::Mul<Factor2d> for PxSize {
107 type Output = PxSize;
108
109 fn mul(self, rhs: Factor2d) -> PxSize {
110 PxSize::new(self.width * rhs.x, self.height * rhs.y)
111 }
112}
113impl ops::Mul<Factor2d> for DipSize {
114 type Output = DipSize;
115
116 fn mul(self, rhs: Factor2d) -> DipSize {
117 DipSize::new(self.width * rhs.x, self.height * rhs.y)
118 }
119}
120impl ops::Div<Factor2d> for PxSize {
121 type Output = PxSize;
122
123 fn div(self, rhs: Factor2d) -> PxSize {
124 PxSize::new(self.width / rhs.x, self.height / rhs.y)
125 }
126}
127impl ops::Div<Factor2d> for DipSize {
128 type Output = DipSize;
129
130 fn div(self, rhs: Factor2d) -> DipSize {
131 DipSize::new(self.width / rhs.x, self.height / rhs.y)
132 }
133}
134impl ops::MulAssign<Factor2d> for PxSize {
135 fn mul_assign(&mut self, rhs: Factor2d) {
136 *self = *self * rhs;
137 }
138}
139impl ops::MulAssign<Factor2d> for DipSize {
140 fn mul_assign(&mut self, rhs: Factor2d) {
141 *self = *self * rhs;
142 }
143}
144impl ops::DivAssign<Factor2d> for PxSize {
145 fn div_assign(&mut self, rhs: Factor2d) {
146 *self = *self / rhs;
147 }
148}
149impl ops::DivAssign<Factor2d> for DipSize {
150 fn div_assign(&mut self, rhs: Factor2d) {
151 *self = *self / rhs;
152 }
153}
154impl ops::Mul<Factor2d> for PxPoint {
155 type Output = PxPoint;
156
157 fn mul(self, rhs: Factor2d) -> PxPoint {
158 PxPoint::new(self.x * rhs.x, self.y * rhs.y)
159 }
160}
161impl ops::Div<Factor2d> for PxPoint {
162 type Output = PxPoint;
163
164 fn div(self, rhs: Factor2d) -> PxPoint {
165 PxPoint::new(self.x / rhs.x, self.y / rhs.y)
166 }
167}
168impl ops::MulAssign<Factor2d> for PxPoint {
169 fn mul_assign(&mut self, rhs: Factor2d) {
170 *self = *self * rhs;
171 }
172}
173impl ops::DivAssign<Factor2d> for PxPoint {
174 fn div_assign(&mut self, rhs: Factor2d) {
175 *self = *self / rhs;
176 }
177}
178
179impl ops::Mul<Factor2d> for DipPoint {
180 type Output = DipPoint;
181
182 fn mul(self, rhs: Factor2d) -> DipPoint {
183 DipPoint::new(self.x * rhs.x, self.y * rhs.y)
184 }
185}
186impl ops::Div<Factor2d> for DipPoint {
187 type Output = DipPoint;
188
189 fn div(self, rhs: Factor2d) -> DipPoint {
190 DipPoint::new(self.x / rhs.x, self.y / rhs.y)
191 }
192}
193impl ops::MulAssign<Factor2d> for DipPoint {
194 fn mul_assign(&mut self, rhs: Factor2d) {
195 *self = *self * rhs;
196 }
197}
198impl ops::DivAssign<Factor2d> for DipPoint {
199 fn div_assign(&mut self, rhs: Factor2d) {
200 *self = *self / rhs;
201 }
202}
203
204impl ops::Mul<Factor2d> for PxVector {
205 type Output = PxVector;
206
207 fn mul(self, rhs: Factor2d) -> PxVector {
208 PxVector::new(self.x * rhs.x, self.y * rhs.y)
209 }
210}
211impl ops::Div<Factor2d> for PxVector {
212 type Output = PxVector;
213
214 fn div(self, rhs: Factor2d) -> PxVector {
215 PxVector::new(self.x / rhs.x, self.y / rhs.y)
216 }
217}
218impl ops::MulAssign<Factor2d> for PxVector {
219 fn mul_assign(&mut self, rhs: Factor2d) {
220 *self = *self * rhs;
221 }
222}
223impl ops::DivAssign<Factor2d> for PxVector {
224 fn div_assign(&mut self, rhs: Factor2d) {
225 *self = *self / rhs;
226 }
227}
228
229impl ops::Mul<Factor2d> for DipVector {
230 type Output = DipVector;
231
232 fn mul(self, rhs: Factor2d) -> DipVector {
233 DipVector::new(self.x * rhs.x, self.y * rhs.y)
234 }
235}
236impl ops::Div<Factor2d> for DipVector {
237 type Output = DipVector;
238
239 fn div(self, rhs: Factor2d) -> DipVector {
240 DipVector::new(self.x / rhs.x, self.y / rhs.y)
241 }
242}
243impl ops::MulAssign<Factor2d> for DipVector {
244 fn mul_assign(&mut self, rhs: Factor2d) {
245 *self = *self * rhs;
246 }
247}
248impl ops::DivAssign<Factor2d> for DipVector {
249 fn div_assign(&mut self, rhs: Factor2d) {
250 *self = *self / rhs;
251 }
252}
253
254impl ops::Mul<Factor2d> for Factor2d {
255 type Output = Factor2d;
256
257 fn mul(self, rhs: Factor2d) -> Factor2d {
258 Factor2d::new(self.x * rhs.x, self.y * rhs.y)
259 }
260}
261impl ops::Div<Factor2d> for Factor2d {
262 type Output = Factor2d;
263
264 fn div(self, rhs: Factor2d) -> Factor2d {
265 Factor2d::new(self.x / rhs.x, self.y / rhs.y)
266 }
267}
268impl ops::MulAssign<Factor2d> for Factor2d {
269 fn mul_assign(&mut self, rhs: Factor2d) {
270 *self = *self * rhs;
271 }
272}
273impl ops::DivAssign<Factor2d> for Factor2d {
274 fn div_assign(&mut self, rhs: Factor2d) {
275 *self = *self / rhs;
276 }
277}
278impl ops::Mul<Factor2d> for PxRect {
279 type Output = PxRect;
280
281 fn mul(self, rhs: Factor2d) -> PxRect {
282 PxRect::new(self.origin * rhs, self.size * rhs)
283 }
284}
285impl ops::Div<Factor2d> for PxRect {
286 type Output = PxRect;
287
288 fn div(self, rhs: Factor2d) -> PxRect {
289 PxRect::new(self.origin / rhs, self.size / rhs)
290 }
291}
292impl ops::MulAssign<Factor2d> for PxRect {
293 fn mul_assign(&mut self, rhs: Factor2d) {
294 *self = *self * rhs;
295 }
296}
297impl ops::DivAssign<Factor2d> for PxRect {
298 fn div_assign(&mut self, rhs: Factor2d) {
299 *self = *self / rhs;
300 }
301}
302
303impl ops::Mul<Factor2d> for DipRect {
304 type Output = DipRect;
305
306 fn mul(self, rhs: Factor2d) -> DipRect {
307 DipRect::new(self.origin * rhs, self.size * rhs)
308 }
309}
310impl ops::Div<Factor2d> for DipRect {
311 type Output = DipRect;
312
313 fn div(self, rhs: Factor2d) -> DipRect {
314 DipRect::new(self.origin / rhs, self.size / rhs)
315 }
316}
317impl ops::MulAssign<Factor2d> for DipRect {
318 fn mul_assign(&mut self, rhs: Factor2d) {
319 *self = *self * rhs;
320 }
321}
322impl ops::DivAssign<Factor2d> for DipRect {
323 fn div_assign(&mut self, rhs: Factor2d) {
324 *self = *self / rhs;
325 }
326}
327
328impl ops::Neg for Factor2d {
329 type Output = Self;
330
331 fn neg(mut self) -> Self::Output {
332 self.x = -self.x;
333 self.y = -self.y;
334 self
335 }
336}
337
338#[derive(Clone, Copy, Debug, PartialEq)]
340pub struct FactorSideOffsets {
341 pub top: Factor,
343 pub right: Factor,
345 pub bottom: Factor,
347 pub left: Factor,
349}
350impl FactorSideOffsets {
351 pub fn new(top: impl Into<Factor>, right: impl Into<Factor>, bottom: impl Into<Factor>, left: impl Into<Factor>) -> Self {
353 Self {
354 top: top.into(),
355 right: right.into(),
356 bottom: bottom.into(),
357 left: left.into(),
358 }
359 }
360
361 pub fn new_vh(top_bottom: impl Into<Factor>, left_right: impl Into<Factor>) -> Self {
363 let tb = top_bottom.into();
364 let lr = left_right.into();
365
366 Self::new(tb, lr, tb, lr)
367 }
368
369 pub fn new_all(uniform: impl Into<Factor>) -> Self {
371 let u = uniform.into();
372 Self::new(u, u, u, u)
373 }
374
375 pub fn zero() -> Self {
377 Self::new_all(0.fct())
378 }
379
380 pub fn one() -> Self {
382 Self::new_all(1.fct())
383 }
384}
385impl ops::Mul<FactorSideOffsets> for FactorSideOffsets {
386 type Output = FactorSideOffsets;
387
388 fn mul(self, rhs: FactorSideOffsets) -> FactorSideOffsets {
389 FactorSideOffsets::new(
390 self.top * rhs.top,
391 self.right * rhs.right,
392 self.bottom * rhs.bottom,
393 self.left * rhs.left,
394 )
395 }
396}
397impl ops::Div<FactorSideOffsets> for FactorSideOffsets {
398 type Output = FactorSideOffsets;
399
400 fn div(self, rhs: FactorSideOffsets) -> FactorSideOffsets {
401 FactorSideOffsets::new(
402 self.top / rhs.top,
403 self.right / rhs.right,
404 self.bottom / rhs.bottom,
405 self.left / rhs.left,
406 )
407 }
408}
409impl ops::MulAssign<FactorSideOffsets> for FactorSideOffsets {
410 fn mul_assign(&mut self, rhs: FactorSideOffsets) {
411 *self = *self * rhs;
412 }
413}
414impl ops::DivAssign<FactorSideOffsets> for FactorSideOffsets {
415 fn div_assign(&mut self, rhs: FactorSideOffsets) {
416 *self = *self / rhs;
417 }
418}
419impl ops::Mul<FactorSideOffsets> for PxSideOffsets {
420 type Output = PxSideOffsets;
421
422 fn mul(self, rhs: FactorSideOffsets) -> PxSideOffsets {
423 PxSideOffsets::new(
424 self.top * rhs.top,
425 self.right * rhs.right,
426 self.bottom * rhs.bottom,
427 self.left * rhs.left,
428 )
429 }
430}
431impl ops::Div<FactorSideOffsets> for PxSideOffsets {
432 type Output = PxSideOffsets;
433
434 fn div(self, rhs: FactorSideOffsets) -> PxSideOffsets {
435 PxSideOffsets::new(
436 self.top / rhs.top,
437 self.right / rhs.right,
438 self.bottom / rhs.bottom,
439 self.left / rhs.left,
440 )
441 }
442}
443impl ops::MulAssign<FactorSideOffsets> for PxSideOffsets {
444 fn mul_assign(&mut self, rhs: FactorSideOffsets) {
445 *self = *self * rhs;
446 }
447}
448impl ops::DivAssign<FactorSideOffsets> for PxSideOffsets {
449 fn div_assign(&mut self, rhs: FactorSideOffsets) {
450 *self = *self / rhs;
451 }
452}
453
454impl ops::Mul<FactorSideOffsets> for DipSideOffsets {
455 type Output = DipSideOffsets;
456
457 fn mul(self, rhs: FactorSideOffsets) -> DipSideOffsets {
458 DipSideOffsets::new(
459 self.top * rhs.top,
460 self.right * rhs.right,
461 self.bottom * rhs.bottom,
462 self.left * rhs.left,
463 )
464 }
465}
466impl ops::Div<FactorSideOffsets> for DipSideOffsets {
467 type Output = DipSideOffsets;
468
469 fn div(self, rhs: FactorSideOffsets) -> DipSideOffsets {
470 DipSideOffsets::new(
471 self.top / rhs.top,
472 self.right / rhs.right,
473 self.bottom / rhs.bottom,
474 self.left / rhs.left,
475 )
476 }
477}
478impl ops::MulAssign<FactorSideOffsets> for DipSideOffsets {
479 fn mul_assign(&mut self, rhs: FactorSideOffsets) {
480 *self = *self * rhs;
481 }
482}
483impl ops::DivAssign<FactorSideOffsets> for DipSideOffsets {
484 fn div_assign(&mut self, rhs: FactorSideOffsets) {
485 *self = *self / rhs;
486 }
487}
488
489impl_from_and_into_var! {
490 fn from(all: Factor) -> FactorSideOffsets {
492 FactorSideOffsets::new_all(all)
493 }
494
495 fn from(percent: FactorPercent) -> FactorSideOffsets {
497 FactorSideOffsets::new_all(percent)
498 }
499
500 fn from<TB: Into<Factor>, LR: Into<Factor>>((top_bottom, left_right): (TB, LR)) -> FactorSideOffsets {
502 FactorSideOffsets::new_vh(top_bottom, left_right)
503 }
504
505 fn from<T: Into<Factor>, R: Into<Factor>, B: Into<Factor>, L: Into<Factor>>(
507 (top, right, bottom, left): (T, R, B, L),
508 ) -> FactorSideOffsets {
509 FactorSideOffsets::new(top, right, bottom, left)
510 }
511}