1use std::{fmt, ops};
2
3use zng_var::{animation::Transitionable, impl_from_and_into_var};
4
5use crate::unit::{LengthCompositeParser, ParseCompositeError};
6
7use super::{
8 Dip, DipVector, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, LengthUnits, Point, Px, PxVector, Size, Transform,
9 impl_length_comp_conversions,
10};
11
12#[derive(Clone, Default, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Transitionable)]
14pub struct Vector {
15 pub x: Length,
17 pub y: Length,
19}
20impl fmt::Debug for Vector {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 if f.alternate() {
23 f.debug_struct("Vector").field("x", &self.x).field("y", &self.y).finish()
24 } else {
25 write!(f, "({:?}, {:?})", self.x, self.y)
26 }
27 }
28}
29impl fmt::Display for Vector {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 if let Some(p) = f.precision() {
32 write!(f, "({:.p$}, {:.p$})", self.x, self.y, p = p)
33 } else {
34 write!(f, "({}, {})", self.x, self.y)
35 }
36 }
37}
38impl std::str::FromStr for Vector {
39 type Err = ParseCompositeError;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 let mut parser = LengthCompositeParser::new(s)?;
43 let a = parser.next()?;
44 if parser.has_ended() {
45 return Ok(Self::splat(a));
46 }
47 let b = parser.expect_last()?;
48 Ok(Self::new(a, b))
49 }
50}
51impl Vector {
52 pub fn new<X: Into<Length>, Y: Into<Length>>(x: X, y: Y) -> Self {
54 Vector { x: x.into(), y: y.into() }
55 }
56
57 pub fn splat(xy: impl Into<Length>) -> Self {
59 let xy = xy.into();
60 Vector { x: xy.clone(), y: xy }
61 }
62
63 pub fn zero() -> Self {
65 Self::new(Length::zero(), Length::zero())
66 }
67
68 pub fn one() -> Self {
70 Self::new(1, 1)
71 }
72
73 pub fn one_px() -> Self {
75 Self::new(1.px(), 1.px())
76 }
77
78 pub fn yx(self) -> Self {
80 Vector { y: self.x, x: self.y }
81 }
82
83 pub fn as_tuple(self) -> (Length, Length) {
85 (self.x, self.y)
86 }
87
88 pub fn as_array(self) -> [Length; 2] {
90 [self.x, self.y]
91 }
92
93 pub fn abs(&self) -> Vector {
95 Vector {
96 x: self.x.abs(),
97 y: self.y.abs(),
98 }
99 }
100
101 pub fn is_default(&self) -> bool {
103 self.x.is_default() && self.y.is_default()
104 }
105
106 pub fn has_default(&self) -> bool {
108 self.x.has_default() && self.y.has_default()
109 }
110
111 pub fn replace_default(&mut self, overwrite: &Vector) {
113 self.x.replace_default(&overwrite.x);
114 self.y.replace_default(&overwrite.y);
115 }
116
117 pub fn as_point(self) -> Point {
119 Point { x: self.x, y: self.y }
120 }
121
122 pub fn as_size(self) -> Size {
124 Size {
125 width: self.x,
126 height: self.y,
127 }
128 }
129
130 pub fn into_transform(self) -> Transform {
132 Transform::new_translate(self.x, self.y)
133 }
134}
135impl super::Layout2d for Vector {
136 type Px = PxVector;
137
138 fn layout_dft(&self, default: Self::Px) -> Self::Px {
139 PxVector::new(self.x.layout_dft_x(default.x), self.y.layout_dft_y(default.y))
140 }
141
142 fn affect_mask(&self) -> LayoutMask {
143 self.x.affect_mask() | self.y.affect_mask()
144 }
145}
146impl_length_comp_conversions! {
147 fn from(x: X, y: Y) -> Vector {
148 Vector::new(x, y)
149 }
150}
151impl_from_and_into_var! {
152 fn from(p: PxVector) -> Vector {
153 Vector::new(p.x, p.y)
154 }
155 fn from(p: DipVector) -> Vector {
156 Vector::new(p.x, p.y)
157 }
158 fn from(p: Point) -> Vector {
159 p.as_vector()
160 }
161 fn from(s: Size) -> Vector {
162 s.as_vector()
163 }
164
165 fn from(length: Length) -> Vector {
167 Vector::splat(length)
168 }
169
170 fn from(percent: FactorPercent) -> Vector {
172 Length::from(percent).into()
173 }
174
175 fn from(norm: Factor) -> Vector {
177 Length::from(norm).into()
178 }
179
180 fn from(f: f32) -> Vector {
182 Length::from(f).into()
183 }
184
185 fn from(i: i32) -> Vector {
187 Length::from(i).into()
188 }
189
190 fn from(l: Px) -> Vector {
192 Length::from(l).into()
193 }
194
195 fn from(l: Dip) -> Vector {
197 Length::from(l).into()
198 }
199}
200impl<V: Into<Vector>> ops::Add<V> for Vector {
201 type Output = Self;
202
203 fn add(self, rhs: V) -> Self {
204 let rhs = rhs.into();
205 Self {
206 x: self.x + rhs.x,
207 y: self.y + rhs.y,
208 }
209 }
210}
211impl<'a> ops::Add<&'a Vector> for &Vector {
212 type Output = Vector;
213
214 fn add(self, rhs: &'a Vector) -> Self::Output {
215 self.clone() + rhs.clone()
216 }
217}
218impl<V: Into<Vector>> ops::AddAssign<V> for Vector {
219 fn add_assign(&mut self, rhs: V) {
220 let rhs = rhs.into();
221 self.x += rhs.x;
222 self.y += rhs.y;
223 }
224}
225impl<V: Into<Vector>> ops::Sub<V> for Vector {
226 type Output = Self;
227
228 fn sub(self, rhs: V) -> Self {
229 let rhs = rhs.into();
230 Self {
231 x: self.x - rhs.x,
232 y: self.y - rhs.y,
233 }
234 }
235}
236impl<'a> ops::Sub<&'a Vector> for &Vector {
237 type Output = Vector;
238
239 fn sub(self, rhs: &'a Vector) -> Self::Output {
240 self.clone() - rhs.clone()
241 }
242}
243impl<V: Into<Vector>> ops::SubAssign<V> for Vector {
244 fn sub_assign(&mut self, rhs: V) {
245 let rhs = rhs.into();
246 self.x -= rhs.x;
247 self.y -= rhs.y;
248 }
249}
250impl<S: Into<Factor2d>> ops::Mul<S> for Vector {
251 type Output = Self;
252
253 fn mul(mut self, rhs: S) -> Self {
254 self *= rhs;
255 self
256 }
257}
258impl<S: Into<Factor2d>> ops::Mul<S> for &Vector {
259 type Output = Vector;
260
261 fn mul(self, rhs: S) -> Self::Output {
262 self.clone() * rhs
263 }
264}
265impl<S: Into<Factor2d>> ops::MulAssign<S> for Vector {
266 fn mul_assign(&mut self, rhs: S) {
267 let rhs = rhs.into();
268
269 self.x *= rhs.x;
270 self.y *= rhs.y;
271 }
272}
273impl<S: Into<Factor2d>> ops::Div<S> for Vector {
274 type Output = Self;
275
276 fn div(mut self, rhs: S) -> Self {
277 self /= rhs;
278 self
279 }
280}
281impl<S: Into<Factor2d>> ops::Div<S> for &Vector {
282 type Output = Vector;
283
284 fn div(self, rhs: S) -> Self::Output {
285 self.clone() / rhs
286 }
287}
288impl<S: Into<Factor2d>> ops::DivAssign<S> for Vector {
289 fn div_assign(&mut self, rhs: S) {
290 let rhs = rhs.into();
291 self.x /= rhs.x;
292 self.y /= rhs.y;
293 }
294}
295impl ops::Neg for Vector {
296 type Output = Self;
297
298 fn neg(self) -> Self {
299 Vector { x: -self.x, y: -self.y }
300 }
301}
302impl ops::Neg for &Vector {
303 type Output = Vector;
304
305 fn neg(self) -> Self::Output {
306 -self.clone()
307 }
308}