diff --git a/config/config_groovebox.edn b/config/config_groovebox.edn index fec1ca2d..d6d72f4d 100644 --- a/config/config_groovebox.edn +++ b/config/config_groovebox.edn @@ -10,7 +10,7 @@ (bsp/e :view-meters-input (bsp/n :view-sample-info (bsp/n (fixed/y 5 :view-sample-viewer) - (bsp/w (fixed/x :w-sidebar :view-pool) + (bsp/w :view-pool (bsp/e :view-samples-keys (fill/y :view-editor))))))))))) diff --git a/crates/app/src/model.rs b/crates/app/src/model.rs index c04f1fb3..8c39ba87 100644 --- a/crates/app/src/model.rs +++ b/crates/app/src/model.rs @@ -171,15 +171,15 @@ content!(TuiOut: |self: Message| match self { Self::FailedToAddDevice => "Failed #[tengri_proc::expose] impl App { - fn _todo_u16_stub (&self) -> u16 { - todo!() - } fn _todo_isize_stub (&self) -> isize { todo!() } fn _todo_item_theme_stub (&self) -> ItemTheme { todo!() } + fn w_sidebar (&self) -> u16 { + self.project.w_sidebar(self.editor.is_some()) + } fn focus_editor (&self) -> bool { self.is_editing() } diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index 55980e5e..2d682638 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -33,9 +33,7 @@ impl App { ArrangerView::new(&self.project, self.editor.as_ref()) } pub fn view_pool (&self) -> impl Content + use<'_> { - let is_editing = self.is_editing(); - Fixed::x(self.project.w_sidebar(is_editing), - PoolView(is_editing, &self.project.pool)) + PoolView(&self.project.pool) } pub fn view_samples_keys (&self) -> impl Content + use<'_> { self.project.sampler().map(|s|s.view_list(false, self.editor().unwrap())) diff --git a/crates/cli/tek.rs b/crates/cli/tek.rs index c1954cb7..1d407373 100644 --- a/crates/cli/tek.rs +++ b/crates/cli/tek.rs @@ -72,43 +72,24 @@ pub enum LaunchMode { impl Cli { pub fn run (&self) -> Usually<()> { - let name = self.name.as_ref().map_or("tek", |x|x.as_str()); - let mode = &self.mode; - let empty = &[] as &[&str]; - let midi_froms = PortConnect::collect(&self.midi_from, empty, &self.midi_from_re); - let midi_tos = PortConnect::collect(&self.midi_to, empty, &self.midi_to_re); - let left_froms = PortConnect::collect(&self.left_from, empty, empty); - let left_tos = PortConnect::collect(&self.left_to, empty, empty); - let right_froms = PortConnect::collect(&self.right_from, empty, empty); - let right_tos = PortConnect::collect(&self.right_to, empty, empty); - let audio_froms = &[left_froms.as_slice(), right_froms.as_slice()]; - let audio_tos = &[left_tos.as_slice(), right_tos.as_slice()]; - let clip = match mode { - LaunchMode::Sequencer | LaunchMode::Groovebox => - Some(Arc::new(RwLock::new(MidiClip::new( - "Clip", true, 384usize, None, Some(ItemColor::random().into())), - ))), - _ => None, - }; - let scenes = vec![]; - let mut tracks = vec![]; - match mode { - LaunchMode::Sequencer => tracks.push(Track::new( - &name, None, jack, - Some(&clock), clip.as_ref(), - midi_froms.as_slice(), midi_tos.as_slice() - )?), - LaunchMode::Groovebox | LaunchMode::Sampler => tracks.push(Track::new_with_sampler( - &name, None, jack, - Some(&clock), clip.as_ref(), - midi_froms.as_slice(), midi_tos.as_slice(), - audio_froms, audio_tos, - )?), - _ => {} - } + let name = self.name.as_ref().map_or("tek", |x|x.as_str()); + let empty = &[] as &[&str]; + let mut midi_ins = vec![]; + let mut midi_outs = vec![]; + let mut tracks = vec![]; + let mut scenes = vec![]; + let midi_froms = PortConnect::collect(&self.midi_from, empty, &self.midi_from_re); + let midi_tos = PortConnect::collect(&self.midi_to, empty, &self.midi_to_re); + let left_froms = PortConnect::collect(&self.left_from, empty, empty); + let left_tos = PortConnect::collect(&self.left_to, empty, empty); + let right_froms = PortConnect::collect(&self.right_from, empty, empty); + let right_tos = PortConnect::collect(&self.right_to, empty, empty); + let audio_froms = &[left_froms.as_slice(), right_froms.as_slice()]; + let audio_tos = &[left_tos.as_slice(), right_tos.as_slice()]; + let clip = Arc::new(RwLock::new(MidiClip::new( + "Clip", true, 384usize, None, Some(ItemColor::random().into())), + )); Tui::new()?.run(&Jack::new(name)?.run(|jack|{ - let mut midi_ins = vec![]; - let mut midi_outs = vec![]; for (index, connect) in midi_froms.iter().enumerate() { let port = JackMidiIn::new(jack, &format!("M/{index}"), &[connect.clone()])?; midi_ins.push(port); @@ -117,53 +98,57 @@ impl Cli { let port = JackMidiOut::new(jack, &format!("{index}/M"), &[connect.clone()])?; midi_outs.push(port); }; - let config_path = match mode { + let config = Configuration::new(&match self.mode { LaunchMode::Clock => "config/config_transport.edn", LaunchMode::Sequencer => "config/config_sequencer.edn", LaunchMode::Groovebox => "config/config_groovebox.edn", LaunchMode::Arranger { .. } => "config/config_arranger.edn", LaunchMode::Sampler => "config/config_sampler.edn", - _ => todo!("{mode:?}"), - }; - let config = Configuration::new(&config_path, false)?; - let clock = Clock::new(jack, self.bpm)?; + _ => todo!("{:?}", self.mode), + }, false)?; + let clock = Clock::new(jack, self.bpm)?; + match self.mode { + LaunchMode::Sequencer => tracks.push(Track::new( + &name, None, jack, Some(&clock), Some(&clip), + midi_froms.as_slice(), midi_tos.as_slice() + )?), + LaunchMode::Groovebox | LaunchMode::Sampler => tracks.push(Track::new_with_sampler( + &name, None, jack, Some(&clock), Some(&clip), + midi_froms.as_slice(), midi_tos.as_slice(), audio_froms, audio_tos, + )?), + _ => {} + } let mut app = App { - jack: jack.clone(), + jack: jack.clone(), + config, color: ItemTheme::random(), - pool: match mode { - LaunchMode::Sequencer | LaunchMode::Groovebox => clip.as_ref().map(Into::into), - LaunchMode::Arranger { .. } => Some(Default::default()), - _ => None, - }, - editor: match mode { - LaunchMode::Sequencer | LaunchMode::Groovebox => clip.as_ref().map(Into::into), - LaunchMode::Arranger { .. } => Some(Default::default()), + editor: match self.mode { + LaunchMode::Sequencer | LaunchMode::Groovebox => Some((&clip).into()), _ => None }, - midi_ins, - midi_outs, - midi_buf: match mode { - LaunchMode::Clock | - LaunchMode::Sampler => - vec![], - LaunchMode::Sequencer | - LaunchMode::Groovebox | - LaunchMode::Arranger {..} => - vec![vec![];65536], - _ => todo!("{mode:?}"), + project: Arrangement { + name: Default::default(), + color: ItemTheme::random(), + jack: jack.clone(), + clock, + tracks, + scenes, + selection: Selection::TrackClip { track: 0, scene: 0 }, + midi_ins, + midi_outs, + pool: match self.mode { + LaunchMode::Sequencer | LaunchMode::Groovebox => (&clip).into(), + _ => Default::default() + }, + ..Default::default() }, - tracks, - scenes, - selected: Selection::TrackClip { track: 0, scene: 0 }, - config, - clock, ..Default::default() }; - if let &LaunchMode::Arranger { scenes, tracks, track_width, .. } = mode { - app.arranger = Default::default(); - app.selected = Selection::TrackClip { track: 1, scene: 1 }; - app.scenes_add(scenes)?; - app.tracks_add(tracks, Some(track_width), &[], &[])?; + if let LaunchMode::Arranger { scenes, tracks, track_width, .. } = self.mode { + app.project.arranger = Default::default(); + app.project.selection = Selection::TrackClip { track: 1, scene: 1 }; + app.project.scenes_add(scenes)?; + app.project.tracks_add(tracks, Some(track_width), &[], &[])?; } jack.sync_lead(self.sync_lead, |mut state|{ let clock = app.clock(); diff --git a/crates/device/src/arranger/arranger_model.rs b/crates/device/src/arranger/arranger_model.rs index a1d680fc..4e3113c4 100644 --- a/crates/device/src/arranger/arranger_model.rs +++ b/crates/device/src/arranger/arranger_model.rs @@ -18,10 +18,6 @@ pub struct Arrangement { pub audio_ins: Vec, /// List of global audio outputs pub audio_outs: Vec, - /// Buffer for writing a midi event - pub note_buf: Vec, - /// Buffer for writing a chunk of midi events - pub midi_buf: Vec>>, /// Last track number (to avoid duplicate port names) pub track_last: usize, /// List of tracks diff --git a/crates/device/src/pool/pool_view.rs b/crates/device/src/pool/pool_view.rs index 82e74ae0..29e4aa01 100644 --- a/crates/device/src/pool/pool_view.rs +++ b/crates/device/src/pool/pool_view.rs @@ -1,31 +1,31 @@ use crate::*; -pub struct PoolView<'a>(pub bool, pub &'a Pool); +pub struct PoolView<'a>(pub &'a Pool); content!(TuiOut: |self: PoolView<'a>| { - let Self(compact, model) = self; - let Pool { clips, .. } = self.1; + let Self(pool) = self; //let color = self.1.clip().map(|c|c.read().unwrap().color).unwrap_or_else(||Tui::g(32).into()); - let on_bg = |x|x;//Bsp::b(Repeat(" "), Tui::bg(color.darkest.rgb, x)); - let border = |x|x;//Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb)).enclose(x); - let iter = | |model.clips().clone().into_iter(); - let height = clips.read().unwrap().len() as u16; - Tui::bg(Reset, Fixed::y(height, on_bg(border(Map::new(iter, move|clip: Arc>, i|{ + //let on_bg = |x|x;//Bsp::b(Repeat(" "), Tui::bg(color.darkest.rgb, x)); + //let border = |x|x;//Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb)).enclose(x); + let height = pool.clips.read().unwrap().len() as u16; + Fixed::x(20, Fill::y(Align::c(Map::new( + ||pool.clips().clone().into_iter(), + move|clip: Arc>, i: usize|{ let item_height = 1; let item_offset = i as u16 * item_height; - let selected = i == model.clip_index(); + let selected = i == pool.clip_index(); let MidiClip { ref name, color, length, .. } = *clip.read().unwrap(); let bg = if selected { color.light.rgb } else { color.base.rgb }; let fg = color.lightest.rgb; - let name = if *compact { format!(" {i:>3}") } else { format!(" {i:>3} {name}") }; - let length = if *compact { String::default() } else { format!("{length} ") }; + let name = if false { format!(" {i:>3}") } else { format!(" {i:>3} {name}") }; + let length = if false { String::default() } else { format!("{length} ") }; Fixed::y(1, map_south(item_offset, item_height, Tui::bg(bg, lay!( Fill::x(Align::w(Tui::fg(fg, Tui::bold(selected, name)))), Fill::x(Align::e(Tui::fg(fg, Tui::bold(selected, length)))), Fill::x(Align::w(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "▶"))))), Fill::x(Align::e(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "◀"))))), )))) - }))))) + })))) }); content!(TuiOut: |self: ClipLength| {