use crate::*; pub trait HasContent { fn content (&self) -> impl Content; } pub trait Content: Draw + Layout {} impl + Layout> Content for T {} impl<'a, O: Out> AsRef + 'a> for dyn Content + 'a { fn as_ref (&self) -> &(dyn Draw + 'a) { self } } impl<'a, O: Out> AsRef + 'a> for dyn Content + 'a { fn as_ref (&self) -> &(dyn Layout + 'a) { self } } /// Drawable with dynamic dispatch. pub trait Draw { fn draw (&self, to: &mut O); } impl Draw for () { fn draw (&self, to: &mut O) {} } impl Draw for fn(&mut O) { fn draw (&self, to: &mut O) { (*self)(to) } } impl Draw for Box> { fn draw (&self, to: &mut O) { (**self).draw(to) } } impl> Draw for &D { fn draw (&self, to: &mut O) { (*self).draw(to) } } impl> Draw for &mut D { fn draw (&self, to: &mut O) { (**self).draw(to) } } impl> Draw for Option { fn draw (&self, to: &mut O) { if let Some(draw) = self { draw.draw(to) } } } /// Drawable area of display. pub trait Layout { fn x (&self, to: O::Area) -> O::Unit { to.x() } fn y (&self, to: O::Area) -> O::Unit { to.y() } fn min_w (&self, to: O::Area) -> O::Unit { 0.into() } fn max_w (&self, to: O::Area) -> O::Unit { to.w() } fn w (&self, to: O::Area) -> O::Unit { to.w().max(self.min_w(to)).min(self.max_w(to)) } fn min_h (&self, to: O::Area) -> O::Unit { 0.into() } fn max_h (&self, to: O::Area) -> O::Unit { to.h() } fn h (&self, to: O::Area) -> O::Unit { to.h().max(self.min_h(to)).min(self.max_h(to)) } fn layout (&self, to: O::Area) -> O::Area { [self.x(to), self.y(to), self.w(to), self.h(to)].into() } } impl Layout for () { fn x (&self, a: O::Area) -> O::Unit { a.x() } fn y (&self, a: O::Area) -> O::Unit { a.y() } fn w (&self, _: O::Area) -> O::Unit { 0.into() } fn min_w (&self, _: O::Area) -> O::Unit { 0.into() } fn max_w (&self, _: O::Area) -> O::Unit { 0.into() } fn h (&self, _: O::Area) -> O::Unit { 0.into() } fn min_h (&self, _: O::Area) -> O::Unit { 0.into() } fn max_h (&self, _: O::Area) -> O::Unit { 0.into() } fn layout (&self, a: O::Area) -> O::Area { [a.x(), a.y(), 0.into(), 0.into()].into() } } impl> Layout for &L { fn x (&self, a: O::Area) -> O::Unit { (*self).x(a) } fn y (&self, a: O::Area) -> O::Unit { (*self).y(a) } fn w (&self, a: O::Area) -> O::Unit { (*self).w(a) } fn min_w (&self, a: O::Area) -> O::Unit { (*self).min_w(a) } fn max_w (&self, a: O::Area) -> O::Unit { (*self).max_w(a) } fn h (&self, a: O::Area) -> O::Unit { (*self).h(a) } fn min_h (&self, a: O::Area) -> O::Unit { (*self).min_h(a) } fn max_h (&self, a: O::Area) -> O::Unit { (*self).max_h(a) } fn layout (&self, a: O::Area) -> O::Area { (*self).layout(a) } } impl> Layout for &mut L { fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) } fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) } fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) } fn min_w (&self, a: O::Area) -> O::Unit { (**self).min_w(a) } fn max_w (&self, a: O::Area) -> O::Unit { (**self).max_w(a) } fn h (&self, a: O::Area) -> O::Unit { (**self).h(a) } fn min_h (&self, a: O::Area) -> O::Unit { (**self).min_h(a) } fn max_h (&self, a: O::Area) -> O::Unit { (**self).max_h(a) } fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) } } impl Layout for Box> { fn x (&self, a: O::Area) -> O::Unit { (**self).x(a) } fn y (&self, a: O::Area) -> O::Unit { (**self).y(a) } fn w (&self, a: O::Area) -> O::Unit { (**self).w(a) } fn min_w (&self, a: O::Area) -> O::Unit { (**self).min_w(a) } fn max_w (&self, a: O::Area) -> O::Unit { (**self).max_w(a) } fn h (&self, a: O::Area) -> O::Unit { (**self).h(a) } fn min_h (&self, a: O::Area) -> O::Unit { (**self).min_h(a) } fn max_h (&self, a: O::Area) -> O::Unit { (**self).max_h(a) } fn layout (&self, a: O::Area) -> O::Area { (**self).layout(a) } } impl> Layout for Option { fn x (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.x(to)).unwrap_or(to.x()) } fn y (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.y(to)).unwrap_or(to.y()) } fn min_w (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.min_w(to)).unwrap_or(0.into()) } fn max_w (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.max_w(to)).unwrap_or(0.into()) } fn w (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.w(to)).unwrap_or(0.into()) } fn min_h (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.min_h(to)).unwrap_or(0.into()) } fn max_h (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.max_h(to)).unwrap_or(0.into()) } fn h (&self, to: O::Area) -> O::Unit { self.as_ref().map(|c|c.h(to)).unwrap_or(0.into()) } fn layout (&self, to: O::Area) -> O::Area { self.as_ref().map(|c|c.layout([self.x(to), self.y(to), self.w(to), self.h(to)].into())) .unwrap_or([to.x(), to.y(), 0.into(), 0.into()].into()) } }