use core::f32;
use sge_vectors::vec2;
use super::*;
#[derive(Debug)]
pub struct SizedBox {
pub dimensions: Vec2,
pub child: Child,
}
impl SizedBox {
pub fn new(dimensions: Vec2, child: Child) -> UiRef {
Self { dimensions, child }.to_ref()
}
pub fn zero(child: Child) -> UiRef {
Self {
dimensions: Vec2::ZERO,
child,
}
.to_ref()
}
pub fn width(width: f32, child: Child) -> UiRef {
Self {
dimensions: Vec2::new(width, f32::INFINITY),
child,
}
.to_ref()
}
pub fn height(height: f32, child: Child) -> UiRef {
Self {
dimensions: Vec2::new(f32::INFINITY, height),
child,
}
.to_ref()
}
pub fn wh(width: f32, height: f32, child: Child) -> UiRef {
Self {
dimensions: Vec2::new(width, height),
child,
}
.to_ref()
}
pub fn grow(child: Child) -> UiRef {
Self {
dimensions: Vec2::INFINITY,
child,
}
.to_ref()
}
}
impl UiRef {
pub fn sized_wh(self, width: f32, height: f32) -> UiRef {
SizedBox::wh(width, height, self)
}
pub fn sized(self, dimensions: Vec2) -> UiRef {
SizedBox::new(dimensions, self)
}
pub fn height(self, height: f32) -> UiRef {
SizedBox::height(height, self)
}
pub fn width(self, width: f32) -> UiRef {
SizedBox::width(width, self)
}
}
fn inf_to_zero(n: f32) -> f32 {
match n {
f32::INFINITY => 0.0,
_ => n,
}
}
impl UiNode for SizedBox {
fn preferred_dimensions(&self) -> Vec2 {
vec2(
inf_to_zero(self.dimensions.x),
inf_to_zero(self.dimensions.y),
)
}
fn size(&self, area: Area) -> Vec2 {
self.dimensions.min(area.size)
}
fn draw(&self, mut area: Area, state: &UiState) -> Vec2 {
let dimensions = self.dimensions.min(area.size);
area.size = dimensions;
self.child.node.draw(area, state).max(dimensions)
}
}
#[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 draw(&self, mut area: Area, state: &UiState) -> Vec2 {
area.size = self.transform_size(area.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()
}
}