use crate::geometry::Point;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Origin {
Global,
Monitor(usize),
Window,
}
impl Origin {
#[must_use]
pub const fn label(self) -> &'static str {
match self {
Self::Global => "global",
Self::Monitor(_) => "monitor",
Self::Window => "window",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Platform {
MacOs,
Windows,
Linux,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Units {
Physical,
Logical,
Auto,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Resolved {
Physical,
Logical,
}
impl Units {
#[must_use]
pub const fn resolve(self, platform: Platform) -> Resolved {
match self {
Self::Physical => Resolved::Physical,
Self::Logical => Resolved::Logical,
Self::Auto => match platform {
Platform::MacOs => Resolved::Logical,
Platform::Windows | Platform::Linux => Resolved::Physical,
},
}
}
}
#[must_use]
pub fn logical_of(physical: Point, scale: f64) -> Point {
Point::new(
(f64::from(physical.x) / scale).round() as i32,
(f64::from(physical.y) / scale).round() as i32,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn auto_follows_the_platforms_input_api() {
assert_eq!(Units::Auto.resolve(Platform::MacOs), Resolved::Logical);
assert_eq!(Units::Auto.resolve(Platform::Windows), Resolved::Physical);
assert_eq!(Units::Auto.resolve(Platform::Linux), Resolved::Physical);
}
#[test]
fn an_explicit_unit_ignores_the_platform() {
for platform in [Platform::MacOs, Platform::Windows, Platform::Linux] {
assert_eq!(Units::Physical.resolve(platform), Resolved::Physical);
assert_eq!(Units::Logical.resolve(platform), Resolved::Logical);
}
}
#[test]
fn logical_halves_a_retina_point_and_leaves_scale_one_alone() {
assert_eq!(logical_of(Point::new(100, 50), 2.0), Point::new(50, 25));
assert_eq!(logical_of(Point::new(100, 50), 1.0), Point::new(100, 50));
}
#[test]
fn logical_rounds_rather_than_truncating() {
assert_eq!(logical_of(Point::new(3, 3), 2.0), Point::new(2, 2));
assert_eq!(logical_of(Point::new(-3, -3), 2.0), Point::new(-2, -2));
}
#[test]
fn origins_label_themselves_for_json() {
assert_eq!(Origin::Global.label(), "global");
assert_eq!(Origin::Monitor(3).label(), "monitor");
assert_eq!(Origin::Window.label(), "window");
}
}