From d5865d941f7b0442dbae8340bacfa0a685649e70 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 23 Aug 2025 12:19:35 +0300 Subject: [PATCH] almost back in commission --- crates/app/app.rs | 184 ++--------------------------------------- crates/app/app_bind.rs | 18 +++- crates/app/app_data.rs | 122 +++++++++++++++++++++++++++ crates/app/app_deps.rs | 24 ++++++ crates/app/app_view.rs | 69 +++++++++------- deps/tengri | 2 +- tek.edn | 16 ++-- 7 files changed, 219 insertions(+), 216 deletions(-) create mode 100644 crates/app/app_data.rs create mode 100644 crates/app/app_deps.rs diff --git a/crates/app/app.rs b/crates/app/app.rs index 5c3fed5f..5f9cac56 100644 --- a/crates/app/app.rs +++ b/crates/app/app.rs @@ -1,38 +1,12 @@ -// ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ -//██Let me play the world's tiniest piano for you. ██ -//█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ -//█▙▙█▙▙▙█▙▙█▙▙▙█▙▙█▙▙▙█▙▙█▙▙▙█▙▙█▙▙▙█▙▙█▙▙▙█▙▙█▙▙▙██ -//█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ -//███████████████████████████████████████████████████ -//█ ▀ ▀ ▀ █ #![allow(unused, clippy::unit_arg)] #![feature(adt_const_params, associated_type_defaults, if_let_guard, impl_trait_in_assoc_type, type_alias_impl_trait, trait_alias, type_changing_struct_update, closure_lifetime_binder)] -pub use ::{ - tek_engine::*, - tek_device, - tek_device::*, - tengri::{ - Usually, Perhaps, Has, MaybeHas, has, maybe_has, - dsl::*, input::*, output::*, tui::*, - tui::ratatui, - tui::ratatui::prelude::buffer::Cell, - tui::ratatui::prelude::Color::{self, *}, - tui::ratatui::prelude::{Style, Stylize, Buffer, Modifier}, - tui::crossterm, - tui::crossterm::event::{Event, KeyCode::{self, *}}, - }, - std::{ - path::{Path, PathBuf}, - sync::{Arc, RwLock}, - sync::atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed}, - error::Error, - collections::BTreeMap, - fmt::Write, - }, - xdg::BaseDirectories, -}; +mod app_deps; pub use self::app_deps::*; mod app_jack; pub use self::app_jack::*; +mod app_bind; pub use self::app_bind::*; +mod app_data; pub use self::app_data::*; +mod app_view; pub use self::app_view::*; + #[cfg(test)] mod app_test; /// Total state #[derive(Default, Debug)] @@ -228,7 +202,7 @@ fn render_dsl <'t> ( state: &'t impl DslNs<'t, Box>>, src: &str ) -> Box> { - let err: Option> = match state.from(src) { + let err: Option> = match state.from(&src) { Ok(Some(value)) => return value, Ok(None) => None, Err(e) => Some(e), }; let (fg_1, bg_1) = (Color::Rgb(240, 160, 100), Color::Rgb(48, 0, 0)); @@ -265,8 +239,6 @@ handle!(TuiIn:|self: App, input|{ } Ok(None) }); -#[derive(Debug)] -pub enum AppCommand { /* TODO */ } impl Dialog { pub fn menu_selected (&self) -> Option { if let Self::Menu(selected) = self { Some(*selected) } else { None } @@ -290,17 +262,6 @@ impl Dialog { todo!() } } -#[tengri_proc::command(Option)] impl DialogCommand { - fn open (dialog: &mut Option, new: Dialog) -> Perhaps { - *dialog = Some(new); - Ok(None) - } - fn close (dialog: &mut Option) -> Perhaps { - *dialog = None; - Ok(None) - } -} - impl App { pub fn editor_focused (&self) -> bool { false @@ -384,107 +345,6 @@ impl App { } -dsl_ns! { |app: App| - - bool => { - ":focused/editor" => app.project.editor.is_some(), - ":focused/dialog" => !matches!(app.dialog, Dialog::None), - ":focused/message" => matches!(app.dialog, Dialog::Message(..)), - ":focused/add_device" => matches!(app.dialog, Dialog::Device(..)), - ":focused/browser" => app.dialog.browser().is_some(), - ":focused/pool/import" => matches!(app.pool.mode, Some(PoolMode::Import(..))), - ":focused/pool/export" => matches!(app.pool.mode, Some(PoolMode::Export(..))), - ":focused/pool/rename" => matches!(app.pool.mode, Some(PoolMode::Rename(..))), - ":focused/pool/length" => matches!(app.pool.mode, Some(PoolMode::Length(..))), - ":focused/clip" => !app.editor_focused() && matches!(app.selection(), - Selection::TrackClip{..}), - ":focused/track" => !app.editor_focused() && matches!(app.selection(), - Selection::Track(..)), - ":focused/scene" => !app.editor_focused() && matches!(app.selection(), - Selection::Scene(..)), - ":focused/mix" => !app.editor_focused() && matches!(app.selection(), - Selection::Mix), - }; - - ItemTheme => { - ":_theme_stub" => Default::default() - }; - - Dialog => { - ":dialog/none" => Dialog::None, - ":dialog/options" => Dialog::Options, - ":dialog/device" => Dialog::Device(0), - ":dialog/device/prev" => Dialog::Device(0), - ":dialog/device/next" => Dialog::Device(0), - ":dialog/help" => Dialog::Help(0), - ":dialog/menu" => Dialog::Menu(0), - ":dialog/save" => Dialog::Browser(BrowserTarget::SaveProject, - Browser::new(None).unwrap().into()), - ":dialog/load" => Dialog::Browser(BrowserTarget::LoadProject, - Browser::new(None).unwrap().into()), - ":dialog/import/clip" => Dialog::Browser(BrowserTarget::ImportClip(Default::default()), - Browser::new(None).unwrap().into()), - ":dialog/export/clip" => Dialog::Browser(BrowserTarget::ExportClip(Default::default()), - Browser::new(None).unwrap().into()), - ":dialog/import/sample" => Dialog::Browser(BrowserTarget::ImportSample(Default::default()), - Browser::new(None).unwrap().into()), - ":dialog/export/sample" => Dialog::Browser(BrowserTarget::ExportSample(Default::default()), - Browser::new(None).unwrap().into()), - }; - - Selection => { - ":select/scene" => app.selection().select_scene(app.tracks().len()), - ":select/scene/next" => app.selection().select_scene_next(app.scenes().len()), - ":select/scene/prev" => app.selection().select_scene_prev(), - ":select/track" => app.selection().select_track(app.tracks().len()), - ":select/track/next" => app.selection().select_track_next(app.tracks().len()), - ":select/track/prev" => app.selection().select_track_prev(), - }; - - Option => { - ":editor/pitch" => Some( - (app.editor().as_ref().map(|e|e.get_note_pos()).unwrap() as u8).into() - ) - }; - - Option => { - ":selected/scene" => app.selection().scene(), - ":selected/track" => app.selection().track(), - }; - - Option>> => { - ":selected/clip" => if let Selection::TrackClip { track, scene } = app.selection() { - app.scenes()[*scene].clips[*track].clone() - } else { - None - } - }; - - Color => { - ("g", n: u8) => Color::Rgb(n, n, n), - ("rgb", red: u8, green: u8, blue: u8) => Color::Rgb(red, green, blue), - ":color/bg" => Color::Rgb(28, 32, 36), - - }; - -} - -dsl_ns! { num |app: App| - u8; - u16 => { - ":w/sidebar" => app.project.w_sidebar(app.editor().is_some()), - ":h/sample-detail" => 6.max(app.height() as u16 * 3 / 9), - }; - usize => { - ":scene-count" => app.scenes().len(), - ":track-count" => app.tracks().len(), - ":device-kind" => app.dialog.device_kind().unwrap_or(0), - ":device-kind/next" => app.dialog.device_kind_next().unwrap_or(0), - ":device-kind/prev" => app.dialog.device_kind_prev().unwrap_or(0), - }; - isize; -} - fn wrap_dialog (dialog: impl Content) -> impl Content { Fixed::xy(70, 23, Tui::fg_bg(Rgb(255,255,255), Rgb(16,16,16), Bsp::b( Repeat(" "), Outer(true, Style::default().fg(Tui::g(96))).enclose(dialog)))) @@ -495,38 +355,6 @@ impl ScenesView for App { fn h_scenes (&self) -> u16 { (self.height() as u16).saturating_sub(20) } } -macro_rules!dsl_words((|$state:ident|->$Type:ty$({ - $($word:literal => $body:expr),* $(,)? -})?)=>{ - const WORDS: DslNsMap<'t, fn (&'t Self)->Perhaps<$Type>> = DslNsMap::new(&[$( - $(($word, |$state: &Self|{Ok(Some($body))})),* - )? ]); -}); -macro_rules!dsl_exprs((|$state:ident|->$Type:ty$({ - $($name:literal ($($arg:ident:$ty:ty),* $(,)?) => $body:expr),* $(,)? -})?)=>{ - const EXPRS: DslNsMap<'t, fn (&'t Self, &str)->Perhaps<$Type>> = DslNsMap::new(&[$( - $(($name, |$state: &Self, tail: &str|{ - $( - let head = tail.head()?.unwrap_or_default(); - let tail = tail.tail()?.unwrap_or_default(); - let $arg: $ty = if let Some(arg) = $state.from(&head)? { - arg - } else { - return Err(format!("{}: arg \"{}\" ({}) got: {head}, remaining: {tail}", - $name, - stringify!($arg), - stringify!($ty), - ).into()) - }; - )* - Ok(Some($body)) - })),* - )? ]); -}); - -mod app_view; pub use self::app_view::*; -mod app_bind; pub use self::app_bind::*; //#[dizzle::ns] //#[dizzle::ns::include(TuiOut)] diff --git a/crates/app/app_bind.rs b/crates/app/app_bind.rs index 9acaa5ca..2a13994b 100644 --- a/crates/app/app_bind.rs +++ b/crates/app/app_bind.rs @@ -1,8 +1,7 @@ use crate::*; impl<'t> DslNs<'t, AppCommand> for App { - dsl_exprs!(|app| -> AppCommand { - }); + dsl_exprs!(|app| -> AppCommand { /* TODO */ }); dsl_words!(|app| -> AppCommand { "x/inc" => todo!(), "x/dec" => todo!(), @@ -11,6 +10,21 @@ impl<'t> DslNs<'t, AppCommand> for App { "confirm" => todo!(), }); } +#[derive(Debug)] +pub enum AppCommand { /* TODO */ } + +#[tengri_proc::command(Option)] +impl DialogCommand { + fn open (dialog: &mut Option, new: Dialog) -> Perhaps { + *dialog = Some(new); + Ok(None) + } + fn close (dialog: &mut Option) -> Perhaps { + *dialog = None; + Ok(None) + } +} + //AppCommand => { //("x/inc" / diff --git a/crates/app/app_data.rs b/crates/app/app_data.rs new file mode 100644 index 00000000..e44ada9f --- /dev/null +++ b/crates/app/app_data.rs @@ -0,0 +1,122 @@ +use crate::*; + +impl<'t> DslNs<'t, Arc> for App { + dsl_exprs!(|app| -> Arc {}); + dsl_words!(|app| -> Arc {}); + fn from_literal (&self, dsl: &D) -> Perhaps> { + Ok(dsl.src()?.map(|x|x.into())) + } +} + +impl<'t> DslNs<'t, bool> for App { + dsl_words!(|app| -> bool { + ":focused/editor" => app.project.editor.is_some(), + ":focused/dialog" => !matches!(app.dialog, Dialog::None), + ":focused/message" => matches!(app.dialog, Dialog::Message(..)), + ":focused/add_device" => matches!(app.dialog, Dialog::Device(..)), + ":focused/browser" => app.dialog.browser().is_some(), + ":focused/pool/import" => matches!(app.pool.mode, Some(PoolMode::Import(..))), + ":focused/pool/export" => matches!(app.pool.mode, Some(PoolMode::Export(..))), + ":focused/pool/rename" => matches!(app.pool.mode, Some(PoolMode::Rename(..))), + ":focused/pool/length" => matches!(app.pool.mode, Some(PoolMode::Length(..))), + ":focused/clip" => !app.editor_focused() && matches!(app.selection(), + Selection::TrackClip{..}), + ":focused/track" => !app.editor_focused() && matches!(app.selection(), + Selection::Track(..)), + ":focused/scene" => !app.editor_focused() && matches!(app.selection(), + Selection::Scene(..)), + ":focused/mix" => !app.editor_focused() && matches!(app.selection(), + Selection::Mix), + }); + //fn from_literal (&self, dsl: &D) -> Perhaps> { + //TODO + //} +} + +impl<'t> DslNs<'t, ItemTheme> for App {} + +impl<'t> DslNs<'t, Dialog> for App { + dsl_words!(|app| -> Dialog { + ":dialog/none" => Dialog::None, + ":dialog/options" => Dialog::Options, + ":dialog/device" => Dialog::Device(0), + ":dialog/device/prev" => Dialog::Device(0), + ":dialog/device/next" => Dialog::Device(0), + ":dialog/help" => Dialog::Help(0), + ":dialog/menu" => Dialog::Menu(0), + ":dialog/save" => Dialog::Browser(BrowserTarget::SaveProject, + Browser::new(None).unwrap().into()), + ":dialog/load" => Dialog::Browser(BrowserTarget::LoadProject, + Browser::new(None).unwrap().into()), + ":dialog/import/clip" => Dialog::Browser(BrowserTarget::ImportClip(Default::default()), + Browser::new(None).unwrap().into()), + ":dialog/export/clip" => Dialog::Browser(BrowserTarget::ExportClip(Default::default()), + Browser::new(None).unwrap().into()), + ":dialog/import/sample" => Dialog::Browser(BrowserTarget::ImportSample(Default::default()), + Browser::new(None).unwrap().into()), + ":dialog/export/sample" => Dialog::Browser(BrowserTarget::ExportSample(Default::default()), + Browser::new(None).unwrap().into()), + }); +} + +impl<'t> DslNs<'t, Selection> for App { + dsl_words!(|app| -> Selection { + ":select/scene" => app.selection().select_scene(app.tracks().len()), + ":select/scene/next" => app.selection().select_scene_next(app.scenes().len()), + ":select/scene/prev" => app.selection().select_scene_prev(), + ":select/track" => app.selection().select_track(app.tracks().len()), + ":select/track/next" => app.selection().select_track_next(app.tracks().len()), + ":select/track/prev" => app.selection().select_track_prev(), + }); +} + +impl<'t> DslNs<'t, Color> for App { + dsl_words!(|app| -> Color { + ":color/bg" => Color::Rgb(28, 32, 36), + }); + dsl_exprs!(|app| -> Color { + "g" (n: u8) => Color::Rgb(n, n, n), + "rgb" (r: u8, g: u8, b: u8) => Color::Rgb(r, g, b), + }); +} + +impl<'t> DslNs<'t, Option> for App { + dsl_words!(|app| -> Option { + ":editor/pitch" => Some( + (app.editor().as_ref().map(|e|e.get_note_pos()).unwrap() as u8).into() + ) + }); +} + +impl<'t> DslNs<'t, Option> for App { + dsl_words!(|app| -> Option { + ":selected/scene" => app.selection().scene(), + ":selected/track" => app.selection().track(), + }); +} + +impl<'t> DslNs<'t, Option>>> for App { + dsl_words!(|app| -> Option>> { + ":selected/clip" => if let Selection::TrackClip { track, scene } = app.selection() { + app.scenes()[*scene].clips[*track].clone() + } else { + None + } + }); +} + +dsl_ns! { num |app: App| + u8; + u16 => { + ":w/sidebar" => app.project.w_sidebar(app.editor().is_some()), + ":h/sample-detail" => 6.max(app.height() as u16 * 3 / 9), + }; + usize => { + ":scene-count" => app.scenes().len(), + ":track-count" => app.tracks().len(), + ":device-kind" => app.dialog.device_kind().unwrap_or(0), + ":device-kind/next" => app.dialog.device_kind_next().unwrap_or(0), + ":device-kind/prev" => app.dialog.device_kind_prev().unwrap_or(0), + }; + isize; +} diff --git a/crates/app/app_deps.rs b/crates/app/app_deps.rs new file mode 100644 index 00000000..508feda5 --- /dev/null +++ b/crates/app/app_deps.rs @@ -0,0 +1,24 @@ +pub use ::{ + tek_engine::*, + tek_device, + tek_device::*, + tengri::{ + Usually, Perhaps, Has, MaybeHas, has, maybe_has, + dsl::*, input::*, output::*, tui::*, + tui::ratatui, + tui::ratatui::prelude::buffer::Cell, + tui::ratatui::prelude::Color::{self, *}, + tui::ratatui::prelude::{Style, Stylize, Buffer, Modifier}, + tui::crossterm, + tui::crossterm::event::{Event, KeyCode::{self, *}}, + }, + std::{ + path::{Path, PathBuf}, + sync::{Arc, RwLock}, + sync::atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed}, + error::Error, + collections::BTreeMap, + fmt::Write, + }, + xdg::BaseDirectories, +}; diff --git a/crates/app/app_view.rs b/crates/app/app_view.rs index 9d9a4a72..6d7faef1 100644 --- a/crates/app/app_view.rs +++ b/crates/app/app_view.rs @@ -2,17 +2,21 @@ use crate::*; impl<'t> DslNs<'t, Box>> for App { dsl_exprs!(|app| -> Box> { - "fg" (color: Color, x: Box>) => Box::new(Tui::fg(color, x)), - "bg" (color: Color, x: Box>) => Box::new(Tui::bg(color, x)), - "fg/bg" (fg: Color, bg: Color, x: Box>) => Box::new(Tui::fg_bg(fg, bg, x)), + "text" (tail: Arc) => Box::new(tail), - "bsp/n" (a: Box>, b: Box>) => Box::new(Bsp::n(a, b)), - "bsp/s" (a: Box>, b: Box>) => Box::new(Bsp::s(a, b)), - "bsp/e" (a: Box>, b: Box>) => Box::new(Bsp::e(a, b)), - "bsp/w" (a: Box>, b: Box>) => Box::new(Bsp::w(a, b)), - "bsp/a" (a: Box>, b: Box>) => Box::new(Bsp::a(a, b)), - "bsp/b" (a: Box>, b: Box>) => Box::new(Bsp::b(a, b)), + "fg" (color: Color, x: Box>) => Box::new(Tui::fg(color, x)), + "bg" (color: Color, x: Box>) => Box::new(Tui::bg(color, x)), + "fg/bg" (fg: Color, bg: Color, x: Box>) => Box::new(Tui::fg_bg(fg, bg, x)), + "bsp/n" (a: Box>, b: Box>) => Box::new(Bsp::n(a, b)), + "bsp/s" (a: Box>, b: Box>) => Box::new(Bsp::s(a, b)), + "bsp/e" (a: Box>, b: Box>) => Box::new(Bsp::e(a, b)), + "bsp/w" (a: Box>, b: Box>) => Box::new(Bsp::w(a, b)), + "bsp/a" (a: Box>, b: Box>) => Box::new(Bsp::a(a, b)), + "bsp/b" (a: Box>, b: Box>) => Box::new(Bsp::b(a, b)), + + "align/nw" (x: Box>) => Box::new(Align::nw(x)), + "align/ne" (x: Box>) => Box::new(Align::ne(x)), "align/n" (x: Box>) => Box::new(Align::n(x)), "align/s" (x: Box>) => Box::new(Align::s(x)), "align/e" (x: Box>) => Box::new(Align::e(x)), @@ -21,43 +25,46 @@ impl<'t> DslNs<'t, Box>> for App { "align/y" (x: Box>) => Box::new(Align::y(x)), "align/c" (x: Box>) => Box::new(Align::c(x)), - "fill/x" (x: Box>) => Box::new(Fill::x(x)), - "fill/y" (x: Box>) => Box::new(Fill::y(x)), - "fill/xy" (x: Box>) => Box::new(Fill::xy(x)), + "fill/x" (x: Box>) => Box::new(Fill::x(x)), + "fill/y" (x: Box>) => Box::new(Fill::y(x)), + "fill/xy" (x: Box>) => Box::new(Fill::xy(x)), "fixed/x" (x: u16, c: Box>) => Box::new(Fixed::x(x, c)), "fixed/y" (y: u16, c: Box>) => Box::new(Fixed::y(y, c)), "fixed/xy" (x: u16, y: u16, c: Box>) => Box::new(Fixed::xy(x, y, c)), - "min/x" (x: u16, c: Box>) => Box::new(Min::x(x, c)), - "min/y" (y: u16, c: Box>) => Box::new(Min::y(y, c)), - "min/xy" (x: u16, y: u16, c: Box>) => Box::new(Min::xy(x, y, c)), + "min/x" (x: u16, c: Box>) => Box::new(Min::x(x, c)), + "min/y" (y: u16, c: Box>) => Box::new(Min::y(y, c)), + "min/xy" (x: u16, y: u16, c: Box>) => Box::new(Min::xy(x, y, c)), - "max/x" (x: u16, c: Box>) => Box::new(Max::x(x, c)), - "max/y" (y: u16, c: Box>) => Box::new(Max::y(y, c)), - "max/xy" (x: u16, y: u16, c: Box>) => Box::new(Max::xy(x, y, c)), + "max/x" (x: u16, c: Box>) => Box::new(Max::x(x, c)), + "max/y" (y: u16, c: Box>) => Box::new(Max::y(y, c)), + "max/xy" (x: u16, y: u16, c: Box>) => Box::new(Max::xy(x, y, c)), }); dsl_words!(|app| -> Box> { ":templates" => Box::new({ let modes = app.config.modes.clone(); let height = (modes.read().unwrap().len() * 2) as u16; - Min::x(30, Fixed::y(height, Stack::south(move|add: &mut dyn FnMut(&dyn Render)|{ + Fixed::y(height, Min::x(30, Stack::south(move|add: &mut dyn FnMut(&dyn Render)|{ for (index, (id, profile)) in modes.read().unwrap().iter().enumerate() { - let bg = if index == 0 { Rgb(48,64,32) } else { Rgb(16, 32, 24) }; + let bg = if index == 0 { Rgb(70,70,70) } else { Rgb(50,50,50) }; let name = profile.name.get(0).map(|x|x.as_ref()).unwrap_or(""); let info = profile.info.get(0).map(|x|x.as_ref()).unwrap_or(""); let fg1 = Rgb(224, 192, 128); let fg2 = Rgb(224, 128, 32); + let field_name = Fill::x(Align::w(Tui::fg(fg1, name))); + let field_id = Fill::x(Align::e(Tui::fg(fg2, id))); + let field_info = Fill::x(Align::w(info)); add(&Fixed::y(2, Fill::x(Tui::bg(bg, Bsp::s( - Bsp::a(Fill::x(Align::w(Tui::fg(fg1, name))), - Fill::x(Align::e(Tui::fg(fg2, id)))), - Align::w(info)))))); - }})))}), - ":sessions" => Box::new(Min::x(30, Fixed::y(6, Stack::south( + Bsp::a(field_name, field_id), field_info))))); + } + }))) + }), + ":sessions" => Box::new(Fixed::y(6, Min::x(30, Stack::south( move|add: &mut dyn FnMut(&dyn Render)|{ let fg = Rgb(224, 192, 128); for (index, name) in ["session1", "session2", "session3"].iter().enumerate() { - let bg = if index == 0 { Rgb(48,64,32) } else { Rgb(16, 32, 24) }; + let bg = if index == 0 { Rgb(50,50,50) } else { Rgb(40,40,40) }; add(&Fixed::y(2, Fill::x(Tui::bg(bg, Align::w(Tui::fg(fg, name)))))); } } @@ -82,7 +89,7 @@ impl<'t> DslNs<'t, Box>> for App { Fill::x(Tui::bg(bg, Bsp::e(lb, Bsp::w(rb, "FIXME device name")))) }))) }, }); /// Resolve an expression if known. - fn from_expr (&'t self, dsl: D) -> Perhaps>> { + fn from_expr (&self, dsl: &D) -> Perhaps>> { if let Some(head) = dsl.expr().head()? { for (key, value) in Self::EXPRS.0.iter() { if head == *key { @@ -93,7 +100,7 @@ impl<'t> DslNs<'t, Box>> for App { return Ok(None) } /// Resolve a symbol if known. - fn from_word (&'t self, dsl: D) -> Perhaps>> { + fn from_word (&self, dsl: &D) -> Perhaps>> { if let Some(dsl) = dsl.word()? { let views = self.config.views.read().unwrap(); if let Some(view) = views.get(dsl) { @@ -101,7 +108,11 @@ impl<'t> DslNs<'t, Box>> for App { std::mem::drop(views); return Ok(Some(render_dsl(self, view.as_ref()))) } - for (word, get) in Self::WORDS.0 { if dsl == *word { return get(self) } } + for (word, get) in Self::WORDS.0 { + if dsl == *word { + return get(self) + } + } } return Ok(None) } diff --git a/deps/tengri b/deps/tengri index 2557a0d2..d92e5efd 160000 --- a/deps/tengri +++ b/deps/tengri @@ -1 +1 @@ -Subproject commit 2557a0d253dfe45eab001dcc08ebc66c2c6715d3 +Subproject commit d92e5efdd0e009ba0492a75b3aad0b3c142b9056 diff --git a/tek.edn b/tek.edn index 3ae28b53..14b11ae6 100644 --- a/tek.edn +++ b/tek.edn @@ -1,12 +1,16 @@ (mode :menu (keys :x :y :confirm) :menu) (keys :x (@left x/dec) (@right x/inc)) (keys :y (@up y/dec) (@down y/inc)) -(keys :confirm (@enter confirm)) -(view :menu (bg :color/bg (bsp/s :ports/out (bsp/n :ports/in (bsp/e :sessions :templates))))) -(view :ports/out (fill/x (fixed/y 3 (bsp/a (fill/x (align/w "L AUDIO OUT") - (bsp/a "MIDI OUT" (fill/x (align/e "AUDIO OUT R")))))))) -(view :ports/in (fill/x (fixed/y 3 (bsp/a (fill/x (align/w "L AUDIO IN ") - (bsp/a "MIDI IN " (fill/x (align/e "AUDIO IN R")))))))) +(keys :confirm (@enter confirm)) +(view :menu (bg (g 40) (bsp/s :ports/out (bsp/n :ports/in + (bg (g 30) (fill/xy (align/c (bg (g 40) (bsp/s + (text CONTINUE-SESSION) + (bsp/s (text LOAD-OTHER-SESSION) + (text BEGIN-NEW-SESSION))))))))))) +(view :ports/out (fill/x (fixed/y 3 (bsp/a (fill/x (align/w (text L-AUDIO-OUT))) + (bsp/a (text MIDI-OUT) (fill/x (align/e (text AUDIO-OUT R)))))))) +(view :ports/in (fill/x (fixed/y 3 (bsp/a (fill/x (align/w (text L-AUDIO-IN))) + (bsp/a (text MIDI-IN) (fill/x (align/e (text AUDIO-IN-R)))))))) (view :browse (bsp/s (padding/xy 3 1 :browse-title) (enclose (fg (g 96)) browser))) (keys :help (@f1 dialog :help))