From 325492ec428532eba48d9369ba2f22588e6c809d Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 31 Oct 2024 23:33:08 +0200 Subject: [PATCH] show tracks ins and outs --- crates/tek_sequencer/src/arranger.rs | 32 +++------ crates/tek_sequencer/src/arranger_tui.rs | 83 ++++++++++++------------ 2 files changed, 52 insertions(+), 63 deletions(-) diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index 552dde42..e2f37225 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -74,11 +74,11 @@ pub struct ArrangementTrack { /// Name of track pub name: Arc>, /// Inputs - pub inputs: Vec<()>, + pub inputs: Vec>, /// MIDI player/recorder pub player: PhrasePlayer, /// Outputs - pub outputs: Vec<()>, + pub outputs: Vec>, /// Preferred width of track column pub width: usize, /// Identifying color of track @@ -152,9 +152,7 @@ impl Arranger { Ok(Some(true)) } /// Focus the editor with the current phrase - pub fn show_phrase (&mut self) { - self.editor.show(self.arrangement.phrase().as_ref()); - } + pub fn show_phrase (&mut self) { self.editor.show(self.arrangement.phrase().as_ref()); } /// Focus the editor with the current phrase pub fn edit_phrase (&mut self) { if self.arrangement.phrase().is_none() { @@ -382,18 +380,10 @@ impl Arrangement { pub fn track_mut (&mut self) -> Option<&mut ArrangementTrack> { self.selected.track().map(|t|self.tracks.get_mut(t)).flatten() } - pub fn track_width_inc (&mut self) { - self.track_mut().map(|t|t.width_inc()); - } - pub fn track_width_dec (&mut self) { - self.track_mut().map(|t|t.width_dec()); - } - pub fn track_next (&mut self) { - self.selected.track_next(self.tracks.len() - 1) - } - pub fn track_prev (&mut self) { - self.selected.track_prev() - } + pub fn track_width_inc (&mut self) { self.track_mut().map(|t|t.width_inc()); } + pub fn track_width_dec (&mut self) { self.track_mut().map(|t|t.width_dec()); } + pub fn track_next (&mut self) { self.selected.track_next(self.tracks.len() - 1) } + pub fn track_prev (&mut self) { self.selected.track_prev() } pub fn track_add ( &mut self, name: Option<&str>, color: Option ) -> Usually<&mut ArrangementTrack> { @@ -460,14 +450,10 @@ impl Arrangement { /// Methods for phrases in arrangement impl Arrangement { pub fn sequencer (&self) -> Option<&ArrangementTrack> { - self.selected.track() - .map(|track|self.tracks.get(track)) - .flatten() + self.selected.track().map(|track|self.tracks.get(track)).flatten() } pub fn sequencer_mut (&mut self) -> Option<&mut ArrangementTrack> { - self.selected.track() - .map(|track|self.tracks.get_mut(track)) - .flatten() + self.selected.track().map(|track|self.tracks.get_mut(track)).flatten() } pub fn phrase (&self) -> Option>> { self.scene()?.clips.get(self.selected.track()?)?.clone() diff --git a/crates/tek_sequencer/src/arranger_tui.rs b/crates/tek_sequencer/src/arranger_tui.rs index 23227827..32e2d359 100644 --- a/crates/tek_sequencer/src/arranger_tui.rs +++ b/crates/tek_sequencer/src/arranger_tui.rs @@ -77,12 +77,12 @@ impl Content for ArrangerStatusBar { ["", "a", "ppend"], ["", "i", "nsert"], ["", "d", "uplicate"], + ["", "Del", "ete"], ["", "c", "olor"], ["re", "n", "ame"], ["leng", "t", "h"], ["", ",.", "move"], ["", "+-", "resize view"], - ["", "Del", "ete"], ]), Self::PhraseView => command(&[ ["", "enter", " edit"], @@ -118,7 +118,8 @@ impl Content for Arrangement { ArrangementViewMode::Vertical(factor) => add(&VerticalArranger(&self, factor)), }?; let color = if self.focused{Color::Rgb(150, 160, 90)}else{Color::Rgb(120, 130, 100)}; - add(&TuiStyle::fg("Session", color).push_x(1)) + add(&TuiStyle::fg("Session", color).push_x(1))?; + add(&self.size) }) } } @@ -137,14 +138,13 @@ impl<'a> Content for VerticalArranger<'a, Tui> { let border_lo = Color::Rgb(70, 80, 50); let border_fg = if self.0.focused { border_hi } else { border_lo }; let border = Lozenge(Style::default().bg(border_bg).fg(border_fg)); - let track_title_h = 3u16; + let track_title_h = 2u16; + let tracks_footer = 3u16; let scene_title_w = 3 + Scene::longest_name(scenes) as u16; // x of 1st track - let content = Layers::new(move |add|{ + let arrangement = Layers::new(move |add|{ let rows: &[(usize, usize)] = rows.as_ref(); let cols: &[(usize, usize)] = cols.as_ref(); let any_size = |_|Ok(Some([0,0])); - // store render area - add(&self.0.size)?; // column separators add(&CustomWidget::new(any_size, move|to: &mut TuiOutput|{ let area = to.area(); @@ -171,12 +171,24 @@ impl<'a> Content for VerticalArranger<'a, Tui> { }))?; // track titles let header = row!((track, w) in tracks.iter().zip(cols.iter().map(|col|col.0))=>{ - let name = track.name.read().unwrap(); - let max_w = w.saturating_sub(1).min(name.len()).max(2); - let name = format!("▎{}", &name[0..max_w]); - let name = TuiStyle::bold(name, true); - let player = &track.player; - let clock = &player.clock; + let name = track.name.read().unwrap(); + let max_w = w.saturating_sub(1).min(name.len()).max(2); + let name = format!("▎{}", &name[0..max_w]); + let name = TuiStyle::bold(name, true); + let input_name = track.inputs.get(0) + .map(|port|port.short_name()) + .transpose()? + .unwrap_or("(none)".into()); + let input = format!("▎i {}", input_name); + col!(name, input) + .min_xy(w as u16, track_title_h) + .bg(track.color) + .push_x(scene_title_w) + }); + // track controls + let footer = row!((track, w) in tracks.iter().zip(cols.iter().map(|col|col.0))=>{ + let player = &track.player; + let clock = &player.clock; let elapsed = player.phrase.as_ref() .map(|_|player.frames_since_start()) .flatten() @@ -185,15 +197,13 @@ impl<'a> Content for VerticalArranger<'a, Tui> { let until_next = player.next_phrase.as_ref() .map(|(t, _)|format!("▎-{:>}", clock.format_beats(t.load(Ordering::Relaxed)))) .unwrap_or(String::from("▎")); - col!( - name, - //"▎> 12345", - //"▎< 12345", - //"▎m s r o", - elapsed, - until_next - ) - .min_xy(w as u16, track_title_h) + let output_name = track.outputs.get(0) + .map(|port|port.short_name()) + .transpose()? + .unwrap_or("(none)".into()); + let output = format!("▎o {}", output_name); + col!(until_next, elapsed, output) + .min_xy(w as u16, tracks_footer) .bg(track.color) .push_x(scene_title_w) }); @@ -218,7 +228,7 @@ impl<'a> Content for VerticalArranger<'a, Tui> { add(&Background(color)) }).fixed_xy(w, h); // tracks and scenes - add(&col!(header, col!( + let content = col!( // scenes: (scene, pulses) in scenes.iter().zip(rows.iter().map(|row|row.0)) => { let height = 1.max((pulses / PPQ) as u16); @@ -232,23 +242,21 @@ impl<'a> Content for VerticalArranger<'a, Tui> { }) }).fixed_y(height) } - )))?; + ).fixed_y((self.0.size.h() as u16).saturating_sub(track_title_h + tracks_footer + 2)); + // full grid with header and footer + add(&col!(header, content, footer))?; // cursor add(&CustomWidget::new(any_size, move|to: &mut TuiOutput|{ let area = to.area(); let focused = state.focused; let selected = state.selected; let get_track_area = |t: usize| [ - scene_title_w + area.x() + cols[t].1 as u16, - area.y(), - cols[t].0 as u16, - area.h(), + scene_title_w + area.x() + cols[t].1 as u16, area.y(), + cols[t].0 as u16, area.h(), ]; let get_scene_area = |s: usize| [ - area.x(), - track_title_h + area.y() + (rows[s].1 / PPQ) as u16, - area.w(), - (rows[s].0 / PPQ) as u16 + area.x(), track_title_h + area.y() + (rows[s].1 / PPQ) as u16, + area.w(), (rows[s].0 / PPQ) as u16 ]; let get_clip_area = |t: usize, s: usize| [ scene_title_w + area.x() + cols[t].1 as u16, @@ -286,15 +294,10 @@ impl<'a> Content for VerticalArranger<'a, Tui> { }) })) }).bg(bg).grow_y(1).border(border); - let title_color = if self.0.focused { - Color::Rgb(150, 160, 90) - } else { - Color::Rgb(120, 130, 100) - }; - let [w, h] = self.0.size.wh(); - let lower_right = TuiStyle::fg(format!("{w}x{h}"), title_color) - .pull_x(1).align_se().fill_xy(); - lay!(content, lower_right) + let color = if self.0.focused {Color::Rgb(150, 160, 90)} else {Color::Rgb(120, 130, 100)}; + let size = format!("{}x{}", self.0.size.w(), self.0.size.h()); + let lower_right = TuiStyle::fg(size, color).pull_x(1).align_se().fill_xy(); + lay!(arrangement, lower_right) } } impl<'a> Content for HorizontalArranger<'a, Tui> {