use crate::core::*; use crate::model::*; use crate::view::*; pub struct SceneGridView<'a> { pub buf: &'a mut Buffer, pub area: Rect, pub name: &'a str, pub focused: bool, pub scenes: &'a[Scene], pub tracks: &'a[Track], pub cursor: &'a(usize, usize), pub mode: bool, } impl<'a> SceneGridView<'a> { fn longest_scene_name (&self) -> u16 { let mut w = 3u16; for scene in self.scenes.iter() { w = w.max(scene.name.len() as u16); } w } fn longest_track_name (&self) -> u16 { let mut w = 3u16; for track in self.tracks.iter() { w = w.max(track.name.len() as u16); } w } pub fn size_horizontal (&mut self) -> (u16, u16) { let (mut w, mut h) = (4, 2); w = w + self.longest_track_name(); w = w + self.scenes.len() as u16 * 10; h = h + self.tracks.len(); (w as u16, h as u16) } pub fn draw (&mut self) -> Usually { match self.mode { true => self.draw_horizontal(), false => self.draw_vertical(), } } pub fn draw_horizontal (&mut self) -> Usually { let (w, h) = self.size_horizontal(); //self.area.x = self.area.x + self.area.width.saturating_sub(w) / 2; self.area.height = self.tracks.len() as u16 + 2; //self.area.width = w; let style = Some(Style::default().green().dim()); if self.focused { let Rect { x, y, width, height } = self.area; lozenge_left(self.buf, x, y, height, style); lozenge_right(self.buf, x + width - 1, y, height, style); } " Mix ".blit(self.buf,self.area.x+1,self.area.y,Some(Style::default().bold().not_dim().white())); let mut x2 = 0; for (i, track) in self.tracks.iter().enumerate() { let label = format!(" {} ", &track.name); label.blit(self.buf, self.area.x+1, self.area.y+1+i as u16, Some(Style::default().bold())); x2 = x2.max(label.len() as u16 + 1); } "╷".blit(self.buf, self.area.x + x2, self.area.y, style); for y in self.area.y+1..self.area.y+self.area.height-1 { "│".blit(self.buf, self.area.x + x2, y, style); } //"╵".blit(self.buf, self.area.x + x2, self.area.y+self.area.height-1, style); x2 = x2 + 1; for scene in self.scenes.iter() { let label = format!("{}", &scene.name); let mut x3 = label.len() as u16; label.blit(self.buf, self.area.x + x2, self.area.y, Some(Style::default().bold())); for (i, clip) in scene.clips.iter().enumerate() { if let Some(clip) = clip { if let Some(phrase) = self.tracks[i].sequencer.phrases.get(*clip) { let label = format!("{}", &phrase.name); label.blit(self.buf, self.area.x + x2, self.area.y + 1 + i as u16, None); x3 = x3.max(label.len() as u16) } } } x2 = x2 + x3; "╷".blit(self.buf, self.area.x + x2, self.area.y, style); for y in self.area.y+1..self.area.y+self.area.height-1 { "┊".blit(self.buf, self.area.x + x2, y, style); } //"╵".blit(self.buf, self.area.x + x2, self.area.y+self.area.height-1, style); x2 = x2 + 1; } if self.focused { HELP.blit(self.buf, self.area.x + 2, self.area.y + self.area.height - 1, Some(Style::default().dim())); } Ok(self.area) } pub fn draw_vertical (&mut self) -> Usually { let width = self.area.width.min(4 + HELP.len() as u16); self.area.height = self.scenes.len() as u16 + 2; //self.area.x = self.area.x + self.area.width.saturating_sub(width) / 2; let style = Some(Style::default().green().dim()); if self.focused { let Rect { x, y, width, height } = self.area; lozenge_left(self.buf, x, y, height, style); lozenge_right(self.buf, x + width - 1, y, height, style); } let columns = self.track_names(); let mut x = self.area.x; for (i, w) in self.track_widths().iter().enumerate() { if x >= self.area.x + self.area.width { break } self.separator_v(x, i == self.cursor.0); x = x + w; self.separator_v(x, i == self.cursor.0); } let (mut x, y) = (self.area.x, self.area.y); for (i, title) in columns.iter().enumerate() { if x >= self.area.x + self.area.width { break } title.blit( self.buf, x+1, y, Some(self.highlight(i == self.cursor.0).bold()) ); if i == 0 { self.scenes(x+1, y + 1); } else if i < columns.len() { self.clips(x+1, y + 1, i - 1); } let w = (title.len() as u16).max(10) + 3; x = x + w; } if self.focused { HELP.blit(self.buf, self.area.x + 2, self.area.y + self.area.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 } 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 { let mut index = 0usize; loop { if index >= self.scenes.len() { break } if y + index as u16 >= self.area.height { break } if let Some(scene) = self.scenes.get(index) { let style = Some(self.highlight( (0 == self.cursor.0) && (index + 1 == self.cursor.1) ).bold()); "⯈".blit(self.buf, x, y + index as u16, style); scene.name.blit(self.buf, x+1, y + index as u16, style); } index = index + 1; } index as u16 } fn clips (&mut self, x: u16, y: u16, track: usize) -> u16 { let mut index = 0; loop { if index >= self.scenes.len() { break } if y + index as u16 >= self.area.height { break } if let Some(scene) = self.scenes.get(index) { let hi = (track + 1 == self.cursor.0) && (index + 1 == self.cursor.1); let style = Some(self.highlight(hi)); let clip = scene.clips.get(track); let index = index as u16; let label = if let Some(Some(clip)) = clip { if let Some(phrase) = self.tracks[track].sequencer.phrases.get(*clip) { format!("⯈{}", phrase.name) } else { format!("????") } } else { format!(" ·········") }; label.blit(self.buf, x, y + index, style); } index = index + 1; } //let hi = (track + 1 == self.cursor.0) && //(self.scenes.len() + 1 == self.cursor.1); //"[Add clip…]".blit(self.buf, x, y + index as u16, Some(if hi { //self.highlight(true) //} else { //Style::default().dim() //})); index as u16 } fn highlight (&self, highlight: bool) -> Style { if highlight { if self.focused { Style::default().green().not_dim() } else { Style::default().green().dim() } } else { Style::default() } } fn separator_v (&mut self, x: u16, highlight: bool) { let style = Some(self.highlight(highlight)); for y in self.area.y+1..self.area.y+self.area.height-1 { "┊".blit(self.buf, x, y, style); } } } const HELP: &'static str = "[C-t] Add track [C-a] Add scene [v] Show/hide track";