tek/src/arranger/arranger_v/v_clips.rs

62 lines
2.3 KiB
Rust

use crate::*;
use super::*;
pub struct ArrangerVClips<'a> {
size: &'a Measure<Tui>,
scenes: &'a Vec<ArrangerScene>,
tracks: &'a Vec<ArrangerTrack>,
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!(<Tui>|self: ArrangerVClips<'a>|Fill::xy(
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<Tui> + use<'a> {
let height = 1.max((pulses / PPQ) as u16);
let playing = scene.is_playing(tracks);
Fixed::y(height, row!([
Tui::bg(scene.color.base.rgb,
if playing { "" } else { " " }),
Tui::fg_bg(scene.color.lightest.rgb, scene.color.base.rgb,
Expand::x(1, 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<Tui> + use<'a> {
Fixed::xy(w, h, Layers::new(move |add|{
if let Some(Some(phrase)) = scene.clips.get(index) {
let mut bg = TuiTheme::border_bg();
let name = &(phrase as &Arc<RwLock<MidiClip>>).read().unwrap().name.to_string();
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::bg(bg,
Push::x(1, Fixed::x(w, &name.as_str()[0..max_w])))
)?;
}
Ok(())
}))
}
}