use core::f32;
use super::*;
#[derive(Debug)]
pub struct SizedBox {
pub x: Option<f32>,
pub y: Option<f32>,
pub child: Child,
}
impl SizedBox {
pub fn new(dimensions: Vec2, child: Child) -> UiRef {
Self {
x: Some(dimensions.x),
y: Some(dimensions.y),
child,
}
.to_ref()
}
pub fn zero(child: Child) -> UiRef {
Self::new(Vec2::ZERO, child)
}
pub fn square(size: f32, child: Child) -> UiRef {
Self::new(Vec2::splat(size), child)
}
pub fn wh(width: f32, height: f32, child: Child) -> UiRef {
Self {
x: Some(width),
y: Some(height),
child,
}
.to_ref()
}
pub fn grow(child: Child) -> UiRef {
Self {
x: Some(f32::INFINITY),
y: Some(f32::INFINITY),
child,
}
.to_ref()
}
pub fn width(width: f32, child: Child) -> UiRef {
Self {
x: Some(width),
y: None,
child,
}
.to_ref()
}
pub fn height(height: f32, child: Child) -> UiRef {
Self {
x: None,
y: Some(height),
child,
}
.to_ref()
}
}
impl UiRef {
pub fn sized_wh(self, width: f32, height: f32) -> UiRef {
SizedBox::wh(width, height, self)
}
pub fn square(self, size: f32) -> UiRef {
SizedBox::wh(size, size, self)
}
pub fn sized(self, dimensions: Vec2) -> UiRef {
SizedBox::new(dimensions, self)
}
pub fn height_infinite_width(self, height: f32) -> UiRef {
SizedBox::height(height, self)
}
pub fn expand_x(self) -> UiRef {
SizedBox::width(f32::INFINITY, self)
}
pub fn expand_y(self) -> UiRef {
SizedBox::height(f32::INFINITY, self)
}
pub fn width_infinite_height(self, width: f32) -> UiRef {
SizedBox::width(width, self)
}
pub fn width(self, width: f32) -> UiRef {
SizedBox::width(width, self)
}
pub fn height(self, height: f32) -> UiRef {
SizedBox::height(height, self)
}
}
impl UiNode for SizedBox {
fn preferred_dimensions(&self) -> Vec2 {
let child_dimensions = self.child.node.preferred_dimensions();
Vec2::new(
self.x.unwrap_or(child_dimensions.x),
self.y.unwrap_or(child_dimensions.y),
)
}
fn size(&self, area: Area) -> Vec2 {
Vec2::new(
match self.x {
Some(x) if x.is_finite() => x,
Some(_) | None => area.width(),
},
match self.y {
Some(y) if y.is_finite() => y,
Some(_) | None => area.height(),
},
)
}
fn draw(&self, mut area: Area, state: &UiState) -> Vec2 {
area.size = self.size(area);
let dimensions = self.child.node.draw(area, state);
Vec2::new(
match self.x {
Some(x) if x.is_finite() => x,
Some(_) | None => dimensions.x,
},
match self.y {
Some(y) if y.is_finite() => y,
Some(_) | None => dimensions.y,
},
)
}
}
#[derive(Debug)]
pub struct ConstrainedBox {
max_size: Vec2,
min_size: Vec2,
child: Child,
}
impl ConstrainedBox {
pub fn max_height(max_height: f32, child: Child) -> UiRef {
Self {
max_size: Vec2::new(f32::INFINITY, max_height),
min_size: Vec2::ZERO,
child,
}
.to_ref()
}
pub fn max_width(max_width: f32, child: Child) -> UiRef {
Self {
max_size: Vec2::new(max_width, f32::INFINITY),
min_size: Vec2::ZERO,
child,
}
.to_ref()
}
pub fn min_height(min_height: f32, child: Child) -> UiRef {
Self {
max_size: Vec2::new(f32::INFINITY, f32::INFINITY),
min_size: Vec2::new(0.0, min_height),
child,
}
.to_ref()
}
pub fn min_width(min_width: f32, child: Child) -> UiRef {
Self {
max_size: Vec2::new(f32::INFINITY, f32::INFINITY),
min_size: Vec2::new(min_width, 0.0),
child,
}
.to_ref()
}
pub fn min_size(min_size: Vec2, child: Child) -> UiRef {
Self {
max_size: Vec2::new(f32::INFINITY, f32::INFINITY),
min_size,
child,
}
.to_ref()
}
pub fn max_size(max_size: Vec2, child: Child) -> UiRef {
Self {
max_size,
min_size: Vec2::ZERO,
child,
}
.to_ref()
}
pub fn new(min_size: Vec2, max_size: Vec2, child: Child) -> UiRef {
Self {
max_size,
min_size,
child,
}
.to_ref()
}
fn transform_size(&self, size: Vec2) -> Vec2 {
size.clamp(self.min_size, self.max_size)
}
pub fn grow_x(child: Child) -> UiRef {
Self {
max_size: Vec2::new(f32::INFINITY, f32::INFINITY),
min_size: Vec2::new(f32::INFINITY, 0.0),
child,
}
.to_ref()
}
pub fn grow_y(child: Child) -> UiRef {
Self {
max_size: Vec2::new(f32::INFINITY, f32::INFINITY),
min_size: Vec2::new(0.0, f32::INFINITY),
child,
}
.to_ref()
}
}
impl UiNode for ConstrainedBox {
fn preferred_dimensions(&self) -> Vec2 {
self.transform_size(self.child.node.preferred_dimensions())
}
fn size(&self, area: Area) -> Vec2 {
self.transform_size(self.child.node.size(area))
}
fn draw(&self, mut area: Area, state: &UiState) -> Vec2 {
area.size = self.transform_size(area.size);
self.transform_size(self.child.node.draw(area, state))
}
}
impl UiRef {
pub fn min_height(self, min_height: f32) -> UiRef {
ConstrainedBox::min_height(min_height, self)
}
pub fn min_width(self, min_width: f32) -> UiRef {
ConstrainedBox::min_width(min_width, self)
}
pub fn max_height(self, max_height: f32) -> UiRef {
ConstrainedBox::max_height(max_height, self)
}
pub fn max_width(self, max_width: f32) -> UiRef {
ConstrainedBox::max_width(max_width, self)
}
pub fn min_size(self, min_size: Vec2) -> UiRef {
ConstrainedBox::min_size(min_size, self)
}
pub fn max_size(self, max_size: Vec2) -> UiRef {
ConstrainedBox::max_size(max_size, self)
}
pub fn grow_x(self) -> UiRef {
ConstrainedBox::grow_x(self)
}
pub fn grow_y(self) -> UiRef {
ConstrainedBox::grow_y(self)
}
}
#[derive(Debug)]
pub struct EmptyBox {
height: f32,
width: f32,
}
impl EmptyBox {
pub fn new(width: f32, height: f32) -> UiRef {
Self { width, height }.to_ref()
}
pub fn height(height: f32) -> UiRef {
Self { width: 0.0, height }.to_ref()
}
pub fn width(width: f32) -> UiRef {
Self { width, height: 0.0 }.to_ref()
}
}
impl UiNode for EmptyBox {
fn preferred_dimensions(&self) -> Vec2 {
Vec2::new(self.width, self.height)
}
fn size(&self, area: Area) -> Vec2 {
self.preferred_dimensions().max(area.size)
}
fn draw(&self, _: Area, _: &UiState) -> Vec2 {
self.preferred_dimensions()
}
}