use crate::prelude::*;
use crate::render::primitive_kind::PrimitiveKind;
use crate::layout::layout::SingleChildLayout;
#[derive(Debug, Clone, Widget)]
pub struct Border<GS> where GS: GlobalState {
id: Uuid,
child: Box<dyn Widget<GS>>,
position: Point,
dimension: Dimensions,
color: Color,
border_width: u32
}
impl<GS: GlobalState> WidgetExt<GS> for Border<GS> {}
impl<S: GlobalState> SingleChildLayout for Border<S> {
fn flexibility(&self) -> u32 {
self.child.flexibility()
}
}
impl<S: GlobalState> CommonWidget<S> for Border<S> {
fn get_id(&self) -> Uuid {
self.id
}
fn get_flag(&self) -> Flags {
Flags::EMPTY
}
fn get_children(&self) -> WidgetIter<S> {
if self.child.get_flag() == Flags::PROXY {
self.child.get_children()
} else {
WidgetIter::single(&self.child)
}
}
fn get_children_mut(&mut self) -> WidgetIterMut<S> {
if self.child.get_flag() == Flags::PROXY {
self.child.get_children_mut()
} else {
WidgetIterMut::single(&mut self.child)
}
}
fn get_proxied_children(&mut self) -> WidgetIterMut<S> {
WidgetIterMut::single(&mut self.child)
}
fn get_position(&self) -> Point {
self.position
}
fn set_position(&mut self, position: Dimensions) {
self.position = position;
}
fn get_dimension(&self) -> Dimensions {
self.dimension
}
fn set_dimension(&mut self, dimensions: Dimensions) {
self.dimension = dimensions
}
}
impl<S: GlobalState> Render<S> for Border<S> {
fn get_primitives(&mut self, fonts: &text::font::Map) -> Vec<Primitive> {
let rect = Rect::new(self.position, self.dimension);
let (l, r, b, t) = rect.l_r_b_t();
let width = self.border_width as f64;
let left_border = Rect::new([l,b], [width, rect.h()]);
let right_border = Rect::new([r-width,b], [width, rect.h()]);
let top_border = Rect::new([l+width,b], [rect.w()-width*2.0, width]);
let bottom_border = Rect::new([l+width,t-width], [rect.w()-width*2.0, width]);
let border_color = self.color;
let mut prims = vec![
Primitive {
kind: PrimitiveKind::Rectangle { color: border_color.clone()},
rect: left_border
},
Primitive {
kind: PrimitiveKind::Rectangle { color: border_color.clone()},
rect: right_border
},
Primitive {
kind: PrimitiveKind::Rectangle { color: border_color.clone()},
rect: top_border
},
Primitive {
kind: PrimitiveKind::Rectangle { color: border_color.clone()},
rect: bottom_border
},
];
let children: Vec<Primitive> = self.get_children_mut().flat_map(|f| f.get_primitives(fonts)).collect();
prims.extend(children);
return prims;
}
}
impl<S: GlobalState> Border<S> {
pub fn color(mut self, color: Color) -> Box<Self> {
self.color = color;
Box::new(self)
}
pub fn border_width(mut self, width: u32) -> Box<Self> {
self.border_width = width;
Box::new(self)
}
pub fn initialize(child: Box<dyn Widget<S>>) -> Box<Self> {
Box::new(Border {
id: Uuid::new_v4(),
child,
position: [0.0,0.0],
dimension: [100.0,100.0],
color: Color::random(),
border_width: 2
})
}
}