use typed_floats::tf64::{Positive, PositiveFinite};
use crate::style::layout::Direction;
#[derive(Clone, Copy, Debug)]
pub enum PreferredSize {
Fixed(PositiveFinite),
Grow(PositiveFinite),
}
impl Default for PreferredSize {
fn default() -> Self {
PreferredSize::Fixed(PositiveFinite::new(0.0).unwrap()) }
}
#[derive(Clone, Copy, Debug)]
pub struct SizingDimensions {
pub min: PositiveFinite, pub preferred: PreferredSize, pub max: Positive, }
impl Default for SizingDimensions {
fn default() -> Self {
SizingDimensions {
min: PositiveFinite::new(0.0).unwrap(),
preferred: PreferredSize::default(),
max: Positive::new(f64::INFINITY).unwrap(), }
}
}
impl SizingDimensions {
pub fn is_fixed(&self) -> bool {
matches!(self.preferred, PreferredSize::Fixed(_))
}
pub fn is_growable(&self) -> bool {
matches!(self.preferred, PreferredSize::Grow(_))
}
pub fn is_shrinkable(&self) -> bool {
self.max > self.min }
pub fn get_grow_factor(&self) -> f64 {
match self.preferred {
PreferredSize::Grow(factor) => factor.into(),
_ => 0.0, }
}
pub fn clamped(&self, value: f64) -> f64 {
if value.is_nan() {
return self.min.into(); }
value.clamp(self.min.into(), self.max.into())
}
pub fn max(&self) -> f64 {
self.max.into()
}
pub fn min(&self) -> f64 {
self.min.into()
}
}
#[derive(Default, Clone, Copy)]
pub struct BoxSizing {
pub width: Sizing,
pub height: Sizing,
}
impl BoxSizing {
pub fn main(&mut self, dir: Direction) -> &mut Sizing {
match dir {
Direction::LeftToRight | Direction::RightToLeft => &mut self.width,
Direction::TopToBottom | Direction::BottomToTop => &mut self.height,
}
}
pub fn cross(&mut self, dir: Direction) -> &mut Sizing {
match dir {
Direction::LeftToRight | Direction::RightToLeft => &mut self.height,
Direction::TopToBottom | Direction::BottomToTop => &mut self.width,
}
}
}
#[macro_export]
macro_rules! sizing {
($width:expr, $height:expr) => {
$crate::style::sizing::BoxSizing {
width: $width,
height: $height,
}
};
($size:expr) => {
$crate::style::sizing::BoxSizing {
width: $size,
height: $size,
}
};
(width: $width:expr, height: $height:expr) => {
$crate::style::sizing::BoxSizing {
width: $width,
height: $height,
}
};
($key:ident : $value:expr$(,)?) => {
$crate::style::sizing::BoxSizing {
$key: $value,
..$crate::style::sizing::BoxSizing::default()
}
};
($($key:ident : $value:expr),* $(,)?) => {
$crate::style::sizing::BoxSizing {
$($key: $value,)*
}
};
() => {
$crate::style::sizing::BoxSizing::default()
};
}
#[derive(Default, Clone, Copy)]
pub enum Sizing {
#[default]
Default,
Fit {
min: Option<PositiveFinite>,
max: Option<Positive>,
},
Fixed(PositiveFinite),
Grow {
factor: Option<PositiveFinite>, min: Option<PositiveFinite>,
max: Option<Positive>,
},
}
impl From<Sizing> for SizingDimensions {
fn from(sizing: Sizing) -> Self {
match sizing {
Sizing::Default => SizingDimensions::default(), Sizing::Fit { min, max } => SizingDimensions {
min: min.unwrap_or_default(),
preferred: PreferredSize::Fixed(min.unwrap_or_default()), max: max.unwrap_or(Positive::new(f64::INFINITY).unwrap()),
},
Sizing::Fixed(size) => SizingDimensions {
min: size,
preferred: PreferredSize::Fixed(size),
max: size.into(),
},
Sizing::Grow { factor, min, max } => SizingDimensions {
min: min.unwrap_or_default(),
preferred: PreferredSize::Grow(factor.unwrap_or(PositiveFinite::new(1.0).unwrap())),
max: max.unwrap_or(Positive::new(f64::INFINITY).unwrap()),
},
}
}
}
#[macro_export]
macro_rules! fit {
($min:expr, $max:expr) => {
$crate::style::sizing::Sizing::Fit {
min: Some(typed_floats::tf64::PositiveFinite::new($min).unwrap()),
max: Some(typed_floats::tf64::Positive::new($max).unwrap()),
}
};
($max:expr) => {
$crate::style::sizing::Sizing::Fit {
min: None,
max: Some(typed_floats::tf64::Positive::new($max).unwrap()),
}
};
() => {
$crate::style::sizing::Sizing::Fit {
min: None,
max: None,
}
};
}
#[macro_export]
macro_rules! fixed {
($size:expr) => {
$crate::style::sizing::Sizing::Fixed(
typed_floats::tf64::PositiveFinite::new($size).unwrap(),
)
};
}
#[macro_export]
macro_rules! grow {
($factor:expr, $min:expr, $max:expr) => {
$crate::style::sizing::Sizing::Grow {
factor: Some(typed_floats::tf64::PositiveFinite::new($factor).unwrap()),
min: Some(typed_floats::tf64::PositiveFinite::new($min).unwrap()),
max: Some(typed_floats::tf64::Positive::new($max).unwrap()),
}
};
($factor:expr) => {
$crate::style::sizing::Sizing::Grow {
factor: Some(typed_floats::tf64::PositiveFinite::new($factor).unwrap()),
min: None,
max: None,
}
};
() => {
$crate::style::sizing::Sizing::Grow {
factor: None,
min: None,
max: None,
}
};
}