use super::*; use crate::{UiNum, util::impl_op}; #[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct Size { pub x: Len, pub y: Len, } #[derive(Debug, Clone, Copy, PartialEq)] pub struct Len { pub abs: f32, pub rel: f32, pub rest: f32, } impl From for Len { fn from(value: N) -> Self { Len::abs(value.to_f32()) } } impl From<(Nx, Ny)> for Size { fn from((x, y): (Nx, Ny)) -> Self { Self { x: x.into(), y: y.into(), } } } impl From for Size { fn from(value: Len) -> Self { Self { x: value, y: value } } } impl Size { pub const ZERO: Self = Self { x: Len::ZERO, y: Len::ZERO, }; pub const REST: Self = Self { x: Len::REST, y: Len::REST, }; pub fn abs(v: Vec2) -> Self { Self { x: Len::abs(v.x), y: Len::abs(v.y), } } pub fn rel(v: Vec2) -> Self { Self { x: Len::rel(v.x), y: Len::rel(v.y), } } pub fn rest(v: Vec2) -> Self { Self { x: Len::rest(v.x), y: Len::rest(v.y), } } pub fn to_uivec2(self) -> UiVec2 { UiVec2 { x: self.x.apply_rest(), y: self.y.apply_rest(), } } pub fn from_axis(axis: Axis, aligned: Len, ortho: Len) -> Self { match axis { Axis::X => Self { x: aligned, y: ortho, }, Axis::Y => Self { x: ortho, y: aligned, }, } } pub fn axis(&self, axis: Axis) -> Len { match axis { Axis::X => self.x, Axis::Y => self.y, } } } impl Len { pub const ZERO: Self = Self { abs: 0.0, rel: 0.0, rest: 0.0, }; pub const REST: Self = Self { abs: 0.0, rel: 0.0, rest: 1.0, }; pub fn apply_rest(&self) -> UiScalar { UiScalar { rel: self.rel + if self.rest > 0.0 { 1.0 } else { 0.0 }, abs: self.abs, } } pub fn abs(abs: impl UiNum) -> Self { Self { abs: abs.to_f32(), rel: 0.0, rest: 0.0, } } pub fn rel(rel: impl UiNum) -> Self { Self { abs: 0.0, rel: rel.to_f32(), rest: 0.0, } } pub fn rest(ratio: impl UiNum) -> Self { Self { abs: 0.0, rel: 0.0, rest: ratio.to_f32(), } } } pub mod len_fns { use super::*; pub fn abs(abs: impl UiNum) -> Len { Len { abs: abs.to_f32(), rel: 0.0, rest: 0.0, } } pub fn rel(rel: impl UiNum) -> Len { Len { abs: 0.0, rel: rel.to_f32(), rest: 0.0, } } pub fn rest(ratio: impl UiNum) -> Len { Len { abs: 0.0, rel: 0.0, rest: ratio.to_f32(), } } } impl_op!(Len Add add; abs rel rest); impl_op!(Len Sub sub; abs rel rest); impl_op!(Size Add add; x y); impl_op!(Size Sub sub; x y); impl Default for Len { fn default() -> Self { Self::rest(1.0) } } impl std::fmt::Display for Size { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "({}, {})", self.x, self.y) } } impl std::fmt::Display for Len { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.abs != 0.0 { write!(f, "{} abs;", self.abs)?; } if self.rel != 0.0 { write!(f, "{} rel;", self.rel)?; } if self.rest != 0.0 { write!(f, "{} rest;", self.rest)?; } Ok(()) } }