1use std::{fmt, ops, time::Duration};
2
3use crate::{
4 Dip, DipPoint, DipRect, DipSize, DipVector, EQ_GRANULARITY, EQ_GRANULARITY_100, Px, PxPoint, PxRect, PxSize, PxVector, about_eq,
5 about_eq_hash, about_eq_ord,
6};
7
8pub trait FactorUnits {
19 fn pct(self) -> FactorPercent;
21
22 fn fct(self) -> Factor;
28}
29impl FactorUnits for f32 {
30 fn pct(self) -> FactorPercent {
31 FactorPercent(self)
32 }
33
34 fn fct(self) -> Factor {
35 self.into()
36 }
37}
38impl FactorUnits for i32 {
39 fn pct(self) -> FactorPercent {
40 FactorPercent(self as f32)
41 }
42
43 fn fct(self) -> Factor {
44 Factor(self as f32)
45 }
46}
47
48#[derive(Copy, Clone, serde::Serialize, serde::Deserialize, bytemuck::Zeroable, bytemuck::Pod)]
58#[repr(transparent)]
59#[serde(transparent)]
60pub struct Factor(pub f32);
61impl Factor {
62 pub fn clamp_range(self) -> Self {
64 Factor(self.0.clamp(0.0, 1.0))
65 }
66
67 pub fn abs(self) -> Factor {
69 Factor(self.0.abs())
70 }
71
72 pub fn flip(self) -> Factor {
76 Self(1.0) - self
77 }
78
79 pub fn pct(self) -> FactorPercent {
81 self.into()
82 }
83}
84impl fmt::Debug for Factor {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 if f.alternate() {
87 f.debug_tuple("Factor").field(&self.0).finish()
88 } else {
89 write!(f, "{}.fct()", self.0)
90 }
91 }
92}
93impl fmt::Display for Factor {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 write!(f, "{}", self.0)
96 }
97}
98impl From<f32> for Factor {
99 fn from(value: f32) -> Self {
100 Factor(value)
101 }
102}
103impl ops::Add for Factor {
104 type Output = Self;
105
106 fn add(self, rhs: Self) -> Self::Output {
107 Self(self.0 + rhs.0)
108 }
109}
110impl ops::AddAssign for Factor {
111 fn add_assign(&mut self, rhs: Self) {
112 self.0 += rhs.0;
113 }
114}
115impl ops::Sub for Factor {
116 type Output = Self;
117
118 fn sub(self, rhs: Self) -> Self::Output {
119 Self(self.0 - rhs.0)
120 }
121}
122impl ops::SubAssign for Factor {
123 fn sub_assign(&mut self, rhs: Self) {
124 self.0 -= rhs.0;
125 }
126}
127impl std::hash::Hash for Factor {
128 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
129 about_eq_hash(self.0, EQ_GRANULARITY, state)
130 }
131}
132impl PartialEq for Factor {
133 fn eq(&self, other: &Self) -> bool {
134 about_eq(self.0, other.0, EQ_GRANULARITY)
135 }
136}
137impl Eq for Factor {}
138impl std::cmp::PartialOrd for Factor {
139 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
140 Some(self.cmp(other))
141 }
142}
143impl std::cmp::Ord for Factor {
144 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
145 about_eq_ord(self.0, other.0, EQ_GRANULARITY)
146 }
147}
148impl ops::Mul for Factor {
149 type Output = Self;
150
151 fn mul(self, rhs: Self) -> Self::Output {
152 Factor(self.0 * rhs.0)
153 }
154}
155impl ops::MulAssign for Factor {
156 fn mul_assign(&mut self, rhs: Self) {
157 *self = *self * rhs;
158 }
159}
160impl ops::Div for Factor {
161 type Output = Self;
162
163 fn div(self, rhs: Self) -> Self::Output {
164 Factor(self.0 / rhs.0)
165 }
166}
167impl ops::DivAssign for Factor {
168 fn div_assign(&mut self, rhs: Self) {
169 *self = *self / rhs;
170 }
171}
172
173impl ops::Mul<Factor> for Px {
174 type Output = Px;
175
176 fn mul(self, rhs: Factor) -> Px {
177 self * rhs.0
178 }
179}
180impl ops::Div<Factor> for Px {
181 type Output = Px;
182
183 fn div(self, rhs: Factor) -> Px {
184 self / rhs.0
185 }
186}
187impl ops::MulAssign<Factor> for Px {
188 fn mul_assign(&mut self, rhs: Factor) {
189 *self = *self * rhs;
190 }
191}
192impl ops::DivAssign<Factor> for Px {
193 fn div_assign(&mut self, rhs: Factor) {
194 *self = *self / rhs;
195 }
196}
197
198impl ops::Mul<Factor> for Dip {
199 type Output = Dip;
200
201 fn mul(self, rhs: Factor) -> Dip {
202 self * rhs.0
203 }
204}
205impl ops::Div<Factor> for Dip {
206 type Output = Dip;
207
208 fn div(self, rhs: Factor) -> Dip {
209 self / rhs.0
210 }
211}
212impl ops::MulAssign<Factor> for Dip {
213 fn mul_assign(&mut self, rhs: Factor) {
214 *self = *self * rhs;
215 }
216}
217impl ops::DivAssign<Factor> for Dip {
218 fn div_assign(&mut self, rhs: Factor) {
219 *self = *self / rhs;
220 }
221}
222
223impl ops::Mul<Factor> for PxPoint {
224 type Output = PxPoint;
225
226 fn mul(mut self, rhs: Factor) -> PxPoint {
227 self.x *= rhs;
228 self.y *= rhs;
229 self
230 }
231}
232impl ops::Div<Factor> for PxPoint {
233 type Output = PxPoint;
234
235 fn div(mut self, rhs: Factor) -> PxPoint {
236 self.x /= rhs;
237 self.y /= rhs;
238 self
239 }
240}
241impl ops::MulAssign<Factor> for PxPoint {
242 fn mul_assign(&mut self, rhs: Factor) {
243 self.x *= rhs;
244 self.y *= rhs;
245 }
246}
247impl ops::DivAssign<Factor> for PxPoint {
248 fn div_assign(&mut self, rhs: Factor) {
249 self.x /= rhs;
250 self.y /= rhs;
251 }
252}
253
254impl ops::Mul<Factor> for euclid::Point2D<f32, Px> {
255 type Output = euclid::Point2D<f32, Px>;
256
257 fn mul(mut self, rhs: Factor) -> euclid::Point2D<f32, Px> {
258 self.x *= rhs.0;
259 self.y *= rhs.0;
260 self
261 }
262}
263impl ops::Div<Factor> for euclid::Point2D<f32, Px> {
264 type Output = euclid::Point2D<f32, Px>;
265
266 fn div(mut self, rhs: Factor) -> euclid::Point2D<f32, Px> {
267 self.x /= rhs.0;
268 self.y /= rhs.0;
269 self
270 }
271}
272impl ops::MulAssign<Factor> for euclid::Point2D<f32, Px> {
273 fn mul_assign(&mut self, rhs: Factor) {
274 self.x *= rhs.0;
275 self.y *= rhs.0;
276 }
277}
278impl ops::DivAssign<Factor> for euclid::Point2D<f32, Px> {
279 fn div_assign(&mut self, rhs: Factor) {
280 self.x /= rhs.0;
281 self.y /= rhs.0;
282 }
283}
284
285impl ops::Mul<Factor> for DipPoint {
286 type Output = DipPoint;
287
288 fn mul(mut self, rhs: Factor) -> DipPoint {
289 self.x *= rhs;
290 self.y *= rhs;
291 self
292 }
293}
294impl ops::Div<Factor> for DipPoint {
295 type Output = DipPoint;
296
297 fn div(mut self, rhs: Factor) -> DipPoint {
298 self.x /= rhs;
299 self.y /= rhs;
300 self
301 }
302}
303impl ops::MulAssign<Factor> for DipPoint {
304 fn mul_assign(&mut self, rhs: Factor) {
305 self.x *= rhs;
306 self.y *= rhs;
307 }
308}
309impl ops::DivAssign<Factor> for DipPoint {
310 fn div_assign(&mut self, rhs: Factor) {
311 self.x /= rhs;
312 self.y /= rhs;
313 }
314}
315
316impl ops::Mul<Factor> for PxVector {
317 type Output = PxVector;
318
319 fn mul(mut self, rhs: Factor) -> PxVector {
320 self.x *= rhs;
321 self.y *= rhs;
322 self
323 }
324}
325impl ops::Div<Factor> for PxVector {
326 type Output = PxVector;
327
328 fn div(mut self, rhs: Factor) -> PxVector {
329 self.x /= rhs;
330 self.y /= rhs;
331 self
332 }
333}
334impl ops::MulAssign<Factor> for PxVector {
335 fn mul_assign(&mut self, rhs: Factor) {
336 self.x *= rhs;
337 self.y *= rhs;
338 }
339}
340impl ops::DivAssign<Factor> for PxVector {
341 fn div_assign(&mut self, rhs: Factor) {
342 self.x /= rhs;
343 self.y /= rhs;
344 }
345}
346
347impl ops::Mul<Factor> for DipVector {
348 type Output = DipVector;
349
350 fn mul(mut self, rhs: Factor) -> DipVector {
351 self.x *= rhs;
352 self.y *= rhs;
353 self
354 }
355}
356impl ops::Div<Factor> for DipVector {
357 type Output = DipVector;
358
359 fn div(mut self, rhs: Factor) -> DipVector {
360 self.x /= rhs;
361 self.y /= rhs;
362 self
363 }
364}
365impl ops::MulAssign<Factor> for DipVector {
366 fn mul_assign(&mut self, rhs: Factor) {
367 self.x *= rhs;
368 self.y *= rhs;
369 }
370}
371impl ops::DivAssign<Factor> for DipVector {
372 fn div_assign(&mut self, rhs: Factor) {
373 self.x /= rhs;
374 self.y /= rhs;
375 }
376}
377
378impl ops::Mul<Factor> for PxSize {
379 type Output = PxSize;
380
381 fn mul(mut self, rhs: Factor) -> PxSize {
382 self.width *= rhs;
383 self.height *= rhs;
384 self
385 }
386}
387impl ops::Div<Factor> for PxSize {
388 type Output = PxSize;
389
390 fn div(mut self, rhs: Factor) -> PxSize {
391 self.width /= rhs;
392 self.height /= rhs;
393 self
394 }
395}
396impl ops::MulAssign<Factor> for PxSize {
397 fn mul_assign(&mut self, rhs: Factor) {
398 self.width *= rhs;
399 self.height *= rhs;
400 }
401}
402impl ops::DivAssign<Factor> for PxSize {
403 fn div_assign(&mut self, rhs: Factor) {
404 self.width /= rhs;
405 self.height /= rhs;
406 }
407}
408
409impl ops::Mul<Factor> for euclid::Size2D<f32, Px> {
410 type Output = euclid::Size2D<f32, Px>;
411
412 fn mul(mut self, rhs: Factor) -> euclid::Size2D<f32, Px> {
413 self.width *= rhs.0;
414 self.height *= rhs.0;
415 self
416 }
417}
418impl ops::Div<Factor> for euclid::Size2D<f32, Px> {
419 type Output = euclid::Size2D<f32, Px>;
420
421 fn div(mut self, rhs: Factor) -> euclid::Size2D<f32, Px> {
422 self.width /= rhs.0;
423 self.height /= rhs.0;
424 self
425 }
426}
427impl ops::MulAssign<Factor> for euclid::Size2D<f32, Px> {
428 fn mul_assign(&mut self, rhs: Factor) {
429 self.width *= rhs.0;
430 self.height *= rhs.0;
431 }
432}
433impl ops::DivAssign<Factor> for euclid::Size2D<f32, Px> {
434 fn div_assign(&mut self, rhs: Factor) {
435 self.width /= rhs.0;
436 self.height /= rhs.0;
437 }
438}
439
440impl ops::Mul<Factor> for DipSize {
441 type Output = DipSize;
442
443 fn mul(mut self, rhs: Factor) -> DipSize {
444 self.width *= rhs;
445 self.height *= rhs;
446 self
447 }
448}
449impl ops::Div<Factor> for DipSize {
450 type Output = DipSize;
451
452 fn div(mut self, rhs: Factor) -> DipSize {
453 self.width /= rhs;
454 self.height /= rhs;
455 self
456 }
457}
458impl ops::MulAssign<Factor> for DipSize {
459 fn mul_assign(&mut self, rhs: Factor) {
460 self.width *= rhs;
461 self.height *= rhs;
462 }
463}
464impl ops::DivAssign<Factor> for DipSize {
465 fn div_assign(&mut self, rhs: Factor) {
466 self.width /= rhs;
467 self.height /= rhs;
468 }
469}
470impl ops::Mul<Factor> for PxRect {
471 type Output = PxRect;
472
473 fn mul(mut self, rhs: Factor) -> PxRect {
474 self.origin *= rhs;
475 self.size *= rhs;
476 self
477 }
478}
479impl ops::Div<Factor> for PxRect {
480 type Output = PxRect;
481
482 fn div(mut self, rhs: Factor) -> PxRect {
483 self.origin /= rhs;
484 self.size /= rhs;
485 self
486 }
487}
488impl ops::MulAssign<Factor> for PxRect {
489 fn mul_assign(&mut self, rhs: Factor) {
490 self.origin *= rhs;
491 self.size *= rhs;
492 }
493}
494impl ops::DivAssign<Factor> for PxRect {
495 fn div_assign(&mut self, rhs: Factor) {
496 self.origin /= rhs;
497 self.size /= rhs;
498 }
499}
500
501impl ops::Mul<Factor> for DipRect {
502 type Output = DipRect;
503
504 fn mul(mut self, rhs: Factor) -> DipRect {
505 self.origin *= rhs;
506 self.size *= rhs;
507 self
508 }
509}
510impl ops::Div<Factor> for DipRect {
511 type Output = DipRect;
512
513 fn div(mut self, rhs: Factor) -> DipRect {
514 self.origin /= rhs;
515 self.size /= rhs;
516 self
517 }
518}
519impl ops::MulAssign<Factor> for DipRect {
520 fn mul_assign(&mut self, rhs: Factor) {
521 self.origin *= rhs;
522 self.size *= rhs;
523 }
524}
525impl ops::DivAssign<Factor> for DipRect {
526 fn div_assign(&mut self, rhs: Factor) {
527 self.origin /= rhs;
528 self.size /= rhs;
529 }
530}
531
532impl ops::Neg for Factor {
533 type Output = Factor;
534
535 fn neg(self) -> Self::Output {
536 Factor(-self.0)
537 }
538}
539impl From<bool> for Factor {
540 fn from(value: bool) -> Self {
541 if value { Factor(1.0) } else { Factor(0.0) }
542 }
543}
544
545macro_rules! impl_for_integer {
546 ($($T:ty),+ $(,)?) => {$(
547 impl ops::Mul<Factor> for $T {
548 type Output = $T;
549
550 fn mul(self, rhs: Factor) -> $T {
551 (self as f64 * rhs.0 as f64).round() as $T
552 }
553 }
554 impl ops::Div<Factor> for $T {
555 type Output = $T;
556
557 fn div(self, rhs: Factor) -> $T {
558 (self as f64 / rhs.0 as f64).round() as $T
559 }
560 }
561 impl ops::MulAssign<Factor> for $T {
562 fn mul_assign(&mut self, rhs: Factor) {
563 *self = *self * rhs;
564 }
565 }
566 impl ops::DivAssign<Factor> for $T {
567 fn div_assign(&mut self, rhs: Factor) {
568 *self = *self / rhs;
569 }
570 }
571 )+}
572}
573impl_for_integer! { u8, i8, u16, i16, u32, i32, u64, i64, usize, isize, u128, i128 }
574
575impl ops::Mul<Factor> for f32 {
576 type Output = f32;
577
578 fn mul(self, rhs: Factor) -> f32 {
579 self * rhs.0
580 }
581}
582impl ops::Div<Factor> for f32 {
583 type Output = f32;
584
585 fn div(self, rhs: Factor) -> f32 {
586 self / rhs.0
587 }
588}
589impl ops::MulAssign<Factor> for f32 {
590 fn mul_assign(&mut self, rhs: Factor) {
591 *self = *self * rhs;
592 }
593}
594impl ops::DivAssign<Factor> for f32 {
595 fn div_assign(&mut self, rhs: Factor) {
596 *self = *self / rhs;
597 }
598}
599
600impl ops::Mul<Factor> for f64 {
601 type Output = f64;
602
603 fn mul(self, rhs: Factor) -> f64 {
604 self * rhs.0 as f64
605 }
606}
607impl ops::Div<Factor> for f64 {
608 type Output = f64;
609
610 fn div(self, rhs: Factor) -> f64 {
611 self / rhs.0 as f64
612 }
613}
614impl ops::MulAssign<Factor> for f64 {
615 fn mul_assign(&mut self, rhs: Factor) {
616 *self = *self * rhs;
617 }
618}
619impl ops::DivAssign<Factor> for f64 {
620 fn div_assign(&mut self, rhs: Factor) {
621 *self = *self / rhs;
622 }
623}
624
625impl ops::Mul<Factor> for Duration {
626 type Output = Duration;
627
628 fn mul(self, rhs: Factor) -> Duration {
629 self.mul_f32(rhs.0)
630 }
631}
632impl ops::Div<Factor> for Duration {
633 type Output = Duration;
634
635 fn div(self, rhs: Factor) -> Duration {
636 self.div_f32(rhs.0)
637 }
638}
639impl ops::MulAssign<Factor> for Duration {
640 fn mul_assign(&mut self, rhs: Factor) {
641 *self = *self * rhs;
642 }
643}
644impl ops::DivAssign<Factor> for Duration {
645 fn div_assign(&mut self, rhs: Factor) {
646 *self = *self / rhs;
647 }
648}
649
650impl From<Factor> for FactorPercent {
651 fn from(value: Factor) -> Self {
652 Self(value.0 * 100.0)
653 }
654}
655impl From<FactorPercent> for Factor {
656 fn from(value: FactorPercent) -> Self {
657 Self(value.0 / 100.0)
658 }
659}
660
661#[derive(Copy, Clone, serde::Serialize, serde::Deserialize)]
669#[serde(transparent)]
670pub struct FactorPercent(pub f32);
671impl FactorPercent {
672 pub fn clamp_range(self) -> Self {
674 FactorPercent(self.0.clamp(0.0, 100.0))
675 }
676
677 pub fn fct(self) -> Factor {
679 self.into()
680 }
681}
682impl ops::Add for FactorPercent {
683 type Output = Self;
684
685 fn add(self, rhs: Self) -> Self::Output {
686 Self(self.0 + rhs.0)
687 }
688}
689impl ops::AddAssign for FactorPercent {
690 fn add_assign(&mut self, rhs: Self) {
691 self.0 += rhs.0;
692 }
693}
694impl ops::Sub for FactorPercent {
695 type Output = Self;
696
697 fn sub(self, rhs: Self) -> Self::Output {
698 Self(self.0 - rhs.0)
699 }
700}
701impl ops::SubAssign for FactorPercent {
702 fn sub_assign(&mut self, rhs: Self) {
703 self.0 -= rhs.0;
704 }
705}
706impl ops::Neg for FactorPercent {
707 type Output = Self;
708
709 fn neg(self) -> Self::Output {
710 FactorPercent(-self.0)
711 }
712}
713impl PartialEq for FactorPercent {
714 fn eq(&self, other: &Self) -> bool {
715 about_eq(self.0, other.0, EQ_GRANULARITY_100)
716 }
717}
718impl Eq for FactorPercent {}
719impl ops::Mul for FactorPercent {
720 type Output = Self;
721
722 fn mul(self, rhs: Self) -> Self::Output {
723 Self(self.0 * rhs.0)
724 }
725}
726impl ops::MulAssign for FactorPercent {
727 fn mul_assign(&mut self, rhs: Self) {
728 *self = *self * rhs;
729 }
730}
731impl ops::Div for FactorPercent {
732 type Output = Self;
733
734 fn div(self, rhs: Self) -> Self::Output {
735 Self(self.0 / rhs.0)
736 }
737}
738impl ops::DivAssign for FactorPercent {
739 fn div_assign(&mut self, rhs: Self) {
740 *self = *self / rhs;
741 }
742}
743impl fmt::Debug for FactorPercent {
744 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
745 if f.alternate() {
746 f.debug_tuple("FactorPercent").field(&self.0).finish()
747 } else {
748 write!(f, "{}.pct()", self.0)
749 }
750 }
751}
752impl fmt::Display for FactorPercent {
753 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
754 write!(f, "{}%", (self.0 * 100.0).round() / 100.0)
756 }
757}
758
759impl ops::Mul<Factor> for FactorPercent {
760 type Output = FactorPercent;
761
762 fn mul(self, rhs: Factor) -> Self {
763 Self(self.0 * rhs.0)
764 }
765}
766impl ops::Div<Factor> for FactorPercent {
767 type Output = FactorPercent;
768
769 fn div(self, rhs: Factor) -> Self {
770 Self(self.0 / rhs.0)
771 }
772}
773impl ops::MulAssign<Factor> for FactorPercent {
774 fn mul_assign(&mut self, rhs: Factor) {
775 *self = *self * rhs;
776 }
777}
778impl ops::DivAssign<Factor> for FactorPercent {
779 fn div_assign(&mut self, rhs: Factor) {
780 *self = *self / rhs;
781 }
782}