wip: borrow checker battles

This commit is contained in:
🪞👃🪞 2024-09-04 16:57:48 +03:00
parent 1d4db3c629
commit 7fbb40fad6
38 changed files with 778 additions and 708 deletions

View file

@ -1,33 +1,39 @@
use crate::*;
/// Draw arranger with 1 row per scene.
pub fn draw_compact_1 (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
pub fn draw_compact_1 <'a> (
state: &Arranger<TuiOutput<'a>, Rect>, to: &mut TuiOutput<'a>
) -> Perhaps<Rect> {
let track_cols = track_clip_name_lengths(state.tracks.as_slice());
let scene_rows = (0..=state.scenes.len()).map(|i|(96, 96*i)).collect::<Vec<_>>();
draw(state, buf, area, track_cols.as_slice(), scene_rows.as_slice())
draw(state, to, track_cols.as_slice(), scene_rows.as_slice())
}
/// Draw arranger with 2 rows per scene.
pub fn draw_compact_2 (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
pub fn draw_compact_2 <'a> (
state: &Arranger<TuiOutput<'a>, Rect>, to: &mut TuiOutput<'a>
) -> Perhaps<Rect> {
let track_cols = track_clip_name_lengths(state.tracks.as_slice());
let scene_rows = (0..=state.scenes.len()).map(|i|(192, 192*i)).collect::<Vec<_>>();
draw(state, buf, area, track_cols.as_slice(), scene_rows.as_slice())
draw(state, to, track_cols.as_slice(), scene_rows.as_slice())
}
/// Draw arranger with number of rows per scene proportional to duration of scene.
pub fn draw_expanded (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
pub fn draw_expanded <'a> (
state: &Arranger<TuiOutput<'a>, Rect>, to: &mut TuiOutput<'a>
) -> Perhaps<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())
draw(state, to, 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> {
pub fn draw <'a, 'b> (
state: &Arranger<TuiOutput<'a>, Rect>,
to: &mut TuiOutput<'a>,
cols: &'b [(usize, usize)],
rows: &'b [(usize, usize)],
) -> Perhaps<Rect> {
let mut area = to.area;
area.height = 2 + (rows[rows.len() - 1].1 / 96) as u16;
let offset = 3 + scene_name_max_len(state.scenes.as_ref()) as u16;
let tracks = state.tracks.as_ref();
@ -40,42 +46,44 @@ pub fn draw (
.add_ref(&Split::down()
.add_ref(&TracksHeader(offset, cols, tracks))
.add_ref(&SceneRows(offset, cols, rows, tracks, scenes)))
.render(buf, area)
.render(to)
}
struct ColumnSeparators<'a>(u16, &'a [(usize, usize)]);
impl<'a> Render for ColumnSeparators<'a> {
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for ColumnSeparators<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let area = to.area;
let Self(offset, cols) = self;
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)?;
"".blit(to.buffer, x, y, style)?;
}
}
Ok(area)
Ok(Some(area))
}
}
struct RowSeparators<'a>(&'a [(usize, usize)]);
impl<'a> Render for RowSeparators<'a> {
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for RowSeparators<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let mut area = to.area;
let Self(rows) = self;
for (_, y) in rows.iter() {
let y = area.y + (*y / 96) as u16 + 1;
if y >= buf.area.height {
if y >= to.buffer.area.height {
break
}
for x in area.x..area.width+area.y-2 {
let cell = buf.get_mut(x, y);
let cell = to.buffer.get_mut(x, y);
cell.modifier = Modifier::UNDERLINED;
cell.underline_color = Nord::SEPARATOR;
}
}
Ok(area)
Ok(Some(area))
}
}
@ -83,8 +91,9 @@ struct CursorFocus<'a>(
ArrangerFocus, u16, &'a [(usize, usize)], &'a [(usize, usize)]
);
impl<'a> Render for CursorFocus<'a> {
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for CursorFocus<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let mut area = to.area;
let Self(selected, offset, cols, rows) = *self;
let get_track_area = |t: usize| Rect {
x: offset + area.x + cols[t].1 as u16 - 1,
@ -109,7 +118,7 @@ impl<'a> Render for CursorFocus<'a> {
let mut clip_area: Option<Rect> = None;
let area = match selected {
ArrangerFocus::Mix => {
fill_bg(buf, area, COLOR_BG0);
fill_bg(to.buffer, area, COLOR_BG0);
area
},
ArrangerFocus::Track(t) => {
@ -128,19 +137,19 @@ impl<'a> Render for CursorFocus<'a> {
},
};
if let Some(Rect { x, y, width, height }) = track_area {
fill_fg(buf, Rect { x, y, width: 1, height }, COLOR_BG5);
fill_fg(buf, Rect { x: x + width, y, width: 1, height }, COLOR_BG5);
fill_fg(to.buffer, Rect { x, y, width: 1, height }, COLOR_BG5);
fill_fg(to.buffer, Rect { x: x + width, y, width: 1, height }, COLOR_BG5);
}
if let Some(Rect { y, height, .. }) = scene_area {
fill_ul(buf, Rect { x: area.x, y: y - 1, width: area.width, height: 1 }, COLOR_BG5);
fill_ul(buf, Rect { x: area.x, y: y + height - 1, width: area.width, height: 1 }, COLOR_BG5);
fill_ul(to.buffer, Rect { x: area.x, y: y - 1, width: area.width, height: 1 }, COLOR_BG5);
fill_ul(to.buffer, Rect { x: area.x, y: y + height - 1, width: area.width, height: 1 }, COLOR_BG5);
}
if let Some(clip_area) = clip_area {
fill_bg(buf, clip_area, COLOR_BG0);
fill_bg(to.buffer, clip_area, COLOR_BG0);
} else if let Some(track_area) = track_area {
fill_bg(buf, track_area, COLOR_BG0);
fill_bg(to.buffer, track_area, COLOR_BG0);
} else if let Some(scene_area) = scene_area {
fill_bg(buf, scene_area, COLOR_BG0);
fill_bg(to.buffer, scene_area, COLOR_BG0);
}
Ok(area)
}
@ -148,8 +157,9 @@ impl<'a> Render for CursorFocus<'a> {
struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer]);
impl<'a> Render for TracksHeader<'a> {
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for TracksHeader<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let mut area = to.area;
let Self(offset, track_cols, tracks) = *self;
let Rect { y, width, .. } = area;
for (track, (w, x)) in tracks.iter().zip(track_cols) {
@ -158,17 +168,18 @@ impl<'a> Render for TracksHeader<'a> {
break
}
let name = track.name.read().unwrap();
fill_bg(buf, Rect { x: offset + x, y, width: *w as u16, height: 2 }, COLOR_BG1);
name.blit(buf, offset + x + 1, y, Some(Style::default().white()))?;
fill_bg(to.buffer, Rect { x: offset + x, y, width: *w as u16, height: 2 }, COLOR_BG1);
name.blit(to.buffer, offset + x + 1, y, Some(Style::default().white()))?;
}
Ok(Rect { x: area.x, y, width, height: 2 })
Ok(Some(Rect { x: area.x, y, width, height: 2 }))
}
}
struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequencer], &'a[Scene]);
impl<'a> Render for SceneRows<'a> {
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for SceneRows<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let area = to.area;
let Self(offset, track_cols, scene_rows, tracks, scenes) = *self;
let black = Some(Style::default().fg(Nord::SEPARATOR));
let Rect { mut y, height, .. } = area;
@ -176,7 +187,7 @@ impl<'a> Render for SceneRows<'a> {
let x = *x as u16;
if x > 0 {
for y in area.y-2..y-2 {
"".blit(buf, x - 1, y, black)?;
"".blit(to.buffer, x - 1, y, black)?;
}
}
}
@ -185,28 +196,27 @@ impl<'a> Render for SceneRows<'a> {
//break
//}
let h = 1.max((pulses / 96) as u16);
SceneRow(tracks, scene, track_cols, offset).render(buf, Rect {
x: area.x,
y,
width: area.width,
height: h,//.min(area.height - y)
SceneRow(tracks, scene, track_cols, offset).render(&mut TuiOutput {
buffer: to.buffer,
area: Rect { x: area.x, y, width: area.width, height: h, }
})?;
y = y + h
}
Ok(area)
Ok(Some(area))
}
}
struct SceneRow<'a>(&'a[Sequencer], &'a Scene, &'a[(usize, usize)], u16);
impl<'a> Render for SceneRow<'a> {
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for SceneRow<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let mut area = to.area;
let Self(tracks, scene, track_cols, offset) = self;
let Rect { x, y, width, .. } = area;
let playing = scene.is_playing(tracks);
(if playing { "" } else { " " }).blit(buf, x, y, None)?;
scene.name.read().unwrap().blit(buf, x + 1, y, Some(Style::default().white()))?;
fill_bg(buf, Rect { x: x, y, width: offset.saturating_sub(1), height: area.height }, COLOR_BG1);
(if playing { "" } else { " " }).blit(to.buffer, x, y, None)?;
scene.name.read().unwrap().blit(to.buffer, x + 1, y, Some(Style::default().white()))?;
fill_bg(to.buffer, Rect { x: x, y, width: offset.saturating_sub(1), height: area.height }, COLOR_BG1);
for (track, (w, x)) in track_cols.iter().enumerate() {
let x = *x as u16 + offset;
@ -217,33 +227,36 @@ impl<'a> Render for SceneRow<'a> {
if let (Some(track), Some(Some(clip))) = (
tracks.get(track), scene.clips.get(track)
) {
let area = Rect { x, y, width: *w as u16, height: area.height, };
SceneClip(track, *clip).render(buf, area)?;
SceneClip(track, *clip).render(&mut TuiOutput {
buffer: to.buffer,
area: Rect { x, y, width: *w as u16, height: area.height, }
})?;
}
}
Ok(area)
Ok(Some(area))
}
}
struct SceneClip<'a>(&'a Sequencer, usize);
impl<'a> Render for SceneClip<'a> {
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for SceneClip<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let area = to.area;
let Self(track, clip) = self;
let style = Some(Style::default().white());
if let Some(phrase) = track.phrases.get(*clip) {
let phrase = phrase.read().unwrap();
let name = phrase.name.read().unwrap();
format!("{clip:02} {name}").blit(buf, area.x + 1, area.y, style)?;
fill_bg(buf, area, if track.sequence == Some(*clip) {
format!("{clip:02} {name}").blit(to.buffer, area.x + 1, area.y, style)?;
fill_bg(to.buffer, area, if track.sequence == Some(*clip) {
Nord::PLAYING
} else {
COLOR_BG1
});
} else {
fill_bg(buf, area, COLOR_BG0)
fill_bg(to.buffer, area, COLOR_BG0)
}
Ok(area)
Ok(Some(area))
}
}