diff --git a/Justfile b/Justfile index 6c5ebfa0..3da3ef07 100644 --- a/Justfile +++ b/Justfile @@ -118,3 +118,11 @@ sampler: plugin: reset cargo run --bin tek_plugin + +edn01: + reset + cd edn && cargo run --example edn01 + +edn02: + reset + cd edn && cargo run --example edn02 diff --git a/edn/examples/edn01.rs b/edn/examples/edn01.rs index 679760f6..ebccfa0f 100644 --- a/edn/examples/edn01.rs +++ b/edn/examples/edn01.rs @@ -11,10 +11,16 @@ fn main () -> Usually<()> { pub struct Example; -impl EdnLayout for Example { +impl EdnLayout for &Example { fn get_content <'a> (&'a self, sym: &'a str) -> Box> { Box::new(Thunk::new(move||if sym == ":hello" { "Hello world!" } else { "" })) } } +impl Content for Example { + fn content (&self) -> impl Render { + EdnView::new(self, EDN).unwrap() + } +} + impl Handle for Example {} diff --git a/edn/examples/edn02.rs b/edn/examples/edn02.rs index 0585c4c2..183f8975 100644 --- a/edn/examples/edn02.rs +++ b/edn/examples/edn02.rs @@ -11,10 +11,16 @@ fn main () -> Usually<()> { pub struct Example; -impl EdnLayout for Example { +impl EdnLayout for &Example { fn get_content <'a> (&'a self, sym: &'a str) -> Box> { Box::new(Thunk::new(move||if sym == ":hello" { "Hello world!" } else { "" })) } } +impl Content for Example { + fn content (&self) -> impl Render { + EdnView::new(self, EDN).unwrap() + } +} + impl Handle for Example {} diff --git a/engine/src/tui/tui_output.rs b/engine/src/tui/tui_output.rs index f0a80aa5..43382fb7 100644 --- a/engine/src/tui/tui_output.rs +++ b/engine/src/tui/tui_output.rs @@ -65,7 +65,7 @@ impl TuiOut { } } -impl Render for &str { +impl Content for &str { fn layout (&self, to: [u16;4]) -> [u16;4] { to.center_xy([self.chars().count() as u16, 1]) } @@ -74,7 +74,7 @@ impl Render for &str { } } -impl Render for String { +impl Content for String { fn layout (&self, to: [u16;4]) -> [u16;4] { to.center_xy([self.chars().count() as u16, 1]) } diff --git a/src/groovebox.rs b/src/groovebox.rs index 8ba0987e..8f248de0 100644 --- a/src/groovebox.rs +++ b/src/groovebox.rs @@ -10,10 +10,8 @@ mod groovebox_audio; pub use self::groovebox_audio::*; mod groovebox_command; pub use self::groovebox_command::*; mod groovebox_tui; pub use self::groovebox_tui::*; -pub struct Groovebox<'a> { +pub struct Groovebox { _jack: Arc>, - pub view: EdnView<'a, Tui, Self>, - pub player: MidiPlayer, pub pool: PoolModel, pub editor: MidiEditor, @@ -27,7 +25,7 @@ pub struct Groovebox<'a> { pub perf: PerfModel, } -impl<'a> Groovebox<'a> { +impl Groovebox { pub fn new ( jack: &Arc>, midi_from: &[impl AsRef], @@ -57,49 +55,44 @@ impl<'a> Groovebox<'a> { midi_buf: vec![vec![];65536], note_buf: vec![], perf: PerfModel::default(), - - view: EdnView::new(include_str!("groovebox/groovebox.edn"))?, }) } } -has_clock!(|self: Groovebox<'a>|self.player.clock()); +has_clock!(|self: Groovebox|self.player.clock()); -impl<'a> EdnLayout<'a, Tui> for Groovebox<'a> { - fn get_bool (&self, item: &EdnItem<&str>) -> bool { todo!() } - fn get_unit (&self, item: &EdnItem<&str>) -> u16 { +impl EdnLayout for Groovebox { + fn get_bool (&self, item: &str) -> bool { todo!() } + fn get_unit (&self, item: &str) -> u16 { use EdnItem::*; match item { - Sym(":sample-h") => if self.compact { 0 } else { 5 }, - Sym(":samples-w") => if self.compact { 4 } else { 11 }, - Sym(":samples-y") => if self.compact { 1 } else { 0 }, - Sym(":pool-w") => if self.compact { 5 } else { + ":sample-h" => if self.compact { 0 } else { 5 }, + ":samples-w" => if self.compact { 4 } else { 11 }, + ":samples-y" => if self.compact { 1 } else { 0 }, + ":pool-w" => if self.compact { 5 } else { let w = self.size.w(); if w > 60 { 20 } else if w > 40 { 15 } else { 10 } }, _ => 0 } } - fn get_content (&'a self, item: &EdnItem<&str>) -> Box> { + fn get_content <'a> (&'a self, item: &str) -> Box> { use EdnItem::*; match item { - Sym(":input-meter-l") => Box::new(Meter("L/", self.sampler.input_meter[0])), - Sym(":input-meter-r") => Box::new(Meter("R/", self.sampler.input_meter[1])), + ":input-meter-l" => Box::new(Meter("L/", self.sampler.input_meter[0])), + ":input-meter-r" => Box::new(Meter("R/", self.sampler.input_meter[1])), - Sym(":transport") => Box::new(TransportView::new(true, &self.player.clock)), - Sym(":clip-play") => Box::new(ClipSelected::play_phrase(&self.player)), - Sym(":clip-next") => Box::new(ClipSelected::next_phrase(&self.player)), - Sym(":clip-edit") => Box::new(MidiEditClip(&self.editor)), - Sym(":edit-stat") => Box::new(MidiEditStatus(&self.editor)), - Sym(":pool-view") => Box::new(PoolView(self.compact, &self.pool)), - Sym(":midi-view") => Box::new(&self.editor), + ":transport" => Box::new(TransportView::new(true, &self.player.clock)), + ":clip-play" => Box::new(ClipSelected::play_phrase(&self.player)), + ":clip-next" => Box::new(ClipSelected::next_phrase(&self.player)), + ":clip-edit" => Box::new(MidiEditClip(&self.editor)), + ":edit-stat" => Box::new(MidiEditStatus(&self.editor)), + ":pool-view" => Box::new(PoolView(self.compact, &self.pool)), + ":midi-view" => Box::new(&self.editor), - Sym(":sample-view") => Box::new(SampleViewer::from_sampler( - &self.sampler, self.editor.note_point())), - Sym(":sample-stat") => Box::new(SamplerStatus( - &self.sampler, self.editor.note_point())), - Sym(":samples-view") => Box::new(SampleList::new( - self.compact, &self.sampler, &self.editor)), + ":sample-view" => Box::new(SampleViewer::from_sampler(&self.sampler, self.editor.note_point())), + ":sample-stat" => Box::new(SamplerStatus(&self.sampler, self.editor.note_point())), + ":samples-view" => Box::new(SampleList::new(self.compact, &self.sampler, &self.editor)), _ => Box::new(()) } @@ -114,7 +107,7 @@ pub struct GrooveboxStatus { pub(crate) size: String, pub(crate) playing: bool, } -from!(|state: &Groovebox<'_>|GrooveboxStatus = { +from!(|state: &Groovebox|GrooveboxStatus = { let samples = state.clock().chunk.load(Relaxed); let rate = state.clock().timebase.sr.get(); let buffer = samples as f64 / rate; diff --git a/src/groovebox/groovebox_audio.rs b/src/groovebox/groovebox_audio.rs index fed0b16c..d0459959 100644 --- a/src/groovebox/groovebox_audio.rs +++ b/src/groovebox/groovebox_audio.rs @@ -1,7 +1,7 @@ use crate::*; use super::*; -audio!(|self: Groovebox<'a>, client, scope|{ +audio!(|self: Groovebox, client, scope|{ let t0 = self.perf.get_t0(); if Control::Quit == ClockAudio(&mut self.player).process(client, scope) { return Control::Quit diff --git a/src/groovebox/groovebox_command.rs b/src/groovebox/groovebox_command.rs index cda5775a..25e73973 100644 --- a/src/groovebox/groovebox_command.rs +++ b/src/groovebox/groovebox_command.rs @@ -14,7 +14,7 @@ pub enum GrooveboxCommand { Sampler(SamplerCommand), } -command!(<'a>|self: GrooveboxCommand, state: Groovebox<'a>|match self { +command!(|self: GrooveboxCommand, state: Groovebox|match self { Self::Enqueue(phrase) => { state.player.enqueue_next(phrase.as_ref()); None @@ -46,10 +46,10 @@ command!(<'a>|self: GrooveboxCommand, state: Groovebox<'a>|match self { }, }); -handle!(|self: Groovebox<'static>, input| +handle!(|self: Groovebox, input| GrooveboxCommand::execute_with_state(self, input.event())); -keymap!(<'a> KEYS_GROOVEBOX = |state: Groovebox<'static>, input: Event| GrooveboxCommand { +keymap!(<'a> KEYS_GROOVEBOX = |state: Groovebox, input: Event| GrooveboxCommand { // Tab: Toggle compact mode key(Tab) => Cmd::Compact(!state.compact), // q: Enqueue currently edited phrase diff --git a/src/groovebox/groovebox_tui.rs b/src/groovebox/groovebox_tui.rs index dba38596..333a1e46 100644 --- a/src/groovebox/groovebox_tui.rs +++ b/src/groovebox/groovebox_tui.rs @@ -4,14 +4,14 @@ use std::marker::ConstParamTy; use tek_engine::Render; use EdnItem::*; -render!(Tui: (self: Groovebox<'a>) => self.size.of( +render!(Tui: (self: Groovebox) => self.size.of( Bsp::s(self.toolbar_view(), Bsp::n(self.selector_view(), Bsp::n(self.sample_view(), Bsp::n(self.status_view(), Bsp::w(self.pool_view(), Fill::xy(Bsp::e(self.sampler_view(), &self.editor))))))))); -impl<'a> Groovebox<'a> { +impl Groovebox { fn toolbar_view (&self) -> impl Content + use<'_> { Fill::x(Fixed::y(2, lay!( Align::w(Meter("L/", self.sampler.input_meter[0])), diff --git a/src/style.rs b/src/style.rs index cc9252e8..36561bb4 100644 --- a/src/style.rs +++ b/src/style.rs @@ -1,27 +1,27 @@ use crate::*; pub trait TuiStyle { - fn fg > (color: Color, w: W) -> Foreground { + fn fg > (color: Color, w: R) -> Foreground { Foreground(color, w) } - fn bg > (color: Color, w: W) -> Background { + fn bg > (color: Color, w: R) -> Background { Background(color, w) } - fn fg_bg > (fg: Color, bg: Color, w: W) -> Background> { + fn fg_bg > (fg: Color, bg: Color, w: R) -> Background> { Background(bg, Foreground(fg, w)) } - fn bold > (on: bool, w: W) -> Bold { + fn bold > (on: bool, w: R) -> Bold { Bold(on, w) } - fn border , S: BorderStyle> (style: S, w: W) -> Bordered { + fn border , S: BorderStyle> (style: S, w: R) -> Bordered { Bordered(style, w) } } impl TuiStyle for Tui {} -pub struct Bold>(pub bool, W); -impl> Content for Bold { +pub struct Bold>(pub bool, R); +impl> Content for Bold { fn content (&self) -> impl Render { &self.1 } fn render (&self, to: &mut TuiOut) { to.fill_bold(to.area(), self.0); @@ -29,8 +29,8 @@ impl> Content for Bold { } } -pub struct Foreground>(pub Color, W); -impl> Content for Foreground { +pub struct Foreground>(pub Color, R); +impl> Content for Foreground { fn content (&self) -> impl Render { &self.1 } fn render (&self, to: &mut TuiOut) { to.fill_fg(to.area(), self.0); @@ -38,8 +38,8 @@ impl> Content for Foreground { } } -pub struct Background>(pub Color, W); -impl> Content for Background { +pub struct Background>(pub Color, R); +impl> Content for Background { fn content (&self) -> impl Render { &self.1 } fn render (&self, to: &mut TuiOut) { to.fill_bg(to.area(), self.0); @@ -47,7 +47,7 @@ impl> Content for Background { } } -pub struct Styled>(pub Option