use crate::types::{Point, Size};
pub struct Canvas;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AxisBound {
Bounded(f32),
Unbounded,
Shrink,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Constraints {
pub min_width: f32,
pub max_width: AxisBound,
pub min_height: f32,
pub max_height: AxisBound,
}
impl Constraints {
pub fn loose(width: f32, height: f32) -> Self {
Constraints {
min_width: 0.0,
max_width: AxisBound::Bounded(width),
min_height: 0.0,
max_height: AxisBound::Bounded(height),
}
}
pub fn tight(width: f32, height: f32) -> Self {
Constraints {
min_width: width,
max_width: AxisBound::Bounded(width),
min_height: height,
max_height: AxisBound::Bounded(height),
}
}
pub fn unbounded() -> Self {
Constraints {
min_width: 0.0,
max_width: AxisBound::Unbounded,
min_height: 0.0,
max_height: AxisBound::Unbounded,
}
}
pub fn max_width_f32(&self) -> f32 {
match &self.max_width {
AxisBound::Bounded(v) => *v,
_ => f32::INFINITY,
}
}
pub fn max_height_f32(&self) -> f32 {
match &self.max_height {
AxisBound::Bounded(v) => *v,
_ => f32::INFINITY,
}
}
pub fn constrain(&self, size: Size) -> Size {
let width = size.width.max(self.min_width).min(self.max_width_f32());
let height = size.height.max(self.min_height).min(self.max_height_f32());
Size { width, height }
}
pub fn is_tight(&self) -> bool {
let w_tight = matches!(&self.max_width, AxisBound::Bounded(v) if (v - self.min_width).abs() < f32::EPSILON);
let h_tight = matches!(&self.max_height, AxisBound::Bounded(v) if (v - self.min_height).abs() < f32::EPSILON);
w_tight && h_tight
}
}
pub trait RenderObject: 'static {
fn layout(&mut self, constraints: Constraints) -> Size;
fn paint(&self, canvas: &mut Canvas, size: Size);
fn hit_test(&self, point: Point, size: Size) -> bool {
point.x >= 0.0
&& point.x <= size.width
&& point.y >= 0.0
&& point.y <= size.height
}
}