From 5d7347137b7b408ec47a440c489310c31b8b27c5 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 20 Jul 2024 16:15:28 +0300 Subject: [PATCH] return impl Render --- src/devices/arranger.rs | 330 ++++++++++++++++++++++------------------ src/view/border.rs | 2 +- 2 files changed, 179 insertions(+), 153 deletions(-) diff --git a/src/devices/arranger.rs b/src/devices/arranger.rs index d80b92b7..ed0d76b1 100644 --- a/src/devices/arranger.rs +++ b/src/devices/arranger.rs @@ -75,7 +75,7 @@ pub struct Arranger { } /// Display mode of arranger -enum ArrangerViewMode { +pub enum ArrangerViewMode { Vertical, VerticalCompact, Horizontal, @@ -132,44 +132,86 @@ render!(Arranger |self, buf, area| match self.mode { }); mod draw_vertical { - use crate::{core::*, view::*, model::Track}; + use crate::{core::*, view::*}; use super::{Arranger, focus::ArrangerFocus, track::track_clip_name_lengths, scene::{Scene, scene_ppqs, scene_name_max_len}}; pub fn draw_expanded (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually { + 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, scene_rows.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 { + let track_cols = track_clip_name_lengths(state.tracks.as_slice()); let scene_rows = (0..=state.scenes.len()).map(|i|(96, 96*(i+1))).collect::>(); - draw(state, buf, area, scene_rows.as_slice()) + draw(state, buf, area, track_cols.as_slice(), scene_rows.as_slice()) } pub fn draw ( - state: &Arranger, buf: &mut Buffer, mut area: Rect, scene_rows: &[(usize, usize)] + state: &Arranger, + buf: &mut Buffer, + mut area: Rect, + cols: &[(usize, usize)], + rows: &[(usize, usize)], ) -> Usually { - let track_cols = track_clip_name_lengths(state.tracks.as_slice()); - area.height = 2 + (scene_rows[scene_rows.len() - 1].1 / 96) as u16; + 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) + } + + 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 track_cols.iter() { + 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(()) + } - fill_bg(buf, area, Nord::bg_lo(state.focused, state.entered)); + 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 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 { + 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 + track_cols[t].1 as u16 - 1, + x: offset + area.x + cols[t].1 as u16 - 1, y: area.y, - width: track_cols[t].0 as u16, + width: cols[t].0 as u16, height: area.height }; fill_bg(buf, area, Nord::bg_hi(state.focused, state.entered)); @@ -178,31 +220,31 @@ mod draw_vertical { ArrangerFocus::Scene(s) => { let area = Rect { x: area.x, - y: 2 + area.y + (scene_rows[s].1 / 96) as u16, + y: 2 + area.y + (rows[s].1 / 96) as u16, width: area.width, - height: (scene_rows[s].0 / 96) as u16 + 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 + track_cols[t].1 as u16 - 1, + x: offset + area.x + cols[t].1 as u16 - 1, y: area.y, - width: track_cols[t].0 as u16, + width: cols[t].0 as u16, height: area.height }; let scene_area = Rect { x: area.x, - y: 2 + area.y + (scene_rows[s].1 / 96) as u16, + y: 2 + area.y + (rows[s].1 / 96) as u16, width: area.width, - height: (scene_rows[s].0 / 96) as u16 + height: (rows[s].0 / 96) as u16 }; let area = Rect { - x: offset + area.x + track_cols[t].1 as u16 - 1, - y: 2 + area.y + (scene_rows[s].1 / 96) as u16, - width: track_cols[t].0 as u16, - height: (scene_rows[s].0 / 96) as u16 + 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); @@ -211,37 +253,18 @@ mod draw_vertical { fill_bg(buf, area, hi); Corners(Style::default().green().not_dim()).draw(buf, area)?; }, - } - - Split::down([ - &|buf: &mut Buffer, area: Rect|state.draw_tracks_header( - buf, area, track_cols.as_slice(), offset), - &|buf: &mut Buffer, area: Rect|state.draw_scene_rows( - buf, area, track_cols.as_slice(), scene_rows, offset), - ]).render(buf, area)?; - for (_, y) in scene_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) + }; + Ok(()) } - /// Rendering with vertical time - impl Arranger { - - pub fn draw_tracks_header ( - &self, - buf: &mut Buffer, - area: Rect, - track_cols: &[(usize, usize)], - offset: u16, - ) -> Usually { + 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 self.tracks.iter().zip(track_cols) { + for (track, (_, x)) in state.tracks.iter().zip(track_cols) { let x = *x as u16; if x > width { break @@ -250,15 +273,15 @@ mod draw_vertical { } Ok(Rect { x: area.x, y, width, height: 2 }) } + } - pub fn draw_scene_rows ( - &self, - buf: &mut Buffer, - area: Rect, - track_cols: &[(usize, usize)], - scene_rows: &[(usize, usize)], - offset: u16, - ) -> Usually { + 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(Color::Rgb(0, 0, 0))); let Rect { mut y, height, .. } = area; for (_, x) in track_cols.iter() { @@ -269,58 +292,56 @@ mod draw_vertical { } } } - for (scene, (pulses, _)) in self.scenes.iter().zip(scene_rows) { + for (scene, (pulses, _)) in state.scenes.iter().zip(scene_rows) { if y > height { break } let h = (pulses / 96) as u16; let area = Rect { x: area.x, y, width: area.width, height: h.min(area.height - y) }; - self.draw_scene_row(buf, area, scene, track_cols, offset)?; + scene_row(state, buf, area, scene, track_cols, offset)?; y = y + h } Ok(area) } + } - fn draw_scene_row ( - &self, - buf: &mut Buffer, - area: Rect, - scene: &Scene, - track_cols: &[(usize, usize)], - offset: u16 - ) -> Usually { - let Rect { y, width, .. } = area; - let tracks = self.tracks.as_ref(); - let playing = scene.is_playing(self.tracks.as_ref()); - (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 - } - let tracks: &[Track] = self.tracks.as_ref(); - 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, - }, Color::Rgb(40,80,50)); - } + fn scene_row ( + state: &Arranger, + buf: &mut Buffer, + area: Rect, + scene: &Scene, + track_cols: &[(usize, usize)], + offset: u16 + ) -> Usually { + 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, + }, Color::Rgb(40,80,50)); } } } - Ok((scene.pulses(tracks) / 96) as u16) } - + Ok((scene.pulses(tracks) / 96) as u16) } } @@ -328,40 +349,36 @@ mod draw_horizontal { use crate::{core::*, view::*}; use super::{Arranger, track::*}; - pub fn draw (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually { + pub fn draw (state: &Arranger, buf: &mut Buffer, mut area: Rect) -> Usually { + area.height = area.height.min((2 + state.tracks.len() * 2) as u16); let area = Split::right([ - // Track name - &|buf: &mut Buffer, area: Rect|state.draw_track_name_column(buf, area), - &|buf: &mut Buffer, area: Rect|state.draw_track_mon_column(buf, area), - &|buf: &mut Buffer, area: Rect|state.draw_track_rec_column(buf, area), - &|buf: &mut Buffer, area: Rect|state.draw_track_ovr_column(buf, area), - &|buf: &mut Buffer, area: Rect|state.draw_track_del_column(buf, area), - &|buf: &mut Buffer, area: Rect|state.draw_track_gain_column(buf, area), - &|buf: &mut Buffer, area: Rect|state.draw_track_scenes_column(buf, area), + &track_name_column(state), + &track_mon_column(state), + &track_rec_column(state), + &track_ovr_column(state), + &track_del_column(state), + &track_gain_column(state), + &track_scenes_column(state), ]).render(buf, area)?; fill_bg(buf, area, Nord::bg_lo(state.focused, state.entered)); Ok(area) } - /// Rendering with horizontal time - impl Arranger { - pub fn draw_track_name_column (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - area.width = 3 + 5.max(track_name_max_len(self.tracks.as_slice())) as u16; - let dim = Some(Style::default().dim()); - let yellow = Some(Style::default().yellow().bold().not_dim()); - let white = Some(Style::default().white().bold().not_dim()); + fn track_name_column <'a> (state: &'a Arranger) -> impl Render + 'a { + let dim = Some(Style::default().dim()); + let yellow = Some(Style::default().yellow().bold().not_dim()); + let white = Some(Style::default().white().bold().not_dim()); + move |buf: &mut Buffer, mut area: Rect| { + area.width = 3 + 5.max(track_name_max_len(state.tracks.as_slice())) as u16; let offset = 0; // track scroll offset for y in 0..area.height { if y == 0 { "Mixer".blit(buf, area.x + 1, area.y + y, dim)?; } else if y % 2 == 0 { let index = (y as usize - 2) / 2 + offset; - if let Some(track) = self.tracks.get(index) { - let style = if self.selected.track() == Some(index) { - yellow - } else { - white - }; + if let Some(track) = state.tracks.get(index) { + let selected = state.selected.track() == Some(index); + let style = if selected { yellow } else { white }; format!(" {index:>02} ").blit(buf, area.x, area.y + y, style)?; track.name.blit(buf, area.x + 4, area.y + y, style)?; } @@ -369,21 +386,21 @@ mod draw_horizontal { } Ok(area) } + } - pub fn draw_track_mon_column (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - let style4 = Some(Style::default().dim()); + fn track_mon_column <'a> (state: &'a Arranger) -> impl Render + 'a { + let on = Some(Style::default().not_dim().green().bold()); + let off = Some(Style::default().dim()); + move |buf: &mut Buffer, mut area: Rect| { area.x = area.x + 1; for y in 0..area.height { if y == 0 { //" MON ".blit(buf, area.x, area.y + y, style2)?; } else if y % 2 == 0 { let index = (y as usize - 2) / 2; - if let Some(track) = self.tracks.get(index) { - " MON ".blit(buf, area.x, area.y + y, if track.monitoring { - Some(Style::default().not_dim().green().bold()) - } else { - style4 - })?; + if let Some(track) = state.tracks.get(index) { + let style = if track.monitoring { on } else { off }; + " MON ".blit(buf, area.x, area.y + y, style)?; } else { area.height = y; break @@ -393,21 +410,21 @@ mod draw_horizontal { area.width = 4; Ok(area) } + } - pub fn draw_track_rec_column (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - let style4 = Some(Style::default().dim()); + fn track_rec_column <'a> (state: &'a Arranger) -> impl Render + 'a { + let on = Some(Style::default().not_dim().red().bold()); + let off = Some(Style::default().dim()); + move |buf: &mut Buffer, mut area: Rect| { area.x = area.x + 1; for y in 0..area.height { if y == 0 { //" REC ".blit(buf, area.x, area.y + y, style2)?; } else if y % 2 == 0 { let index = (y as usize - 2) / 2; - if let Some(track) = self.tracks.get(index) { - " REC ".blit(buf, area.x, area.y + y, if track.recording { - Some(Style::default().not_dim().red().bold()) - } else { - style4 - })?; + if let Some(track) = state.tracks.get(index) { + let style = if track.recording { on } else { off }; + " REC ".blit(buf, area.x, area.y + y, style)?; } else { area.height = y; break @@ -417,20 +434,23 @@ mod draw_horizontal { area.width = 4; Ok(area) } + } - pub fn draw_track_ovr_column (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - let style4 = Some(Style::default().dim()); + fn track_ovr_column <'a> (state: &'a Arranger) -> impl Render + 'a { + let on = Some(Style::default().not_dim().yellow().bold()); + let off = Some(Style::default().dim()); + move |buf: &mut Buffer, mut area: Rect| { area.x = area.x + 1; for y in 0..area.height { if y == 0 { //" OVR ".blit(buf, area.x, area.y + y, style2)?; } else if y % 2 == 0 { let index = (y as usize - 2) / 2; - if let Some(track) = self.tracks.get(index) { + if let Some(track) = state.tracks.get(index) { " OVR ".blit(buf, area.x, area.y + y, if track.overdub { - Some(Style::default().not_dim().yellow().bold()) + on } else { - style4 + off })?; } else { area.height = y; @@ -441,17 +461,19 @@ mod draw_horizontal { area.width = 4; Ok(area) } + } - pub fn draw_track_del_column (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - let style4 = Some(Style::default().dim()); + fn track_del_column <'a> (state: &'a Arranger) -> impl Render + 'a { + let off = Some(Style::default().dim()); + move |buf: &mut Buffer, mut area: Rect| { area.x = area.x + 1; for y in 0..area.height { if y == 0 { //" DEL ".blit(buf, area.x, area.y + y, style2)?; } else if y % 2 == 0 { let index = (y as usize - 2) / 2; - if let Some(_) = self.tracks.get(index) { - " DEL ".blit(buf, area.x, area.y + y, style4)?; + if let Some(_) = state.tracks.get(index) { + " DEL ".blit(buf, area.x, area.y + y, off)?; } else { area.height = y; break @@ -461,17 +483,19 @@ mod draw_horizontal { area.width = 4; Ok(area) } + } - pub fn draw_track_gain_column (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - let style4 = Some(Style::default().dim()); + fn track_gain_column <'a> (state: &'a Arranger) -> impl Render + 'a { + let off = Some(Style::default().dim()); + move |buf: &mut Buffer, mut area: Rect| { area.x = area.x + 1; for y in 0..area.height { if y == 0 { //" GAIN ".blit(buf, area.x, area.y + y, style2)?; } else if y % 2 == 0 { let index = (y as usize - 2) / 2; - if let Some(_) = self.tracks.get(index) { - " +0.0 ".blit(buf, area.x, area.y + y, style4)?; + if let Some(_) = state.tracks.get(index) { + " +0.0 ".blit(buf, area.x, area.y + y, off)?; } else { area.height = y; break @@ -481,12 +505,14 @@ mod draw_horizontal { area.width = 7; Ok(area) } + } - pub fn draw_track_scenes_column (&self, buf: &mut Buffer, area: Rect) -> Usually { + fn track_scenes_column <'a> (state: &'a Arranger) -> impl Render + 'a { + |buf: &mut Buffer, area: Rect| { let mut x2 = 0; let Rect { x, y, height, .. } = area; - for (scene_index, scene) in self.scenes.iter().enumerate() { - let active_scene = self.selected.scene() == Some(scene_index); + for (scene_index, scene) in state.scenes.iter().enumerate() { + let active_scene = state.selected.scene() == Some(scene_index); let sep = Some(if active_scene { Style::default().yellow().not_dim() } else { @@ -498,10 +524,10 @@ mod draw_horizontal { let mut x3 = scene.name.len() as u16; scene.name.blit(buf, x + x2, y, sep)?; for (i, clip) in scene.clips.iter().enumerate() { - let active_track = self.selected.track() == Some(i); + let active_track = state.selected.track() == Some(i); if let Some(clip) = clip { let y2 = y + 2 + i as u16 * 2; - let label = match self.tracks[i].phrases.get(*clip) { + let label = match state.tracks[i].phrases.get(*clip) { Some(phrase) => &format!("{}", phrase.read().unwrap().name), None => "...." }; diff --git a/src/view/border.rs b/src/view/border.rs index 51262214..c33c90dd 100644 --- a/src/view/border.rs +++ b/src/view/border.rs @@ -151,7 +151,7 @@ border! { } }, Corners { - "🬆" "" "🬊" + "🬆" "" "🬊" // 🬴 🬸 "" "" "🬱" "" "🬵" fn style (&self) -> Option