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 px: f32, pub rel: f32, pub leftover: f32, } impl From for Len { fn from(value: N) -> Self { Len::px(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 LEFTOVER: Self = Self { x: Len::LEFTOVER, y: Len::LEFTOVER, }; pub fn px(v: Vec2) -> Self { Self { x: Len::px(v.x), y: Len::px(v.y), } } pub fn rel(v: Vec2) -> Self { Self { x: Len::rel(v.x), y: Len::rel(v.y), } } pub fn leftover(v: Vec2) -> Self { Self { x: Len::leftover(v.x), y: Len::leftover(v.y), } } pub fn to_uivec2(self) -> UiVec2 { UiVec2 { x: self.x.apply_leftover(), y: self.y.apply_leftover(), } } 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 { px: 0.0, rel: 0.0, leftover: 0.0, }; pub const LEFTOVER: Self = Self { px: 0.0, rel: 0.0, leftover: 1.0, }; pub fn apply_leftover(&self) -> UiScalar { UiScalar { rel: self.rel + if self.leftover > 0.0 { 1.0 } else { 0.0 }, px: self.px, } } pub fn px(px: impl UiNum) -> Self { Self { px: px.to_f32(), rel: 0.0, leftover: 0.0, } } pub fn rel(rel: impl UiNum) -> Self { Self { px: 0.0, rel: rel.to_f32(), leftover: 0.0, } } pub fn leftover(ratio: impl UiNum) -> Self { Self { px: 0.0, rel: 0.0, leftover: ratio.to_f32(), } } } pub mod len_fns { use super::*; pub fn px(px: impl UiNum) -> Len { Len { px: px.to_f32(), rel: 0.0, leftover: 0.0, } } pub fn rel(rel: impl UiNum) -> Len { Len { px: 0.0, rel: rel.to_f32(), leftover: 0.0, } } pub fn leftover(ratio: impl UiNum) -> Len { Len { px: 0.0, rel: 0.0, leftover: ratio.to_f32(), } } } impl_op!(Len Add add; px rel leftover); impl_op!(Len Sub sub; px rel leftover); impl_op!(Size Add add; x y); impl_op!(Size Sub sub; x y); impl Default for Len { fn default() -> Self { Self::leftover(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.px != 0.0 { write!(f, "{} px;", self.px)?; } if self.rel != 0.0 { write!(f, "{} rel;", self.rel)?; } if self.leftover != 0.0 { write!(f, "{} leftover;", self.leftover)?; } Ok(()) } }