use crate::*; pub trait Widget: Send + Sync { type Engine: Engine; fn layout (&self, to: <::Engine as Engine>::Area) -> Perhaps<<::Engine as Engine>::Area> { Ok(Some(to)) } fn render (&self, to: &mut Self::Engine) -> Perhaps<<::Engine as Engine>::Area>; } impl<'a, E: Engine> Widget for Box + 'a> { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { (**self).layout(to) } fn render (&self, to: &mut E) -> Perhaps { (**self).render(to) } } impl Widget for &dyn Widget { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { (*self).layout(to) } fn render (&self, to: &mut E) -> Perhaps { (*self).render(to) } } impl Widget for &mut dyn Widget { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { (**self).layout(to) } fn render (&self, to: &mut E) -> Perhaps { (**self).render(to) } } impl> Widget for Arc { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { self.as_ref().layout(to) } fn render (&self, to: &mut E) -> Perhaps { self.as_ref().render(to) } } impl> Widget for Mutex { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { self.lock().unwrap().layout(to) } fn render (&self, to: &mut E) -> Perhaps { self.lock().unwrap().render(to) } } impl> Widget for RwLock { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { self.read().unwrap().layout(to) } fn render (&self, to: &mut E) -> Perhaps { self.read().unwrap().render(to) } } impl> Widget for Option { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { Ok(self.as_ref().map(|widget|widget.layout(to)).transpose()?.flatten()) } fn render (&self, to: &mut E) -> Perhaps { Ok(self.as_ref().map(|widget|widget.render(to)).transpose()?.flatten()) } } pub trait Content: Send + Sync { type Engine: Engine; fn content (&self) -> impl Widget::Engine>; } //impl Content for () where E: Engine { //fn content (&self) -> impl Widget { //() //} //} impl> Widget for W { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { self.content().layout(to) } fn render (&self, to: &mut E) -> Perhaps { match self.layout(to.area())? { Some(area) => to.render_in(area, &self.content()), None => Ok(None) } } } /// A UI component. pub trait Component: Widget + Handle {} /// Everything that implements [Render] and [Handle] is a [Component]. impl + Handle> Component for C {}