From 2a60808239be9d052f5ad4f86f4a0fa892ed1ce3 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Tue, 6 Aug 2024 16:43:04 +0300 Subject: [PATCH] wip: fixing some assumptions --- crates/tek_chain/src/chain.rs | 35 +++++++------ crates/tek_chain/src/chain_view.rs | 46 +++++++++-------- crates/tek_core/src/render.rs | 2 +- crates/tek_sequencer/src/arranger.rs | 13 ++--- crates/tek_sequencer/src/arranger_scene.rs | 6 +-- crates/tek_sequencer/src/arranger_track.rs | 14 ++--- crates/tek_sequencer/src/arranger_view_h.rs | 1 - crates/tek_sequencer/src/arranger_view_v.rs | 6 --- crates/tek_sequencer/src/lib.rs | 17 +++++- crates/tek_sequencer/src/sequencer.rs | 1 - crates/tek_sequencer/src/sequencer_track.rs | 57 --------------------- 11 files changed, 73 insertions(+), 125 deletions(-) diff --git a/crates/tek_chain/src/chain.rs b/crates/tek_chain/src/chain.rs index 885b8463..75471c9a 100644 --- a/crates/tek_chain/src/chain.rs +++ b/crates/tek_chain/src/chain.rs @@ -24,26 +24,27 @@ impl Chain { pub fn device_mut (&self) -> Option>> { self.get_device_mut(self.device) } - 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(()) - } - pub fn connect_last_device (&self, app: &App) -> Usually<()> { - Ok(match self.devices.get(self.devices.len().saturating_sub(1)) { - Some(device) => { - app.audio_out(0).map(|left|device.connect_audio_out(0, &left)).transpose()?; - app.audio_out(1).map(|right|device.connect_audio_out(1, &right)).transpose()?; - () - }, - None => () - }) - } - pub fn add_device (&mut self, device: JackDevice) -> Usually<&mut JackDevice> { + /// Add a device to the end of the chain. + pub fn append_device (&mut self, device: JackDevice) -> Usually<&mut JackDevice> { self.devices.push(device); let index = self.devices.len() - 1; Ok(&mut self.devices[index]) } + //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(()) + //} + //pub fn connect_last_device (&self, app: &App) -> Usually<()> { + //Ok(match self.devices.get(self.devices.len().saturating_sub(1)) { + //Some(device) => { + //app.audio_out(0).map(|left|device.connect_audio_out(0, &left)).transpose()?; + //app.audio_out(1).map(|right|device.connect_audio_out(1, &right)).transpose()?; + //() + //}, + //None => () + //}) + //} } diff --git a/crates/tek_chain/src/chain_view.rs b/crates/tek_chain/src/chain_view.rs index 6f6147e2..cb2cebba 100644 --- a/crates/tek_chain/src/chain_view.rs +++ b/crates/tek_chain/src/chain_view.rs @@ -2,39 +2,26 @@ use crate::*; use tek_core::Direction; pub struct ChainView<'a> { - pub track: Option<&'a Chain>, + pub chain: Option<&'a Chain>, pub direction: Direction, pub focused: bool, pub entered: bool, } -impl<'a> ChainView<'a> { - pub fn horizontal (app: &'a App) -> Self { - Self::new(app, Direction::Right) - } - pub fn vertical (app: &'a App) -> Self { - Self::new(app, Direction::Down) - } - pub fn new (app: &'a App, direction: Direction) -> Self { - Self { - direction, - entered: app.entered, - focused: app.section == AppFocus::Chain, - track: app.arranger.track() - } - } -} - impl<'a> Render for ChainView<'a> { fn render (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - if let Some(track) = self.track { + if let Some(chain) = self.chain { match self.direction { Direction::Down => area.width = area.width.min(40), Direction::Right => area.width = area.width.min(10), } fill_bg(buf, area, Nord::bg_lo(self.focused, self.entered)); + let devices: Vec<&(dyn Render + Send + Sync)> = chain.devices.as_slice() + .iter() + .map(|d|d as &(dyn Render + Send + Sync)) + .collect(); let (area, areas) = self.direction - .split_focus(0, track.devices.as_slice(), if self.focused { + .split_focus(0, devices.as_slice(), if self.focused { Style::default().green().dim() } else { Style::default().dim() @@ -46,7 +33,7 @@ impl<'a> Render for ChainView<'a> { Ok(area) } else { let Rect { x, y, width, height } = area; - let label = "No track selected"; + let label = "No chain selected"; let x = x + (width - label.len() as u16) / 2; let y = y + height / 2; label.blit(buf, x, y, Some(Style::default().dim().bold()))?; @@ -55,4 +42,19 @@ impl<'a> Render for ChainView<'a> { } } - +//impl<'a> ChainView<'a> { + //pub fn horizontal (app: &'a App) -> Self { + //Self::new(app, Direction::Right) + //} + //pub fn vertical (app: &'a App) -> Self { + //Self::new(app, Direction::Down) + //} + //pub fn new (app: &'a App, direction: Direction) -> Self { + //Self { + //direction, + //entered: app.entered, + //focused: app.section == AppFocus::Chain, + //chain: app.arranger.chain() + //} + //} +//} diff --git a/crates/tek_core/src/render.rs b/crates/tek_core/src/render.rs index 4ab823ef..582d4438 100644 --- a/crates/tek_core/src/render.rs +++ b/crates/tek_core/src/render.rs @@ -291,7 +291,7 @@ impl<'a, const N: usize> Render for Split<'a, N> { } } -type Renderables<'a> = &'a [&'a dyn Component]; +type Renderables<'a> = &'a [&'a (dyn Render + Send + Sync)]; pub struct SplitFocus<'a>(pub Direction, pub usize, pub Renderables<'a>, pub Style); diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index d645c71c..dec7882b 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -2,11 +2,6 @@ use crate::*; -use self::arr_focus::ArrangerFocus; -pub use self::arr_scene::Scene; - -submod! { arr_draw_h arr_draw_v arr_focus arr_phrase arr_scene arr_track } - /// 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| { @@ -68,7 +63,7 @@ pub struct Arranger { /// Currently selected element. pub selected: ArrangerFocus, /// Collection of tracks. - pub tracks: Vec, + pub tracks: Vec, /// Collection of scenes. pub scenes: Vec, @@ -135,10 +130,10 @@ impl Arranger { render!(Arranger |self, buf, area| match self.mode { ArrangerViewMode::Horizontal => - self::arr_draw_h::draw(self, buf, area), + super::arranger_view_h::draw(self, buf, area), ArrangerViewMode::Vertical => - self::arr_draw_v::draw_expanded(self, buf, area), + super::arranger_view_v::draw_expanded(self, buf, area), ArrangerViewMode::VerticalCompact => - self::arr_draw_v::draw_compact(self, buf, area), + super::arranger_view_v::draw_compact(self, buf, area), }); diff --git a/crates/tek_sequencer/src/arranger_scene.rs b/crates/tek_sequencer/src/arranger_scene.rs index 51fefeba..b4c6e019 100644 --- a/crates/tek_sequencer/src/arranger_scene.rs +++ b/crates/tek_sequencer/src/arranger_scene.rs @@ -15,14 +15,14 @@ impl Scene { Self { name, clips, } } /// Returns the pulse length of the longest phrase in the scene - pub fn pulses (&self, tracks: &[Track]) -> usize { + pub fn pulses (&self, tracks: &[SequencerTrack]) -> usize { self.clips.iter().enumerate() .filter_map(|(i, c)|c.map(|c|tracks[i].phrases.get(c))) .filter_map(|p|p) .fold(0, |a, p|a.max(p.read().unwrap().length)) } /// Returns true if all phrases in the scene are currently playing - pub fn is_playing (&self, tracks: &[Track]) -> bool { + pub fn is_playing (&self, tracks: &[SequencerTrack]) -> bool { self.clips.iter().enumerate() .all(|(track_index, phrase_index)|match phrase_index { Some(i) => tracks[track_index].sequence == Some(*i), @@ -37,7 +37,7 @@ pub fn scene_name_max_len (scenes: &[Scene]) -> usize { .fold(0, usize::max) } -pub fn scene_ppqs (tracks: &[Track], scenes: &[Scene]) -> Vec<(usize, usize)> { +pub fn scene_ppqs (tracks: &[SequencerTrack], scenes: &[Scene]) -> Vec<(usize, usize)> { let mut total = 0; let mut scenes: Vec<(usize, usize)> = scenes.iter().map(|scene|{ let pulses = scene.pulses(tracks); diff --git a/crates/tek_sequencer/src/arranger_track.rs b/crates/tek_sequencer/src/arranger_track.rs index f4e43a80..a7c78fc5 100644 --- a/crates/tek_sequencer/src/arranger_track.rs +++ b/crates/tek_sequencer/src/arranger_track.rs @@ -4,10 +4,10 @@ use super::Arranger; /// Track management methods impl Arranger { - pub fn track (&self) -> Option<&Track> { + pub fn track (&self) -> Option<&SequencerTrack> { self.selected.track().map(|t|self.tracks.get(t)).flatten() } - pub fn track_mut (&mut self) -> Option<&mut Track> { + pub fn track_mut (&mut self) -> Option<&mut SequencerTrack> { self.selected.track().map(|t|self.tracks.get_mut(t)).flatten() } pub fn track_next (&mut self) { @@ -16,10 +16,10 @@ impl Arranger { pub fn track_prev (&mut self) { self.selected.track_prev() } - pub fn track_add (&mut self, name: Option<&str>) -> Usually<&mut Track> { + pub fn track_add (&mut self, name: Option<&str>) -> Usually<&mut SequencerTrack> { self.tracks.push(name.map_or_else( - || Track::new(&self.track_default_name()), - |name| Track::new(name), + || SequencerTrack::new(&self.track_default_name()), + |name| SequencerTrack::new(name), )?); let index = self.tracks.len() - 1; Ok(&mut self.tracks[index]) @@ -32,13 +32,13 @@ impl Arranger { } } -pub fn track_name_max_len (tracks: &[Track]) -> usize { +pub fn track_name_max_len (tracks: &[SequencerTrack]) -> usize { tracks.iter() .map(|s|s.name.len()) .fold(0, usize::max) } -pub fn track_clip_name_lengths (tracks: &[Track]) -> Vec<(usize, usize)> { +pub fn track_clip_name_lengths (tracks: &[SequencerTrack]) -> Vec<(usize, usize)> { let mut total = 0; let mut lengths: Vec<(usize, usize)> = tracks.iter().map(|track|{ let len = 2 + track.phrases diff --git a/crates/tek_sequencer/src/arranger_view_h.rs b/crates/tek_sequencer/src/arranger_view_h.rs index 5db1d47b..9a0d76d7 100644 --- a/crates/tek_sequencer/src/arranger_view_h.rs +++ b/crates/tek_sequencer/src/arranger_view_h.rs @@ -1,5 +1,4 @@ use crate::*; -use super::{Arranger, arr_track::*}; pub fn draw (state: &Arranger, buf: &mut Buffer, mut area: Rect) -> Usually { area.height = area.height.min((2 + state.tracks.len() * 2) as u16); diff --git a/crates/tek_sequencer/src/arranger_view_v.rs b/crates/tek_sequencer/src/arranger_view_v.rs index d2a9b096..27145c66 100644 --- a/crates/tek_sequencer/src/arranger_view_v.rs +++ b/crates/tek_sequencer/src/arranger_view_v.rs @@ -1,10 +1,4 @@ use crate::*; -use super::{ - Arranger, - arr_focus::ArrangerFocus, - arr_track::track_clip_name_lengths, - arr_scene::{Scene, scene_ppqs, scene_name_max_len} -}; pub fn draw_expanded (state: &Arranger, buf: &mut Buffer, area: Rect) -> Usually { let track_cols = track_clip_name_lengths(state.tracks.as_slice()); diff --git a/crates/tek_sequencer/src/lib.rs b/crates/tek_sequencer/src/lib.rs index 518cf6c8..fb4aca4f 100644 --- a/crates/tek_sequencer/src/lib.rs +++ b/crates/tek_sequencer/src/lib.rs @@ -8,7 +8,22 @@ pub(crate) use tek_jack::{*, jack::*}; pub(crate) use tek_timer::*; pub(crate) use std::sync::{Arc, RwLock}; -submod! { midi phrase arranger sequencer sequencer_track } +submod! { + midi + phrase + sequencer + sequencer_track + arranger + arranger_focus + arranger_phrase + arranger_scene + arranger_track +} + +pubmod! { + arranger_view_h + arranger_view_v +} /// Key bindings for phrase editor. pub const KEYMAP_SEQUENCER: &'static [KeyBinding] = keymap!(Sequencer { diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index 6bfcba47..a08beef7 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -18,7 +18,6 @@ pub struct Sequencer { pub ppq: usize, pub note_axis: FixedAxis, pub time_axis: ScaledAxis, - } render!(Sequencer |self, buf, area| { diff --git a/crates/tek_sequencer/src/sequencer_track.rs b/crates/tek_sequencer/src/sequencer_track.rs index 15d54b49..7cb3806e 100644 --- a/crates/tek_sequencer/src/sequencer_track.rs +++ b/crates/tek_sequencer/src/sequencer_track.rs @@ -168,60 +168,3 @@ impl SequencerTrack { } } } - - -pub struct ChainView<'a> { - pub track: Option<&'a Track>, - pub direction: Direction, - pub focused: bool, - pub entered: bool, -} - -impl<'a> ChainView<'a> { - pub fn horizontal (app: &'a App) -> Self { - Self::new(app, Direction::Right) - } - pub fn vertical (app: &'a App) -> Self { - Self::new(app, Direction::Down) - } - pub fn new (app: &'a App, direction: Direction) -> Self { - Self { - direction, - entered: app.entered, - focused: app.section == AppFocus::Chain, - track: app.arranger.track() - } - } -} - -impl<'a> Render for ChainView<'a> { - fn render (&self, buf: &mut Buffer, mut area: Rect) -> Usually { - if let Some(track) = self.track { - match self.direction { - Direction::Down => area.width = area.width.min(40), - Direction::Right => area.width = area.width.min(10), - } - fill_bg(buf, area, Nord::bg_lo(self.focused, self.entered)); - let (area, areas) = self.direction - .split_focus(0, track.devices.as_slice(), if self.focused { - Style::default().green().dim() - } else { - Style::default().dim() - }) - .render_areas(buf, area)?; - if self.focused && self.entered { - Corners(Style::default().green().not_dim()).draw(buf, areas[0])?; - } - Ok(area) - } else { - let Rect { x, y, width, height } = area; - let label = "No track selected"; - let x = x + (width - label.len() as u16) / 2; - let y = y + height / 2; - label.blit(buf, x, y, Some(Style::default().dim().bold()))?; - Ok(area) - } - } -} - -