use crate::*; /// Composable renderable with static dispatch. pub trait Content { /// Return a [Render]able of a specific type. fn content (&self) -> impl Render + '_ { () } /// Perform layout. By default, delegates to [Self::content]. fn layout (&self, area: E::Area) -> E::Area { self.content().layout(area) } /// Draw to output. By default, delegates to [Self::content]. fn render (&self, output: &mut E) { self.content().render(output) } } /// Every pointer to [Content] is a [Content]. impl> Content for &C { fn content (&self) -> impl Render + '_ { (*self).content() } fn layout (&self, area: E::Area) -> E::Area { (*self).layout(area) } fn render (&self, output: &mut E) { (*self).render(output) } } /// The platonic ideal unit of [Content]: total emptiness at dead center (e=1vg^sqrt(-1)) impl Content for () { fn layout (&self, area: E::Area) -> E::Area { area.center().to_area_pos().into() } fn render (&self, _: &mut E) {} } impl> Content for Option { fn content (&self) -> impl Render + '_ { self.as_ref() } fn layout (&self, area: E::Area) -> E::Area { self.as_ref() .map(|content|content.layout(area)) .unwrap_or([0.into(), 0.into(), 0.into(), 0.into(),].into()) } fn render (&self, output: &mut E) { self.as_ref() .map(|content|content.render(output)); } } /// You can render from a box. impl Content for RenderBox { fn content (&self) -> impl Render + '_ { self.deref() } //fn boxed <'b> (self) -> RenderBox<'b, E> where Self: Sized + 'b { self } } /// You can render from an opaque pointer. impl Content for &dyn Render where Self: Sized { fn content (&self) -> impl Render + '_ { #[allow(suspicious_double_ref_op)] self.deref() } fn layout (&self, area: E::Area) -> E::Area { #[allow(suspicious_double_ref_op)] Render::layout(self.deref(), area) } fn render (&self, output: &mut E) { #[allow(suspicious_double_ref_op)] Render::render(self.deref(), output) } } /// Implement [Content] with custom rendering for a struct. #[macro_export] macro_rules! render { (|$self:ident:$Struct:ident $(< $($L:lifetime),* $($T:ident $(:$Trait:path)?),* >)?, $to:ident | $render:expr) => { impl <$($($L),*)? E: Output, $($T$(:$Trait)?),*> Content for $Struct $(<$($L),* $($T),*>>)? { fn render (&$self, $to: &mut E) { $render } } }; ($Output:ty:| $self:ident: $Struct:ident $(<$($($L:lifetime)? $($T:ident)? $(:$Trait:path)?),+>)?, $to:ident |$render:expr) => { impl $(<$($($L)? $($T)? $(:$Trait)?),+>)? Content<$Output> for $Struct $(<$($($L)? $($T)?),+>)? { fn render (&$self, $to: &mut $Output) { $render } } }; }