tengri flat

This commit is contained in:
i do not exist 2026-07-31 06:59:00 +03:00
parent ba8ff1ae69
commit 5357e83245
4 changed files with 40 additions and 6 deletions

View file

@ -131,7 +131,7 @@ impl MidiEditor {
} }
/// ``` /// ```
/// use tek::{*, tengri::{*, lang::*}}; /// use tek::{*, tengri::*};
/// ///
/// struct Test(Option<MidiEditor>); /// struct Test(Option<MidiEditor>);
/// impl_as_ref_opt!(MidiEditor: |self: Test|self.0.as_ref()); /// impl_as_ref_opt!(MidiEditor: |self: Test|self.0.as_ref());

View file

@ -13,8 +13,8 @@
:transport) :transport)
(mode :menu (name Menu) (info Mode selector.) (keys :axis/y :confirm) (mode :menu (name Menu) (info Mode selector.) (keys :axis/y :confirm)
(view (bg (g 64) (view (bg (g 16)
(bsp/s (max/xy 80 2 :transport) (bsp/s (fill/x (bg (g 32) (max/xy 80 2 :transport)))
(bsp/s (max/y 3 (bg (g 80) :ports/out)) (bsp/s (max/y 3 (bg (g 80) :ports/out))
(bsp/n (max/y 3 (bg (g 80) :ports/in)) (bsp/n (max/y 3 (bg (g 80) :ports/in))
(bg (g 30) (bsp/s (max/y 6 :logo) :dialog/menu)))))))) (bg (g 30) (bsp/s (max/y 6 :logo) :dialog/menu))))))))

View file

