diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index 7ed1134b..9635da64 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -4,7 +4,8 @@ edition = { workspace = true } version = { workspace = true } [dependencies] -tengri = { workspace = true } +tengri = { workspace = true } +tengri_proc = { workspace = true } tek_engine = { workspace = true } tek_device = { workspace = true } diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index b2b8b9e9..42ab6b4a 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -2,39 +2,58 @@ 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.config.view)); { - ":nil" => Box::new("nil"), - ":modal" => self.view_modal(), - ":status" => self.view_status(), - ":transport" => self.view_transport(), - ":arranger" => self.view_arranger(), - ":pool" => self.view_pool(), - ":editor" => self.editor().map(|e|Bsp::n(Bsp::e(e.clip_status(), e.edit_status()), e)), - ":samples-keys" => self.sampler().map(|s|s.view_list(false, self.editor().unwrap())), - ":samples-grid" => self.sampler().map(|s|s.view_grid()), - ":sample-viewer" => self.sampler().map(|s|s.view_sample(self.editor().unwrap().note_pos())), -}); - -trait ScenesColors<'a> = Iterator>; - -type SceneWithColor<'a> = (usize, &'a Scene, usize, usize, Option); - +#[tengri_proc::view(self.config.view)] impl Tek { - pub fn view_modal (&self) -> impl Content + use<'_> { - When::new(self.modal.is_some(), Bsp::b( - Fill::xy(Tui::fg_bg(Rgb(64,64,64), Rgb(32,32,32), "")), - Fixed::xy(30, 15, Tui::fg_bg(Rgb(255,255,255), Rgb(16,16,16), Bsp::b( - Repeat(" "), - Outer(true, Style::default().fg(Tui::g(96))) - .enclose(self.modal.map(|modal|match modal { - Modal::Menu => self.view_modal_menu().boxed(), - Modal::Help => self.view_modal_help().boxed(), - })) - ))) - )) + #[view(":nil")] "nil" + + #[view(":status")] { + self.update_clock(); + let cache = self.view_cache.read().unwrap(); + view_status( + self.selected.describe(&self.tracks, &self.scenes), + cache.sr.view.clone(), cache.buf.view.clone(), cache.lat.view.clone(), + ) } + #[view(":transport")] { + self.update_clock(); + let cache = self.view_cache.read().unwrap(); + view_transport( + self.clock.is_rolling(), + cache.bpm.view.clone(), cache.beat.view.clone(), cache.time.view.clone(), + ) + } + + #[view(":arranger")] ArrangerView::new(self) + + #[view(":pool")] self.pool() + .map(|p|Fixed::x(self.w_sidebar(), PoolView(self.is_editing(), p))) + + #[view(":editor")] self.editor() + .map(|e|Bsp::n(Bsp::e(e.clip_status(), e.edit_status()), e)) + + #[view(":samples-keys")] self.sampler() + .map(|s|s.view_list(false, self.editor().unwrap())) + + #[view(":samples-grid")] self.sampler() + .map(|s|s.view_grid()) + + #[view(":sample-viewer")] self.sampler() + .map(|s|s.view_sample(self.editor().unwrap().note_pos())) + + #[view(":modal")] When::new(self.modal.is_some(), Bsp::b( + Fill::xy(Tui::fg_bg(Rgb(64,64,64), Rgb(32,32,32), "")), + Fixed::xy(30, 15, Tui::fg_bg(Rgb(255,255,255), Rgb(16,16,16), Bsp::b( + Repeat(" "), + Outer(true, Style::default().fg(Tui::g(96))) + .enclose(self.modal.map(|modal|match modal { + Modal::Menu => self.view_modal_menu().boxed(), + Modal::Help => self.view_modal_help().boxed(), + })) + ))) + )) + fn view_modal_menu (&self) -> impl Content { let options = ||["Projects", "Settings", "Help", "Quit"].iter(); let option = |a,i|Tui::fg(Rgb(255,255,255), format!("{}", a)); @@ -69,36 +88,6 @@ impl Tek { Bsp::s(Tui::bold(true, "Help"), Bsp::s("", Map::south(1, bindings, binding))) } - pub fn view_status (&self) -> impl Content + use<'_> { - self.update_clock(); - let cache = self.view_cache.read().unwrap(); - view_status( - self.selected.describe(&self.tracks, &self.scenes), - cache.sr.view.clone(), - cache.buf.view.clone(), - cache.lat.view.clone(), - ) - } - - pub fn view_transport (&self) -> impl Content + use<'_> { - self.update_clock(); - let cache = self.view_cache.read().unwrap(); - view_transport( - self.clock.is_rolling(), - cache.bpm.view.clone(), - cache.beat.view.clone(), - cache.time.view.clone(), - ) - } - - pub fn view_arranger (&self) -> impl Content + use<'_> { - ArrangerView::new(self) - } - - pub fn view_pool (&self) -> impl Content + use<'_> { - self.pool().map(|p|Fixed::x(self.w_sidebar(), PoolView(self.is_editing(), p))) - } - /// Spacing between tracks. pub(crate) const TRACK_SPACING: usize = 0; @@ -619,6 +608,10 @@ impl<'a> ArrangerView<'a> { } +trait ScenesColors<'a> = Iterator>; + +type SceneWithColor<'a> = (usize, &'a Scene, usize, usize, Option); + /// Define a type alias for iterators of sized items (columns). macro_rules! def_sizes_iter { ($Type:ident => $($Item:ty),+) => {