From abc1cc8fcee1d911911de19651d1c76304db6593 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Mon, 6 Jan 2025 21:42:33 +0100 Subject: [PATCH] wip: unfuck arranger more --- src/arranger.rs | 74 +++++++++++++++++++++++++++++++++++++++--------- src/lib.rs | 1 - src/sequencer.rs | 50 ++++++++++++++++++++++++++++++++ src/status.rs | 51 --------------------------------- 4 files changed, 110 insertions(+), 66 deletions(-) delete mode 100644 src/status.rs diff --git a/src/arranger.rs b/src/arranger.rs index 0ac28a63..4a858692 100644 --- a/src/arranger.rs +++ b/src/arranger.rs @@ -29,6 +29,7 @@ pub struct Arranger { pub midi_buf: Vec>>, pub editor: MidiEditor, pub perf: PerfModel, + pub compact: bool, } impl Arranger { pub fn selected (&self) -> ArrangerSelection { @@ -94,6 +95,7 @@ from_jack!(|jack| Arranger { note_buf: vec![], perf: PerfModel::default(), jack: jack.clone(), + compact: false, } }); impl Arranger { @@ -104,20 +106,64 @@ impl Arranger { } } } -render!(TuiOut: (self: Arranger) => { - let pool_w = if self.pool.visible { self.splits[1] } else { 0 }; - let color = self.color; - let layout = Bsp::a(Fill::xy(ArrangerStatus::from(self)), - Bsp::n(Fixed::x(pool_w, PoolView(self.pool.visible, &self.pool)), - Bsp::n(TransportView::new(true, &self.clock), - Bsp::s(Fixed::y(1, MidiEditStatus(&self.editor)), - Bsp::n(Fill::x(Fixed::y(20, - Bsp::a(Fill::xy(Tui::bg(color.darkest.rgb, "background")), - Bsp::a( - Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))), - Self::render_mode(self))))), Fill::y(&"fixme: self.editor")))))); - self.size.of(layout) -}); +//render!(TuiOut: (self: Arranger) => { + //let pool_w = if self.pool.visible { self.splits[1] } else { 0 }; + //let color = self.color; + //let layout = Bsp::a(Fill::xy(ArrangerStatus::from(self)), + //Bsp::n(Fixed::x(pool_w, PoolView(self.pool.visible, &self.pool)), + //Bsp::n(TransportView::new(true, &self.clock), + //Bsp::s(Fixed::y(1, MidiEditStatus(&self.editor)), + //Bsp::n(Fill::x(Fixed::y(20, + //Bsp::a(Fill::xy(Tui::bg(color.darkest.rgb, "background")), + //Bsp::a( + //Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))), + //Self::render_mode(self))))), Fill::y(&"fixme: self.editor")))))); + //self.size.of(layout) +//}); +render!(TuiOut: (self: Arranger) => self.size.of( + Bsp::s(self.toolbar_view(), + Bsp::n(self.selector_view(), + Bsp::n(self.status_view(), + Bsp::w(self.pool_view(), Fill::xy(&self.editor))))))); +impl Arranger { + fn toolbar_view (&self) -> impl Content + use<'_> { + Fill::x(Fixed::y(2, Align::x(TransportView::new(true, &self.clock)))) + } + fn status_view (&self) -> impl Content + use<'_> { + let edit_clip = MidiEditClip(&self.editor); + //let selectors = When(false, Bsp::e(ClipSelected::play_phrase(&self.player), ClipSelected::next_phrase(&self.player))); + row!(/*selectors,*/ edit_clip, MidiEditStatus(&self.editor)) + } + fn selector_view (&self) -> impl Content + use<'_> { + row!( + //ClipSelected::play_phrase(&self.player), + //ClipSelected::next_phrase(&self.player), + MidiEditClip(&self.editor), + MidiEditStatus(&self.editor), + ) + } + fn pool_view (&self) -> impl Content + use<'_> { + let w = self.size.w(); + let phrase_w = if w > 60 { 20 } else if w > 40 { 15 } else { 10 }; + let pool_w = if self.pool.visible { phrase_w } else { 0 }; + let pool = Pull::y(1, Fill::y(Align::e(PoolView(self.pool.visible, &self.pool)))); + Fixed::x(pool_w, Align::e(Fill::y(PoolView(self.compact, &self.pool)))) + } +} +//render!(TuiOut: (self: Arranger) => { + //let pool_w = if self.pool.visible { self.splits[1] } else { 0 }; + //let color = self.color; + //let layout = Bsp::a(Fill::xy(ArrangerStatus::from(self)), + //Bsp::n(Fixed::x(pool_w, PoolView(self.pool.visible, &self.pool)), + //Bsp::n(TransportView::new(true, &self.clock), + //Bsp::s(Fixed::y(1, MidiEditStatus(&self.editor)), + //Bsp::n(Fill::x(Fixed::y(20, + //Bsp::a(Fill::xy(Tui::bg(color.darkest.rgb, "background")), + //Bsp::a( + //Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))), + //Self::render_mode(self))))), Fill::y(&"fixme: self.editor")))))); + //self.size.of(layout) +//}); audio!(|self: Arranger, client, scope|{ // Start profiling cycle let t0 = self.perf.get_t0(); diff --git a/src/lib.rs b/src/lib.rs index 3f9d9ef8..70231d0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,6 @@ pub mod plugin; pub use self::plugin::*; pub mod pool; pub use self::pool::*; pub mod sampler; pub use self::sampler::*; pub mod sequencer; pub use self::sequencer::*; -pub mod status; pub use self::status::*; pub use ::atomic_float; pub(crate) use atomic_float::*; diff --git a/src/sequencer.rs b/src/sequencer.rs index 9880ec6a..2e7ea1de 100644 --- a/src/sequencer.rs +++ b/src/sequencer.rs @@ -175,3 +175,53 @@ command!(|self: SequencerCommand, state: Sequencer|match self { None }, }); + +/// Status bar for sequencer app +#[derive(Clone)] +pub struct SequencerStatus { + pub(crate) width: usize, + pub(crate) cpu: Option, + pub(crate) size: String, + pub(crate) playing: bool, +} +from!(|state:&Sequencer|SequencerStatus = { + let samples = state.clock.chunk.load(Relaxed); + let rate = state.clock.timebase.sr.get(); + let buffer = samples as f64 / rate; + let width = state.size.w(); + Self { + width, + playing: state.clock.is_rolling(), + cpu: state.perf.percentage().map(|cpu|format!("│{cpu:.01}%")), + size: format!("{}x{}│", width, state.size.h()), + } +}); +render!(TuiOut: (self: SequencerStatus) => Fixed::y(2, lay!( + Self::help(), + Fill::xy(Align::se(Tui::fg_bg(TuiTheme::orange(), TuiTheme::g(25), self.stats()))), +))); +impl SequencerStatus { + fn help () -> impl Content { + let single = |binding, command|row!(" ", col!( + Tui::fg(TuiTheme::yellow(), binding), + command + )); + let double = |(b1, c1), (b2, c2)|col!( + row!(" ", Tui::fg(TuiTheme::yellow(), b1), " ", c1,), + row!(" ", Tui::fg(TuiTheme::yellow(), b2), " ", c2,), + ); + Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(50), row!( + single("SPACE", "play/pause"), + double(("▲▼▶◀", "cursor"), ("Ctrl", "scroll"), ), + double(("a", "append"), ("s", "set note"),), + double((",.", "length"), ("<>", "triplet"), ), + double(("[]", "phrase"), ("{}", "order"), ), + double(("q", "enqueue"), ("e", "edit"), ), + double(("c", "color"), ("", ""),), + )) + } + fn stats (&self) -> impl Content + use<'_> { + row!(&self.cpu, &self.size) + } +} + diff --git a/src/status.rs b/src/status.rs deleted file mode 100644 index bb77ea85..00000000 --- a/src/status.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::*; - -/// Status bar for sequencer app -#[derive(Clone)] -pub struct SequencerStatus { - pub(crate) width: usize, - pub(crate) cpu: Option, - pub(crate) size: String, - pub(crate) playing: bool, -} -from!(|state:&Sequencer|SequencerStatus = { - let samples = state.clock.chunk.load(Relaxed); - let rate = state.clock.timebase.sr.get(); - let buffer = samples as f64 / rate; - let width = state.size.w(); - Self { - width, - playing: state.clock.is_rolling(), - cpu: state.perf.percentage().map(|cpu|format!("│{cpu:.01}%")), - size: format!("{}x{}│", width, state.size.h()), - } -}); -render!(TuiOut: (self: SequencerStatus) => Fixed::y(2, lay!( - Self::help(), - Fill::xy(Align::se(Tui::fg_bg(TuiTheme::orange(), TuiTheme::g(25), self.stats()))), -))); -impl SequencerStatus { - fn help () -> impl Content { - let single = |binding, command|row!(" ", col!( - Tui::fg(TuiTheme::yellow(), binding), - command - )); - let double = |(b1, c1), (b2, c2)|col!( - row!(" ", Tui::fg(TuiTheme::yellow(), b1), " ", c1,), - row!(" ", Tui::fg(TuiTheme::yellow(), b2), " ", c2,), - ); - Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(50), row!( - single("SPACE", "play/pause"), - double(("▲▼▶◀", "cursor"), ("Ctrl", "scroll"), ), - double(("a", "append"), ("s", "set note"),), - double((",.", "length"), ("<>", "triplet"), ), - double(("[]", "phrase"), ("{}", "order"), ), - double(("q", "enqueue"), ("e", "edit"), ), - double(("c", "color"), ("", ""),), - )) - } - fn stats (&self) -> impl Content + use<'_> { - row!(&self.cpu, &self.size) - } -} -