diff --git a/src/view.rs b/src/view.rs index 44fb36f2..12913c89 100644 --- a/src/view.rs +++ b/src/view.rs @@ -20,94 +20,46 @@ render!(App |self, buf, area| { let Rect { x, y, width, height } = area; let transport = TransportView::new(self).render(buf, area)?; let y = y + transport.height; - let arranger = if self.arranger_mode { - self.draw_arranger_horizontal(buf, Rect { - x, y, width, height: height / 3 - })? + let arranger = Rect { x, y, width, height }; + let arranger = ArrangerView::new(&self, !self.arranger_mode).render(buf, arranger)?; + let style_entered = if self.entered { + Style::default().green() } else { - self.draw_arranger_vertical(buf, Rect { - x, y, width, height: height / 3 - })? + Style::default().green().dim() }; if self.section == AppSection::Arranger { - QuarterV(if self.entered { - Style::default().green() - } else { - Style::default().green().dim() - }).draw(buf, arranger) + QuarterV(style_entered).draw(buf, arranger) } let y = y + arranger.height; if self.track_cursor > 0 { - let chain = ChainView::new(&self, false).render(buf, Rect { - x, y: y + height - height / 3 - 1, width, height: height / 3 - })?; + let chain = Rect { x, y: y + height - height / 3 - 1, width, height: height / 3 }; + let chain = ChainView::new(&self, false).render(buf, chain)?; if self.section == AppSection::Chain { - QuarterV(if self.entered { - Style::default().green() - } else { - Style::default().green().dim() - }).draw(buf, Rect { width, ..chain }) + QuarterV(style_entered).draw(buf, Rect { width, ..chain }) } - let phrase = SequencerView::new(&self).render(buf, Rect { - x, y, width, height: height - height / 3 - })?; + let phrase = Rect { x, y, width, height: height - height / 3 }; + let phrase = SequencerView::new(&self).render(buf, phrase)?; if self.section == AppSection::Sequencer { - QuarterV(if self.entered { - Style::default().green() - } else { - Style::default().green().dim() - }).draw(buf, phrase) + QuarterV(style_entered).draw(buf, phrase) } - chain } else { - self.draw_mixer(buf, Rect { - x, y, width, height - })? + let area = Rect { x, y, width, height }; + let mut x = area.x; + for track in self.tracks.iter() { + track.name.blit(buf, x + 1, area.y, Some(Style::default().white().bold())); + let chain = Rect { x, y: area.y + 1, width: width, height: height - y - 1 }; + x = x + ChainView { + focused: self.section == AppSection::Chain, + track: Some(track), + vertical: true, + } + .render(buf, chain)? + .width + .max(track.name.len() as u16); + } }; if let Some(ref modal) = self.modal { modal.render(buf, area)?; } Ok(area) }); - -impl App { - fn draw_mixer (&self, buf: &mut Buffer, area: Rect) -> Usually { - let mut x = area.x; - for track in self.tracks.iter() { - track.name.blit(buf, x + 1, area.y, Some(Style::default().white().bold())); - x = x + ChainView { - focused: self.section == AppSection::Chain, - track: Some(track), - vertical: true, - } - .render(buf, Rect { - x, y: area.y + 1, width: area.width, height: area.height - area.y - 1 - })? - .width - .max(track.name.len() as u16); - } - Ok(area) - } - fn draw_arranger_horizontal (&self, buf: &mut Buffer, area: Rect) -> Usually { - ArrangerViewHorizontal { - buf, - area, - focused: self.section == AppSection::Arranger, - entered: self.entered, - scenes: &self.scenes, - tracks: &self.tracks, - cursor: &(self.track_cursor, self.scene_cursor), - }.draw() - } - fn draw_arranger_vertical (&self, buf: &mut Buffer, area: Rect) -> Usually { - ArrangerViewVertical { - buf, - area, - focused: self.section == AppSection::Arranger, - entered: self.entered, - scenes: &self.scenes, - tracks: &self.tracks, - cursor: &(self.track_cursor, self.scene_cursor), - }.draw() - } -} diff --git a/src/view/arranger.rs b/src/view/arranger.rs index f899037c..e196a35e 100644 --- a/src/view/arranger.rs +++ b/src/view/arranger.rs @@ -1,24 +1,58 @@ use crate::core::*; use crate::model::*; use crate::view::*; -pub struct ArrangerViewVertical<'a> { - pub buf: &'a mut Buffer, - pub area: Rect, - pub scenes: &'a[Scene], - pub tracks: &'a[Track], - pub cursor: &'a(usize, usize), - pub focused: bool, - pub entered: bool, + +pub struct ArrangerView<'a> { + pub scenes: &'a[Scene], + pub tracks: &'a[Track], + pub cursor: (usize, usize), + pub focused: bool, + pub entered: bool, + pub vertical: bool, } -impl<'a> ArrangerViewVertical<'a> { - pub fn size (&self) -> (u16, u16) { - unimplemented!(); + +impl<'a> ArrangerView<'a> { + pub fn new (app: &'a App, vertical: bool) -> Self { + Self { + focused: app.section == AppSection::Arranger, + entered: app.entered, + scenes: &app.scenes, + tracks: &app.tracks, + cursor: (app.track_cursor, app.scene_cursor), + vertical + } } - pub fn draw (&mut self) -> Usually { - self.area.height = self.scenes.len() as u16 + 3; - let Rect { x, y, width, height } = self.area; + fn track_names (&self) -> Vec<&'a str> { + let mut track_names = vec!["Mix"]; + for track in self.tracks.iter() { + track_names.push(track.name.as_str()); + } + track_names + } + fn track_widths (&self) -> Vec { + self.track_names() + .iter() + .map(|name|(name.len() as u16).max(10) + 3) + .collect() + } +} + +impl<'a> Render for ArrangerView<'a> { + fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { + if self.vertical { + self.draw_vertical(buf, area) + } else { + self.draw_horizontal(buf, 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 style = Some(Style::default().green().dim()); - fill_bg(&mut self.buf, self.area, if self.focused && self.entered { + fill_bg(buf, area, if self.focused && self.entered { Color::Rgb(25, 60, 15) } else if self.focused { Color::Rgb(20, 45, 5) @@ -26,9 +60,9 @@ impl<'a> ArrangerViewVertical<'a> { Color::Reset }); if self.focused && self.entered { - QuarterV(Style::default().green().dim()).draw(self.buf, Rect { x, y, width, height }); - //lozenge_left(self.buf, x, y, height, style); - //lozenge_right(self.buf, x + width - 1, y, height, style); + QuarterV(Style::default().green().dim()).draw(buf, Rect { x, y, width, height }); + //lozenge_left(buf, x, y, height, style); + //lozenge_right(buf, x + width - 1, y, height, style); } let bg_color = if self.focused && self.entered { Color::Rgb(30, 90, 25) @@ -45,7 +79,7 @@ impl<'a> ArrangerViewVertical<'a> { } if focus_column { fill_bg( - &mut self.buf, + buf, Rect { x: x2, y, width: *w, height }, bg_color ); @@ -61,7 +95,7 @@ impl<'a> ArrangerViewVertical<'a> { } let w = (title.len() as u16).max(10); fill_bg( - &mut self.buf, + buf, Rect { x: x2, y: if self.cursor.1 == 0 { y2 } else { @@ -70,13 +104,13 @@ impl<'a> ArrangerViewVertical<'a> { bg_color ); if i == 0 { - self.scenes(x2+1, y2+2); + self.vertical_scenes(buf, x2+1, y2+2, area.height); } else if i < columns.len() { - self.clips(x2+1, y2+2, i - 1); + 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(self.buf, x2, y2, Some(if self.tracks[i-1].recording { + "⏺".blit(buf, x2, y2, Some(if self.tracks[i-1].recording { Style::default().red() } else if self.tracks[i-1].monitoring { Style::default().green() @@ -84,11 +118,11 @@ impl<'a> ArrangerViewVertical<'a> { Style::default().black() })); } - title.blit(self.buf, x2+2, y2, style); + title.blit(buf, x2+2, y2, style); x2 = x2 + w + 3; } fill_bg( - &mut self.buf, + buf, Rect { x: x2, y: if self.cursor.1 == 0 { y2 } else { @@ -97,68 +131,54 @@ impl<'a> ArrangerViewVertical<'a> { bg_color ); if self.focused { - HELP.blit(self.buf, x + 2, y + height - 1, Some(Style::default().dim())); + HELP.blit(buf, x + 2, y + height - 1, Some(Style::default().dim())); } - Ok(self.area) - } - fn track_names (&self) -> Vec<&'a str> { - let mut track_names = vec!["Mix"]; - for track in self.tracks.iter() { - track_names.push(track.name.as_str()); - } - track_names + Ok(area) } - fn track_widths (&self) -> Vec { - self.track_names() - .iter() - .map(|name|(name.len() as u16).max(10) + 3) - .collect() - } - - fn scenes (&mut self, x: u16, y: u16) -> u16 { + fn vertical_scenes (&self, buf: &mut Buffer, x: u16, y: u16, height: u16) -> u16 { let mut index = 0usize; loop { if index >= self.scenes.len() { break } - if y + index as u16 >= self.area.height { + if y + index as u16 >= height { break } - self.scene(x, y + index as u16, index); + self.vertical_scene(buf, x, y + index as u16, index); index = index + 1; } longest_scene_name(&self.scenes) } - fn scene (&mut self, x: u16, y: u16, index: usize) { + fn vertical_scene (&self, buf: &mut Buffer, x: u16, y: u16, index: usize) { if let Some(scene) = self.scenes.get(index) { let style = Some(highlight( self.focused, (0 == self.cursor.0) && (index + 1 == self.cursor.1) ).bold()); - "⯈".blit(self.buf, x, y, style); - scene.name.blit(self.buf, x + 2, y, style); + "⯈".blit(buf, x, y, style); + scene.name.blit(buf, x + 2, y, style); } } - fn clips (&mut self, x: u16, y: u16, track: usize) -> u16 { + fn vertical_clips (&self, buf: &mut Buffer, x: u16, y: u16, height: u16, track: usize) -> u16 { let mut index = 0; let mut width = 10; loop { if index >= self.scenes.len() { break } - if y + index as u16 >= self.area.height { + if y + index as u16 >= height { break } - width = 10.max(self.clip(x, y, track, index)); + width = 10.max(self.vertical_clip(buf, x, y, track, index)); index = index + 1; } width } - fn clip (&mut self, x: u16, y: u16, track: usize, index: usize) -> u16 { + fn vertical_clip (&self, buf: &mut Buffer, x: u16, y: u16, track: usize, index: usize) -> u16 { if let Some(scene) = self.scenes.get(index) { let hi = (track + 1 == self.cursor.0) && (index + 1 == self.cursor.1); @@ -178,42 +198,20 @@ impl<'a> ArrangerViewVertical<'a> { } else { format!(" ·········") }; - label.blit(self.buf, x, y + index, style); + label.blit(buf, x, y + index, style); label.len() as u16 } else { 0u16 } } - - fn separator_v (&mut self, x: u16, hi: bool) { - let style = Some(highlight(self.focused, hi)); - for y in self.area.y+1..self.area.y+self.area.height-1 { - "┊".blit(self.buf, x, y, style); - } - } - } -pub struct ArrangerViewHorizontal<'a> { - pub buf: &'a mut Buffer, - pub area: Rect, - pub scenes: &'a[Scene], - pub tracks: &'a[Track], - pub cursor: &'a(usize, usize), - pub focused: bool, - pub entered: bool, -} -impl<'a> ArrangerViewHorizontal<'a> { - pub fn size (&self) -> (u16, u16) { - let w = (4 + longest_track_name(&self.tracks) + self.scenes.len() as u16 * 10) as u16; - let h = (2 + self.tracks.len()) as u16; - (w, h) - } - pub fn draw (&mut self) -> Usually { - self.area.height = self.tracks.len() as u16 * 2 + 2; +impl<'a> ArrangerView<'a> { + fn draw_horizontal (&self, buf: &mut Buffer, mut area: Rect) -> Usually { + area.height = self.tracks.len() as u16 * 2 + 2; //let style = Some(Style::default().green().dim()); - let Rect { x, y, width, height } = self.area; - fill_bg(&mut self.buf, self.area, if self.focused && self.entered { + let Rect { x, y, width, height } = area; + fill_bg(buf, area, if self.focused && self.entered { Color::Rgb(25, 60, 15) } else if self.focused { Color::Rgb(20, 45, 5) @@ -221,63 +219,68 @@ impl<'a> ArrangerViewHorizontal<'a> { Color::Reset }); if self.focused && self.entered { - //RailV::draw(self.buf, Rect { x, y, width, height }); - QuarterV(Style::default().green().dim()).draw(self.buf, Rect { x, y, width, height }); - //lozenge_left(self.buf, x, y, height, style); - //lozenge_right(self.buf, x + width - 1, y, height, style); + //RailV::draw(buf, Rect { x, y, width, height }); + QuarterV(Style::default().green().dim()).draw(buf, Rect { x, y, width, height }); + //lozenge_left(buf, x, y, height, style); + //lozenge_right(buf, x + width - 1, y, height, style); } let mut x2 = 0; - self.draw_tracks(&mut x2); + self.horizontal_tracks(buf, area, &mut x2); x2 = x2 + 1; - self.draw_scenes(&mut x2); + self.horizontal_scenes(buf, area, &mut x2); if self.focused { - HELP.blit(self.buf, x + 2, y + height - 1, Some(Style::default().dim())); + HELP.blit(buf, x + 2, y + height - 1, Some(Style::default().dim())); } - Ok(self.area) + Ok(area) } - fn draw_tracks (&mut self, x2: &mut u16) { + fn horizontal_size (&self) -> (u16, u16) { + let w = (4 + longest_track_name(&self.tracks) + self.scenes.len() as u16 * 10) as u16; + let h = (2 + self.tracks.len()) as u16; + (w, h) + } + fn horizontal_tracks (&self, buf: &mut Buffer, area: Rect, x2: &mut u16) { let style = Some(Style::default().bold().not_dim().white()); - let Rect { x, y, height, .. } = self.area; - "Mix".blit(self.buf, x + 1, y, style); + let Rect { x, y, height, .. } = area; + "Mix".blit(buf, x + 1, y, style); let style = Some(Style::default().bold()); for (i, track) in self.tracks.iter().enumerate() { let y2 = y + 1 + i as u16 * 2; let label = format!(" {:8}", &track.name); - label.blit(self.buf, x + 1, y2, style); - "RDM".blit(self.buf, x + 10, y2, Some(Style::default().dim())); - " 0.0dB".blit(self.buf, x + 15, y2, Some(Style::default().dim())); + label.blit(buf, x + 1, y2, style); + "RDM".blit(buf, x + 10, y2, Some(Style::default().dim())); + " 0.0dB".blit(buf, x + 15, y2, Some(Style::default().dim())); *x2 = (*x2).max(label.len() as u16 + 13); } - "╷".blit(self.buf, x + *x2, y, style); + "╷".blit(buf, x + *x2, y, style); for y in y+1..y+height-1 { - "│".blit(self.buf, x + *x2, y, style); + "│".blit(buf, x + *x2, y, style); } - //"╵".blit(self.buf, x + x2, y+height-1, style); + //"╵".blit(buf, x + x2, y+height-1, style); } - fn draw_scenes (&mut self, x2: &mut u16) { - let Rect { x, y, height, .. } = self.area; + fn horizontal_scenes (&self, buf: &mut Buffer, area: Rect, x2: &mut u16) { + let Rect { x, y, height, .. } = area; let bold = Some(Style::default().bold()); let sep = Some(Style::default().dim()); for scene in self.scenes.iter() { let mut x3 = scene.name.len() as u16; - scene.name.blit(self.buf, x + *x2, y, bold); + scene.name.blit(buf, x + *x2, y, bold); for (i, clip) in scene.clips.iter().enumerate() { if let Some(clip) = clip { if let Some(phrase) = self.tracks[i].phrases.get(*clip) { let y2 = y + 1 + i as u16 * 2; let label = format!("{}", &phrase.name); - label.blit(self.buf, x + *x2, y2, None); + label.blit(buf, x + *x2, y2, None); x3 = x3.max(label.len() as u16) } } } *x2 = *x2 + x3; - "╷".blit(self.buf, x + *x2, y, sep); + "╷".blit(buf, x + *x2, y, sep); for y in y+1..y+height-1 { - "┊".blit(self.buf, x + *x2, y, sep); + "┊".blit(buf, x + *x2, y, sep); } - "╵".blit(self.buf, x + *x2, y+height-1, sep); + "╵".blit(buf, x + *x2, y+height-1, sep); *x2 = *x2 + 1; } }