diff --git a/crates/tek/src/tui/arranger_mode_v.rs b/crates/tek/src/tui/arranger_mode_v.rs index 131dab81..921761d1 100644 --- a/crates/tek/src/tui/arranger_mode_v.rs +++ b/crates/tek/src/tui/arranger_mode_v.rs @@ -8,7 +8,9 @@ impl ArrangerTui { ArrangerVRowSep::from((state, factor)), col!([ ArrangerVHead::from(state), - ArrangerVClips::from((state, factor)) + ArrangerVIns::from(state), + ArrangerVClips::from((state, factor)), + ArrangerVOuts::from(state), ]), ArrangerVCursor::from((state, factor)), ]) @@ -78,6 +80,7 @@ render!(|self: ArrangerVHead<'a>|Tui::push_x(self.scenes_w, row!( ])))) } ))); + impl<'a> ArrangerVHead<'a> { /// name and width of track fn format_name (track: &ArrangerTrack, w: usize) -> impl Render { @@ -124,6 +127,94 @@ impl<'a> ArrangerVHead<'a> { Some(result) } } + +pub struct ArrangerVIns<'a> { + size: &'a Measure, + tracks: &'a Vec, +} +from!(<'a>|args: &'a ArrangerTui|ArrangerVIns<'a> = Self { + size: &args.size, + tracks: &args.tracks, +}); +render!(|self: ArrangerVIns<'a>|""); + +pub struct ArrangerVOuts<'a> { + size: &'a Measure, + tracks: &'a Vec, +} +from!(<'a>|args: &'a ArrangerTui|ArrangerVOuts<'a> = Self { + size: &args.size, + tracks: &args.tracks, +}); +render!(|self: ArrangerVOuts<'a>|""); + +pub struct ArrangerVClocks<'a> { + size: &'a Measure, + tracks: &'a Vec, +} +from!(<'a>|args: &'a ArrangerTui|ArrangerVClocks<'a> = Self { + size: &args.size, + tracks: &args.tracks, +}); +render!(|self: ArrangerVClocks<'a>|""); + +pub struct ArrangerVClips<'a> { + size: &'a Measure, + scenes: &'a Vec, + tracks: &'a Vec, + rows: Vec<(usize, usize)>, +} +from!(<'a>|args:(&'a ArrangerTui, usize)|ArrangerVClips<'a> = Self { + size: &args.0.size, + scenes: &args.0.scenes, + tracks: &args.0.tracks, + rows: ArrangerScene::ppqs(args.0.scenes(), args.1), +}); +render!(|self: ArrangerVClips<'a>|Fill::wh( + col!((scene, pulses) in self.scenes.iter().zip(self.rows.iter().map(|row|row.0)) => { + Self::format_scene(&self.tracks, scene, pulses) + }) +)); +impl<'a> ArrangerVClips<'a> { + 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 ( + 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(); + 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(&Tui::push_x(1, Tui::bg(bg, + Tui::push_x(1, Fixed::w(w as u16, &name.as_str()[0..max_w]))) + ))?; + } + //add(&Background(bg)) + Ok(()) + })) + } +} + pub struct ArrangerVCursor { cols: Vec<(usize, usize)>, rows: Vec<(usize, usize)>, @@ -200,59 +291,3 @@ render!(|self: ArrangerVCursor|render(move|to: &mut TuiOutput|{ else { area.clip_w(self.scenes_w).clip_h(HEADER_H) }, &self.reticle)? }) })); -pub struct ArrangerVClips<'a> { - size: &'a Measure, - scenes: &'a Vec, - tracks: &'a Vec, - rows: Vec<(usize, usize)>, -} -from!(<'a>|args:(&'a ArrangerTui, usize)|ArrangerVClips<'a> = Self { - size: &args.0.size, - scenes: &args.0.scenes, - tracks: &args.0.tracks, - rows: ArrangerScene::ppqs(args.0.scenes(), args.1), -}); -render!(|self: ArrangerVClips<'a>|Fill::wh( - col!((scene, pulses) in self.scenes.iter().zip(self.rows.iter().map(|row|row.0)) => { - Self::format_scene(&self.tracks, scene, pulses) - }) -)); -impl<'a> ArrangerVClips<'a> { - 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 ( - 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(); - 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(&Tui::push_x(1, Tui::bg(bg, - Tui::push_x(1, Fixed::w(w as u16, &name.as_str()[0..max_w]))) - ))?; - } - //add(&Background(bg)) - Ok(()) - })) - } -}