@ -25,7 +25,7 @@ pub(crate) use ::{
}, },
tengri::{ tengri::{
*, *,
lang::*, dizzle::*,
midly::{ midly::{
Smf, TrackEventKind, MidiMessage, Error as MidiError, Smf, TrackEventKind, MidiMessage, Error as MidiError,
num::*, num::*,
@ -451,9 +451,11 @@ mod app {
} }
} }
} }
fn get_arc_str (&self, src: impl Language) -> Perhaps<Arc<str>> { fn get_arc_str (&self, src: impl Language) -> Perhaps<Arc<str>> {
Ok(src.src()?.map(|x|x.into())) Ok(src.src()?.map(|x|x.into()))
} }
fn get_u16 (&self, src: impl Language) -> Perhaps<u16> { fn get_u16 (&self, src: impl Language) -> Perhaps<u16> {
Ok(Some(match src.word()? { Ok(Some(match src.word()? {
Some(":w/sidebar") => self.project.w_sidebar(self.editor().is_some()), Some(":w/sidebar") => self.project.w_sidebar(self.editor().is_some()),
@ -461,6 +463,7 @@ mod app {
_ => return try_to_u16(src) _ => return try_to_u16(src)
})) }))
} }
fn get_usize (&self, src: impl Language) -> Perhaps<usize> { fn get_usize (&self, src: impl Language) -> Perhaps<usize> {
Ok(Some(match src.word()? { Ok(Some(match src.word()? {
Some(":scene-count") => self.scenes().len(), Some(":scene-count") => self.scenes().len(),
@ -471,6 +474,7 @@ mod app {
_ => return try_to_usize(src) _ => return try_to_usize(src)
})) }))
} }
fn get_bool (&self, src: impl Language) -> Perhaps<bool> { fn get_bool (&self, src: impl Language) -> Perhaps<bool> {
src.word()?.map(|word|Ok(match word { src.word()?.map(|word|Ok(match word {
"Y" => true, "Y" => true,
@ -491,6 +495,7 @@ mod app {
_ => return Err(format!("not bool: {word}").into()) _ => return Err(format!("not bool: {word}").into())
})).transpose() })).transpose()
} }
fn get_selection (&self, src: impl Language) -> Perhaps<Selection> { fn get_selection (&self, src: impl Language) -> Perhaps<Selection> {
src.word()?.map(|word|Ok(match word { src.word()?.map(|word|Ok(match word {
":select/scene" => self.selection().select_scene(self.tracks().len()), ":select/scene" => self.selection().select_scene(self.tracks().len()),
@ -502,6 +507,7 @@ mod app {
_ => return Err(format!("not selection: {word}").into()) _ => return Err(format!("not selection: {word}").into())
})).transpose() })).transpose()
} }
fn get_color (&self, src: impl Language) -> Perhaps<Color> { fn get_color (&self, src: impl Language) -> Perhaps<Color> {
if let Some(expr) = src.expr()? { if let Some(expr) = src.expr()? {
match (expr.head()?, expr.tail()?) { match (expr.head()?, expr.tail()?) {
@ -531,6 +537,7 @@ mod app {
return Err(format!("not a color: {:?}", src.src()?).into()) return Err(format!("not a color: {:?}", src.src()?).into())
} }
} }
fn get_opt_u7 (&self, src: impl Language) -> Perhaps<Option<u7>> { fn get_opt_u7 (&self, src: impl Language) -> Perhaps<Option<u7>> {
src.word()?.map(|word|Ok(match word { src.word()?.map(|word|Ok(match word {
":editor/pitch" => Some(( ":editor/pitch" => Some((
@ -539,9 +546,11 @@ mod app {
_ => return Err(format!("unknown midi note: {word}").into()) _ => return Err(format!("unknown midi note: {word}").into())
})).transpose() })).transpose()
} }
fn get_opt_u16 (&self, _src: impl Language) -> Perhaps<Option<u16>> { fn get_opt_u16 (&self, _src: impl Language) -> Perhaps<Option<u16>> {
Ok(None) Ok(None)
} }
fn get_opt_usize (&self, src: impl Language) -> Perhaps<Option<usize>> { fn get_opt_usize (&self, src: impl Language) -> Perhaps<Option<usize>> {
src.word()?.map(|word|Ok(match word { src.word()?.map(|word|Ok(match word {
":selected/scene" => self.selection().scene(), ":selected/scene" => self.selection().scene(),
@ -549,6 +558,7 @@ mod app {
_ => return Err(format!("unknown opt<usize>: {word}").into()) _ => return Err(format!("unknown opt<usize>: {word}").into())
})).transpose() })).transpose()
} }
fn get_clip (&self, src: impl Language) -> Perhaps<Option<Arc<RwLock<MidiClip>>>> { fn get_clip (&self, src: impl Language) -> Perhaps<Option<Arc<RwLock<MidiClip>>>> {
src.word()?.map(|word|Ok(match word { src.word()?.map(|word|Ok(match word {
":selected/clip" if let Selection::TrackClip { track, scene } = self.selection() => ":selected/clip" if let Selection::TrackClip { track, scene } = self.selection() =>
@ -556,6 +566,7 @@ mod app {
_ => return Err(format!("not a clip: {word}").into()) _ => return Err(format!("not a clip: {word}").into())
})).transpose() })).transpose()
} }
pub fn inc (&mut self, axis: &ControlAxis) -> Perhaps<AppCommand> { pub fn inc (&mut self, axis: &ControlAxis) -> Perhaps<AppCommand> {
Ok(match (&self.dialog, axis) { Ok(match (&self.dialog, axis) {
(Dialog::None, _) => todo!(), (Dialog::None, _) => todo!(),
@ -564,6 +575,7 @@ mod app {
_ => todo!() _ => todo!()
}) })
} }
pub fn dec (&mut self, axis: &ControlAxis) -> Perhaps<AppCommand> { pub fn dec (&mut self, axis: &ControlAxis) -> Perhaps<AppCommand> {
Ok(match (&self.dialog, axis) { Ok(match (&self.dialog, axis) {
(Dialog::None, _) => None, (Dialog::None, _) => None,
@ -572,6 +584,7 @@ mod app {
_ => todo!() _ => todo!()
}) })
} }
pub fn confirm (&mut self) -> Perhaps<AppCommand> { pub fn confirm (&mut self) -> Perhaps<AppCommand> {
Ok(match &self.dialog { Ok(match &self.dialog {
Dialog::Menu(index, items) => { Dialog::Menu(index, items) => {
@ -582,6 +595,7 @@ mod app {
_ => todo!(), _ => todo!(),
}) })
} }
} }
pub fn swap_value <T: Clone + PartialEq, U> ( pub fn swap_value <T: Clone + PartialEq, U> (
@ -1033,6 +1047,26 @@ pub fn show_version () {
//})?)? //})?)?
//} //}
/// Define an enum containing commands, and implement [Command] trait for over given `State`.
#[macro_export] macro_rules! def_command (
($Command:ident: |$state:ident: $State:ty| {
// FIXME: support attrs (docstrings)
$($Variant:ident$({$($arg:ident:$Arg:ty),+ $(,)?})?=>$body:expr),* $(,)?
})=>{
#[derive(Debug)] pub enum $Command {
// FIXME: support attrs (docstrings)
$($Variant $({ $($arg: $Arg),* })?),*
}
impl ::tengri::dizzle::Act<$State> for $Command {
fn act (&self, $state: &mut $State) -> Perhaps<Self> {
match self {
$(Self::$Variant $({ $($arg),* })? => $body,)*
_ => unimplemented!("Act<{}>: {self:?}", stringify!($State)),
}
}
}
});
pub use self::config::*; pub use self::config::*;
mod config { mod config {
use crate::*; use crate::*;
@ -1456,7 +1490,7 @@ mod draw {
fn tek_draw_expr (state: &App, to: &mut Tui, lang: &impl Expression) -> Drawn<u16> { fn tek_draw_expr (state: &App, to: &mut Tui, lang: &impl Expression) -> Drawn<u16> {
Ok(Some(if let Some(area) = eval_view(state, to, lang)? { Ok(Some(if let Some(area) = eval_view(state, to, lang)? {
area area
} else if let Some(area) = eval_view_tui(state, to, lang)? { } else if let Some(area) = Tui::eval_view(state, to, lang)? {
area area
} else { } else {
return Err(format!("App::interpret_expr: unexpected: {lang:?}").into()) return Err(format!("App::interpret_expr: unexpected: {lang:?}").into())

2
tengri

@ -1 +1 @@
Subproject commit 5ca329292f808c137b6e2b7e80892e2a9e855696 Subproject commit fc01fd6ad3a6ed4ee17d65a65b3e59df522f895a