use crate::*; /// A UI component. pub trait Component: Widget + Handle {} /// Everything that implements [Render] and [Handle] is a [Component]. impl + Handle> Component for C {} /// Marker trait for [Component]s that can [Exit] pub trait ExitableComponent: Exit + Component where E: Engine { /// Perform type erasure for collecting heterogeneous components. fn boxed (self) -> Box> where Self: Sized + 'static { Box::new(self) } } impl + Exit> ExitableComponent for C {} pub trait Widget { type Engine: Engine; fn layout (&self, to: <::Engine as Engine>::Area) -> Perhaps<<::Engine as Engine>::Area>; fn render (&self, to: &mut Self::Engine) -> Perhaps<<::Engine as Engine>::Area>; } impl Widget for Box> { 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 { type Engine: Engine; fn content (&self) -> impl Widget::Engine>; } //impl Content for () where E: Engine { //fn content (&self) -> impl Widget { //() //} //} impl Widget for W where W: Content { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { self.content().layout(to) } fn render (&self, to: &mut E) -> Perhaps { self.content().render(to) } }