refactor + not sure whats up with the double padding

This commit is contained in:
🪞👃🪞 2024-09-10 14:39:53 +03:00
parent 39407c9760
commit c51d1cf643
10 changed files with 388 additions and 393 deletions

View file

@ -1,5 +1,12 @@
use crate::*;
submod! {
focus
handle
keymap
layout
}
/// Entry point for main loop
pub trait App<T: Engine> {
fn run (self, context: T) -> Usually<T>;
@ -31,13 +38,122 @@ pub trait Engine: Send + Sync + Sized {
) -> Perhaps<Self::Area>;
}
submod! {
collect
component
exit
focus
handle
keymap
layout
//render
pub trait Widget: Send + Sync {
type Engine: Engine;
fn layout (&self, to: <<Self as Widget>::Engine as Engine>::Area) ->
Perhaps<<<Self as Widget>::Engine as Engine>::Area>
{
Ok(Some(to))
}
fn render (&self, to: &mut Self::Engine) ->
Perhaps<<<Self as Widget>::Engine as Engine>::Area>;
}
impl<'a, E: Engine> Widget for Box<dyn Widget<Engine = E> + 'a> {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
(**self).layout(to)
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
(**self).render(to)
}
}
impl<E: Engine> Widget for &dyn Widget<Engine = E> {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
(*self).layout(to)
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
(*self).render(to)
}
}
impl<E: Engine> Widget for &mut dyn Widget<Engine = E> {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
(**self).layout(to)
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
(**self).render(to)
}
}
impl<E: Engine, W: Widget<Engine = E>> Widget for Arc<W> {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
self.as_ref().layout(to)
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
self.as_ref().render(to)
}
}
impl<E: Engine, W: Widget<Engine = E>> Widget for Mutex<W> {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
self.lock().unwrap().layout(to)
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
self.lock().unwrap().render(to)
}
}
impl<E: Engine, W: Widget<Engine = E>> Widget for RwLock<W> {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
self.read().unwrap().layout(to)
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
self.read().unwrap().render(to)
}
}
impl<E: Engine, W: Widget<Engine = E>> Widget for Option<W> {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
Ok(self.as_ref().map(|widget|widget.layout(to)).transpose()?.flatten())
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
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 = <Self as Content>::Engine>;
}
//impl<E> Content<E> for () where E: Engine {
//fn content (&self) -> impl Widget<E> {
//()
//}
//}
impl<E: Engine, W: Content<Engine = E>> Widget for W {
type Engine = E;
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
self.content().layout(to)
}
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
match self.layout(to.area())? {
Some(area) => to.render_in(area, &self.content()),
None => Ok(None)
}
}
}
/// A UI component.
pub trait Component<E: Engine>: Widget<Engine = E> + Handle<E> {}
/// Everything that implements [Render] and [Handle] is a [Component].
impl<E: Engine, C: Widget<Engine = E> + Handle<E>> Component<E> for C {}
pub trait Exit: Send {
fn exited (&self) -> bool;
fn exit (&mut self);
fn boxed (self) -> Box<dyn Exit> where Self: Sized + 'static {
Box::new(self)
}
}
/// Marker trait for [Component]s that can [Exit]
pub trait ExitableComponent<E>: Exit + Component<E> where E: Engine {
/// Perform type erasure for collecting heterogeneous components.
fn boxed (self) -> Box<dyn ExitableComponent<E>> where Self: Sized + 'static {
Box::new(self)
}
}
impl<E: Engine, C: Component<E> + Exit> ExitableComponent<E> for C {}