1use std::ops::{Add, Div, Mul, Neg, Sub};
4
5#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd)]
7pub struct MotionPx(f32);
8
9impl MotionPx {
10 pub const ZERO: Self = Self(0.0);
12
13 pub const ONE: Self = Self(1.0);
15
16 pub const fn new(value: f32) -> Self {
18 Self(value)
19 }
20
21 pub const fn as_f32(self) -> f32 {
23 self.0
24 }
25
26 pub const fn half(self) -> Self {
28 Self(self.0 * 0.5)
29 }
30
31 pub const fn min(self, other: Self) -> Self {
33 if self.0 <= other.0 { self } else { other }
34 }
35
36 pub const fn max(self, other: Self) -> Self {
38 if self.0 >= other.0 { self } else { other }
39 }
40}
41
42impl Add for MotionPx {
43 type Output = Self;
44
45 fn add(self, rhs: Self) -> Self::Output {
46 Self(self.0 + rhs.0)
47 }
48}
49
50impl Sub for MotionPx {
51 type Output = Self;
52
53 fn sub(self, rhs: Self) -> Self::Output {
54 Self(self.0 - rhs.0)
55 }
56}
57
58impl Neg for MotionPx {
59 type Output = Self;
60
61 fn neg(self) -> Self::Output {
62 Self(-self.0)
63 }
64}
65
66impl Mul<f32> for MotionPx {
67 type Output = Self;
68
69 fn mul(self, rhs: f32) -> Self::Output {
70 Self(self.0 * rhs)
71 }
72}
73
74impl Div<f32> for MotionPx {
75 type Output = Self;
76
77 fn div(self, rhs: f32) -> Self::Output {
78 Self(self.0 / rhs)
79 }
80}
81
82pub const fn motion_px(value: f32) -> MotionPx {
84 MotionPx::new(value)
85}
86
87#[derive(Debug, Clone, Copy, Default, PartialEq)]
89pub struct MotionPoint {
90 pub x: MotionPx,
92 pub y: MotionPx,
94}
95
96impl MotionPoint {
97 pub const fn new(x: MotionPx, y: MotionPx) -> Self {
99 Self { x, y }
100 }
101}
102
103pub const fn motion_point(x: MotionPx, y: MotionPx) -> MotionPoint {
105 MotionPoint::new(x, y)
106}
107
108#[derive(Debug, Clone, Copy, Default, PartialEq)]
110pub struct MotionSize {
111 pub width: MotionPx,
113 pub height: MotionPx,
115}
116
117impl MotionSize {
118 pub const fn new(width: MotionPx, height: MotionPx) -> Self {
120 Self { width, height }
121 }
122}
123
124pub const fn motion_size(width: MotionPx, height: MotionPx) -> MotionSize {
126 MotionSize::new(width, height)
127}
128
129#[derive(Debug, Clone, Copy, Default, PartialEq)]
131pub struct MotionRect {
132 pub origin: MotionPoint,
134 pub size: MotionSize,
136}
137
138impl MotionRect {
139 pub const fn new(origin: MotionPoint, size: MotionSize) -> Self {
141 Self { origin, size }
142 }
143
144 pub const fn top_left(self) -> MotionPoint {
146 self.origin
147 }
148
149 pub fn top_center(self) -> MotionPoint {
151 MotionPoint::new(self.origin.x + self.size.width.half(), self.origin.y)
152 }
153
154 pub fn top_right(self) -> MotionPoint {
156 MotionPoint::new(self.origin.x + self.size.width, self.origin.y)
157 }
158
159 pub fn right_center(self) -> MotionPoint {
161 MotionPoint::new(
162 self.origin.x + self.size.width,
163 self.origin.y + self.size.height.half(),
164 )
165 }
166
167 pub fn bottom_left(self) -> MotionPoint {
169 MotionPoint::new(self.origin.x, self.origin.y + self.size.height)
170 }
171
172 pub fn bottom_center(self) -> MotionPoint {
174 MotionPoint::new(
175 self.origin.x + self.size.width.half(),
176 self.origin.y + self.size.height,
177 )
178 }
179
180 pub fn bottom_right(self) -> MotionPoint {
182 MotionPoint::new(
183 self.origin.x + self.size.width,
184 self.origin.y + self.size.height,
185 )
186 }
187
188 pub fn left_center(self) -> MotionPoint {
190 MotionPoint::new(self.origin.x, self.origin.y + self.size.height.half())
191 }
192
193 pub fn inset(self, amount: MotionPx) -> Self {
195 let double = MotionPx::new(amount.as_f32() * 2.0);
196 Self {
197 origin: MotionPoint::new(self.origin.x + amount, self.origin.y + amount),
198 size: MotionSize::new(self.size.width - double, self.size.height - double),
199 }
200 }
201}
202
203pub const fn motion_rect(origin: MotionPoint, size: MotionSize) -> MotionRect {
205 MotionRect::new(origin, size)
206}
207
208#[derive(Debug, Clone, Copy, Default, PartialEq)]
210pub struct MotionEdges {
211 pub top: MotionPx,
213 pub right: MotionPx,
215 pub bottom: MotionPx,
217 pub left: MotionPx,
219}
220
221impl MotionEdges {
222 pub const fn new(top: MotionPx, right: MotionPx, bottom: MotionPx, left: MotionPx) -> Self {
224 Self {
225 top,
226 right,
227 bottom,
228 left,
229 }
230 }
231
232 pub const fn uniform(value: MotionPx) -> Self {
234 Self {
235 top: value,
236 right: value,
237 bottom: value,
238 left: value,
239 }
240 }
241}
242
243pub const fn motion_edges(
245 top: MotionPx,
246 right: MotionPx,
247 bottom: MotionPx,
248 left: MotionPx,
249) -> MotionEdges {
250 MotionEdges::new(top, right, bottom, left)
251}