use thunderdome::Index as TdIndex;
use crate::{Alignment, Anchor, NodeCache, Rect, UiNode, UiTree};
pub struct Clamp {
pub max_override: (f32, f32),
pub anchor: (Anchor, Anchor),
child: Option<TdIndex>,
align: (Alignment, Alignment),
}
impl Clamp {
pub fn new() -> Self {
Self {
max_override: (0.0, 0.0),
child: None,
anchor: (Anchor::Center, Anchor::Center),
align: (Alignment::Begin, Alignment::Begin),
}
}
pub fn with_child(mut self, child: impl UiNode, tree: &mut UiTree) -> Self {
assert!(self.child.is_none());
self.child = Some(tree.add_node(child));
self
}
pub fn with_align(mut self, align: (Alignment, Alignment)) -> Self {
self.align = align;
self
}
pub fn with_anchor(mut self, anchor: (Anchor, Anchor)) -> Self {
self.anchor = anchor;
self
}
pub fn with_max(mut self, max: (f32, f32)) -> Self {
self.max_override = max;
self
}
pub fn get_child(&self) -> Option<TdIndex> {
self.child
}
}
impl Default for Clamp {
fn default() -> Self {
Self::new()
}
}
impl UiNode for Clamp {
fn get_align(&self) -> (Alignment, Alignment) {
self.align
}
fn get_align_mut(&mut self) -> (&mut Alignment, &mut Alignment) {
(&mut self.align.0, &mut self.align.1)
}
fn calculate_min_size(&self, tree: &UiTree) -> (f32, f32) {
if let Some(index) = self.child {
tree.get_cache(index).expect("Child not in cache").min_size
} else {
(0.0, 0.0)
}
}
fn calculate_rects(&self, cache: &NodeCache, tree: &UiTree) -> Vec<Rect> {
if let Some(index) = self.child {
let child_min = tree.get_cache(index).expect("Child not in cache").min_size;
let child = tree.get_node(index).expect("Child not in cache");
let w = cache.rect.w.clamp(child_min.0, self.max_override.0);
let h = cache.rect.h.clamp(child_min.1, self.max_override.1);
let shrunk = cache.rect.anchor(self.anchor, (w, h));
let space = shrunk.align(child.get_align(), child_min);
vec![space]
} else {
vec![]
}
}
fn get_children(&self) -> Vec<TdIndex> {
self.child.into_iter().collect()
}
}