generalize Layers

This commit is contained in:
🪞👃🪞 2024-09-15 19:53:20 +03:00
parent 35b37e3e3a
commit f7b2134310
3 changed files with 53 additions and 33 deletions

View file

@ -12,8 +12,8 @@ pub trait Engine: Send + Sync + Sized {
type Output: Output<Self>; type Output: Output<Self>;
type Unit: Number; type Unit: Number;
type Area: Area<Self::Unit> + From<[Self::Unit;4]> + Debug; type Area: Area<Self::Unit> + From<[Self::Unit;4]> + Debug + Copy;
type Size: Size<Self::Unit> + From<[Self::Unit;2]> + Debug; type Size: Size<Self::Unit> + From<[Self::Unit;2]> + Debug + Copy;
fn setup (&mut self) -> Usually<()> { Ok(()) } fn setup (&mut self) -> Usually<()> { Ok(()) }
fn exited (&self) -> bool; fn exited (&self) -> bool;
@ -163,13 +163,11 @@ impl<E: Engine, C: Component<E> + Exit> ExitableComponent<E> for C {}
pub trait Handle<E: Engine>: Send + Sync { pub trait Handle<E: Engine>: Send + Sync {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled>; fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled>;
} }
impl<H, E: Engine> Handle<E> for &mut H where H: Handle<E> { impl<H, E: Engine> Handle<E> for &mut H where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> { fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
(*self).handle(context) (*self).handle(context)
} }
} }
impl<H, E: Engine> Handle<E> for Option<H> where H: Handle<E> { impl<H, E: Engine> Handle<E> for Option<H> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> { fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
if let Some(ref mut handle) = self { if let Some(ref mut handle) = self {
@ -179,25 +177,21 @@ impl<H, E: Engine> Handle<E> for Option<H> where H: Handle<E> {
} }
} }
} }
impl<H, E: Engine> Handle<E> for Mutex<H> where H: Handle<E> { impl<H, E: Engine> Handle<E> for Mutex<H> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> { fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
self.lock().unwrap().handle(context) self.lock().unwrap().handle(context)
} }
} }
impl<H, E: Engine> Handle<E> for Arc<Mutex<H>> where H: Handle<E> { impl<H, E: Engine> Handle<E> for Arc<Mutex<H>> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> { fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
self.lock().unwrap().handle(context) self.lock().unwrap().handle(context)
} }
} }
impl<H, E: Engine> Handle<E> for RwLock<H> where H: Handle<E> { impl<H, E: Engine> Handle<E> for RwLock<H> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> { fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
self.write().unwrap().handle(context) self.write().unwrap().handle(context)
} }
} }
impl<H, E: Engine> Handle<E> for Arc<RwLock<H>> where H: Handle<E> { impl<H, E: Engine> Handle<E> for Arc<RwLock<H>> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> { fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
self.write().unwrap().handle(context) self.write().unwrap().handle(context)

View file

@ -145,6 +145,32 @@ impl<
} }
} }
impl<E: Engine, F> Widget for Layers<E, F>
where
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
{
type Engine = E;
fn layout (&self, area: E::Size) -> Perhaps<E::Size> {
let mut w: E::Unit = 0.into();
let mut h: E::Unit = 0.into();
(self.0)(&mut |layer| {
if let Some(layer_area) = layer.layout(area)? {
w = w.max(layer_area.w());
h = h.max(layer_area.h());
}
Ok(())
})?;
Ok(Some([w, h].into()))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
if let Some(size) = self.layout(to.area().wh().into())? {
(self.0)(&mut |layer|to.render_in(to.area().clip(size).into(), &layer))
} else {
Ok(())
}
}
}
//pub fn collect <'a, E: Engine, const N: usize> ( //pub fn collect <'a, E: Engine, const N: usize> (
//items: &'a [&'a dyn Widget<Engine = E>;N] //items: &'a [&'a dyn Widget<Engine = E>;N]
//) -> impl Send + Sync + Fn(&'a mut dyn FnMut(&'a dyn Widget<Engine = E>)->Usually<()>)->Usually<()> + '_ { //) -> impl Send + Sync + Fn(&'a mut dyn FnMut(&'a dyn Widget<Engine = E>)->Usually<()>)->Usually<()> + '_ {

View file

@ -416,31 +416,31 @@ where
} }
} }
impl<F> Widget for Layers<Tui, F> //impl<F> Widget for Layers<Tui, F>
where //where
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()> //F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
{ //{
type Engine = Tui; //type Engine = Tui;
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> { //fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
let mut w = 0; //let mut w = 0;
let mut h = 0; //let mut h = 0;
(self.0)(&mut |layer| { //(self.0)(&mut |layer| {
if let Some(layer_area) = layer.layout(area)? { //if let Some(layer_area) = layer.layout(area)? {
w = w.max(layer_area.w()); //w = w.max(layer_area.w());
h = h.max(layer_area.h()); //h = h.max(layer_area.h());
} //}
Ok(()) //Ok(())
})?; //})?;
Ok(Some([w, h])) //Ok(Some([w, h]))
} //}
fn render (&self, to: &mut TuiOutput) -> Usually<()> { //fn render (&self, to: &mut TuiOutput) -> Usually<()> {
if let Some(size) = self.layout(to.area().wh())? { //if let Some(size) = self.layout(to.area().wh())? {
(self.0)(&mut |layer|to.render_in(to.area().clip(size), &layer)) //(self.0)(&mut |layer|to.render_in(to.area().clip(size), &layer))
} else { //} else {
Ok(()) //Ok(())
} //}
} //}
} //}
pub struct Border<S: BorderStyle>(pub S); pub struct Border<S: BorderStyle>(pub S);