From 8a2f7da8b30a7582dcb07afaac4a6c1352778c37 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 21 Dec 2024 03:37:23 +0100 Subject: [PATCH] move widths and with_widths to ArrangerTrack --- crates/tek/src/tui/arranger_mode_v.rs | 100 ++++++++++++-------------- crates/tek/src/tui/arranger_track.rs | 23 ++++++ 2 files changed, 67 insertions(+), 56 deletions(-) diff --git a/crates/tek/src/tui/arranger_mode_v.rs b/crates/tek/src/tui/arranger_mode_v.rs index 0909b5b3..bbb1a416 100644 --- a/crates/tek/src/tui/arranger_mode_v.rs +++ b/crates/tek/src/tui/arranger_mode_v.rs @@ -1,16 +1,8 @@ use crate::*; -const HEADER_H: u16 = 3; -fn track_widths (tracks: &[ArrangerTrack]) -> Vec<(usize, usize)> { - let mut widths = vec![]; - let mut total = 0; - for track in tracks.iter() { - let width = track.width; - widths.push((width, total)); - total += width; - } - widths.push((0, total)); - widths -} + +const HEADER_H: u16 = 3; +const SCENES_W_OFFSET: u16 = 3; + fn tracks_with_widths (tracks: &[ArrangerTrack]) -> impl Iterator { @@ -21,6 +13,7 @@ fn tracks_with_widths (tracks: &[ArrangerTrack]) data }) } + pub struct ArrangerVHead<'a> { scenes_w: u16, timebase: &'a Arc, @@ -31,10 +24,10 @@ from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a> = Self { // A tracks: state.tracks(), timebase: state.clock().timebase(), current: &state.clock().playhead, - scenes_w: 3 + ArrangerScene::longest_name(state.scenes()) as u16, + scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(state.scenes()) as u16, }); render!(|self: ArrangerVHead<'a>|Tui::push_x(self.scenes_w, row!( - (_, track, x1, x2) in tracks_with_widths(self.tracks) => { + (_, track, x1, x2) in ArrangerTrack::with_widths(self.tracks) => { let (w, h) = (x2 - x1, HEADER_H); let color = track.color(); Tui::bg(color.base.rgb, Tui::min_xy(w as u16, h, Fixed::wh(w as u16, 5, col!([ @@ -100,8 +93,8 @@ pub struct ArrangerVColSep { sep_fg: Color, } from!(|state:&ArrangerTui|ArrangerVColSep = Self { - cols: track_widths(state.tracks()), - scenes_w: 3 + ArrangerScene::longest_name(state.scenes()) as u16, + cols: ArrangerTrack::widths(state.tracks()), + scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(state.scenes()) as u16, sep_fg: TuiTheme::separator_fg(false), }); render!(|self: ArrangerVColSep|render(move|to: &mut TuiOutput|{ @@ -141,26 +134,22 @@ pub struct ArrangerVCursor { scenes_w: u16, } from!(|args:(&ArrangerTui, usize)|ArrangerVCursor = Self { - cols: track_widths(args.0.tracks()), + cols: ArrangerTrack::widths(args.0.tracks()), rows: ArrangerScene::ppqs(args.0.scenes(), args.1), selected: args.0.selected(), - scenes_w: 3 + ArrangerScene::longest_name(args.0.scenes()) as u16, + scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(args.0.scenes()) as u16, }); render!(|self: ArrangerVCursor|render(move|to: &mut TuiOutput|{ let area = to.area(); let focused = true; let selected = self.selected; let get_track_area = |t: usize| [ - self.scenes_w + area.x() + self.cols[t].1 as u16, - area.y(), - self.cols[t].0 as u16, - area.h(), + self.scenes_w + area.x() + self.cols[t].1 as u16, area.y(), + self.cols[t].0 as u16, area.h(), ]; let get_scene_area = |s: usize| [ - area.x(), - HEADER_H + area.y() + (self.rows[s].1 / PPQ) as u16, - area.w(), - (self.rows[s].0 / PPQ) as u16 + area.x(), HEADER_H + area.y() + (self.rows[s].1 / PPQ) as u16, + area.w(), (self.rows[s].0 / PPQ) as u16 ]; let get_clip_area = |t: usize, s: usize| [ self.scenes_w + area.x() + self.cols[t].1 as u16, @@ -220,42 +209,41 @@ from!(<'a>|args:(&'a ArrangerTui, usize)|ArrangerVBody<'a> = Self { render!(|self: ArrangerVBody<'a>|Fixed::h( (self.size.h() as u16).saturating_sub(HEADER_H), col!((scene, pulses) in self.scenes.iter().zip(self.rows.iter().map(|row|row.0)) => { - let height = 1.max((pulses / PPQ) as u16); - let playing = scene.is_playing(self.tracks); - Fixed::h(height, row!([ - Self::format_play(playing), - Tui::bold(true, scene.name.read().unwrap().as_str()), - row!((index, _, x1, x2) in tracks_with_widths(self.tracks) => { - Self::format_clip(&self.tracks, &scene, index, (x2 - x1) as u16, height) - })]) - ) + Self::format_scene(&self.tracks, scene, pulses) }) )); impl<'a> ArrangerVBody<'a> { - fn format_play (playing: bool) -> &'static str { - if playing { "▶ " } else { " " } + fn format_scene ( + tracks: &'a [ArrangerTrack], scene: &'a ArrangerScene, pulses: usize + ) -> impl Render + use<'a> { + let height = 1.max((pulses / PPQ) as u16); + let playing = scene.is_playing(tracks); + Fixed::h(height, row!([ + if playing { "▶ " } else { " " }, + Tui::bold(true, scene.name.read().unwrap().as_str()), + row!((index, track, x1, x2) in ArrangerTrack::with_widths(tracks) => { + Self::format_clip(scene, index, track, (x2 - x1) as u16, height) + })]) + ) } - fn format_clip (tracks: &'a [ArrangerTrack], scene: &'a ArrangerScene, i: usize, w: u16, h: u16) - -> impl Render + use<'a> - { + fn format_clip ( + scene: &'a ArrangerScene, index: usize, track: &'a ArrangerTrack, w: u16, h: u16 + ) -> impl Render + use<'a> { Fixed::wh(w, h, Layers::new(move |add|{ let mut bg = TuiTheme::border_bg(); - match (tracks.get(i), scene.clips.get(i)) { - (Some(track), Some(Some(phrase))) => { - let name = &(phrase as &Arc>).read().unwrap().name; - let name = format!("{}", name); - let max_w = name.len().min((w as usize).saturating_sub(2)); - let color = phrase.read().unwrap().color; - bg = color.dark.rgb; - if let Some((_, Some(ref playing))) = track.player.play_phrase() { - if *playing.read().unwrap() == *phrase.read().unwrap() { - bg = color.light.rgb - } - }; - add(&Fixed::w(w as u16, Tui::push_x(1, &name.as_str()[0..max_w])))?; - }, - _ => {} - }; + if let Some(Some(phrase)) = scene.clips.get(index) { + let name = &(phrase as &Arc>).read().unwrap().name; + let name = format!("{}", name); + let max_w = name.len().min((w as usize).saturating_sub(2)); + let color = phrase.read().unwrap().color; + bg = color.dark.rgb; + if let Some((_, Some(ref playing))) = track.player.play_phrase() { + if *playing.read().unwrap() == *phrase.read().unwrap() { + bg = color.light.rgb + } + }; + add(&Fixed::w(w as u16, Tui::push_x(1, &name.as_str()[0..max_w])))?; + } //add(&Background(bg)) Ok(()) })) diff --git a/crates/tek/src/tui/arranger_track.rs b/crates/tek/src/tui/arranger_track.rs index 45e93081..80c366ff 100644 --- a/crates/tek/src/tui/arranger_track.rs +++ b/crates/tek/src/tui/arranger_track.rs @@ -13,6 +13,29 @@ use KeyCode::{Char, Delete}; } has_clock!(|self:ArrangerTrack|self.player.clock()); has_player!(|self:ArrangerTrack|self.player); +impl ArrangerTrack { + pub fn widths (tracks: &[Self]) -> Vec<(usize, usize)> { + let mut widths = vec![]; + let mut total = 0; + for track in tracks.iter() { + let width = track.width; + widths.push((width, total)); + total += width; + } + widths.push((0, total)); + widths + } + pub fn with_widths (tracks: &[ArrangerTrack]) + -> impl Iterator + { + let mut x = 0; + tracks.iter().enumerate().map(move |(index, track)|{ + let data = (index, track, x, x + track.width); + x += track.width; + data + }) + } +} impl ArrangerTrackApi for ArrangerTrack { /// Name of track fn name (&self) -> &Arc> {