use super::{DebugWidget, Widget};
use crate::{
graphics::{
colours::RGBA,
shapes::{self, Shape},
Size,
},
Align, Border, Direction, Overflow, ToAny,
};
#[derive(Debug)]
pub struct Layout {
pub colour: RGBA,
pub borders: Option<[Border; 4]>,
pub widgets: Vec<Box<dyn Widget>>,
pub overflow: Overflow,
pub wx_align: Align,
pub wy_align: Align,
pub direction: Direction,
}
impl Default for Layout {
fn default() -> Self {
Self {
colour: RGBA::default(),
borders: None,
widgets: vec![],
overflow: Overflow::Ignore,
wx_align: Align::Center,
wy_align: Align::Center,
direction: Direction::Column,
}
}
}
crate::dynamic_widget!(Layout);
impl Widget for Layout {
fn shape(&self, size: Option<Size>) -> Shape {
shapes::Builder::new()
.rectangle(size.unwrap(), self.borders)
.fill(self.colour)
.finish()
}
}
impl Layout {
pub fn new(
colour: RGBA,
borders: [Border; 4],
widgets: Vec<Box<dyn Widget>>,
overflow: Overflow,
wx_align: Align,
wy_align: Align,
direction: Direction,
) -> Self {
Self {
colour,
borders: Some(borders),
widgets,
overflow,
wx_align,
wy_align,
direction,
}
}
pub fn simple(
widgets: Vec<Box<dyn Widget>>,
overflow: Overflow,
wx_align: Align,
wy_align: Align,
direction: Direction,
) -> Self {
Self {
colour: RGBA::default(),
borders: None,
widgets,
overflow,
wx_align,
wy_align,
direction,
}
}
pub fn coloured(
widgets: Vec<Box<dyn Widget>>,
colour: RGBA,
overflow: Overflow,
wx_align: Align,
wy_align: Align,
direction: Direction,
) -> Self {
Self {
colour,
borders: None,
widgets,
overflow,
wx_align,
wy_align,
direction,
}
}
pub fn bordered(
borders: [Border; 4],
widgets: Vec<Box<dyn Widget>>,
overflow: Overflow,
wx_align: Align,
wy_align: Align,
direction: Direction,
) -> Self {
Self {
colour: RGBA::default(),
borders: Some(borders),
widgets,
overflow,
wx_align,
wy_align,
direction,
}
}
pub fn widgets<T: 'static>(&self) -> Vec<&T> {
let mut widgets = vec![];
for boxed in &self.widgets {
match boxed.as_any().downcast_ref::<T>() {
Some(widget) => widgets.push(widget),
None => {} }
}
widgets
}
pub fn not_widget<T: 'static>(&self) -> Vec<&Box<dyn Widget>> {
let mut widgets = vec![];
for boxed in &self.widgets {
match boxed.as_any().downcast_ref::<T>() {
Some(_) => {} None => widgets.push(boxed),
}
}
widgets
}
}