diff --git a/demos/project.edn b/demos/project.edn index e47dcb2c..5cf6a21e 100644 --- a/demos/project.edn +++ b/demos/project.edn @@ -19,20 +19,25 @@ (:08 (36 128)) (:12 (36 100)) (:14 (36 110))) - (phrase { :name "D Beat" :beats 4 :steps 16 } - (:00 (36 128) (49 110)) - (:00 (44 50)) + (phrase { :name "D Beat" :beats 8 :steps 32 } + (:00 (44 70) (36 128) (49 110)) (:02 (44 30)) - (:04 (40 100)) - (:04 (44 80)) + (:04 (44 80) (40 100)) (:06 (44 50)) - (:08 (36 100)) - (:08 (44 30)) - (:10 (36 100)) - (:10 (44 50)) - (:12 (40 100)) - (:12 (44 80)) - (:14 (44 50))) + (:08 (44 30) (36 100)) + (:10 (44 50) (36 100)) + (:12 (44 80) (40 100)) + (:14 (44 50)) + (:15 (36 50)) + (:16 (44 60) (36 80)) + (:18 (44 60) (36 80)) + (:20 (44 60) (40 80)) + (:22 (44 60)) + (:24 (44 60)) + (:26 (44 30) (36 80)) + (:27 (44 60)) + (:28 (44 60) (40 80)) + (:30 (44 60))) (phrase { :name "Garage" :beats 4 :steps 16 } (:00 (44 100) (36 100) (35 100)) (:01 (44 100)) diff --git a/src/view/arranger.rs b/src/view/arranger.rs index c89147f4..6e7b9308 100644 --- a/src/view/arranger.rs +++ b/src/view/arranger.rs @@ -11,6 +11,8 @@ pub struct ArrangerView<'a> { vertical: bool, } +const HELP: &'static str = "[C-t] Add track [C-a] Add scene [v] Show/hide track"; + impl<'a> ArrangerView<'a> { pub fn new (app: &'a App, vertical: bool) -> Self { Self { @@ -35,7 +37,7 @@ impl<'a> ArrangerView<'a> { .map(|name|(name.len() as u16).max(10) + 3) .collect() } - fn bg_color (&self) -> Color { + fn bg_color_lo (&self) -> Color { if self.focused && self.entered { Color::Rgb(25, 60, 15) } else if self.focused { @@ -44,6 +46,15 @@ impl<'a> ArrangerView<'a> { Color::Reset } } + fn bg_color_hi (&self) -> Color { + if self.focused && self.entered { + Color::Rgb(30, 90, 25) + } else if self.focused { + Color::Rgb(25, 60, 15) + } else { + Color::Reset + } + } } impl<'a> Render for ArrangerView<'a> { @@ -53,85 +64,23 @@ impl<'a> Render for ArrangerView<'a> { } else { self.tracks.len() as u16 * 2 }); - fill_bg(buf, area, self.bg_color()); + fill_bg(buf, area, self.bg_color_lo()); area = if self.vertical { self.draw_vertical(buf, area) } else { self.draw_horizontal(buf, area) }?; - if self.focused && self.entered { - QuarterV(Style::default().green().dim()).draw(buf, area)?; + if self.focused { + //HELP.blit(buf, area.x + 2, area.y + area.height - 1, Some(Style::default().dim()))?; + if self.entered { + QuarterV(Style::default().green().dim()).draw(buf, area)?; + } } Ok(area) } } impl<'a> ArrangerView<'a> { - fn draw_vertical (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - area.height = self.scenes.len() as u16 + 3; - let Rect { x, y, width, height } = area; - let mut x2 = x; - let bg_color = self.bg_color(); - for (i, w) in self.track_widths().iter().enumerate() { - let focus_column = i == self.cursor.0; - if x2 >= x + width { - break - } - if focus_column { - let bg_area = Rect { x: x2, y, width: *w, height }; - fill_bg(buf, bg_area, bg_color); - } - x2 = x2 + w; - } - let (mut x2, y2) = (x, y); - let columns = self.track_names(); - for (i, title) in columns.iter().enumerate() { - let focus_column = i == self.cursor.0; - if x2 >= x + width { - break - } - let w = (title.len() as u16).max(10); - fill_bg( - buf, - Rect { x: x2, y: if self.cursor.1 == 0 { - y2 - } else { - y2 + 1 + self.cursor.1 as u16 - }, width: w + 3, height: 1 }, - bg_color - ); - if i == 0 { - self.vertical_scenes(buf, x2+1, y2+2, area.height)?; - } else if i < columns.len() { - self.vertical_clips(buf, x2+1, y2+2, area.height, i - 1)?; - }; - let style = Some(highlight(self.focused, focus_column).bold()); - if i > 0 { - "⏺".blit(buf, x2, y2, Some(if self.tracks[i-1].recording { - Style::default().red() - } else if self.tracks[i-1].monitoring { - Style::default().green() - } else { - Style::default().black() - }))?; - } - title.blit(buf, x2+2, y2, style)?; - x2 = x2 + w + 3; - } - fill_bg( - buf, - Rect { x: x2, y: if self.cursor.1 == 0 { - y2 - } else { - y2 + 1 + self.cursor.1 as u16 - }, width: width - x2, height: 1 }, - bg_color - ); - if self.focused { - HELP.blit(buf, x + 2, y + height - 1, Some(Style::default().dim()))?; - } - Ok(area) - } fn vertical_scenes (&self, buf: &mut Buffer, x: u16, y: u16, height: u16) -> Usually { let mut index = 0usize; @@ -145,7 +94,10 @@ impl<'a> ArrangerView<'a> { self.vertical_scene(buf, x, y + index as u16, index)?; index = index + 1; } - Ok(longest_scene_name(&self.scenes)) + Ok(self.scenes + .iter() + .map(|x|&x.name) + .fold(0, |x,y|x.max(y.len() as u16))) } fn vertical_scene (&self, buf: &mut Buffer, x: u16, y: u16, index: usize) -> Usually<()> { @@ -202,6 +154,73 @@ impl<'a> ArrangerView<'a> { 0u16 }) } + + fn draw_vertical (&self, buf: &mut Buffer, area: Rect) -> Usually { + let Rect { x, y, width, height } = area; + let mut x2 = x; + let bg_color = self.bg_color_hi(); + for (i, w) in self.track_widths().iter().enumerate() { + let focus_column = i == self.cursor.0; + if x2 >= x + width { + break + } + if focus_column { + let bg_area = Rect { x: x2, y, width: *w, height }; + fill_bg(buf, bg_area, bg_color); + } + x2 = x2 + w; + } + let (mut x2, y2) = (x, y); + let columns = self.track_names(); + for (i, title) in columns.iter().enumerate() { + let focus_column = i == self.cursor.0; + if x2 >= x + width { + break + } + let w = (title.len() as u16).max(10); + let bg_area = Rect { x: x2, y: if self.cursor.1 == 0 { + y2 + } else { + y2 + 1 + self.cursor.1 as u16 + }, width: w + 3, height: 1 }; + fill_bg(buf, bg_area, bg_color); + if i == 0 { + self.vertical_scenes(buf, x2+1, y2+2, area.height)?; + } else if i < columns.len() { + self.vertical_clips(buf, x2+1, y2+2, area.height, i - 1)?; + }; + let style = Some(highlight(self.focused, focus_column).bold()); + if i > 0 { + "⏺".blit(buf, x2, y2, Some(if self.tracks[i-1].recording { + Style::default().red() + } else if self.tracks[i-1].monitoring { + Style::default().yellow() + } else { + Style::default().black() + }))?; + } + title.blit(buf, x2+2, y2, style)?; + x2 = x2 + w + 3; + } + let bg_area = Rect { x: x2, y: if self.cursor.1 == 0 { + y2 + } else { + y2 + 1 + self.cursor.1 as u16 + }, width: width - x2, height: 1 }; + fill_bg(buf, bg_area, bg_color); + Ok(area) + } + + fn draw_vertical_2 (&self, buf: &mut Buffer, area: Rect) -> Usually { + Split::right([ + // Scene list + &|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()), + // Track columns + &|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()), + &|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()), + &|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()), + ]).render(buf, area) + } } impl<'a> ArrangerView<'a> { @@ -219,7 +238,7 @@ impl<'a> ArrangerView<'a> { let mut width = 0; for y in 0..area.height { if y == 0 { - "MIX".blit(buf, area.x, area.y + y, style1)?; + "MIX".blit(buf, area.x + 1, area.y + y, style1)?; } else if y % 2 == 1 { let index = y as usize / 2; if let Some(track) = self.tracks.get(index) { @@ -352,16 +371,23 @@ impl<'a> ArrangerView<'a> { &|buf: &mut Buffer, area: Rect|{ let mut x2 = 0; let Rect { x, y, height, .. } = area; - let sep = Some(Style::default().dim()); - for scene in self.scenes.iter() { + for (i, scene) in self.scenes.iter().enumerate() { + let active_scene = self.cursor.1 > 0 && self.cursor.1 - 1 == i; + let sep = Some(if active_scene { + Style::default().yellow().not_dim() + } else { + Style::default().dim() + }); "╷".blit(buf, x + x2, y, sep)?; for y in y+1..y+height-1 { "┊".blit(buf, x + x2, y, sep)?; } "╵".blit(buf, x + x2, y+height-1, sep)?; + let mut x3 = scene.name.len() as u16; - scene.name.blit(buf, x + x2, y, Some(Style::default().white().bold().not_dim()))?; + scene.name.blit(buf, x + x2, y, Some(Style::default().bold().not_dim()))?; for (i, clip) in scene.clips.iter().enumerate() { + let active_track = self.cursor.0 > 0 && self.cursor.0 - 1 == i; if let Some(clip) = clip { let y2 = y + 1 + i as u16 * 2; let label = format!("{}", if let Some(phrase) = self.tracks[i].phrases.get(*clip) { @@ -369,7 +395,11 @@ impl<'a> ArrangerView<'a> { } else { "...." }); - label.blit(buf, x + x2, y2, Some(Style::default().white().not_dim()))?; + label.blit(buf, x + x2, y2, Some(if active_track && active_scene { + Style::default().not_dim().yellow().bold() + } else { + Style::default().not_dim() + }))?; x3 = x3.max(label.len() as u16) } } @@ -383,27 +413,18 @@ impl<'a> ArrangerView<'a> { } } -const HELP: &'static str = "[C-t] Add track [C-a] Add scene [v] Show/hide track"; - fn highlight (focused: bool, highlight: bool) -> Style { if highlight { if focused { - Style::default().green().not_dim() + Style::default().yellow().not_dim() } else { - Style::default().green().dim() + Style::default().yellow().dim() } } else { Style::default() } } -fn longest_scene_name (scenes: &[Scene]) -> u16 { - let mut w = 3u16; - for scene in scenes.iter() { - w = w.max(scene.name.len() as u16); - } - w -} //use crate::core::*; //use crate::view::*; //use crate::model::*;