From 7685072e4c1407f5f646a6f333524b9e8958ec71 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 10 Aug 2024 14:23:51 +0300 Subject: [PATCH] wip: enabling standalone arranger --- crates/tek/src/app.rs | 2 +- crates/tek_sequencer/Cargo.toml | 6 +- crates/tek_sequencer/src/arranger.rs | 80 +---- crates/tek_sequencer/src/arranger_cli.rs | 40 +++ crates/tek_sequencer/src/arranger_handle.rs | 57 ++++ crates/tek_sequencer/src/arranger_main.rs | 5 + crates/tek_sequencer/src/arranger_view.rs | 16 + crates/tek_sequencer/src/lib.rs | 6 +- crates/tek_sequencer/src/sequencer.rs | 286 ----------------- crates/tek_sequencer/src/sequencer_cli.rs | 4 +- ...quencer_control.rs => sequencer_handle.rs} | 2 + .../src/{main.rs => sequencer_main.rs} | 0 crates/tek_sequencer/src/sequencer_render.rs | 287 ++++++++++++++++++ crates/tek_timer/README.md | 10 + crates/tek_timer/src/transport.rs | 7 +- crates/tek_timer/src/transport_render.rs | 7 +- 16 files changed, 445 insertions(+), 370 deletions(-) create mode 100644 crates/tek_sequencer/src/arranger_cli.rs create mode 100644 crates/tek_sequencer/src/arranger_handle.rs create mode 100644 crates/tek_sequencer/src/arranger_main.rs create mode 100644 crates/tek_sequencer/src/arranger_view.rs rename crates/tek_sequencer/src/{sequencer_control.rs => sequencer_handle.rs} (95%) rename crates/tek_sequencer/src/{main.rs => sequencer_main.rs} (100%) create mode 100644 crates/tek_sequencer/src/sequencer_render.rs diff --git a/crates/tek/src/app.rs b/crates/tek/src/app.rs index 8f332739..5e6d1044 100644 --- a/crates/tek/src/app.rs +++ b/crates/tek/src/app.rs @@ -47,7 +47,7 @@ impl App { entered: true, section: AppFocus::default(), transport: TransportToolbar::new(Some(jack.transport())), - arranger: Arranger::new(), + arranger: Arranger::new(""), mixer: Mixer::new("")?, jack: Some(jack), audio_outs: vec![], diff --git a/crates/tek_sequencer/Cargo.toml b/crates/tek_sequencer/Cargo.toml index 0cada3ff..e1ac9479 100644 --- a/crates/tek_sequencer/Cargo.toml +++ b/crates/tek_sequencer/Cargo.toml @@ -13,4 +13,8 @@ path = "src/lib.rs" [[bin]] name = "tek_sequencer" -path = "src/main.rs" +path = "src/sequencer_main.rs" + +[[bin]] +name = "tek_arranger" +path = "src/arranger_main.rs" diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index ff01585b..a9a3239a 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -4,6 +4,8 @@ use crate::*; /// Represents the tracks and scenes of the composition. pub struct Arranger { + /// Name of arranger + pub name: String, /// Display mode of arranger pub mode: ArrangerViewMode, /// Currently selected element. @@ -16,28 +18,13 @@ pub struct Arranger { pub entered: bool, pub fixed_height: bool, pub sequencer: Sequencer, -} - -/// Display mode of arranger -pub enum ArrangerViewMode { - Vertical, - VerticalCompact, - Horizontal, -} - -impl ArrangerViewMode { - fn to_next (&mut self) { - *self = match self { - Self::Vertical => Self::VerticalCompact, - Self::VerticalCompact => Self::Horizontal, - Self::Horizontal => Self::Vertical, - } - } + pub transport: Option>>, } impl Arranger { - pub fn new () -> Self { + pub fn new (name: &str) -> Self { Self { + name: name.into(), mode: ArrangerViewMode::Vertical, selected: ArrangerFocus::Clip(0, 0), scenes: vec![], @@ -46,6 +33,7 @@ impl Arranger { focused: true, fixed_height: false, sequencer: Sequencer::new(), + transport: None } } pub fn activate (&mut self) { @@ -63,7 +51,7 @@ impl Arranger { _ => {} } } - fn show_phrase (&mut self) -> Usually<()> { + pub fn show_phrase (&mut self) -> Usually<()> { unimplemented!() //let phrase = self.phrase(); //self.sequencer.show(phrase) @@ -155,57 +143,3 @@ render!(Arranger |self, buf, area| match self.mode { ArrangerViewMode::VerticalCompact => super::arranger_view_v::draw_compact(self, buf, area), }); - -/// Key bindings for arranger section. -pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { - [Char('`'), NONE, "arranger_mode_switch", "switch the display mode", |app: &mut Arranger| { - app.mode.to_next(); - Ok(true) - }], - [Up, NONE, "arranger_cursor_up", "move cursor up", |app: &mut Arranger| { - match app.mode { - ArrangerViewMode::Horizontal => app.track_prev(), - _ => app.scene_prev(), - }; - app.show_phrase()?; - Ok(true) - }], - [Down, NONE, "arranger_cursor_down", "move cursor down", |app: &mut Arranger| { - match app.mode { - ArrangerViewMode::Horizontal => app.track_next(), - _ => app.scene_next(), - }; - app.show_phrase()?; - Ok(true) - }], - [Left, NONE, "arranger_cursor_left", "move cursor left", |app: &mut Arranger| { - match app.mode { - ArrangerViewMode::Horizontal => app.scene_prev(), - _ => app.track_prev(), - }; - app.show_phrase()?; - Ok(true) - }], - [Right, NONE, "arranger_cursor_right", "move cursor right", |app: &mut Arranger| { - match app.mode { - ArrangerViewMode::Horizontal => app.scene_next(), - _ => app.track_next(), - }; - app.show_phrase()?; - Ok(true) - }], - [Char('.'), NONE, "arranger_increment", "set next clip at cursor", |app: &mut Arranger| { - app.phrase_next(); - app.sequencer.phrase = app.phrase().map(Clone::clone); - Ok(true) - }], - [Char(','), NONE, "arranger_decrement", "set previous clip at cursor", |app: &mut Arranger| { - app.phrase_prev(); - app.sequencer.phrase = app.phrase().map(Clone::clone); - Ok(true) - }], - [Enter, NONE, "arranger_activate", "activate item at cursor", |app: &mut Arranger| { - app.activate(); - Ok(true) - }], -}); diff --git a/crates/tek_sequencer/src/arranger_cli.rs b/crates/tek_sequencer/src/arranger_cli.rs new file mode 100644 index 00000000..c3a32573 --- /dev/null +++ b/crates/tek_sequencer/src/arranger_cli.rs @@ -0,0 +1,40 @@ +use tek_core::clap::{self, Parser}; +use tek_timer::TransportToolbar; +use crate::*; + +#[derive(Debug, Parser)] +#[command(version, about, long_about = None)] +pub struct ArrangerCli { + /// Name of JACK client + #[arg(short, long)] name: Option, + /// Pulses per quarter note (arruencer resolution; default: 96) + #[arg(short, long)] ppq: Option, + /// Whether to include a transport toolbar (default: true) + #[arg(short, long)] transport: Option, + /// Number of tracks + #[arg(short = 'x', long)] tracks: Option, + /// Number of scenes + #[arg(short, long)] scenes: Option, +} + +impl Arranger { + pub fn from_args () -> Usually { + let args = ArrangerCli::parse(); + let mut arr = Self::new(""); + if let Some(name) = args.name { + arr.name = name.clone(); + } + if args.transport == Some(true) { + arr.transport = Some(Arc::new(RwLock::new(TransportToolbar::new(None)))); + } + if let Some(tracks) = args.tracks { + for track in 0..tracks { + arr.track_add(None)?; + if let Some(scenes) = args.scenes { + } + } + } + Ok(arr) + } +} + diff --git a/crates/tek_sequencer/src/arranger_handle.rs b/crates/tek_sequencer/src/arranger_handle.rs new file mode 100644 index 00000000..fab477a6 --- /dev/null +++ b/crates/tek_sequencer/src/arranger_handle.rs @@ -0,0 +1,57 @@ +use crate::*; + +handle!(Arranger |self, e| handle_keymap(self, e, KEYMAP_ARRANGER)); + +/// Key bindings for arranger section. +pub const KEYMAP_ARRANGER: &'static [KeyBinding] = keymap!(Arranger { + [Char('`'), NONE, "arranger_mode_switch", "switch the display mode", |arranger: &mut Arranger| { + arranger.mode.to_next(); + Ok(true) + }], + [Up, NONE, "arranger_cursor_up", "move cursor up", |arranger: &mut Arranger| { + match arranger.mode { + ArrangerViewMode::Horizontal => arranger.track_prev(), + _ => arranger.scene_prev(), + }; + arranger.show_phrase()?; + Ok(true) + }], + [Down, NONE, "arranger_cursor_down", "move cursor down", |arranger: &mut Arranger| { + match arranger.mode { + ArrangerViewMode::Horizontal => arranger.track_next(), + _ => arranger.scene_next(), + }; + arranger.show_phrase()?; + Ok(true) + }], + [Left, NONE, "arranger_cursor_left", "move cursor left", |arranger: &mut Arranger| { + match arranger.mode { + ArrangerViewMode::Horizontal => arranger.scene_prev(), + _ => arranger.track_prev(), + }; + arranger.show_phrase()?; + Ok(true) + }], + [Right, NONE, "arranger_cursor_right", "move cursor right", |arranger: &mut Arranger| { + match arranger.mode { + ArrangerViewMode::Horizontal => arranger.scene_next(), + _ => arranger.track_next(), + }; + arranger.show_phrase()?; + Ok(true) + }], + [Char('.'), NONE, "arranger_increment", "set next clip at cursor", |arranger: &mut Arranger| { + arranger.phrase_next(); + arranger.sequencer.phrase = arranger.phrase().map(Clone::clone); + Ok(true) + }], + [Char(','), NONE, "arranger_decrement", "set previous clip at cursor", |arranger: &mut Arranger| { + arranger.phrase_prev(); + arranger.sequencer.phrase = arranger.phrase().map(Clone::clone); + Ok(true) + }], + [Enter, NONE, "arranger_activate", "activate item at cursor", |arranger: &mut Arranger| { + arranger.activate(); + Ok(true) + }], +}); diff --git a/crates/tek_sequencer/src/arranger_main.rs b/crates/tek_sequencer/src/arranger_main.rs new file mode 100644 index 00000000..7601f2a5 --- /dev/null +++ b/crates/tek_sequencer/src/arranger_main.rs @@ -0,0 +1,5 @@ +include!("lib.rs"); +pub fn main () -> Usually<()> { + tek_core::run(Arc::new(RwLock::new(crate::Arranger::from_args()?)))?; + Ok(()) +} diff --git a/crates/tek_sequencer/src/arranger_view.rs b/crates/tek_sequencer/src/arranger_view.rs new file mode 100644 index 00000000..f820426e --- /dev/null +++ b/crates/tek_sequencer/src/arranger_view.rs @@ -0,0 +1,16 @@ +/// Display mode of arranger +pub enum ArrangerViewMode { + Vertical, + VerticalCompact, + Horizontal, +} + +impl ArrangerViewMode { + pub fn to_next (&mut self) { + *self = match self { + Self::Vertical => Self::VerticalCompact, + Self::VerticalCompact => Self::Horizontal, + Self::Horizontal => Self::Vertical, + } + } +} diff --git a/crates/tek_sequencer/src/lib.rs b/crates/tek_sequencer/src/lib.rs index 118406ba..8b61cf57 100644 --- a/crates/tek_sequencer/src/lib.rs +++ b/crates/tek_sequencer/src/lib.rs @@ -13,11 +13,15 @@ submod! { phrase sequencer sequencer_cli - sequencer_control + sequencer_handle + sequencer_render sequencer_track arranger + arranger_cli arranger_focus + arranger_handle arranger_track + arranger_view scene } diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index 975fe39c..77813de4 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -22,17 +22,6 @@ pub struct Sequencer { pub time_axis: ScaledAxis, } -render!(Sequencer |self, buf, area| { - fill_bg(buf, area, Nord::bg_lo(self.focused, self.entered)); - self.horizontal_draw(buf, area)?; - if self.focused && self.entered { - Corners(Style::default().green().not_dim()).draw(buf, area)?; - } - Ok(area) -}); - -handle!(Sequencer |self, e| handle_keymap(self, e, KEYMAP_SEQUENCER)); - impl Sequencer { pub fn new () -> Self { Self { @@ -59,279 +48,4 @@ impl Sequencer { }, } } - /// Select which pattern to display. This pre-renders it to the buffer at full resolution. - /// FIXME: Support phrases longer that 65536 ticks - pub fn show (&mut self, phrase: Option<&Arc>>) -> Usually<()> { - self.phrase = phrase.map(Clone::clone); - if let Some(ref phrase) = self.phrase { - let width = usize::MAX.min(phrase.read().unwrap().length); - let mut buffer = BigBuffer::new(width, 64); - let phrase = phrase.read().unwrap(); - fill_seq_bg(&mut buffer, phrase.length, self.ppq)?; - fill_seq_fg(&mut buffer, &phrase)?; - self.buffer = buffer; - } else { - self.buffer = Default::default(); - } - Ok(()) - } - - fn style_focus (&self) -> Option