zng_layout/unit/
point.rs
1use std::{fmt, ops};
2
3use zng_var::{animation::Transitionable, impl_from_and_into_var};
4
5use super::{DipPoint, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, PxPoint, Size, Vector, impl_length_comp_conversions};
6
7#[derive(Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
9pub struct Point {
10 pub x: Length,
12 pub y: Length,
14}
15impl fmt::Debug for Point {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 if f.alternate() {
18 f.debug_struct("Point").field("x", &self.x).field("y", &self.y).finish()
19 } else {
20 write!(f, "({:?}, {:?})", self.x, self.y)
21 }
22 }
23}
24impl fmt::Display for Point {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 if let Some(p) = f.precision() {
27 write!(f, "({:.p$}, {:.p$})", self.x, self.y, p = p)
28 } else {
29 write!(f, "({}, {})", self.x, self.y)
30 }
31 }
32}
33impl Point {
34 pub fn new<X: Into<Length>, Y: Into<Length>>(x: X, y: Y) -> Self {
36 Point { x: x.into(), y: y.into() }
37 }
38
39 pub fn splat(xy: impl Into<Length>) -> Self {
41 let xy = xy.into();
42 Point { x: xy.clone(), y: xy }
43 }
44
45 pub fn zero() -> Self {
47 Self::new(Length::zero(), Length::zero())
48 }
49
50 pub fn top() -> Self {
54 Self::new(Length::half(), Length::zero())
55 }
56
57 pub fn bottom() -> Self {
61 Self::new(Length::half(), Length::fill())
62 }
63
64 pub fn left() -> Self {
68 Self::new(Length::zero(), Length::half())
69 }
70
71 pub fn right() -> Self {
75 Self::new(Length::fill(), Length::half())
76 }
77
78 pub fn top_left() -> Self {
82 Self::zero()
83 }
84
85 pub fn top_right() -> Self {
89 Self::new(Length::fill(), Length::zero())
90 }
91
92 pub fn bottom_left() -> Self {
96 Self::new(Length::zero(), Length::fill())
97 }
98
99 pub fn bottom_right() -> Self {
103 Self::new(Length::fill(), Length::fill())
104 }
105
106 pub fn center() -> Self {
110 Self::new(Length::half(), Length::half())
111 }
112
113 pub fn yx(self) -> Self {
115 Point { y: self.x, x: self.y }
116 }
117
118 pub fn as_tuple(self) -> (Length, Length) {
120 (self.x, self.y)
121 }
122
123 pub fn as_array(self) -> [Length; 2] {
125 [self.x, self.y]
126 }
127
128 pub fn is_default(&self) -> bool {
130 self.x.is_default() && self.y.is_default()
131 }
132
133 pub fn replace_default(&mut self, overwrite: &Point) {
135 self.x.replace_default(&overwrite.x);
136 self.y.replace_default(&overwrite.y);
137 }
138
139 pub fn as_vector(self) -> Vector {
141 Vector { x: self.x, y: self.y }
142 }
143}
144impl super::Layout2d for Point {
145 type Px = PxPoint;
146
147 fn layout_dft(&self, default: Self::Px) -> Self::Px {
148 PxPoint::new(self.x.layout_dft_x(default.x), self.y.layout_dft_y(default.y))
149 }
150
151 fn affect_mask(&self) -> LayoutMask {
152 self.x.affect_mask() | self.y.affect_mask()
153 }
154}
155impl_length_comp_conversions! {
156 fn from(x: X, y: Y) -> Point {
157 Point::new(x, y)
158 }
159}
160impl_from_and_into_var! {
161 fn from(all: Length) -> Point {
163 Point::splat(all)
164 }
165 fn from(percent: FactorPercent) -> Point {
167 Point::splat(percent)
168 }
169 fn from(norm: Factor) -> Point {
171 Point::splat(norm)
172 }
173
174 fn from(f: f32) -> Point {
176 Point::splat(f)
177 }
178 fn from(i: i32) -> Point {
180 Point::splat(i)
181 }
182 fn from(p: PxPoint) -> Point {
183 Point::new(p.x, p.y)
184 }
185 fn from(p: DipPoint) -> Point {
186 Point::new(p.x, p.y)
187 }
188 fn from(v: Vector) -> Point {
189 v.as_point()
190 }
191}
192impl<V: Into<Vector>> ops::Add<V> for Point {
193 type Output = Self;
194
195 fn add(mut self, rhs: V) -> Self {
196 self += rhs;
197 self
198 }
199}
200impl<'a> ops::Add<&'a Vector> for &Point {
201 type Output = Point;
202
203 fn add(self, rhs: &'a Vector) -> Self::Output {
204 self.clone() + rhs.clone()
205 }
206}
207impl<'a> ops::Add<&'a Size> for &Point {
208 type Output = Point;
209
210 fn add(self, rhs: &'a Size) -> Self::Output {
211 self.clone() + rhs.clone()
212 }
213}
214impl<V: Into<Vector>> ops::AddAssign<V> for Point {
215 fn add_assign(&mut self, rhs: V) {
216 let rhs = rhs.into();
217 self.x += rhs.x;
218 self.y += rhs.y;
219 }
220}
221impl<'a> ops::AddAssign<&'a Vector> for Point {
222 fn add_assign(&mut self, rhs: &'a Vector) {
223 *self += rhs.clone();
224 }
225}
226impl<'a> ops::AddAssign<&'a Size> for Point {
227 fn add_assign(&mut self, rhs: &'a Size) {
228 *self += rhs.clone();
229 }
230}
231impl<V: Into<Vector>> ops::Sub<V> for Point {
232 type Output = Self;
233
234 fn sub(mut self, rhs: V) -> Self {
235 self -= rhs;
236 self
237 }
238}
239impl<'a> ops::Sub<&'a Vector> for &Point {
240 type Output = Point;
241
242 fn sub(self, rhs: &'a Vector) -> Self::Output {
243 self.clone() - rhs.clone()
244 }
245}
246impl<'a> ops::Sub<&'a Size> for &Point {
247 type Output = Point;
248
249 fn sub(self, rhs: &'a Size) -> Self::Output {
250 self.clone() - rhs.clone()
251 }
252}
253impl<V: Into<Vector>> ops::SubAssign<V> for Point {
254 fn sub_assign(&mut self, rhs: V) {
255 let rhs = rhs.into();
256 self.x -= rhs.x;
257 self.y -= rhs.y;
258 }
259}
260impl<'a> ops::SubAssign<&'a Vector> for Point {
261 fn sub_assign(&mut self, rhs: &'a Vector) {
262 *self -= rhs.clone();
263 }
264}
265impl<'a> ops::SubAssign<&'a Size> for Point {
266 fn sub_assign(&mut self, rhs: &'a Size) {
267 *self -= rhs.clone();
268 }
269}
270impl<S: Into<Factor2d>> ops::Mul<S> for Point {
271 type Output = Self;
272
273 fn mul(mut self, rhs: S) -> Self {
274 self *= rhs;
275 self
276 }
277}
278impl<S: Into<Factor2d>> ops::Mul<S> for &Point {
279 type Output = Point;
280
281 fn mul(self, rhs: S) -> Self::Output {
282 self.clone() * rhs
283 }
284}
285impl<S: Into<Factor2d>> ops::MulAssign<S> for Point {
286 fn mul_assign(&mut self, rhs: S) {
287 let rhs = rhs.into();
288 self.x *= rhs.x;
289 self.y *= rhs.y;
290 }
291}
292impl<S: Into<Factor2d>> ops::Div<S> for Point {
293 type Output = Self;
294
295 fn div(mut self, rhs: S) -> Self {
296 self /= rhs;
297 self
298 }
299}
300impl<S: Into<Factor2d>> ops::Div<S> for &Point {
301 type Output = Point;
302
303 fn div(self, rhs: S) -> Self::Output {
304 self.clone() / rhs
305 }
306}
307impl<S: Into<Factor2d>> ops::DivAssign<S> for Point {
308 fn div_assign(&mut self, rhs: S) {
309 let rhs = rhs.into();
310 self.x /= rhs.x;
311 self.y /= rhs.y;
312 }
313}
314impl ops::Neg for Point {
315 type Output = Self;
316
317 fn neg(self) -> Self {
318 Point { x: -self.x, y: -self.y }
319 }
320}
321
322impl ops::Neg for &Point {
323 type Output = Point;
324
325 fn neg(self) -> Self::Output {
326 -self.clone()
327 }
328}