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/// 2D vector in [`Length`] units.
11#[derive(Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
12pub struct Vector {
13    /// *x* displacement in length units.
14    pub x: Length,
15    /// *y* displacement in length units.
16    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    /// New x, y from any [`Length`] unit.
38    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    /// New x, y from single value of any [`Length`] unit.
43    pub fn splat(xy: impl Into<Length>) -> Self {
44        let xy = xy.into();
45        Vector { x: xy.clone(), y: xy }
46    }
47
48    /// ***x:*** [`Length::zero`], ***y:*** [`Length::zero`].
49    pub fn zero() -> Self {
50        Self::new(Length::zero(), Length::zero())
51    }
52
53    /// `(1, 1)`.
54    pub fn one() -> Self {
55        Self::new(1, 1)
56    }
57
58    /// `(1.px(), 1.px())`.
59    pub fn one_px() -> Self {
60        Self::new(1.px(), 1.px())
61    }
62
63    /// Swap `x` and `y`.
64    pub fn yx(self) -> Self {
65        Vector { y: self.x, x: self.y }
66    }
67
68    /// Returns `(x, y)`.
69    pub fn as_tuple(self) -> (Length, Length) {
70        (self.x, self.y)
71    }
72
73    /// Returns `[x, y]`.
74    pub fn as_array(self) -> [Length; 2] {
75        [self.x, self.y]
76    }
77
78    /// Returns a vector that computes the absolute layout vector of `self`.
79    pub fn abs(&self) -> Vector {
80        Vector {
81            x: self.x.abs(),
82            y: self.y.abs(),
83        }
84    }
85
86    /// Returns `true` if all values are [`Length::Default`].
87    pub fn is_default(&self) -> bool {
88        self.x.is_default() && self.y.is_default()
89    }
90
91    /// Replaces [`Length::Default`] values with `overwrite` values.
92    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    /// Cast to [`Point`].
98    pub fn as_point(self) -> Point {
99        Point { x: self.x, y: self.y }
100    }
101
102    /// Cast to [`Size`].
103    pub fn as_size(self) -> Size {
104        Size {
105            width: self.x,
106            height: self.y,
107        }
108    }
109
110    /// Create a translate transform from `self`.
111    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    /// Use the length for x and y.
146    fn from(length: Length) -> Vector {
147        Vector::splat(length)
148    }
149
150    /// Conversion to [`Length::Factor`] then to vector.
151    fn from(percent: FactorPercent) -> Vector {
152        Length::from(percent).into()
153    }
154
155    /// Conversion to [`Length::Factor`] then to vector.
156    fn from(norm: Factor) -> Vector {
157        Length::from(norm).into()
158    }
159
160    /// Conversion to [`Length::Dip`] then to vector.
161    fn from(f: f32) -> Vector {
162        Length::from(f).into()
163    }
164
165    /// Conversion to [`Length::Dip`] then to vector.
166    fn from(i: i32) -> Vector {
167        Length::from(i).into()
168    }
169
170    /// Conversion to [`Length::Px`] then to vector.
171    fn from(l: Px) -> Vector {
172        Length::from(l).into()
173    }
174
175    /// Conversion to [`Length::Dip`] then to vector.
176    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}