diff --git a/crates/tek_core/src/audio.rs b/crates/tek_core/src/audio.rs index 6cb9934f..d0f151cd 100644 --- a/crates/tek_core/src/audio.rs +++ b/crates/tek_core/src/audio.rs @@ -310,13 +310,13 @@ impl Widget for JackDevice { fn layout (&self, to: E::Size) -> Perhaps { self.state.read().unwrap().layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { self.state.read().unwrap().render(to) } } impl Handle for JackDevice { - fn handle (&mut self, from: &E::HandleInput) -> Perhaps { + fn handle (&mut self, from: &E::Input) -> Perhaps { self.state.write().unwrap().handle(from) } } diff --git a/crates/tek_core/src/engine.rs b/crates/tek_core/src/engine.rs index 3fa5e7ca..acaaa1c6 100644 --- a/crates/tek_core/src/engine.rs +++ b/crates/tek_core/src/engine.rs @@ -16,38 +16,37 @@ pub trait Engine: Send + Sync + Sized { type Area: Area + From<[Self::Unit;4]> + Debug; type Size: Size + From<[Self::Unit;2]> + Debug; - type HandleInput; + type Input; type Handled; + type Output: RenderTarget; +} - #[inline] fn area (&self) -> Self::Area; - #[inline] fn area_mut (&mut self) -> &mut Self::Area; - #[inline] fn render_in ( - &mut self, area: Self::Area, widget: &impl Widget - ) -> Perhaps { - let last = self.area(); - *self.area_mut() = area; - let next = widget.render(self)?; - *self.area_mut() = last; - Ok(next) - } +pub trait RenderTarget { + fn area (&self) + -> E::Area; + fn area_mut (&mut self) + -> &mut E::Area; + fn render_in (&mut self, area: E::Area, widget: &impl Widget) + -> Perhaps; } pub trait Widget: Send + Sync { type Engine: Engine; - fn layout (&self, to: <::Engine as Engine>::Size) -> - Perhaps<<::Engine as Engine>::Size> - { + fn layout ( + &self, to: ::Size + ) -> Perhaps<::Size> { Ok(Some(to)) } - fn render (&self, to: &mut Self::Engine) -> - Perhaps<<::Engine as Engine>::Area>; + fn render ( + &self, to: &mut ::Output + ) -> Perhaps<<::Engine as Engine>::Area>; } impl<'a, E: Engine> Widget for Box + 'a> { type Engine = E; fn layout (&self, to: E::Size) -> Perhaps { (**self).layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { (**self).render(to) } } @@ -56,7 +55,7 @@ impl Widget for &dyn Widget { fn layout (&self, to: E::Size) -> Perhaps { (*self).layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { (*self).render(to) } } @@ -65,7 +64,7 @@ impl Widget for &mut dyn Widget { fn layout (&self, to: E::Size) -> Perhaps { (**self).layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { (**self).render(to) } } @@ -74,7 +73,7 @@ impl> Widget for Arc { fn layout (&self, to: E::Size) -> Perhaps { self.as_ref().layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { self.as_ref().render(to) } } @@ -83,7 +82,7 @@ impl> Widget for Mutex { fn layout (&self, to: E::Size) -> Perhaps { self.lock().unwrap().layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { self.lock().unwrap().render(to) } } @@ -92,7 +91,7 @@ impl> Widget for RwLock { fn layout (&self, to: E::Size) -> Perhaps { self.read().unwrap().layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { self.read().unwrap().render(to) } } @@ -101,7 +100,7 @@ impl> Widget for Option { fn layout (&self, to: E::Size) -> Perhaps { Ok(self.as_ref().map(|widget|widget.layout(to)).transpose()?.flatten()) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { Ok(self.as_ref().map(|widget|widget.render(to)).transpose()?.flatten()) } } @@ -120,7 +119,7 @@ impl> Widget for W { fn layout (&self, to: E::Size) -> Perhaps { self.content().layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { match self.layout(to.area().wh().into())? { Some(wh) => to.render_in(to.area().clip(wh).into(), &self.content()), None => Ok(None) @@ -154,17 +153,17 @@ impl + Exit> ExitableComponent for C {} /// Handle input pub trait Handle: Send + Sync { - fn handle (&mut self, context: &E::HandleInput) -> Perhaps; + fn handle (&mut self, context: &E::Input) -> Perhaps; } impl Handle for &mut H where H: Handle { - fn handle (&mut self, context: &E::HandleInput) -> Perhaps { + fn handle (&mut self, context: &E::Input) -> Perhaps { (*self).handle(context) } } impl Handle for Option where H: Handle { - fn handle (&mut self, context: &E::HandleInput) -> Perhaps { + fn handle (&mut self, context: &E::Input) -> Perhaps { if let Some(ref mut handle) = self { handle.handle(context) } else { @@ -174,25 +173,25 @@ impl Handle for Option where H: Handle { } impl Handle for Mutex where H: Handle { - fn handle (&mut self, context: &E::HandleInput) -> Perhaps { + fn handle (&mut self, context: &E::Input) -> Perhaps { self.lock().unwrap().handle(context) } } impl Handle for Arc> where H: Handle { - fn handle (&mut self, context: &E::HandleInput) -> Perhaps { + fn handle (&mut self, context: &E::Input) -> Perhaps { self.lock().unwrap().handle(context) } } impl Handle for RwLock where H: Handle { - fn handle (&mut self, context: &E::HandleInput) -> Perhaps { + fn handle (&mut self, context: &E::Input) -> Perhaps { self.write().unwrap().handle(context) } } impl Handle for Arc> where H: Handle { - fn handle (&mut self, context: &E::HandleInput) -> Perhaps { + fn handle (&mut self, context: &E::Input) -> Perhaps { self.write().unwrap().handle(context) } } @@ -450,7 +449,7 @@ impl> Widget for Align { //Self::SE(_) => { todo!() }, //}) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { let outer_area = to.area(); Ok(if let Some(inner_size) = self.layout(outer_area.wh().into())? { let inner_area = outer_area.clip(inner_size); @@ -505,7 +504,7 @@ impl> Widget for Min { }.into())) } // TODO: 🡘 🡙 ←🡙→ - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { Ok(self.layout(to.area().wh().into())? .map(|size|to.render_in(to.area().clip(size).into(), self.inner())) .transpose()?.flatten()) @@ -537,7 +536,7 @@ impl> Widget for Max { Self::XY(w, h, _) => [to.w().min(w), to.h().min(h)], }.into())) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { Ok(self.layout(to.area().wh().into())? .map(|size|to.render_in(to.area().clip(size).into(), self.inner())) .transpose()?.flatten()) @@ -569,7 +568,7 @@ impl> Widget for Grow { Self::XY(w, h, _) => [to.w() + w, to.h() + h], }.into())) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { Ok(self.layout(to.area().wh().into())? .map(|size|to.render_in(to.area().clip(size).into(), self.inner())) .transpose()?.flatten()) @@ -601,7 +600,7 @@ impl> Widget for Shrink { Self::XY(w, h, _) => [to.w() - w, to.h() - h] }.into())) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { Ok(self.layout(to.area().wh().into())? .map(|size|to.render_in(to.area().clip(size).into(), self.inner())) .transpose()?.flatten()) @@ -649,7 +648,7 @@ impl> Widget for Inset { Self::XY(x, y, ref inner) => Shrink::XY(x + x, y + y, inner as &dyn Widget), }.layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { match *self { Self::X(x, ref inner) => Plus::X(x, inner as &dyn Widget), Self::Y(y, ref inner) => Plus::Y(y, inner as &dyn Widget), @@ -667,7 +666,7 @@ impl> Widget for Outset { Self::XY(x, y, ref inner) => Grow::XY(x + x, y + y, inner as &dyn Widget), }.layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { match *self { Self::X(x, ref inner) => Plus::X(x, inner as &dyn Widget), Self::Y(y, ref inner) => Plus::Y(y, inner as &dyn Widget), @@ -703,7 +702,7 @@ impl> Widget for Plus { fn layout (&self, to: E::Size) -> Perhaps { self.inner().layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { let area = to.area(); Ok(self.layout(area.wh().into())? .map(|size|to.render_in(match *self { @@ -741,7 +740,7 @@ impl> Widget for Minus { fn layout (&self, to: E::Size) -> Perhaps { self.inner().layout(to) } - fn render (&self, to: &mut E) -> Perhaps { + fn render (&self, to: &mut E::Output) -> Perhaps { let area = to.area(); Ok(self.layout(area.wh().into())? .map(|size|to.render_in(match *self { diff --git a/crates/tek_core/src/test.rs b/crates/tek_core/src/test.rs index 928a34e2..79180784 100644 --- a/crates/tek_core/src/test.rs +++ b/crates/tek_core/src/test.rs @@ -3,11 +3,11 @@ use crate::*; struct TestEngine([u16;4], Vec>); impl Engine for TestEngine { - type Unit = u16; - type Size = [Self::Unit;2]; - type Area = [Self::Unit;4]; - type HandleInput = Self; - type Handled = bool; + type Unit = u16; + type Size = [Self::Unit;2]; + type Area = [Self::Unit;4]; + type Input = Self; + type Handled = bool; fn exited (&self) -> bool { true } diff --git a/crates/tek_core/src/tui.rs b/crates/tek_core/src/tui.rs index e7a2aaf9..cd3e206a 100644 --- a/crates/tek_core/src/tui.rs +++ b/crates/tek_core/src/tui.rs @@ -21,11 +21,12 @@ pub struct Tui { } impl Engine for Tui { - type Unit = u16; - type Size = [Self::Unit;2]; - type Area = [Self::Unit;4]; - type HandleInput = Self; - type Handled = bool; + type Unit = u16; + type Size = [Self::Unit;2]; + type Area = [Self::Unit;4]; + type Input = Self; + type Handled = bool; + type Output = Self; fn exited (&self) -> bool { self.exited.fetch_and(true, Ordering::Relaxed) } @@ -46,13 +47,27 @@ impl Engine for Tui { self.backend.show_cursor()?; disable_raw_mode().map_err(Into::into) } - #[inline] fn area (&self) -> Self::Area { +} +impl RenderTarget for Tui { + #[inline] fn area (&self) -> ::Area { self.area } - #[inline] fn area_mut (&mut self) -> &mut Self::Area { + #[inline] fn area_mut (&mut self) -> &mut ::Area { &mut self.area } + #[inline] fn render_in ( + &mut self, + area: ::Area, + widget: &impl Widget + ) -> Perhaps<::Area> { + let last = self.area(); + *self.area_mut() = area; + let next = widget.render(self)?; + *self.area_mut() = last; + Ok(next) + } } + impl Tui { /// Run the main loop. pub fn run + Sized + 'static> ( @@ -90,7 +105,7 @@ impl Tui { let event = TuiEvent::Input(::crossterm::event::read().unwrap()); match event { key!(Ctrl-KeyCode::Char('c')) => { - engine.write().unwrap().exited.store(true, Ordering::Relaxed); + exited.store(true, Ordering::Relaxed); }, _ => { *engine.write().unwrap().event.write().unwrap() = Some(event);