diff --git a/demos/project.edn b/demos/project.edn index 5cf6a21e..f7554a5b 100644 --- a/demos/project.edn +++ b/demos/project.edn @@ -92,19 +92,19 @@ (:90 (42 70))) (sampler { :name "DrumKit1" :dir "/home/user/Lab/Music/pak" } - (sample { :midi 34 :name "808" :file "808.wav" }) - (sample { :midi 35 :name "KC1" :file "kik.wav" }) - (sample { :midi 36 :name "KC2" :file "kik2.wav" }) - (sample { :midi 37 :name "RIM" :file "rim.wav" }) - (sample { :midi 38 :name "SN1" :file "sna.wav" }) - (sample { :midi 39 :name "SHK" :file "shk.wav" }) - (sample { :midi 40 :name "SN2" :file "sna2.wav" }) - (sample { :midi 42 :name "HH1" :file "chh.wav" }) - (sample { :midi 45 :name "HH1" :file "ohh.wav" }) - (sample { :midi 46 :name "HH1" :file "ohh1.wav" }) - (sample { :midi 47 :name "HH1" :file "ohh2.wav" }) - (sample { :midi 44 :name "HH2" :file "chh2.wav" }) - (sample { :midi 49 :name "CRS" :file "crs.wav" }))) + (sample { :midi 34 :name "808 D" :file "808.wav" }) + (sample { :midi 35 :name "Kick 1" :file "kik.wav" }) + (sample { :midi 36 :name "Kick 2" :file "kik2.wav" }) + (sample { :midi 37 :name "Rim" :file "rim.wav" }) + (sample { :midi 38 :name "Snare 1" :file "sna.wav" }) + (sample { :midi 39 :name "Shaker" :file "shk.wav" }) + (sample { :midi 40 :name "Snare 2" :file "sna2.wav" }) + (sample { :midi 42 :name "Closed HH 1" :file "chh.wav" }) + (sample { :midi 44 :name "Closed HH 2" :file "chh2.wav" }) + (sample { :midi 45 :name "Open HH 0" :file "ohh.wav" }) + (sample { :midi 46 :name "Open HH 1" :file "ohh1.wav" }) + (sample { :midi 47 :name "Open HH 2" :file "ohh2.wav" }) + (sample { :midi 49 :name "Crash" :file "crs.wav" }))) (track { :name "Bass" :gain +0.0 } (phrase { :name "Bass 1" :beats 4 }) diff --git a/src/model/track.rs b/src/model/track.rs index e7d75831..ffde2874 100644 --- a/src/model/track.rs +++ b/src/model/track.rs @@ -96,30 +96,18 @@ impl Track { reset: true, }) } - fn get_device (&self, i: usize) -> Option>> { - self.devices.get(i).map(|d|d.state.read().unwrap()) - } fn get_device_mut (&self, i: usize) -> Option>> { self.devices.get(i).map(|d|d.state.write().unwrap()) } - fn device (&self) -> Option>> { - self.get_device(self.device) - } pub fn device_mut (&self) -> Option>> { self.get_device_mut(self.device) } - fn first_device (&self) -> Option>> { - self.get_device(0) - } pub fn connect_first_device (&self) -> Usually<()> { if let (Some(port), Some(device)) = (&self.midi_out, self.devices.get(0)) { device.client.as_client().connect_ports(&port, &device.midi_ins()?[0])?; } Ok(()) } - fn last_device (&self) -> Option>> { - self.get_device(self.devices.len().saturating_sub(1)) - } pub fn connect_last_device (&self, app: &App) -> Usually<()> { Ok(match self.devices.get(self.devices.len().saturating_sub(1)) { Some(device) => { @@ -135,37 +123,6 @@ impl Track { let index = self.devices.len() - 1; Ok(&mut self.devices[index]) } - fn add_device_with_cb ( - &mut self, - mut device: JackDevice, - init: impl Fn(&Self, &mut JackDevice)->Usually<()> - ) -> Usually<&mut JackDevice> { - init(&self, &mut device)?; - self.devices.push(device); - let index = self.devices.len() - 1; - Ok(&mut self.devices[index]) - } - fn phrase (&self) -> Option<&Phrase> { - if let Some(phrase) = self.sequence { - return self.phrases.get(phrase) - } else { - None - } - } - fn phrase_mut (&mut self) -> Option<&mut Phrase> { - if let Some(phrase) = self.sequence { - return self.phrases.get_mut(phrase) - } else { - None - } - } - fn add_phrase ( - &mut self, name: &str, length: usize, data: Option - ) -> &mut Phrase { - self.phrases.push(Phrase::new(name, length, data)); - let index = self.phrases.len() - 1; - &mut self.phrases[index] - } pub fn toggle_monitor (&mut self) { self.monitoring = !self.monitoring; } @@ -201,8 +158,6 @@ impl Track { all_notes_off(&mut self.midi_out_buf); } } - // For highlighting keys and note repeat - // Currently playing phrase if let ( Some(TransportState::Rolling), Some((start_frame, _)), Some(phrase) ) = ( diff --git a/src/view/arranger.rs b/src/view/arranger.rs index 6e7b9308..eaba3ac0 100644 --- a/src/view/arranger.rs +++ b/src/view/arranger.rs @@ -59,8 +59,8 @@ impl<'a> ArrangerView<'a> { impl<'a> Render for ArrangerView<'a> { fn render (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - area.height = area.height.min(if self.vertical { - self.scenes.len() as u16 + 3 + area.height = area.height.min(1 + if self.vertical { + self.scenes.len() as u16 * 2 } else { self.tracks.len() as u16 * 2 }); @@ -82,36 +82,6 @@ impl<'a> Render for ArrangerView<'a> { impl<'a> ArrangerView<'a> { - fn vertical_scenes (&self, buf: &mut Buffer, x: u16, y: u16, height: u16) -> Usually { - let mut index = 0usize; - loop { - if index >= self.scenes.len() { - break - } - if y + index as u16 >= height { - break - } - self.vertical_scene(buf, x, y + index as u16, index)?; - index = index + 1; - } - 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<()> { - 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(buf, x, y, style)?; - scene.name.blit(buf, x + 2, y, style)?; - } - Ok(()) - } - fn vertical_clips (&self, buf: &mut Buffer, x: u16, y: u16, height: u16, track: usize) -> Usually { let mut index = 0; let mut width = 10; @@ -122,104 +92,115 @@ impl<'a> ArrangerView<'a> { if y + index as u16 >= height { break } - width = 10.max(self.vertical_clip(buf, x, y, track, index)?); + width = 10.max(if let Some(scene) = self.scenes.get(index) { + let hi = (track + 1 == self.cursor.0) && + (index + 1 == self.cursor.1); + let style = Some(highlight(self.focused, 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].phrases.get(*clip) { + format!("{} {}", if self.tracks[track].sequence == Some(*clip) { + "" + } else { + " " + }, phrase.name) + } else { + format!(" ??? ") + } + } else { + format!(" ·········") + }; + label.blit(buf, x, y + index, style)?; + label.len() as u16 + } else { + 0u16 + }); index = index + 1; } Ok(width) } - fn vertical_clip (&self, buf: &mut Buffer, x: u16, y: u16, track: usize, index: usize) -> Usually { - Ok(if let Some(scene) = self.scenes.get(index) { - let hi = (track + 1 == self.cursor.0) && - (index + 1 == self.cursor.1); - let style = Some(highlight(self.focused, 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].phrases.get(*clip) { - format!("{} {}", if self.tracks[track].sequence == Some(*clip) { - "⯈" - } else { - " " - }, phrase.name) - } else { - format!(" ??? ") - } - } else { - format!(" ·········") - }; - label.blit(buf, x, y + index, style)?; - label.len() as u16 - } else { - 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()), + return Split::right([ + + // Scene column + &|buf: &mut Buffer, area: Rect|{ + let Rect { x, y, height, .. } = area; + for (scene_index, scene) in self.scenes.iter().enumerate() { + if y + 2 * scene_index as u16 >= height { + break + } + let style = Some(highlight( + self.focused, + (0 == self.cursor.0) && (scene_index + 1 == self.cursor.1) + ).bold()); + let y = 1 + y + 2 * scene_index as u16; + "⯈".blit(buf, x+1, y, style)?; + scene.name.blit(buf, x + 2, y, style)?; + } + let width = 2+self.scenes.iter() + .map(|x|&x.name).fold(0, |x,y|x.max(y.len() as u16+1)); + Ok(Rect { width, ..area }) + }, + // 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) + &|buf: &mut Buffer, area: Rect|{ + let Rect { mut x, y, width, height } = area; + for (track_index, track) in self.tracks.iter().enumerate() { + if x >= width { + break + } + let mut width = 16u16; + track.name.blit(buf, x, y, Some(Style::default().bold()))?; + for (scene_index, scene) in self.scenes.iter().enumerate() { + if y + 2 * scene_index as u16 >= height { + break + } + let label = if let Some(Some(clip)) = scene.clips.get(track_index) { + if let Some(phrase) = track.phrases.get(*clip) { + format!("{} {}", if track.sequence == Some(*clip) { + "" + } else { + "┊" + }, phrase.name) + } else { + format!(" ??? ") + } + } else { + format!("┊ ········") + }; + let hi = (track_index + 1 == self.cursor.0) && (scene_index + 1 == self.cursor.1); + let style = Some(highlight(self.focused, hi)); + let y = 1 + y + 2 * scene_index as u16; + "┊".blit(buf, x, y, Some(Style::default().dim()))?; + "┊".blit(buf, x, y + 1, Some(Style::default().dim()))?; + label.blit(buf, x, y, style)?; + //width = width.max(2label.len() as u16 + 3); + } + if track_index + 1 == self.cursor.0 { + if self.cursor.1 == 0 { + let y = area.y; + fill_bg(buf, Rect { x, y, width, height: 1 }, if self.focused { + Color::Rgb(30, 90, 25) + } else { + Color::Rgb(25, 60, 15) + }) + } else { + let y = 1 + area.y + 2 * (self.cursor.1 as u16 - 1); + fill_bg(buf, Rect { x, y, width, height: 2 }, if self.focused { + Color::Rgb(30, 90, 25) + } else { + Color::Rgb(25, 60, 15) + }) + } + }; + x = x + width as u16; + } + Ok(Rect { x: area.x, y, width: x - area.x, height }) + } + ]).render(buf, area); } }