wip: refactor into crates

This commit is contained in:
🪞👃🪞 2024-08-03 21:55:38 +03:00
parent 96e17e7f7c
commit 5ae99b4ada
87 changed files with 2281 additions and 2217 deletions

View file

@ -0,0 +1,225 @@
use crate::*;
use super::{
Arranger,
arr_focus::ArrangerFocus,
arr_track::track_clip_name_lengths,
arr_scene::{Scene, scene_ppqs, scene_name_max_len}
};
pub fn draw_expanded (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
let track_cols = track_clip_name_lengths(state.tracks.as_slice());
let scene_rows = scene_ppqs(state.tracks.as_slice(), state.scenes.as_slice());
draw(state, buf, area, track_cols.as_slice(), scene_rows.as_slice())
}
pub fn draw_compact (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
let track_cols = track_clip_name_lengths(state.tracks.as_slice());
let scene_rows = (0..=state.scenes.len()+3).map(|i|(96, 96*i)).collect::<Vec<_>>();
draw(state, buf, area, track_cols.as_slice(), scene_rows.as_slice())
}
pub fn draw (
state: &Arranger,
buf: &mut Buffer,
mut area: Rect,
cols: &[(usize, usize)],
rows: &[(usize, usize)],
) -> Usually<Rect> {
area.height = 2 + (rows[rows.len() - 1].1 / 96) as u16;
let offset = 3 + scene_name_max_len(state.scenes.as_ref()) as u16;
Layered([
&to_fill_bg(Nord::bg_lo(state.focused, state.entered)),
&column_separators(offset, cols),
&cursor_focus(state, offset, cols, rows),
&Split::down([
&tracks_header(state, cols, offset),
&scene_rows(state, cols, rows, offset),
]),
&row_separators(rows),
]).render(buf, area)
}
fn column_separators <'a> (offset: u16, cols: &'a [(usize, usize)]) -> impl Render + 'a {
move |buf: &mut Buffer, area: Rect|{
let style = Some(Style::default().fg(Nord::SEPARATOR));
for (_, x) in cols.iter() {
let x = offset + area.x + *x as u16 - 1;
for y in area.y..area.height+area.y {
"".blit(buf, x, y, style)?;
}
}
Ok(area)
}
}
fn row_separators <'a> (rows: &'a [(usize, usize)]) -> impl Render + 'a {
move |buf: &mut Buffer, area: Rect| {
for (_, y) in rows.iter() {
let y = area.y + (*y / 96) as u16 + 1;
if y >= buf.area.height {
break
}
for x in area.x..area.width+area.y-2 {
let cell = buf.get_mut(x, y);
cell.modifier = Modifier::UNDERLINED;
cell.underline_color = Nord::SEPARATOR;
}
}
Ok(area)
}
}
fn cursor_focus <'a> (
state: &'a Arranger, offset: u16, cols: &'a [(usize, usize)], rows: &'a [(usize, usize)],
) -> impl Render + 'a {
move |buf: &mut Buffer, area: Rect| {
match state.selected {
ArrangerFocus::Mix => if state.focused
&& state.entered
&& state.selected == ArrangerFocus::Mix
{
fill_bg(buf, area, Nord::bg_hi(state.focused, state.entered));
Corners(Style::default().green().not_dim()).draw(buf, area)
} else {
Ok(area)
},
ArrangerFocus::Track(t) => {
let area = Rect {
x: offset + area.x + cols[t].1 as u16 - 1,
y: area.y,
width: cols[t].0 as u16,
height: area.height
};
fill_bg(buf, area, Nord::bg_hi(state.focused, state.entered));
Corners(Style::default().green().not_dim()).draw(buf, area)
},
ArrangerFocus::Scene(s) => {
let area = Rect {
x: area.x,
y: 2 + area.y + (rows[s].1 / 96) as u16,
width: area.width,
height: (rows[s].0 / 96) as u16
};
fill_bg(buf, area, Nord::bg_hi(state.focused, state.entered));
Corners(Style::default().green().not_dim()).draw(buf, area)
},
ArrangerFocus::Clip(t, s) => {
let track_area = Rect {
x: offset + area.x + cols[t].1 as u16 - 1,
y: area.y,
width: cols[t].0 as u16,
height: area.height
};
let scene_area = Rect {
x: area.x,
y: 2 + area.y + (rows[s].1 / 96) as u16,
width: area.width,
height: (rows[s].0 / 96) as u16
};
let area = Rect {
x: offset + area.x + cols[t].1 as u16 - 1,
y: 2 + area.y + (rows[s].1 / 96) as u16,
width: cols[t].0 as u16,
height: (rows[s].0 / 96) as u16
};
let lo = Nord::bg_hi(state.focused, state.entered);
let hi = Nord::bg_hier(state.focused, state.entered);
fill_bg(buf, track_area, lo);
fill_bg(buf, scene_area, lo);
fill_bg(buf, area, hi);
Corners(Style::default().green().not_dim()).draw(buf, area)
},
}
}
}
pub fn tracks_header <'a> (
state: &'a Arranger,
track_cols: &'a [(usize, usize)],
offset: u16,
) -> impl Render + 'a {
move |buf: &mut Buffer, area: Rect| {
let Rect { y, width, .. } = area;
for (track, (_, x)) in state.tracks.iter().zip(track_cols) {
let x = *x as u16;
if x > width {
break
}
track.name.blit(buf, offset + x, y, Some(Style::default()))?;
}
Ok(Rect { x: area.x, y, width, height: 2 })
}
}
pub fn scene_rows <'a> (
state: &'a Arranger,
track_cols: &'a [(usize, usize)],
scene_rows: &'a [(usize, usize)],
offset: u16,
) -> impl Render + 'a {
move |buf: &mut Buffer, area: Rect| {
let black = Some(Style::default().fg(Nord::SEPARATOR));
let Rect { mut y, height, .. } = area;
for (_, x) in track_cols.iter() {
let x = *x as u16;
if x > 0 {
for y in area.y-2..y-2 {
"".blit(buf, x - 1, y, black)?;
}
}
}
for (scene, (pulses, _)) in state.scenes.iter().zip(scene_rows) {
if y > height {
break
}
let h = 1.max((pulses / 96) as u16);
scene_row(state, buf, Rect {
x: area.x,
y,
width: area.width,
height: h,//.min(area.height - y)
}, scene, track_cols, offset)?;
y = y + h
}
Ok(area)
}
}
fn scene_row (
state: &Arranger,
buf: &mut Buffer,
area: Rect,
scene: &Scene,
track_cols: &[(usize, usize)],
offset: u16
) -> Usually<u16> {
let Rect { y, width, .. } = area;
let tracks = state.tracks.as_ref();
let playing = scene.is_playing(tracks);
(if playing { "" } else { " " }).blit(buf, area.x, y, None)?;
scene.name.blit(buf, area.x + 1, y, None)?;
let style = Some(Style::default().white());
for (track, (w, x)) in track_cols.iter().enumerate() {
let x = *x as u16 + offset;
if x > width {
break
}
if let (Some(track), Some(Some(clip))) = (
tracks.get(track), scene.clips.get(track)
) {
if let Some(phrase) = track.phrases.get(*clip) {
let phrase = phrase.read().unwrap();
phrase.name.blit(buf, x, y, style)?;
if track.sequence == Some(*clip) {
fill_bg(buf, Rect {
x: x - 1,
y,
width: *w as u16,
height: area.height,
}, Nord::PLAYING);
}
}
}
}
Ok((scene.pulses(tracks) / 96) as u16)
}