use std::{
fmt::Display,
hash::{Hash, Hasher},
mem,
ops::Range,
};
use glam::Vec2;
pub use Unit::*;
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub enum Unit {
Px(f32),
Pt(f32),
Pc(f32),
Vw(f32),
Vh(f32),
Em(f32),
}
impl Eq for Unit {}
impl Hash for Unit {
fn hash<H: Hasher>(&self, state: &mut H) {
mem::discriminant(self).hash(state);
match self {
Px(value) => value.to_bits().hash(state),
Pt(value) => value.to_bits().hash(state),
Pc(value) => value.to_bits().hash(state),
Vw(value) => value.to_bits().hash(state),
Vh(value) => value.to_bits().hash(state),
Em(value) => value.to_bits().hash(state),
}
}
}
impl Default for Unit {
fn default() -> Self {
Self::ZERO
}
}
impl Unit {
pub const ZERO: Self = Px(0.0);
pub fn pixels(self, range: Range<f32>, scale: f32, window_size: Vec2) -> f32 {
match self {
Px(value) => value,
Pt(value) => value * 96.0 / 72.0 * scale,
Pc(value) => value * (range.end - range.start) / 100.0,
Vw(value) => value * window_size.x / 100.0,
Vh(value) => value * window_size.y / 100.0,
Em(value) => value * 16.0 * scale,
}
}
}
impl Display for Unit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Px(value) => write!(f, "{}px", value),
Pt(value) => write!(f, "{}pt", value),
Pc(value) => write!(f, "{}%", value),
Vw(value) => write!(f, "{}vw", value),
Vh(value) => write!(f, "{}vh", value),
Em(value) => write!(f, "{}em", value),
}
}
}