diff --git a/crates/app/src/api.rs b/crates/app/src/api.rs index a97068b7..8d5863c2 100644 --- a/crates/app/src/api.rs +++ b/crates/app/src/api.rs @@ -1,29 +1,5 @@ use crate::*; -view!(TuiOut: |self: Tek| self.size.of(View(self, self.view)); { - ":nil" => - Box::new("nil"), - ":transport" => - self.view_transport().boxed(), - ":arranger" => - ArrangerView::new(self).boxed(), - ":editor" => - self.editor.as_ref() - .map(|e|Bsp::s(Bsp::e(e.clip_status(), e.edit_status()), e)) - .boxed(), - ":sample" => - ().boxed(),//self.view_sample(self.is_editing()).boxed(), - ":sampler" => - ().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(), - ":samples-grid" => - self.tracks[0].sampler(0).map(|s|s.view_grid()).boxed(), - ":status" => - self.view_status().boxed(), - ":pool" => self.pool.as_ref() - .map(|pool|Fixed::x(self.w_sidebar(), PoolView(self.is_editing(), pool))) - .boxed(), -}); - expose!([self: Tek] { [bool] => {} [u16] => { diff --git a/crates/app/src/model.rs b/crates/app/src/model.rs index b60877a3..329db14d 100644 --- a/crates/app/src/model.rs +++ b/crates/app/src/model.rs @@ -266,10 +266,18 @@ pub trait HasSelection { /// Focus identification methods impl Selection { - fn is_mix (&self) -> bool { matches!(self, Self::Mix) } - fn is_track (&self) -> bool { matches!(self, Self::Track(_)) } - fn is_scene (&self) -> bool { matches!(self, Self::Scene(_)) } - fn is_clip (&self) -> bool { matches!(self, Self::Clip(_, _)) } + pub fn is_mix (&self) -> bool { + matches!(self, Self::Mix) + } + pub fn is_track (&self) -> bool { + matches!(self, Self::Track(_)) + } + pub fn is_scene (&self) -> bool { + matches!(self, Self::Scene(_)) + } + pub fn is_clip (&self) -> bool { + matches!(self, Self::Clip(_, _)) + } pub fn track (&self) -> Option { use Selection::*; match self { Clip(t, _) => Some(*t), Track(t) => Some(*t), _ => None } diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index 2d575de7..9d334b55 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -2,6 +2,32 @@ use crate::*; pub(crate) use std::fmt::Write; pub(crate) use ::tengri::tui::ratatui::prelude::Position; +view!(TuiOut: |self: Tek| self.size.of(View(self, self.view)); { + ":nil" => + Box::new("nil"), + ":transport" => + self.view_transport().boxed(), + ":arranger" => + ArrangerView::new(self).boxed(), + ":editor" => + self.editor.as_ref() + .map(|e|Bsp::s(Bsp::e(e.clip_status(), e.edit_status()), e)) + .boxed(), + ":sample" => + ().boxed(),//self.view_sample(self.is_editing()).boxed(), + ":sampler" => + ().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(), + ":samples-keys" => + self.tracks[0].sampler(0).map(|s|s.view_list(false, self.editor.as_ref().unwrap())).boxed(), + ":samples-grid" => + self.tracks[0].sampler(0).map(|s|s.view_grid()).boxed(), + ":status" => + self.view_status().boxed(), + ":pool" => self.pool.as_ref() + .map(|pool|Fixed::x(self.w_sidebar(), PoolView(self.is_editing(), pool))) + .boxed(), +}); + pub(crate) struct ArrangerView<'a> { app: &'a Tek, diff --git a/crates/cli/edn/groovebox.edn b/crates/cli/edn/groovebox.edn index 819e0d6d..1f7814cc 100644 --- a/crates/cli/edn/groovebox.edn +++ b/crates/cli/edn/groovebox.edn @@ -2,5 +2,5 @@ (bsp/s :sample (bsp/n (fixed/y 1 :status) (bsp/w (fixed/x :w-sidebar :pool) - (bsp/e :sampler + (bsp/e :samples-keys (fill/y :editor)))))) diff --git a/crates/sampler/sampler_scratch.rs b/crates/sampler/sampler_scratch.rs index 82009355..2a46396d 100644 --- a/crates/sampler/sampler_scratch.rs +++ b/crates/sampler/sampler_scratch.rs @@ -103,3 +103,47 @@ //gain: 1.0 //})))) //}); + +//content!(TuiOut: |self: Sampler| { + //let keys_width = 5; + //let keys = move||"";//SamplerKeys(self); + //let fg = self.color.base.rgb; + //let bg = self.color.darkest.rgb; + //let border = Fill::xy(Outer(true, Style::default().fg(fg).bg(bg))); + //let with_border = |x|lay!(border, Fill::xy(x)); + //let with_size = |x|lay!(self.size.clone(), x); + //Tui::bg(bg, Fill::xy(with_border(Bsp::s( + //Tui::fg(self.color.light.rgb, Tui::bold(true, &"Sampler")), + //with_size(Shrink::y(1, Bsp::e( + //Fixed::x(keys_width, keys()), + //Fill::xy(SamplesTui { + //color: self.color, + //note_hi: self.note_hi(), + //note_pt: self.note_pos(), + //height: self.size.h(), + //}), + //))), + //)))) +//}); + +//struct SamplesTui { + //color: ItemPalette, + //note_hi: usize, + //note_pt: usize, + //height: usize, +//} + +//render!(TuiOut: |self: SamplesTui, to| { + //let x = to.area.x(); + //let bg_base = self.color.darkest.rgb; + //let bg_selected = self.color.darker.rgb; + //let style_empty = Style::default().fg(self.color.base.rgb); + //let style_full = Style::default().fg(self.color.lighter.rgb); + //for y in 0..self.height { + //let note = self.note_hi - y as usize; + //let bg = if note == self.note_pt { bg_selected } else { bg_base }; + //let style = Some(style_empty.bg(bg)); + //to.blit(&" (no sample) ", x, to.area.y() + y as u16, style); + //} +//}); + diff --git a/crates/sampler/src/sampler_view.rs b/crates/sampler/src/sampler_view.rs index edc0d524..88be7822 100644 --- a/crates/sampler/src/sampler_view.rs +++ b/crates/sampler/src/sampler_view.rs @@ -1,6 +1,7 @@ use crate::*; impl Sampler { + pub fn view_grid (&self) -> impl Content + use<'_> { let cells_x = 8u16; let cells_y = 8u16; @@ -19,6 +20,7 @@ impl Sampler { ); cols } + pub fn view_grid_cell <'a> ( &'a self, name: &'a str, x: u16, y: u16, w: u16, h: u16 ) -> impl Content + use<'a> { @@ -48,58 +50,18 @@ impl Sampler { ), )) } -} -content!(TuiOut: |self: Sampler| { - let keys_width = 5; - let keys = move||"";//SamplerKeys(self); - let fg = self.color.base.rgb; - let bg = self.color.darkest.rgb; - let border = Fill::xy(Outer(true, Style::default().fg(fg).bg(bg))); - let with_border = |x|lay!(border, Fill::xy(x)); - let with_size = |x|lay!(self.size.clone(), x); - Tui::bg(bg, Fill::xy(with_border(Bsp::s( - Tui::fg(self.color.light.rgb, Tui::bold(true, &"Sampler")), - with_size(Shrink::y(1, Bsp::e( - Fixed::x(keys_width, keys()), - Fill::xy(SamplesTui { - color: self.color, - note_hi: self.note_hi(), - note_pt: self.note_pos(), - height: self.size.h(), - }), - ))), - )))) -}); - -struct SamplesTui { - color: ItemPalette, - note_hi: usize, - note_pt: usize, - height: usize, -} - -render!(TuiOut: |self: SamplesTui, to| { - let x = to.area.x(); - let bg_base = self.color.darkest.rgb; - let bg_selected = self.color.darker.rgb; - let style_empty = Style::default().fg(self.color.base.rgb); - let style_full = Style::default().fg(self.color.lighter.rgb); - for y in 0..self.height { - let note = self.note_hi - y as usize; - let bg = if note == self.note_pt { bg_selected } else { bg_base }; - let style = Some(style_empty.bg(bg)); - to.blit(&" (no sample) ", x, to.area.y() + y as u16, style); - } -}); - -impl Sampler { const _EMPTY: &[(f64, f64)] = &[(0., 0.), (1., 1.), (2., 2.), (0., 2.), (2., 0.)]; - pub fn list <'a> (&'a self, compact: bool, editor: &MidiEditor) -> impl Content + 'a { + + pub fn view_list <'a> ( + &'a self, + compact: bool, + editor: &MidiEditor + ) -> impl Content + 'a { let note_lo = editor.note_lo().load(Relaxed); let note_pt = editor.note_pos(); let note_hi = editor.note_hi(); - Outer(true, Style::default().fg(Tui::g(96))).enclose(Map::new( + Fixed::x(16, Map::new( move||(note_lo..=note_hi).rev(), move|note, i| { let offset = |a|Push::y(i as u16, Align::n(Fixed::y(1, Fill::x(a)))); @@ -116,10 +78,10 @@ impl Sampler { fg = Color::Rgb(224,64,32) } } - offset(Tui::fg_bg(fg, bg, format!("{note:3} {}", self.list_item(note, compact)))) + offset(Tui::fg_bg(fg, bg, format!("{note:3} {}", self.view_list_item(note, compact)))) })) } - pub fn list_item (&self, note: usize, compact: bool) -> String { + pub fn view_list_item (&self, note: usize, compact: bool) -> String { if compact { String::default() } else {