diff --git a/src/groovebox/groovebox_tui.rs b/src/groovebox/groovebox_tui.rs index 54542d95..03acbae1 100644 --- a/src/groovebox/groovebox_tui.rs +++ b/src/groovebox/groovebox_tui.rs @@ -18,10 +18,10 @@ impl Groovebox { } fn selector_view (&self) -> impl Content + use<'_> { row!( - MidiEditClip(&self.editor), - MidiEditStatus(&self.editor), ClipSelected::play_phrase(&self.player), ClipSelected::next_phrase(&self.player), + MidiEditClip(&self.editor), + MidiEditStatus(&self.editor), ) } fn sample_view (&self) -> impl Content + use<'_> { diff --git a/src/midi/midi_editor.rs b/src/midi/midi_editor.rs index bab9a1fb..b1439082 100644 --- a/src/midi/midi_editor.rs +++ b/src/midi/midi_editor.rs @@ -73,7 +73,7 @@ impl TimePoint for MidiEditor { fn set_time_point (&self, x: usize) { self.mode.set_time_point(x) } } -impl MidiViewMode for MidiEditor { +impl MidiViewer for MidiEditor { fn buffer_size (&self, phrase: &MidiClip) -> (usize, usize) { self.mode.buffer_size(phrase) } diff --git a/src/midi/midi_status.rs b/src/midi/midi_status.rs index b8fda05c..b294a04f 100644 --- a/src/midi/midi_status.rs +++ b/src/midi/midi_status.rs @@ -8,9 +8,8 @@ render!(Tui: (self: MidiEditClip<'a>) => { (ItemPalette::from(TuiTheme::g(64)), String::new(), 0, false) }; row!( - FieldV(color, "Edit", name.to_string()), - FieldV(color, "Length", length.to_string()), - FieldV(color, "Loop", looped.to_string()) + FieldV(color, "Edit", format!("{name} ({length})")), + FieldV(color, "Loop", looped.to_string()) ) }); diff --git a/src/midi/midi_view.rs b/src/midi/midi_view.rs index 47573902..211367a4 100644 --- a/src/midi/midi_view.rs +++ b/src/midi/midi_view.rs @@ -1,6 +1,6 @@ use crate::*; -pub trait MidiViewMode: HasSize + MidiRange + MidiPoint + Debug + Send + Sync { +pub trait MidiViewer: HasSize + MidiRange + MidiPoint + Debug + Send + Sync { fn buffer_size (&self, phrase: &MidiClip) -> (usize, usize); fn redraw (&self); fn phrase (&self) -> &Option>>; diff --git a/src/piano/piano_h.rs b/src/piano/piano_h.rs index f7b9e8d3..69e5a204 100644 --- a/src/piano/piano_h.rs +++ b/src/piano/piano_h.rs @@ -104,7 +104,7 @@ impl TimePoint for PianoHorizontal { fn time_point (&self) -> usize { self.point.time_point() } fn set_time_point (&self, x: usize) { self.point.set_time_point(x) } } -impl MidiViewMode for PianoHorizontal { +impl MidiViewer for PianoHorizontal { fn phrase (&self) -> &Option>> { &self.phrase } diff --git a/src/pool/clip_select.rs b/src/pool/clip_select.rs index 5c14a25c..44a2b3d7 100644 --- a/src/pool/clip_select.rs +++ b/src/pool/clip_select.rs @@ -12,27 +12,34 @@ render!(Tui: (self: ClipSelected) => impl ClipSelected { - // beats elapsed + /// Shows currently playing phrase with beats elapsed pub fn play_phrase (state: &T) -> Self { let (name, color) = if let Some((_, Some(phrase))) = state.play_phrase() { let MidiClip { ref name, color, .. } = *phrase.read().unwrap(); (name.clone(), color) } else { - ("".to_string(), ItemPalette::from(TuiTheme::g(64))) + ("".to_string(), TuiTheme::g(64).into()) }; - let time = if let Some(elapsed) = state.pulses_since_start_looped() { - format!("+{:>}", state.clock().timebase.format_beats_0(elapsed)) - } else { - String::from(" ") - }; - Self { title: "Now", time, name, color, } + Self { + title: "Now", + name, + color, + time: state.pulses_since_start_looped() + .map(|elapsed|format!("+{:>}", state.clock().timebase.format_beats_0(elapsed))) + .unwrap_or_else(||String::from(" ")) + } } - // beats until switchover + /// Shows next phrase with beats remaining until switchover pub fn next_phrase (state: &T) -> Self { - let (time, name, color) = if let Some((t, Some(phrase))) = state.next_phrase() { - let MidiClip { ref name, color, .. } = *phrase.read().unwrap(); - let time = { + let mut time = String::from("--.-.--"); + let mut name = String::from(""); + let mut color = ItemPalette::from(TuiTheme::g(64)); + if let Some((t, Some(phrase))) = state.next_phrase() { + let phrase = phrase.read().unwrap(); + name = phrase.name.clone(); + color = phrase.color.clone(); + time = { let target = t.pulse.get(); let current = state.clock().playhead.pulse.get(); if target > current { @@ -41,17 +48,20 @@ impl ClipSelected { } else { String::new() } - }; - (time, name.clone(), color) - } else if let Some((_, Some(phrase))) = state.play_phrase() { + } + } else if let Some((t, Some(phrase))) = state.play_phrase() { let phrase = phrase.read().unwrap(); if phrase.looped { - (" ".into(), phrase.name.clone(), phrase.color) + name = phrase.name.clone(); + color = phrase.color.clone(); + let target = t.pulse.get() + phrase.length as f64; + let current = state.clock().playhead.pulse.get(); + if target > current { + time = format!("-{:>}", state.clock().timebase.format_beats_0(target - current)) + } } else { - (" ".into(), " ".into(), TuiTheme::g(64).into()) + name = "Stop".to_string(); } - } else { - (" ".into(), " ".into(), TuiTheme::g(64).into()) }; Self { title: "Next", time, name, color, } }