From 694970bf0d79f9b7e9e54cfec7cd98f0cbe31798 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 5 Sep 2024 16:01:01 +0300 Subject: [PATCH] wip: <200 errors yay --- crates/tek_core/src/tui.rs | 23 ++--- crates/tek_mixer/Cargo.toml | 3 +- crates/tek_mixer/src/lib.rs | 1 + crates/tek_mixer/src/mixer.rs | 6 +- crates/tek_mixer/src/sample_add.rs | 40 ++++----- crates/tek_mixer/src/sampler.rs | 60 +++---------- crates/tek_mixer/src/sampler_view.rs | 45 ++++++++++ crates/tek_mixer/src/track_view.rs | 8 +- crates/tek_proc/Cargo.toml | 11 +++ crates/tek_proc/src/lib.rs | 18 ++++ crates/tek_sequencer/Cargo.toml | 1 + crates/tek_sequencer/src/arranger.rs | 27 +++--- crates/tek_sequencer/src/arranger_rename.rs | 91 ++++++++++---------- crates/tek_sequencer/src/arranger_view_h.rs | 58 ++++++------- crates/tek_sequencer/src/sequencer_handle.rs | 6 +- crates/tek_sequencer/src/sequencer_view.rs | 8 +- crates/tek_sequencer/src/sequencer_view_h.rs | 91 +++++++++++--------- crates/tek_sequencer/src/transport.rs | 38 ++++---- crates/tek_sequencer/src/transport_handle.rs | 81 ++++++++++------- crates/tek_sequencer/src/transport_render.rs | 73 ++++++++-------- 20 files changed, 384 insertions(+), 305 deletions(-) create mode 100644 crates/tek_mixer/src/sampler_view.rs create mode 100644 crates/tek_proc/Cargo.toml create mode 100644 crates/tek_proc/src/lib.rs diff --git a/crates/tek_core/src/tui.rs b/crates/tek_core/src/tui.rs index af16b1db..f7440725 100644 --- a/crates/tek_core/src/tui.rs +++ b/crates/tek_core/src/tui.rs @@ -117,16 +117,7 @@ impl Tui { &mut self.buffers[self.buffer] } pub fn buffer_update (&mut self, area: Rect, callback: &impl Fn(&mut Cell, u16, u16)) { - let buf = self.buffer(); - for row in 0..area.height { - let y = area.y + row; - for col in 0..area.width { - let x = area.x + col; - if x < buf.area.width && y < buf.area.height { - callback(buf.get_mut(x, y), col, row); - } - } - } + buffer_update(self.buffer(), area, callback) } pub fn fill_bg (&mut self, area: Rect, color: Color) { self.buffer_update(area, &|cell,_,_|{cell.set_bg(color);}) @@ -628,3 +619,15 @@ impl> Render for (Outset, R) { ))) } } + +pub fn buffer_update (buf: &mut Buffer, area: Rect, callback: &impl Fn(&mut Cell, u16, u16)) { + for row in 0..area.height { + let y = area.y + row; + for col in 0..area.width { + let x = area.x + col; + if x < buf.area.width && y < buf.area.height { + callback(buf.get_mut(x, y), col, row); + } + } + } +} diff --git a/crates/tek_mixer/Cargo.toml b/crates/tek_mixer/Cargo.toml index 20e48eaa..65472614 100644 --- a/crates/tek_mixer/Cargo.toml +++ b/crates/tek_mixer/Cargo.toml @@ -5,6 +5,7 @@ version = "0.1.0" [dependencies] tek_core = { path = "../tek_core" } +tek_proc = { path = "../tek_proc" } livi = "0.7.4" suil-rs = { path = "../suil" } @@ -31,4 +32,4 @@ path = "src/sampler_main.rs" [[bin]] name = "tek_plugin" -path = "src/plugin_main.rs" +path = "src/sampler_main.rs" diff --git a/crates/tek_mixer/src/lib.rs b/crates/tek_mixer/src/lib.rs index 72d47000..71117c39 100644 --- a/crates/tek_mixer/src/lib.rs +++ b/crates/tek_mixer/src/lib.rs @@ -25,5 +25,6 @@ submod! { sample_add sampler sampler_edn + sampler_view voice } diff --git a/crates/tek_mixer/src/mixer.rs b/crates/tek_mixer/src/mixer.rs index 1cac4de6..206cd913 100644 --- a/crates/tek_mixer/src/mixer.rs +++ b/crates/tek_mixer/src/mixer.rs @@ -1,12 +1,12 @@ use crate::*; -pub struct Mixer { +pub struct Mixer { pub name: String, pub tracks: Vec>, pub selected_track: usize, pub selected_column: usize, } -impl Mixer { +impl Mixer { pub fn new (name: &str) -> Usually { let (client, _status) = Client::new(name, ClientOptions::NO_START_SERVER)?; Ok(Self { @@ -25,7 +25,7 @@ impl Mixer { self.tracks.get(self.selected_track) } } -impl Process for Mixer { +impl Process for Mixer { fn process (&mut self, _: &Client, _: &ProcessScope) -> Control { Control::Continue } diff --git a/crates/tek_mixer/src/sample_add.rs b/crates/tek_mixer/src/sample_add.rs index d2a27409..2d6b9f02 100644 --- a/crates/tek_mixer/src/sample_add.rs +++ b/crates/tek_mixer/src/sample_add.rs @@ -22,21 +22,20 @@ pub struct AddSampleModal { exit!(AddSampleModal); -impl<'a> Render, Rect> for AddSampleModal { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { - make_dim(to.buffer); +impl Render for AddSampleModal { + fn render (&self, to: &mut Tui) -> Perhaps { + let area = to.area(); + to.make_dim(); let area = center_box( - to.area, - 64.max(to.area.width.saturating_sub(8)), - 20.max(to.area.width.saturating_sub(8)), + area, + 64.max(area.width.saturating_sub(8)), + 20.max(area.width.saturating_sub(8)), ); - fill_fg(to.buffer, area, Color::Reset); - fill_bg(to.buffer, area, Nord::bg_lo(true, true)); - fill_char(to.buffer, area, ' '); - format!("{}", &self.dir.to_string_lossy()) - .blit(to.buffer, area.x+2, area.y+1, Some(Style::default().bold()))?; - "Select sample:" - .blit(to.buffer, area.x+2, area.y+2, Some(Style::default().bold()))?; + to.fill_fg(area, Color::Reset); + to.fill_bg(area, Nord::bg_lo(true, true)); + to.fill_char(area, ' '); + to.blit(&format!("{}", &self.dir.to_string_lossy()), area.x+2, area.y+1, Some(Style::default().bold()))?; + to.blit(&"Select sample:", area.x+2, area.y+2, Some(Style::default().bold()))?; for (i, (is_dir, name)) in self.subdirs.iter() .map(|path|(true, path)) .chain(self.files.iter().map(|path|(false, path))) @@ -49,7 +48,7 @@ impl<'a> Render, Rect> for AddSampleModal { let t = if is_dir { "" } else { "" }; let line = format!("{t} {}", name.to_string_lossy()); let line = &line[..line.len().min(area.width as usize - 4)]; - line.blit(to.buffer, area.x + 2, area.y + 3 + i as u16, Some(if i == self.cursor { + to.blit(&line, area.x + 2, area.y + 3 + i as u16, Some(if i == self.cursor { Style::default().green() } else { Style::default().white() @@ -58,13 +57,14 @@ impl<'a> Render, Rect> for AddSampleModal { Lozenge(Style::default()).draw(to) } } - -handle!(AddSampleModal |self,e|{ - if handle_keymap(self, e, KEYMAP_ADD_SAMPLE)? { - return Ok(true) +impl Handle for AddSampleModal { + fn handle (&mut self, e: &Tui) -> Usually { + if handle_keymap(self, e, KEYMAP_ADD_SAMPLE)? { + return Ok(true) + } + Ok(true) } - Ok(true) -}); +} impl AddSampleModal { pub fn new ( diff --git a/crates/tek_mixer/src/sampler.rs b/crates/tek_mixer/src/sampler.rs index 8e00f3cf..6df1b95b 100644 --- a/crates/tek_mixer/src/sampler.rs +++ b/crates/tek_mixer/src/sampler.rs @@ -13,56 +13,20 @@ pub struct Sampler { pub modal: Arc>>>, pub output_gain: f32 } +impl Handle for Sampler { + fn handle (&mut self, e: &E) -> Usually { + handle_keymap(self, event, KEYMAP_SAMPLER) + } +} +impl Render for Sampler { + fn render (&self, to: &mut Tui) -> Perhaps { + tui_render_sampler(self, to) + } +} process!(Sampler = Sampler::process); -handle!(Sampler |self, event| handle_keymap(self, event, KEYMAP_SAMPLER)); -impl Render for Sampler { - fn render (&self, to: &mut Tui) -> Perhaps { - let Rect { x, y, height, .. } = to.area(); - let style = Style::default().gray(); - let title = format!(" {} ({})", self.name, self.voices.read().unwrap().len()); - title.blit(to.buffer(), x+1, y, Some(style.white().bold().not_dim()))?; - let mut width = title.len() + 2; - let mut y1 = 1; - let mut j = 0; - for (note, sample) in self.mapped.iter() - .map(|(note, sample)|(Some(note), sample)) - .chain(self.unmapped.iter().map(|sample|(None, sample))) - { - if y1 >= height { - break - } - let active = j == self.cursor.0; - width = width.max( - draw_sample(to.buffer(), x, y + y1, note, &*sample.read().unwrap(), active)? - ); - y1 = y1 + 1; - j = j + 1; - } - let height = ((2 + y1) as u16).min(height); - Ok(Some(Rect { x, y, width: (width as u16).min(to.area().width), height })) - } -} - -fn draw_sample ( - buf: &mut Buffer, x: u16, y: u16, note: Option<&u7>, sample: &Sample, focus: bool -) -> Usually { - let style = if focus { Style::default().green() } else { Style::default() }; - if focus { - "🬴".blit(buf, x+1, y, Some(style.bold()))?; - } - let label1 = format!("{:3} {:12}", - note.map(|n|n.to_string()).unwrap_or(String::default()), - sample.name); - let label2 = format!("{:>6} {:>6} +0.0", - sample.start, - sample.end); - label1.blit(buf, x+2, y, Some(style.bold()))?; - label2.blit(buf, x+3+label1.len()as u16, y, Some(style))?; - Ok(label1.len() + label2.len() + 4) -} /// Key bindings for sampler device. pub const KEYMAP_SAMPLER: &'static [KeyBinding] = keymap!(Sampler { @@ -105,7 +69,7 @@ pub const KEYMAP_SAMPLER: &'static [KeyBinding] = keymap!(Sampler { }); impl Sampler { - pub fn from_edn <'e, E> (args: &[Edn<'e>]) -> Usually> { + pub fn from_edn <'e, E: Engine> (args: &[Edn<'e>]) -> Usually> { let mut name = String::new(); let mut dir = String::new(); let mut samples = BTreeMap::new(); @@ -134,7 +98,7 @@ impl Sampler { Self::new(&name, Some(samples)) } - pub fn new ( + pub fn new ( name: &str, mapped: Option>>> ) -> Usually> { Jack::new(name)? diff --git a/crates/tek_mixer/src/sampler_view.rs b/crates/tek_mixer/src/sampler_view.rs new file mode 100644 index 00000000..fd3e910f --- /dev/null +++ b/crates/tek_mixer/src/sampler_view.rs @@ -0,0 +1,45 @@ +use crate::*; + +pub fn tui_render_sampler (sampler: &Sampler, to: &mut Tui) -> Perhaps { + let Rect { x, y, height, .. } = to.area(); + let style = Style::default().gray(); + let title = format!(" {} ({})", sampler.name, sampler.voices.read().unwrap().len()); + to.blit(&title, x+1, y, Some(style.white().bold().not_dim()))?; + let mut width = title.len() + 2; + let mut y1 = 1; + let mut j = 0; + for (note, sample) in sampler.mapped.iter() + .map(|(note, sample)|(Some(note), sample)) + .chain(sampler.unmapped.iter().map(|sample|(None, sample))) + { + if y1 >= height { + break + } + let active = j == sampler.cursor.0; + width = width.max( + draw_sample(to, x, y + y1, note, &*sample.read().unwrap(), active)? + ); + y1 = y1 + 1; + j = j + 1; + } + let height = ((2 + y1) as u16).min(height); + Ok(Some(Rect { x, y, width: (width as u16).min(to.area().width), height })) +} + +fn draw_sample ( + to: &mut Tui, x: u16, y: u16, note: Option<&u7>, sample: &Sample, focus: bool +) -> Usually { + let style = if focus { Style::default().green() } else { Style::default() }; + if focus { + to.blit(&"🬴", x+1, y, Some(style.bold()))?; + } + let label1 = format!("{:3} {:12}", + note.map(|n|n.to_string()).unwrap_or(String::default()), + sample.name); + let label2 = format!("{:>6} {:>6} +0.0", + sample.start, + sample.end); + to.blit(&label1, x+2, y, Some(style.bold()))?; + to.blit(&label2, x+3+label1.len()as u16, y, Some(style))?; + Ok(label1.len() + label2.len() + 4) +} diff --git a/crates/tek_mixer/src/track_view.rs b/crates/tek_mixer/src/track_view.rs index b2e8aa19..746e6b02 100644 --- a/crates/tek_mixer/src/track_view.rs +++ b/crates/tek_mixer/src/track_view.rs @@ -1,8 +1,8 @@ use crate::*; use tek_core::Direction; -impl<'a> Render for Track { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl Render for Track { + fn render (&self, to: &mut Tui) -> Perhaps { TrackView { chain: Some(&self), direction: tek_core::Direction::Right, @@ -24,8 +24,8 @@ impl<'a> Render for Track { }.render(to) } } -pub struct TrackView<'a, T, U> { - pub chain: Option<&'a Track>, +pub struct TrackView<'a, E: Engine> { + pub chain: Option<&'a Track>, pub direction: Direction, pub focused: bool, pub entered: bool, diff --git a/crates/tek_proc/Cargo.toml b/crates/tek_proc/Cargo.toml new file mode 100644 index 00000000..b1a1f78d --- /dev/null +++ b/crates/tek_proc/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "tek_proc" +edition = "2021" +version = "0.1.0" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "2.0", features = ["full"] } +quote = "1.0" diff --git a/crates/tek_proc/src/lib.rs b/crates/tek_proc/src/lib.rs new file mode 100644 index 00000000..1fec2767 --- /dev/null +++ b/crates/tek_proc/src/lib.rs @@ -0,0 +1,18 @@ +use proc_macro::TokenStream; +use syn::{parse_macro_input, Attribute, Meta}; + +#[proc_macro_attribute] +pub fn render (attr: TokenStream, item: TokenStream) -> TokenStream { + println!("attr: \"{attr}\""); + println!("item: \"{item}\""); + let input = syn::parse_macro_input!(attr as Meta); + panic!("attr: \"{input:?}\""); + item +} + +#[proc_macro_attribute] +pub fn handle (attr: TokenStream, item: TokenStream) -> TokenStream { + println!("attr: \"{attr}\""); + println!("item: \"{item}\""); + item +} diff --git a/crates/tek_sequencer/Cargo.toml b/crates/tek_sequencer/Cargo.toml index e9a6c4d9..064d3e4b 100644 --- a/crates/tek_sequencer/Cargo.toml +++ b/crates/tek_sequencer/Cargo.toml @@ -5,6 +5,7 @@ version = "0.1.0" [dependencies] tek_core = { path = "../tek_core" } +tek_proc = { path = "../tek_proc" } [lib] path = "src/lib.rs" diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index 31eac8af..20d41b74 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -101,7 +101,7 @@ impl ArrangerViewMode { } /// Render arranger to terminal impl Render for Arranger { - fn render (&'a self, to: &'a mut TuiOutput<'a>) -> Perhaps { + fn render (&self, to: &mut Tui) -> Perhaps { let area = (|to|match self.mode { ArrangerViewMode::Horizontal => super::arranger_view_h::draw(self, to), @@ -111,18 +111,19 @@ impl Render for Arranger { super::arranger_view_v::draw_compact_2(self, to), ArrangerViewMode::VerticalExpanded => super::arranger_view_v::draw_expanded(self, to), - })(&mut to.area(Rect { - x: to.area.x + 1, - width: to.area.width - 2, - y: to.area.y + 1, - height: to.area.height - 2 - }))?.unwrap(); - Lozenge(Style::default().fg(Nord::BG2)).draw(&mut to.area(Rect { - x: area.x.saturating_sub(1), - width: area.width + 2, - y: area.y.saturating_sub(1), - height: area.height + 2, - })) + })(&mut to.alter_area(|x, y, w, h|( + x + 1, + y + 1, + w.saturating_sub(2), + h.saturating_sub(2), + )))?.unwrap(); + Lozenge(Style::default().fg(Nord::BG2)) + .draw(&mut to.alter_area(|x, y, w, h|( + x.saturating_sub(1), + y.saturating_sub(1), + w + 2, + h + 2, + ))) } } impl Focusable for Arranger { diff --git a/crates/tek_sequencer/src/arranger_rename.rs b/crates/tek_sequencer/src/arranger_rename.rs index 24a348d3..e6c1c11c 100644 --- a/crates/tek_sequencer/src/arranger_rename.rs +++ b/crates/tek_sequencer/src/arranger_rename.rs @@ -1,5 +1,5 @@ use crate::*; -impl<'a> Arranger, Rect> { +impl<'a> Arranger { pub fn rename_selected (&mut self) { self.modal = Some(Box::new(ArrangerRenameModal::new( self.selected, @@ -31,16 +31,17 @@ impl ArrangerRenameModal { } } } -impl<'a> Render, Rect> for ArrangerRenameModal { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { - let y = to.area.y + to.area.height / 2; +impl Render for ArrangerRenameModal { + fn render (&self, to: &mut Tui) -> Perhaps { + let area = to.area(); + let y = area.y + area.height / 2; let bg_area = Rect { x: 1, y: y - 1, - width: to.area.width - 2, + width: area.width - 2, height: 3 }; - fill_bg(to.buffer, bg_area, Nord::BG0); + to.fill_bg(bg_area, Nord::BG0); Lozenge(Style::default().bold().white().dim()).draw(to.buffer, bg_area)?; let label = match self.target { ArrangerFocus::Mix => "Rename project:", @@ -49,50 +50,52 @@ impl<'a> Render, Rect> for ArrangerRenameModal { ArrangerFocus::Clip(_, _) => "Rename clip:", }; let style = Some(Style::default().not_bold().white().not_dim()); - label.blit(to.buffer, to.area.x + 3, y, style)?; + to.blit(&label, area.x + 3, y, style)?; let style = Some(Style::default().bold().white().not_dim()); - self.value.blit(to.buffer, to.area.x + 3 + label.len() as u16 + 1, y, style)?; + to.blit(&self.value, area.x + 3 + label.len() as u16 + 1, y, style)?; let style = Some(Style::default().bold().white().not_dim().reversed()); - "▂".blit(to.buffer, to.area.x + 3 + label.len() as u16 + 1 + self.cursor as u16, y, style)?; - Ok(Some(to.area)) + to.blit(&"▂", area.x + 3 + label.len() as u16 + 1 + self.cursor as u16, y, style)?; + Ok(Some(area)) } } -handle!(ArrangerRenameModal |self, e| { - match e { - AppEvent::Input(Event::Key(k)) => { - match k.code { - KeyCode::Esc => { - self.exit(); - }, - KeyCode::Enter => { - *self.result.write().unwrap() = self.value.clone(); - self.exit(); - }, - KeyCode::Left => { - self.cursor = self.cursor.saturating_sub(1); - }, - KeyCode::Right => { - self.cursor = self.value.len().min(self.cursor + 1) - }, - KeyCode::Backspace => { - let last = self.value.len().saturating_sub(1); - self.value = format!("{}{}", - &self.value[0..self.cursor.min(last)], - &self.value[self.cursor.min(last)..last] - ); - self.cursor = self.cursor.saturating_sub(1) +impl Handle for TransportQuantize { + fn handle (&mut self, from: &Tui) -> Perhaps { + match e { + AppEvent::Input(Event::Key(k)) => { + match k.code { + KeyCode::Esc => { + self.exit(); + }, + KeyCode::Enter => { + *self.result.write().unwrap() = self.value.clone(); + self.exit(); + }, + KeyCode::Left => { + self.cursor = self.cursor.saturating_sub(1); + }, + KeyCode::Right => { + self.cursor = self.value.len().min(self.cursor + 1) + }, + KeyCode::Backspace => { + let last = self.value.len().saturating_sub(1); + self.value = format!("{}{}", + &self.value[0..self.cursor.min(last)], + &self.value[self.cursor.min(last)..last] + ); + self.cursor = self.cursor.saturating_sub(1) + } + KeyCode::Char(c) => { + self.value.insert(self.cursor, c); + self.cursor = self.value.len().min(self.cursor + 1) + }, + _ => {} } - KeyCode::Char(c) => { - self.value.insert(self.cursor, c); - self.cursor = self.value.len().min(self.cursor + 1) - }, - _ => {} - } - Ok(true) - }, - _ => Ok(false), + Ok(true) + }, + _ => Ok(false), + } } -}); +} impl Exit for ArrangerRenameModal { fn exited (&self) -> bool { self.done diff --git a/crates/tek_sequencer/src/arranger_view_h.rs b/crates/tek_sequencer/src/arranger_view_h.rs index 6d7d8271..bcd4130f 100644 --- a/crates/tek_sequencer/src/arranger_view_h.rs +++ b/crates/tek_sequencer/src/arranger_view_h.rs @@ -1,9 +1,7 @@ use crate::*; -pub fn draw <'a> ( - state: &Arranger, Rect>, to: &mut TuiOutput<'a> -) -> Perhaps { - let mut area = to.area; +pub fn draw (state: &Arranger, to: &mut Tui) -> Perhaps { + let mut area = to.area(); area.height = area.height.min((2 + state.tracks.len() * 2) as u16); let tracks = state.tracks.as_slice(); Layered::new() @@ -21,10 +19,10 @@ pub fn draw <'a> ( struct TrackNameColumn<'a>(&'a [Sequencer], ArrangerFocus); -impl<'a> Render, Rect> for TrackNameColumn<'a> { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for TrackNameColumn<'a> { + fn render (&self, to: &mut Tui) -> Perhaps { let Self(tracks, selected) = self; - let mut area = to.area; + let mut area = to.area(); let yellow = Some(Style::default().yellow().bold().not_dim()); let white = Some(Style::default().white().bold().not_dim()); area.width = 3 + 5.max(track_name_max_len(tracks)) as u16; @@ -48,10 +46,10 @@ impl<'a> Render, Rect> for TrackNameColumn<'a> { struct TrackMonitorColumn<'a>(&'a [Sequencer]); -impl<'a> Render, Rect> for TrackMonitorColumn<'a> { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for TrackMonitorColumn<'a> { + fn render (&self, to: &mut Tui) -> Perhaps { let Self(tracks) = self; - let mut area = to.area; + let mut area = to.area(); let on = Some(Style::default().not_dim().green().bold()); let off = Some(DIM); area.x += 1; @@ -76,10 +74,10 @@ impl<'a> Render, Rect> for TrackMonitorColumn<'a> { struct TrackRecordColumn<'a>(&'a [Sequencer]); -impl<'a> Render, Rect> for TrackRecordColumn<'a> { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for TrackRecordColumn<'a> { + fn render (&self, to: &mut Tui) -> Perhaps { let Self(tracks) = self; - let mut area = to.area; + let mut area = to.area(); let on = Some(Style::default().not_dim().red().bold()); let off = Some(Style::default().dim()); area.x += 1; @@ -104,10 +102,10 @@ impl<'a> Render, Rect> for TrackRecordColumn<'a> { struct TrackOverdubColumn<'a>(&'a [Sequencer]); -impl<'a> Render, Rect> for TrackOverdubColumn<'a> { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for TrackOverdubColumn<'a> { + fn render (&self, to: &mut Tui) -> Perhaps { let Self(tracks) = self; - let mut area = to.area; + let mut area = to.area(); let on = Some(Style::default().not_dim().yellow().bold()); let off = Some(Style::default().dim()); area.x = area.x + 1; @@ -135,10 +133,10 @@ impl<'a> Render, Rect> for TrackOverdubColumn<'a> { struct TrackEraseColumn<'a>(&'a [Sequencer]); -impl<'a> Render, Rect> for TrackEraseColumn<'a> { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for TrackEraseColumn<'a> { + fn render (&self, to: &mut Tui) -> Perhaps { let Self(tracks) = self; - let mut area = to.area; + let mut area = to.area(); let off = Some(Style::default().dim()); area.x = area.x + 1; for y in 0..area.height { @@ -147,7 +145,7 @@ impl<'a> Render, Rect> for TrackEraseColumn<'a> { } else if y % 2 == 0 { let index = (y as usize - 2) / 2; if let Some(_) = tracks.get(index) { - " DEL ".blit(to.buffer, area.x, area.y + y, off)?; + to.blit(&" DEL ", area.x, area.y + y, off)?; } else { area.height = y; break @@ -161,10 +159,10 @@ impl<'a> Render, Rect> for TrackEraseColumn<'a> { struct TrackGainColumn<'a>(&'a [Sequencer]); -impl<'a> Render, Rect> for TrackGainColumn<'a> { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for TrackGainColumn<'a> { + fn render (&self, to: &mut Tui) -> Perhaps { let Self(tracks) = self; - let mut area = to.area; + let mut area = to.area(); let off = Some(Style::default().dim()); area.x = area.x + 1; for y in 0..area.height { @@ -173,7 +171,7 @@ impl<'a> Render, Rect> for TrackGainColumn<'a> { } else if y % 2 == 0 { let index = (y as usize - 2) / 2; if let Some(_) = tracks.get(index) { - " +0.0 ".blit(to.buffer, area.x, area.y + y, off)?; + to.blit(&" +0.0 ", area.x, area.y + y, off)?; } else { area.height = y; break @@ -187,10 +185,10 @@ impl<'a> Render, Rect> for TrackGainColumn<'a> { struct TrackScenesColumn<'a>(&'a [Sequencer], &'a [Scene], ArrangerFocus); -impl<'a> Render, Rect> for TrackScenesColumn<'a> { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for TrackScenesColumn<'a> { + fn render (&self, to: &mut Tui) -> Perhaps { let Self(tracks, scenes, selected) = self; - let area = to.area; + let area = to.area(); let mut x2 = 0; let Rect { x, y, height, .. } = area; for (scene_index, scene) in scenes.iter().enumerate() { @@ -201,11 +199,11 @@ impl<'a> Render, Rect> for TrackScenesColumn<'a> { Style::default().dim() }); for y in y+1..y+height { - "│".blit(to.buffer, x + x2, y, sep)?; + to.blit(&"│", x + x2, y, sep)?; } let name = scene.name.read().unwrap(); let mut x3 = name.len() as u16; - name.blit(to.buffer, x + x2, y, sep)?; + to.blit(&name, x + x2, y, sep)?; for (i, clip) in scene.clips.iter().enumerate() { let active_track = selected.track() == Some(i); if let Some(clip) = clip { @@ -214,7 +212,7 @@ impl<'a> Render, Rect> for TrackScenesColumn<'a> { Some(phrase) => &format!("{}", phrase.read().unwrap().name.read().unwrap()), None => "...." }; - label.blit(to.buffer, x + x2, y2, Some(if active_track && active_scene { + to.blit(&label, x + x2, y2, Some(if active_track && active_scene { Style::default().not_dim().yellow().bold() } else { Style::default().not_dim() diff --git a/crates/tek_sequencer/src/sequencer_handle.rs b/crates/tek_sequencer/src/sequencer_handle.rs index 4b97a5ac..5b93e418 100644 --- a/crates/tek_sequencer/src/sequencer_handle.rs +++ b/crates/tek_sequencer/src/sequencer_handle.rs @@ -1,6 +1,10 @@ use crate::*; -handle!(Sequencer |self, e| handle_keymap(self, e, KEYMAP_SEQUENCER)); +impl Handle for TransportQuantize { + fn handle (&mut self, from: &Tui) -> Perhaps { + handle_keymap(self, e, KEYMAP_SEQUENCER) + } +} /// Key bindings for phrase editor. pub const KEYMAP_SEQUENCER: &'static [KeyBinding] = keymap!(Sequencer { diff --git a/crates/tek_sequencer/src/sequencer_view.rs b/crates/tek_sequencer/src/sequencer_view.rs index 881cd2f3..bad0a558 100644 --- a/crates/tek_sequencer/src/sequencer_view.rs +++ b/crates/tek_sequencer/src/sequencer_view.rs @@ -1,12 +1,12 @@ use crate::*; -impl<'a> Render, Rect> for Sequencer { - fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps { +impl<'a> Render for Sequencer { + fn render (&self, to: &mut Tui) -> Perhaps { self.horizontal_draw(to)?; if self.focused && self.entered { - Corners(Style::default().green().not_dim()).draw(to.buffer, to.area)?; + Corners(Style::default().green().not_dim()).draw(to)?; } - Ok(Some(to.area)) + Ok(Some(to.area())) } } diff --git a/crates/tek_sequencer/src/sequencer_view_h.rs b/crates/tek_sequencer/src/sequencer_view_h.rs index d338fd97..2db221a1 100644 --- a/crates/tek_sequencer/src/sequencer_view_h.rs +++ b/crates/tek_sequencer/src/sequencer_view_h.rs @@ -4,8 +4,8 @@ impl Sequencer { const H_KEYS_OFFSET: usize = 5; - pub(crate) fn horizontal_draw <'a> (&self, to: &mut TuiOutput<'a>) -> Usually<()> { - let mut area = to.area; + pub(crate) fn horizontal_draw <'a> (&self, to: &mut Tui) -> Usually<()> { + let mut area = to.area(); Split::down() .add_ref(&SequenceName(&self)) .add_ref(&SequenceRange) @@ -32,7 +32,10 @@ impl Sequencer { .add_ref(&SequenceNotes(&self)) .add_ref(&SequenceCursor(&self)) .add_ref(&SequenceZoom(&self)) - .render(&mut TuiOutput { buffer: to.buffer, area: area })?; + .render(&mut TuiOutput { + buffer: to.buffer, + area: area + })?; Ok(()) } @@ -56,9 +59,9 @@ const STYLE_VALUE: Option