From 333e8bf98ae7cf6be029cf90fd08a19af0fa8215 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 10 Oct 2024 09:10:36 +0300 Subject: [PATCH] shrink and grow track widths --- crates/tek_sequencer/src/arranger.rs | 66 +++++++++++++++++++----- crates/tek_sequencer/src/arranger_tui.rs | 18 +++---- 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index 13458716..9f14ce09 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -47,6 +47,8 @@ pub struct ArrangementTrack { pub player: PhrasePlayer, /// Outputs pub outputs: Vec<()>, + /// Preferred width of track column + pub width: usize, } #[derive(Default)] pub struct Scene { @@ -143,6 +145,33 @@ impl Arrangement { _ => {} } } + pub fn delete (&mut self) { + match self.selected { + ArrangementFocus::Track(t) => self.track_del(), + ArrangementFocus::Scene(s) => self.scene_del(), + ArrangementFocus::Clip(t, s) => self.phrase_del(), + _ => {} + } + self.show_phrase() + } + pub fn increment (&mut self) { + match self.selected { + ArrangementFocus::Track(t) => self.track_width_inc(), + ArrangementFocus::Scene(s) => self.scene_next(), + ArrangementFocus::Clip(t, s) => self.phrase_next(), + _ => {} + } + self.show_phrase() + } + pub fn decrement (&mut self) { + match self.selected { + ArrangementFocus::Track(t) => self.track_width_dec(), + ArrangementFocus::Scene(s) => self.scene_prev(), + ArrangementFocus::Clip(t, s) => self.phrase_prev(), + _ => {} + } + self.show_phrase() + } pub fn is_first_row (&self) -> bool { let selected = self.selected; selected.is_mix() || selected.is_track() @@ -166,6 +195,12 @@ 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) } @@ -187,21 +222,15 @@ impl Arrangement { format!("Track {}", self.tracks.len() + 1) } pub fn track_widths (&self) -> Vec<(usize, usize)> { - let to_len = |track: &ArrangementTrack|track.name.read().unwrap().len(); - let mut lens: Vec = self.tracks.iter().map(to_len).collect(); - for scene in self.scenes.iter() { - for track_index in 0..self.tracks.len() { - if let Some(phrase) = scene.clip(track_index) { - let len = phrase.read().unwrap().name.read().unwrap().len(); - lens[track_index] = lens[track_index].max(len); - } - } - } + let mut widths = vec![]; let mut total = 0; - let to_x_and_w = |len: &usize|{ total = total + *len; (*len, total - *len) }; - let mut lens: Vec<(usize, usize)> = lens.iter().map(to_x_and_w).collect(); - lens.push((0, total)); - lens + for track in self.tracks.iter() { + let width = track.width; + widths.push((width, total)); + total += width; + } + widths.push((0, total)); + widths } } /// Methods for scenes in arrangement @@ -326,6 +355,7 @@ impl ArrangementTrack { inputs: vec![], player: PhrasePlayer::new(name), outputs: vec![], + width: name.len() + 2, } } pub fn longest_name (tracks: &[Self]) -> usize { @@ -333,6 +363,14 @@ impl ArrangementTrack { .map(|s|s.name.read().unwrap().len()) .fold(0, usize::max) } + pub fn width_inc (&mut self) { + self.width += 1; + } + pub fn width_dec (&mut self) { + if self.width > 1 { + self.width -= 1; + } + } } /// Focus identification methods impl ArrangementFocus { diff --git a/crates/tek_sequencer/src/arranger_tui.rs b/crates/tek_sequencer/src/arranger_tui.rs index 7fa73d46..f60e6bcb 100644 --- a/crates/tek_sequencer/src/arranger_tui.rs +++ b/crates/tek_sequencer/src/arranger_tui.rs @@ -80,15 +80,15 @@ impl Arranger { impl Handle for Arrangement { fn handle (&mut self, from: &TuiInput) -> Perhaps { match from.event() { - key!(KeyCode::Char('`')) => { self.mode.to_next(); }, - key!(KeyCode::Delete) => { self.phrase_del(); self.show_phrase(); }, - key!(KeyCode::Char('.')) => { self.phrase_next(); self.show_phrase(); }, - key!(KeyCode::Char(',')) => { self.phrase_prev(); self.show_phrase(); }, + key!(KeyCode::Char('`')) => { self.mode.to_next(); }, + key!(KeyCode::Delete) => { self.delete(); }, + key!(KeyCode::Char('.')) => { self.increment(); }, + key!(KeyCode::Char(',')) => { self.decrement(); }, // TODO: next/prev scene - key!(KeyCode::Enter) => { self.activate(); }, - key!(Ctrl-KeyCode::Char('a')) => { self.scene_add(None)?; }, - key!(Ctrl-KeyCode::Char('t')) => { self.track_add(None)?; }, - key!(KeyCode::Char('n')) => { todo!("rename selected"); }, + key!(KeyCode::Enter) => { self.activate(); }, + key!(Ctrl-KeyCode::Char('a')) => { self.scene_add(None)?; }, + key!(Ctrl-KeyCode::Char('t')) => { self.track_add(None)?; }, + key!(KeyCode::Char('n')) => { todo!("rename selected"); }, key!(KeyCode::Char('c')) => { todo!("recolor selected"); }, key!(KeyCode::Char('l')) => if let Some(phrase) = self.phrase() { phrase.write().unwrap().toggle_loop() @@ -147,11 +147,9 @@ impl<'a> Content for VerticalArranger<'a, Tui> { let Self(state, factor) = self; let (cols, rows) = if *factor == 0 {( state.track_widths(), - //ArrangementTrack::clip_name_lengths(state.tracks.as_slice()), Scene::ppqs(state.tracks.as_slice(), state.scenes.as_slice()), )} else {( state.track_widths(), - //ArrangementTrack::clip_name_lengths(state.tracks.as_slice()), (0..=state.scenes.len()).map(|i|(factor*PPQ, factor*PPQ*i)).collect::>(), )}; //let height = rows.last().map(|(w,y)|(y+w)/PPQ).unwrap_or(16);