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