zng_layout/unit/
vector.rs

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/// 2D vector in [`Length`] units.
13#[derive(Clone, Default, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Transitionable)]
14pub struct Vector {
15    /// *x* displacement in length units.
16    pub x: Length,
17    /// *y* displacement in length units.
18    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    /// New x, y from any [`Length`] unit.
53    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    /// New x, y from single value of any [`Length`] unit.
58    pub fn splat(xy: impl Into<Length>) -> Self {
59        let xy = xy.into();
60        Vector { x: xy.clone(), y: xy }
61    }
62
63    /// ***x:*** [`Length::zero`], ***y:*** [`Length::zero`].
64    pub fn zero() -> Self {
65        Self::new(Length::zero(), Length::zero())
66    }
67
68    /// `(1, 1)`.
69    pub fn one() -> Self {
70        Self::new(1, 1)
71    }
72
73    /// `(1.px(), 1.px())`.
74    pub fn one_px() -> Self {
75        Self::new(1.px(), 1.px())
76    }
77
78    /// Swap `x` and `y`.
79    pub fn yx(self) -> Self {
80        Vector { y: self.x, x: self.y }
81    }
82
83    /// Returns `(x, y)`.
84    pub fn as_tuple(self) -> (Length, Length) {
85        (self.x, self.y)
86    }
87
88    /// Returns `[x, y]`.
89    pub fn as_array(self) -> [Length; 2] {
90        [self.x, self.y]
91    }
92
93    /// Returns a vector that computes the absolute layout vector of `self`.
94    pub fn abs(&self) -> Vector {
95        Vector {
96            x: self.x.abs(),
97            y: self.y.abs(),
98        }
99    }
100
101    /// Returns `true` if all values are [`Length::Default`].
102    pub fn is_default(&self) -> bool {
103        self.x.is_default() && self.y.is_default()
104    }
105
106    /// Returns `true` if any value is [`Length::Default`].
107    pub fn has_default(&self) -> bool {
108        self.x.has_default() && self.y.has_default()
109    }
110
111    /// Replaces [`Length::Default`] values with `overwrite` values.
112    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    /// Cast to [`Point`].
118    pub fn as_point(self) -> Point {
119        Point { x: self.x, y: self.y }
120    }
121
122    /// Cast to [`Size`].
123    pub fn as_size(self) -> Size {
124        Size {
125            width: self.x,
126            height: self.y,
127        }
128    }
129
130    /// Create a translate transform from `self`.
131    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    /// Use the length for x and y.
166    fn from(length: Length) -> Vector {
167        Vector::splat(length)
168    }
169
170    /// Conversion to [`Length::Factor`] then to vector.
171    fn from(percent: FactorPercent) -> Vector {
172        Length::from(percent).into()
173    }
174
175    /// Conversion to [`Length::Factor`] then to vector.
176    fn from(norm: Factor) -> Vector {
177        Length::from(norm).into()
178    }
179
180    /// Conversion to [`Length::Dip`] then to vector.
181    fn from(f: f32) -> Vector {
182        Length::from(f).into()
183    }
184
185    /// Conversion to [`Length::Dip`] then to vector.
186    fn from(i: i32) -> Vector {
187        Length::from(i).into()
188    }
189
190    /// Conversion to [`Length::Px`] then to vector.
191    fn from(l: Px) -> Vector {
192        Length::from(l).into()
193    }
194
195    /// Conversion to [`Length::Dip`] then to vector.
196    fn from(l: Dip) -> Vector {
197        Length::from(l).into()
198    }
199}
200impl ops::Add for Vector {
201    type Output = Self;
202
203    fn add(mut self, rhs: Self) -> Self {
204        self += rhs;
205        self
206    }
207}
208impl<'a> ops::Add<&'a Vector> for &Vector {
209    type Output = Vector;
210
211    fn add(self, rhs: &'a Vector) -> Self::Output {
212        self.clone() + rhs.clone()
213    }
214}
215impl ops::AddAssign for Vector {
216    fn add_assign(&mut self, rhs: Self) {
217        self.x += rhs.x;
218        self.y += rhs.y;
219    }
220}
221impl ops::Sub for Vector {
222    type Output = Self;
223
224    fn sub(mut self, rhs: Self) -> Self {
225        self -= rhs;
226        self
227    }
228}
229impl<'a> ops::Sub<&'a Vector> for &Vector {
230    type Output = Vector;
231
232    fn sub(self, rhs: &'a Vector) -> Self::Output {
233        self.clone() - rhs.clone()
234    }
235}
236impl ops::SubAssign for Vector {
237    fn sub_assign(&mut self, rhs: Self) {
238        self.x -= rhs.x;
239        self.y -= rhs.y;
240    }
241}
242impl<S: Into<Factor2d>> ops::Mul<S> for Vector {
243    type Output = Self;
244
245    fn mul(mut self, rhs: S) -> Self {
246        self *= rhs;
247        self
248    }
249}
250impl<S: Into<Factor2d>> ops::Mul<S> for &Vector {
251    type Output = Vector;
252
253    fn mul(self, rhs: S) -> Self::Output {
254        self.clone() * rhs
255    }
256}
257impl<S: Into<Factor2d>> ops::MulAssign<S> for Vector {
258    fn mul_assign(&mut self, rhs: S) {
259        let rhs = rhs.into();
260
261        self.x *= rhs.x;
262        self.y *= rhs.y;
263    }
264}
265impl<S: Into<Factor2d>> ops::Div<S> for Vector {
266    type Output = Self;
267
268    fn div(mut self, rhs: S) -> Self {
269        self /= rhs;
270        self
271    }
272}
273impl<S: Into<Factor2d>> ops::Div<S> for &Vector {
274    type Output = Vector;
275
276    fn div(self, rhs: S) -> Self::Output {
277        self.clone() / rhs
278    }
279}
280impl<S: Into<Factor2d>> ops::DivAssign<S> for Vector {
281    fn div_assign(&mut self, rhs: S) {
282        let rhs = rhs.into();
283        self.x /= rhs.x;
284        self.y /= rhs.y;
285    }
286}
287impl ops::Neg for Vector {
288    type Output = Self;
289
290    fn neg(self) -> Self {
291        Vector { x: -self.x, y: -self.y }
292    }
293}
294impl ops::Neg for &Vector {
295    type Output = Vector;
296
297    fn neg(self) -> Self::Output {
298        -self.clone()
299    }
300}