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