1use super::*;
4
5#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
7pub enum OS {
8 Mac,
10 Linux,
12 Windows,
14 Android,
16 IPhone,
18 IPad,
20 #[default]
22 Unknown,
23}
24
25impl OS {
26 pub fn is_mobile(&self) -> bool {
28 match self {
29 OS::Android | OS::IPhone | OS::IPad => true,
30 _ => false,
31 }
32 }
33
34 pub fn is_desktop(&self) -> bool {
36 match self {
37 OS::Mac | OS::Linux | OS::Windows => true,
38 _ => false,
39 }
40 }
41
42 pub fn is_ios(&self) -> bool {
44 matches!(self, OS::IPhone | OS::IPad)
45 }
46
47 pub fn is_iphone(&self) -> bool {
49 matches!(self, OS::IPhone)
50 }
51
52 pub fn is_ipad(&self) -> bool {
54 matches!(self, OS::IPad)
55 }
56
57 pub fn is_macos(&self) -> bool {
59 matches!(self, OS::Mac)
60 }
61
62 pub fn is_android(&self) -> bool {
64 matches!(self, OS::Android)
65 }
66
67 pub fn is_windows(&self) -> bool {
69 matches!(self, OS::Windows)
70 }
71
72 pub fn is_linux(&self) -> bool {
74 matches!(self, OS::Linux)
75 }
76}
77
78#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
80pub enum Platform {
81 Web,
83 Native,
85 #[default]
87 Unknown,
88}
89
90#[derive(Default, Debug, Clone, PartialEq)]
92pub struct NativeLiquidGlassScope {
93 pub group_id: u32,
95 pub spacing: f64,
97 pub interactive: bool,
99 pub tint: Option<Color>,
101 pub variant: String,
103}
104
105impl NativeLiquidGlassScope {
106 pub fn to_message(&self) -> AppleLiquidGlassPatch {
108 AppleLiquidGlassPatch {
109 group_id: self.group_id,
110 spacing: self.spacing,
111 interactive: self.interactive,
112 tint: self.tint.as_ref().map(Into::into),
113 variant: self.variant.clone(),
114 }
115 }
116}
117
118impl Interpolatable for NativeLiquidGlassScope {}
119
120impl Platform {
121 pub fn is_web(&self) -> bool {
123 matches!(self, Platform::Web)
124 }
125
126 pub fn is_native(&self) -> bool {
128 matches!(self, Platform::Native)
129 }
130}
131
132#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
134pub struct TargetInfo {
135 pub web: bool,
137 pub native: bool,
139 pub ios: bool,
141 pub iphone: bool,
143 pub ipad: bool,
145 pub macos: bool,
147 pub android: bool,
149 pub windows: bool,
151 pub linux: bool,
153 pub mobile: bool,
155 pub desktop: bool,
157}
158
159impl TargetInfo {
160 pub fn new(platform: Platform, os: OS) -> Self {
162 Self {
163 web: platform.is_web(),
164 native: platform.is_native(),
165 ios: os.is_ios(),
166 iphone: os.is_iphone(),
167 ipad: os.is_ipad(),
168 macos: os.is_macos(),
169 android: os.is_android(),
170 windows: os.is_windows(),
171 linux: os.is_linux(),
172 mobile: os.is_mobile(),
173 desktop: os.is_desktop(),
174 }
175 }
176}
177
178impl ToPaxValue for TargetInfo {
179 fn to_pax_value(self) -> PaxValue {
180 PaxValue::Object(
181 vec![
182 ("web".to_string(), self.web.to_pax_value()),
183 ("native".to_string(), self.native.to_pax_value()),
184 ("ios".to_string(), self.ios.to_pax_value()),
185 ("iphone".to_string(), self.iphone.to_pax_value()),
186 ("ipad".to_string(), self.ipad.to_pax_value()),
187 ("macos".to_string(), self.macos.to_pax_value()),
188 ("android".to_string(), self.android.to_pax_value()),
189 ("windows".to_string(), self.windows.to_pax_value()),
190 ("linux".to_string(), self.linux.to_pax_value()),
191 ("mobile".to_string(), self.mobile.to_pax_value()),
192 ("desktop".to_string(), self.desktop.to_pax_value()),
193 ]
194 .into_iter()
195 .collect(),
196 )
197 }
198}
199
200impl Interpolatable for TargetInfo {}
201
202#[derive(Default, Debug, Clone, Copy)]
205pub struct Viewport {
206 pub width: f64,
208 pub height: f64,
210 pub major: f64,
212 pub minor: f64,
214 pub aspect: f64,
216 pub landscape: bool,
218 pub portrait: bool,
220 pub square: bool,
222}
223
224impl Viewport {
225 pub const SQUARE_EPSILON: f64 = 0.5;
227
228 pub fn new(width: f64, height: f64) -> Self {
230 let square = (width - height).abs() <= Self::SQUARE_EPSILON;
231 Self {
232 width,
233 height,
234 major: width.max(height),
235 minor: width.min(height),
236 aspect: if height.abs() <= f64::EPSILON {
237 0.0
238 } else {
239 width / height
240 },
241 landscape: width > height + Self::SQUARE_EPSILON,
242 portrait: height > width + Self::SQUARE_EPSILON,
243 square,
244 }
245 }
246}
247
248impl ToPaxValue for Viewport {
249 fn to_pax_value(self) -> PaxValue {
250 PaxValue::Object(
251 vec![
252 ("width".to_string(), self.width.to_pax_value()),
253 ("height".to_string(), self.height.to_pax_value()),
254 ("major".to_string(), self.major.to_pax_value()),
255 ("minor".to_string(), self.minor.to_pax_value()),
256 ("aspect".to_string(), self.aspect.to_pax_value()),
257 ("landscape".to_string(), self.landscape.to_pax_value()),
258 ("portrait".to_string(), self.portrait.to_pax_value()),
259 ("square".to_string(), self.square.to_pax_value()),
260 ]
261 .into_iter()
262 .collect(),
263 )
264 }
265}
266
267impl Interpolatable for Viewport {
268 fn interpolate(&self, other: &Self, t: f64) -> Self {
269 Viewport {
270 width: self.width + (other.width - self.width) * t,
271 height: self.height + (other.height - self.height) * t,
272 major: self.major + (other.major - self.major) * t,
273 minor: self.minor + (other.minor - self.minor) * t,
274 aspect: self.aspect + (other.aspect - self.aspect) * t,
275 landscape: self.landscape,
276 portrait: self.portrait,
277 square: self.square,
278 }
279 }
280}
281
282#[derive(Default, Debug, Clone, Copy, PartialEq)]
287pub struct Gyro {
288 pub x: f64,
290 pub y: f64,
292 pub z: f64,
294}
295
296impl ToPaxValue for Gyro {
297 fn to_pax_value(self) -> PaxValue {
298 PaxValue::Object(
299 vec![
300 ("x".to_string(), self.x.to_pax_value()),
301 ("y".to_string(), self.y.to_pax_value()),
302 ("z".to_string(), self.z.to_pax_value()),
303 ]
304 .into_iter()
305 .collect(),
306 )
307 }
308}
309
310impl Interpolatable for Gyro {
311 fn interpolate(&self, other: &Self, t: f64) -> Self {
312 Gyro {
313 x: self.x + (other.x - self.x) * t,
314 y: self.y + (other.y - self.y) * t,
315 z: self.z + (other.z - self.z) * t,
316 }
317 }
318}
319
320#[derive(Default, Debug, Clone, Copy, PartialEq)]
325pub struct Accel {
326 pub x: f64,
328 pub y: f64,
330 pub z: f64,
332}
333
334impl ToPaxValue for Accel {
335 fn to_pax_value(self) -> PaxValue {
336 PaxValue::Object(
337 vec![
338 ("x".to_string(), self.x.to_pax_value()),
339 ("y".to_string(), self.y.to_pax_value()),
340 ("z".to_string(), self.z.to_pax_value()),
341 ]
342 .into_iter()
343 .collect(),
344 )
345 }
346}
347
348impl Interpolatable for Accel {
349 fn interpolate(&self, other: &Self, t: f64) -> Self {
350 Accel {
351 x: self.x + (other.x - self.x) * t,
352 y: self.y + (other.y - self.y) * t,
353 z: self.z + (other.z - self.z) * t,
354 }
355 }
356}
357
358pub struct Window;
360
361impl Space for Window {}