zng_layout/unit/
size.rs
1use std::{fmt, ops};
2
3use zng_var::{animation::Transitionable, impl_from_and_into_var};
4
5use super::{DipSize, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, PxSize, Rect, Vector, impl_length_comp_conversions};
6
7#[derive(Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
9pub struct Size {
10 pub width: Length,
12 pub height: Length,
14}
15impl fmt::Debug for Size {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 if f.alternate() {
18 f.debug_struct("Size")
19 .field("width", &self.width)
20 .field("height", &self.height)
21 .finish()
22 } else {
23 write!(f, "({:?}, {:?})", self.width, self.height)
24 }
25 }
26}
27impl fmt::Display for Size {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 if let Some(p) = f.precision() {
30 write!(f, "{:.p$} × {:.p$}", self.width, self.height, p = p)
31 } else {
32 write!(f, "{} × {}", self.width, self.height)
33 }
34 }
35}
36impl Size {
37 pub fn new<W: Into<Length>, H: Into<Length>>(width: W, height: H) -> Self {
39 Size {
40 width: width.into(),
41 height: height.into(),
42 }
43 }
44
45 pub fn splat(wh: impl Into<Length>) -> Self {
47 let wh = wh.into();
48 Size {
49 width: wh.clone(),
50 height: wh,
51 }
52 }
53
54 pub fn zero() -> Self {
56 Self::new(Length::zero(), Length::zero())
57 }
58
59 pub fn fill() -> Self {
63 Self::new(Length::fill(), Length::fill())
64 }
65
66 pub fn as_tuple(self) -> (Length, Length) {
68 (self.width, self.height)
69 }
70
71 pub fn as_array(self) -> [Length; 2] {
73 [self.width, self.height]
74 }
75
76 pub fn is_default(&self) -> bool {
78 self.width.is_default() && self.height.is_default()
79 }
80
81 pub fn replace_default(&mut self, overwrite: &Size) {
83 self.width.replace_default(&overwrite.width);
84 self.height.replace_default(&overwrite.height);
85 }
86
87 pub fn as_vector(self) -> Vector {
89 Vector {
90 x: self.width,
91 y: self.height,
92 }
93 }
94}
95impl super::Layout2d for Size {
96 type Px = PxSize;
97
98 fn layout_dft(&self, default: Self::Px) -> Self::Px {
99 PxSize::new(self.width.layout_dft_x(default.width), self.height.layout_dft_y(default.height))
100 }
101
102 fn affect_mask(&self) -> LayoutMask {
103 self.width.affect_mask() | self.height.affect_mask()
104 }
105}
106impl_length_comp_conversions! {
107 fn from(width: W, height: H) -> Size {
108 Size::new(width, height)
109 }
110}
111impl_from_and_into_var! {
112 fn from(all: Length) -> Size {
114 Size::splat(all)
115 }
116
117 fn from(percent: FactorPercent) -> Size {
119 Size::splat(percent)
120 }
121 fn from(norm: Factor) -> Size {
123 Size::splat(norm)
124 }
125
126 fn from(f: f32) -> Size {
128 Size::splat(f)
129 }
130 fn from(i: i32) -> Size {
132 Size::splat(i)
133 }
134 fn from(size: PxSize) -> Size {
135 Size::new(size.width, size.height)
136 }
137 fn from(size: DipSize) -> Size {
138 Size::new(size.width, size.height)
139 }
140 fn from(v: Vector) -> Size {
141 v.as_size()
142 }
143 fn from(r: Rect) -> Size {
144 r.size
145 }
146}
147impl<S: Into<Size>> ops::Add<S> for Size {
148 type Output = Size;
149
150 fn add(self, rhs: S) -> Self::Output {
151 let rhs = rhs.into();
152
153 Size {
154 width: self.width + rhs.width,
155 height: self.height + rhs.height,
156 }
157 }
158}
159impl<S: Into<Size>> ops::AddAssign<S> for Size {
160 fn add_assign(&mut self, rhs: S) {
161 let rhs = rhs.into();
162 self.width += rhs.width;
163 self.height += rhs.height;
164 }
165}
166impl<S: Into<Size>> ops::Sub<S> for Size {
167 type Output = Size;
168
169 fn sub(self, rhs: S) -> Self::Output {
170 let rhs = rhs.into();
171
172 Size {
173 width: self.width - rhs.width,
174 height: self.height - rhs.height,
175 }
176 }
177}
178impl<S: Into<Size>> ops::SubAssign<S> for Size {
179 fn sub_assign(&mut self, rhs: S) {
180 let rhs = rhs.into();
181 self.width -= rhs.width;
182 self.height -= rhs.height;
183 }
184}
185impl<S: Into<Factor2d>> ops::Mul<S> for Size {
186 type Output = Self;
187
188 fn mul(mut self, rhs: S) -> Self {
189 self *= rhs;
190 self
191 }
192}
193impl<S: Into<Factor2d>> ops::Mul<S> for &Size {
194 type Output = Size;
195
196 fn mul(self, rhs: S) -> Self::Output {
197 self.clone() * rhs
198 }
199}
200impl<S: Into<Factor2d>> ops::MulAssign<S> for Size {
201 fn mul_assign(&mut self, rhs: S) {
202 let rhs = rhs.into();
203 self.width *= rhs.x;
204 self.height *= rhs.y;
205 }
206}
207impl<S: Into<Factor2d>> ops::Div<S> for Size {
208 type Output = Self;
209
210 fn div(mut self, rhs: S) -> Self {
211 self /= rhs;
212 self
213 }
214}
215impl<S: Into<Factor2d>> ops::Div<S> for &Size {
216 type Output = Size;
217
218 fn div(self, rhs: S) -> Self::Output {
219 self.clone() / rhs
220 }
221}
222impl<S: Into<Factor2d>> ops::DivAssign<S> for Size {
223 fn div_assign(&mut self, rhs: S) {
224 let rhs = rhs.into();
225 self.width /= rhs.x;
226 self.height /= rhs.y;
227 }
228}