use super::*;
impl Interpolatable for SafeAreaInsets {}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub enum OS {
Mac,
Linux,
Windows,
Android,
IPhone,
IPad,
#[default]
Unknown,
}
impl OS {
pub fn is_mobile(&self) -> bool {
match self {
OS::Android | OS::IPhone | OS::IPad => true,
_ => false,
}
}
pub fn is_desktop(&self) -> bool {
match self {
OS::Mac | OS::Linux | OS::Windows => true,
_ => false,
}
}
pub fn is_ios(&self) -> bool {
matches!(self, OS::IPhone | OS::IPad)
}
pub fn is_iphone(&self) -> bool {
matches!(self, OS::IPhone)
}
pub fn is_ipad(&self) -> bool {
matches!(self, OS::IPad)
}
pub fn is_macos(&self) -> bool {
matches!(self, OS::Mac)
}
pub fn is_android(&self) -> bool {
matches!(self, OS::Android)
}
pub fn is_windows(&self) -> bool {
matches!(self, OS::Windows)
}
pub fn is_linux(&self) -> bool {
matches!(self, OS::Linux)
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Platform {
Web,
Native,
#[default]
Unknown,
}
#[derive(Default, Debug, Clone, PartialEq)]
pub struct NativeLiquidGlassScope {
pub group_id: u32,
pub spacing: f64,
pub interactive: bool,
pub tint: Option<Color>,
pub variant: String,
}
impl NativeLiquidGlassScope {
pub fn to_message(&self) -> AppleLiquidGlassPatch {
AppleLiquidGlassPatch {
group_id: self.group_id,
spacing: self.spacing,
interactive: self.interactive,
tint: self.tint.as_ref().map(Into::into),
variant: self.variant.clone(),
}
}
}
impl Interpolatable for NativeLiquidGlassScope {}
impl Platform {
pub fn is_web(&self) -> bool {
matches!(self, Platform::Web)
}
pub fn is_native(&self) -> bool {
matches!(self, Platform::Native)
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct TargetInfo {
pub web: bool,
pub native: bool,
pub ios: bool,
pub iphone: bool,
pub ipad: bool,
pub macos: bool,
pub android: bool,
pub windows: bool,
pub linux: bool,
pub mobile: bool,
pub desktop: bool,
}
impl TargetInfo {
pub fn new(platform: Platform, os: OS) -> Self {
Self {
web: platform.is_web(),
native: platform.is_native(),
ios: os.is_ios(),
iphone: os.is_iphone(),
ipad: os.is_ipad(),
macos: os.is_macos(),
android: os.is_android(),
windows: os.is_windows(),
linux: os.is_linux(),
mobile: os.is_mobile(),
desktop: os.is_desktop(),
}
}
}
impl ToPaxValue for TargetInfo {
fn to_pax_value(self) -> PaxValue {
PaxValue::Object(
vec![
("web".to_string(), self.web.to_pax_value()),
("native".to_string(), self.native.to_pax_value()),
("ios".to_string(), self.ios.to_pax_value()),
("iphone".to_string(), self.iphone.to_pax_value()),
("ipad".to_string(), self.ipad.to_pax_value()),
("macos".to_string(), self.macos.to_pax_value()),
("android".to_string(), self.android.to_pax_value()),
("windows".to_string(), self.windows.to_pax_value()),
("linux".to_string(), self.linux.to_pax_value()),
("mobile".to_string(), self.mobile.to_pax_value()),
("desktop".to_string(), self.desktop.to_pax_value()),
]
.into_iter()
.collect(),
)
}
}
impl Interpolatable for TargetInfo {}
#[derive(Default, Debug, Clone, Copy)]
pub struct Viewport {
pub width: f64,
pub height: f64,
pub major: f64,
pub minor: f64,
pub aspect: f64,
pub landscape: bool,
pub portrait: bool,
pub square: bool,
}
impl Viewport {
pub const SQUARE_EPSILON: f64 = 0.5;
pub fn new(width: f64, height: f64) -> Self {
let square = (width - height).abs() <= Self::SQUARE_EPSILON;
Self {
width,
height,
major: width.max(height),
minor: width.min(height),
aspect: if height.abs() <= f64::EPSILON {
0.0
} else {
width / height
},
landscape: width > height + Self::SQUARE_EPSILON,
portrait: height > width + Self::SQUARE_EPSILON,
square,
}
}
}
impl ToPaxValue for Viewport {
fn to_pax_value(self) -> PaxValue {
PaxValue::Object(
vec![
("width".to_string(), self.width.to_pax_value()),
("height".to_string(), self.height.to_pax_value()),
("major".to_string(), self.major.to_pax_value()),
("minor".to_string(), self.minor.to_pax_value()),
("aspect".to_string(), self.aspect.to_pax_value()),
("landscape".to_string(), self.landscape.to_pax_value()),
("portrait".to_string(), self.portrait.to_pax_value()),
("square".to_string(), self.square.to_pax_value()),
]
.into_iter()
.collect(),
)
}
}
impl Interpolatable for Viewport {
fn interpolate(&self, other: &Self, t: f64) -> Self {
Viewport {
width: self.width + (other.width - self.width) * t,
height: self.height + (other.height - self.height) * t,
major: self.major + (other.major - self.major) * t,
minor: self.minor + (other.minor - self.minor) * t,
aspect: self.aspect + (other.aspect - self.aspect) * t,
landscape: self.landscape,
portrait: self.portrait,
square: self.square,
}
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq)]
pub struct Gyro {
pub x: f64,
pub y: f64,
pub z: f64,
}
impl ToPaxValue for Gyro {
fn to_pax_value(self) -> PaxValue {
PaxValue::Object(
vec![
("x".to_string(), self.x.to_pax_value()),
("y".to_string(), self.y.to_pax_value()),
("z".to_string(), self.z.to_pax_value()),
]
.into_iter()
.collect(),
)
}
}
impl Interpolatable for Gyro {
fn interpolate(&self, other: &Self, t: f64) -> Self {
Gyro {
x: self.x + (other.x - self.x) * t,
y: self.y + (other.y - self.y) * t,
z: self.z + (other.z - self.z) * t,
}
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq)]
pub struct Accel {
pub x: f64,
pub y: f64,
pub z: f64,
}
impl ToPaxValue for Accel {
fn to_pax_value(self) -> PaxValue {
PaxValue::Object(
vec![
("x".to_string(), self.x.to_pax_value()),
("y".to_string(), self.y.to_pax_value()),
("z".to_string(), self.z.to_pax_value()),
]
.into_iter()
.collect(),
)
}
}
impl Interpolatable for Accel {
fn interpolate(&self, other: &Self, t: f64) -> Self {
Accel {
x: self.x + (other.x - self.x) * t,
y: self.y + (other.y - self.y) * t,
z: self.z + (other.z - self.z) * t,
}
}
}
pub struct Window;
impl Space for Window {}