diff --git a/src/core/render.rs b/src/core/render.rs index b3db7454..3e0576fa 100644 --- a/src/core/render.rs +++ b/src/core/render.rs @@ -24,6 +24,12 @@ pub fn fill_fg (buf: &mut Buffer, area: Rect, color: Color) { pub fn fill_bg (buf: &mut Buffer, area: Rect, color: Color) { buffer_update(buf, area, &|cell,_,_|{cell.set_bg(color);}) } +pub fn to_fill_bg (color: Color) -> impl Render { + move |buf: &mut Buffer, area: Rect|{ + fill_bg(buf, area, color); + Ok(area) + } +} pub fn fill_char (buf: &mut Buffer, area: Rect, c: char) { buffer_update(buf, area, &|cell,_,_|{cell.set_char(c);}) } diff --git a/src/devices/arranger.rs b/src/devices/arranger.rs index ed0d76b1..53a563fa 100644 --- a/src/devices/arranger.rs +++ b/src/devices/arranger.rs @@ -156,105 +156,107 @@ mod draw_vertical { ) -> Usually { area.height = 2 + (rows[rows.len() - 1].1 / 96) as u16; let offset = 3 + scene_name_max_len(state.scenes.as_ref()) as u16; - column_separators(buf, area, offset, cols)?; - fill_bg(buf, area, Nord::bg_lo(state.focused, state.entered)); - cursor_focus(state, buf, area, offset, cols, rows)?; - Split::down([ - &tracks_header(state, cols, offset), - &scene_rows(state, cols, rows, offset), - ]).render(buf, area)?; - row_separators(buf, area, rows); - Ok(area) + 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 ( - buf: &mut Buffer, area: Rect, offset: u16, cols: &[(usize, usize)] - ) -> Usually<()> { - let style = Some(Style::default().fg(Color::Rgb(0,0,0))); - 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(()) - } - - fn row_separators (buf: &mut Buffer, area: Rect, rows: &[(usize, usize)]) { - for (_, y) in rows.iter() { - let y = area.y + (*y / 96) as u16 + 1; - for x in area.x..area.width+area.y-2 { - let cell = buf.get_mut(x, y); - cell.modifier = Modifier::UNDERLINED; - cell.underline_color = Color::Rgb(0, 0, 0); + 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(Color::Rgb(0,0,0))); + 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 cursor_focus ( - state: &Arranger, - buf: &mut Buffer, - area: Rect, - offset: u16, - cols: &[(usize, usize)], - rows: &[(usize, usize)], - ) -> Usually<()> { - 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)?; - }, - 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)?; - }, - }; - Ok(()) + 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; + for x in area.x..area.width+area.y-2 { + let cell = buf.get_mut(x, y); + cell.modifier = Modifier::UNDERLINED; + cell.underline_color = Color::Rgb(0, 0, 0); + } + } + 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> ( diff --git a/src/view/split.rs b/src/view/split.rs index fa318923..e711ec9e 100644 --- a/src/view/split.rs +++ b/src/view/split.rs @@ -1,5 +1,16 @@ use crate::{core::*, view::*}; +pub struct Layered<'a, const N: usize>(pub [&'a (dyn Render + Sync); N]); + +impl<'a, const N: usize> Render for Layered<'a, N> { + fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { + for layer in self.0.iter() { + layer.render(buf, area)?; + } + Ok(area) + } +} + pub struct If<'a>(pub bool, pub &'a (dyn Render + Sync)); impl<'a> Render for If<'a> {