diff --git a/src/device.rs b/src/device.rs index 2bed067c..8bcd8ed1 100644 --- a/src/device.rs +++ b/src/device.rs @@ -4,8 +4,6 @@ mod chain; mod launcher; mod looper; mod mixer; -mod plugin; -mod sampler; mod sequencer; mod track; mod transport; @@ -13,26 +11,31 @@ mod transport; pub use self::track::Track; pub use self::launcher::{Launcher, Scene}; pub use self::sequencer::{Sequencer, Phrase}; -pub use self::chain::Chain; -pub use self::plugin::Plugin; +pub use self::chain::{Chain, Sampler, Plugin}; pub use self::looper::Looper; pub use self::mixer::Mixer; -pub use self::sampler::Sampler; pub use self::transport::Transport; use crossterm::event; use ::jack::{Port, PortSpec, Client}; +/// A UI component that may have presence on the JACK grap. pub trait Device: Render + Handle + PortList + Send + Sync { fn boxed (self) -> Box where Self: Sized + 'static { Box::new(self) } } +/// All things that implement the required traits can be treated as `Device`. +impl Device for T {} + +/// Run a device as the root of the app. pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box> { let device = Arc::new(Mutex::new(device)); let exited = Arc::new(AtomicBool::new(false)); + + // Spawn input (handle) thread let _input_thread = { let poll = std::time::Duration::from_millis(100); let exited = exited.clone(); @@ -60,25 +63,23 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box Result<(), Box Device for T {} - -pub trait Named { -} - +/// Trait for things that handle input events. pub trait Handle { - // Handle an input event. - // Returns Ok(true) if the device handled the event. - // This is the mechanism which allows nesting of components;. + /// Handle an input event. + /// Returns Ok(true) if the device handled the event. + /// This is the mechanism which allows nesting of components;. fn handle (&mut self, _e: &AppEvent) -> Usually { Ok(false) } } +#[derive(Debug)] +pub enum AppEvent { + /// Terminal input + Input(::crossterm::event::Event), + /// Update values but not the whole form. + Update, + /// Update the whole form. + Redraw, + /// Device gains focus + Focus, + /// Device loses focus + Blur, + /// JACK notification + Jack(JackEvent) +} + +/// Trait for things that render to the display. pub trait Render { // Render something to an area of the buffer. // Returns area used by component. @@ -122,6 +136,24 @@ pub trait Render { } } +impl Render for Box { + fn render (&self, b: &mut Buffer, a: Rect) -> Usually { + (**self).render(b, a) + } +} + +impl WidgetRef for &dyn Render { + fn render_ref (&self, area: Rect, buf: &mut Buffer) { + Render::render(*self, buf, area).expect("Failed to render device."); + } +} + +impl WidgetRef for dyn Render { + fn render_ref (&self, area: Rect, buf: &mut Buffer) { + Render::render(self, buf, area).expect("Failed to render device."); + } +} + pub trait Blit { // Render something to X, Y coordinates in a buffer, ignoring width/height. fn blit (&self, buf: &mut Buffer, x: u16, y: u16, style: Option