diff --git a/src/device/dialog.rs b/src/device/dialog.rs index 66f51abb..40dcfbb7 100644 --- a/src/device/dialog.rs +++ b/src/device/dialog.rs @@ -65,8 +65,9 @@ impl Dialog { MenuItem("Load session".into(), Arc::new(Box::new(|_|Ok(())))), - MenuItem("Exit".into(), Arc::new(Box::new(|_|Ok({ - () + MenuItem("Exit".into(), Arc::new(Box::new(|app|Ok({ + app.exit.exit(); + println!("Exited cleanly.") })))), ].into())) diff --git a/src/tek.rs b/src/tek.rs index a2bac85e..18ca7439 100644 --- a/src/tek.rs +++ b/src/tek.rs @@ -72,7 +72,7 @@ fn run_new_plain (config: Config) -> Usually<()> { let clock = Clock::new(&jack, Some(bpm))?; let tracks = []; let scenes = []; - Ok(App::new(Arrangement::new( + Ok(App::new(None, Arrangement::new( &jack, title.into(), clock, @@ -129,9 +129,14 @@ fn run_new_plain (config: Config) -> Usually<()> { Config => config.print(), Resume => todo!("resume session"), List => todo!("list sessions"), - New(sesh) => Tui::run_main( - Arc::new(RwLock::new(App::new(sesh.init()?, config, ":menu"))) - ).map(|_|())?, + New(sesh) => Exit::run(|exit|Tui::run_main( + exit.clone(), + Arc::new(RwLock::new(App::new( + Some(exit), + sesh.init()?, + config, + ":menu" + ))))).map(|_|())?, _ => todo!() } Ok(()) @@ -684,6 +689,8 @@ mod app { #[namespace(Option App::get_opt_usize)] #[namespace(Option>> App::get_clip)] pub struct App { + /// Exit flag + pub exit: Exit, /// Base color. pub color: ItemTheme, /// Must not be dropped for the duration of the process @@ -715,10 +722,16 @@ mod app { /// proj.jack = tek::tengri::Jack::new(&"test_tek").expect("failed to connect to jack"); /// let mut conf = std::sync::Arc::new(tek::Config::default()); /// conf.add("(mode hello)"); - /// let tek = tek::App::new(proj, conf, "hello"); + /// let tek = tek::App::new(None, proj, conf, "hello"); /// ``` - pub fn new (project: Arrangement, config: Arc, mode: impl AsRef) -> Self { + pub fn new ( + exit: Option, + project: Arrangement, + config: Arc, + mode: impl AsRef + ) -> Self { App { + exit: exit.unwrap_or_default(), jack: project.jack.clone(), color: ItemTheme::random(), dialog: Dialog::welcome(), @@ -1482,6 +1495,14 @@ mod draw { Ok(()) } + impl Keywords> for App { + fn keywords () -> impl Iterator Perhaps>> { + [kw_when, kw_either, kw_split, kw_align, kw_exact, kw_min, kw_max, kw_push, + kw_tui_text, kw_tui_fg, kw_tui_bg] + .into_iter() + } + } + /// The [Draw] implementation for [App] handles the loaded view, /// which is defined in terms of [dizzle] DSL. /// @@ -1540,14 +1561,6 @@ mod draw { } } - impl Keywords> for App { - fn keywords () -> impl Iterator Perhaps>> { - [kw_when, kw_either, kw_split, kw_align, kw_exact, kw_min, kw_max, kw_push, - kw_tui_text, kw_tui_fg, kw_tui_bg] - .into_iter() - } - } - impl Interpret>> for App { fn interpret_expr <'a> (&'a self, to: &mut Tui, lang: &'a impl Expression) -> Drawn { self.keyword(to, lang) @@ -1624,17 +1637,21 @@ mod draw { to: &mut Tui, mut frags: std::str::Split<&str>, state: &App, dsl: &impl Expression) -> Drawn { match frags.next() { Some("menu") => if let Dialog::Menu(selected, items) = &state.dialog { + //Some(iter_south(move||items.0.iter().enumerate().map(move|(index, MenuItem(item, _))|{ + //let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) }; + //let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) }; + //fg_bg(f, b, item.full_w().align_x().exact_h(2)).push_y(index as u16 * 4) + //})).full_wh()) let items = items.clone(); let selected = selected; Some(draw(move|to: &mut Tui|{ for (index, MenuItem(item, _)) in items.0.iter().enumerate() { let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) }; let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) }; - fg_bg(f, b, item.full_w().align_w().exact_h(2)) - .push_y((4 * index) as u16).draw(to)?; + fg_bg(f, b, item.exact_h(2).full_w().align_x()).push_y(1 + (2 * index) as u16).draw(to)?; } Ok(Some(to.area().into())) - }).full_wh()) + })) } else { None }.draw(to), diff --git a/tengri b/tengri index b0971999..cf67185f 160000 --- a/tengri +++ b/tengri @@ -1 +1 @@ -Subproject commit b09719993af0b9150b8b79c3ec08601795c5cd4e +Subproject commit cf67185ffde1719bd5cc0c75cb0f9ac49d95a6d7