shrink and grow track widths

This commit is contained in:
🪞👃🪞 2024-10-10 09:10:36 +03:00
parent 5282dab918
commit 333e8bf98a
2 changed files with 60 additions and 24 deletions

View file

@ -47,6 +47,8 @@ pub struct ArrangementTrack<E: Engine> {
pub player: PhrasePlayer<E>, pub player: PhrasePlayer<E>,
/// Outputs /// Outputs
pub outputs: Vec<()>, pub outputs: Vec<()>,
/// Preferred width of track column
pub width: usize,
} }
#[derive(Default)] #[derive(Default)]
pub struct Scene { pub struct Scene {
@ -143,6 +145,33 @@ impl<E: Engine> Arrangement<E> {
_ => {} _ => {}
} }
} }
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 { pub fn is_first_row (&self) -> bool {
let selected = self.selected; let selected = self.selected;
selected.is_mix() || selected.is_track() selected.is_mix() || selected.is_track()
@ -166,6 +195,12 @@ impl<E: Engine> Arrangement<E> {
pub fn track_mut (&mut self) -> Option<&mut ArrangementTrack<E>> { pub fn track_mut (&mut self) -> Option<&mut ArrangementTrack<E>> {
self.selected.track().map(|t|self.tracks.get_mut(t)).flatten() 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) { pub fn track_next (&mut self) {
self.selected.track_next(self.tracks.len() - 1) self.selected.track_next(self.tracks.len() - 1)
} }
@ -187,21 +222,15 @@ impl<E: Engine> Arrangement<E> {
format!("Track {}", self.tracks.len() + 1) format!("Track {}", self.tracks.len() + 1)
} }
pub fn track_widths (&self) -> Vec<(usize, usize)> { pub fn track_widths (&self) -> Vec<(usize, usize)> {
let to_len = |track: &ArrangementTrack<E>|track.name.read().unwrap().len(); let mut widths = vec![];
let mut lens: Vec<usize> = 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 total = 0; let mut total = 0;
let to_x_and_w = |len: &usize|{ total = total + *len; (*len, total - *len) }; for track in self.tracks.iter() {
let mut lens: Vec<(usize, usize)> = lens.iter().map(to_x_and_w).collect(); let width = track.width;
lens.push((0, total)); widths.push((width, total));
lens total += width;
}
widths.push((0, total));
widths
} }
} }
/// Methods for scenes in arrangement /// Methods for scenes in arrangement
@ -326,6 +355,7 @@ impl<E: Engine> ArrangementTrack<E> {
inputs: vec![], inputs: vec![],
player: PhrasePlayer::new(name), player: PhrasePlayer::new(name),
outputs: vec![], outputs: vec![],
width: name.len() + 2,
} }
} }
pub fn longest_name (tracks: &[Self]) -> usize { pub fn longest_name (tracks: &[Self]) -> usize {
@ -333,6 +363,14 @@ impl<E: Engine> ArrangementTrack<E> {
.map(|s|s.name.read().unwrap().len()) .map(|s|s.name.read().unwrap().len())
.fold(0, usize::max) .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 /// Focus identification methods
impl ArrangementFocus { impl ArrangementFocus {

View file

@ -81,9 +81,9 @@ impl Handle<Tui> for Arrangement<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> { fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
match from.event() { match from.event() {
key!(KeyCode::Char('`')) => { self.mode.to_next(); }, key!(KeyCode::Char('`')) => { self.mode.to_next(); },
key!(KeyCode::Delete) => { self.phrase_del(); self.show_phrase(); }, key!(KeyCode::Delete) => { self.delete(); },
key!(KeyCode::Char('.')) => { self.phrase_next(); self.show_phrase(); }, key!(KeyCode::Char('.')) => { self.increment(); },
key!(KeyCode::Char(',')) => { self.phrase_prev(); self.show_phrase(); }, key!(KeyCode::Char(',')) => { self.decrement(); },
// TODO: next/prev scene // TODO: next/prev scene
key!(KeyCode::Enter) => { self.activate(); }, key!(KeyCode::Enter) => { self.activate(); },
key!(Ctrl-KeyCode::Char('a')) => { self.scene_add(None)?; }, key!(Ctrl-KeyCode::Char('a')) => { self.scene_add(None)?; },
@ -147,11 +147,9 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
let Self(state, factor) = self; let Self(state, factor) = self;
let (cols, rows) = if *factor == 0 {( let (cols, rows) = if *factor == 0 {(
state.track_widths(), state.track_widths(),
//ArrangementTrack::clip_name_lengths(state.tracks.as_slice()),
Scene::ppqs(state.tracks.as_slice(), state.scenes.as_slice()), Scene::ppqs(state.tracks.as_slice(), state.scenes.as_slice()),
)} else {( )} else {(
state.track_widths(), state.track_widths(),
//ArrangementTrack::clip_name_lengths(state.tracks.as_slice()),
(0..=state.scenes.len()).map(|i|(factor*PPQ, factor*PPQ*i)).collect::<Vec<_>>(), (0..=state.scenes.len()).map(|i|(factor*PPQ, factor*PPQ*i)).collect::<Vec<_>>(),
)}; )};
//let height = rows.last().map(|(w,y)|(y+w)/PPQ).unwrap_or(16); //let height = rows.last().map(|(w,y)|(y+w)/PPQ).unwrap_or(16);