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 Unit: Number;
type Area: Area<Self::Unit> + From<[Self::Unit;4]> + Debug;
type Size: Size<Self::Unit> + From<[Self::Unit;2]> + Debug;
type Area: Area<Self::Unit> + From<[Self::Unit;4]> + Debug + Copy;
type Size: Size<Self::Unit> + From<[Self::Unit;2]> + Debug + Copy;
fn setup (&mut self) -> Usually<()> { Ok(()) }
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 {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled>;
}
impl<H, E: Engine> Handle<E> for &mut H where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
(*self).handle(context)
}
}
impl<H, E: Engine> Handle<E> for Option<H> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
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> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
self.lock().unwrap().handle(context)
}
}
impl<H, E: Engine> Handle<E> for Arc<Mutex<H>> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
self.lock().unwrap().handle(context)
}
}
impl<H, E: Engine> Handle<E> for RwLock<H> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
self.write().unwrap().handle(context)
}
}
impl<H, E: Engine> Handle<E> for Arc<RwLock<H>> where H: Handle<E> {
fn handle (&mut self, context: &E::Input) -> Perhaps<E::Handled> {
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> (
//items: &'a [&'a dyn Widget<Engine = E>;N]
//) -> 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>
where
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
{
type Engine = Tui;
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
let mut w = 0;
let mut h = 0;
(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]))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
if let Some(size) = self.layout(to.area().wh())? {
(self.0)(&mut |layer|to.render_in(to.area().clip(size), &layer))
} else {
Ok(())
}
}
}
//impl<F> Widget for Layers<Tui, F>
//where
//F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
//{
//type Engine = Tui;
//fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
//let mut w = 0;
//let mut h = 0;
//(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]))
//}
//fn render (&self, to: &mut TuiOutput) -> Usually<()> {
//if let Some(size) = self.layout(to.area().wh())? {
//(self.0)(&mut |layer|to.render_in(to.area().clip(size), &layer))
//} else {
//Ok(())
//}
//}
//}
pub struct Border<S: BorderStyle>(pub S);