From 8b96ddb4111583e33b5896548872d966356ee39c Mon Sep 17 00:00:00 2001 From: i do not exist Date: Sun, 20 Sep 2026 14:17:28 +0300 Subject: [PATCH] improve cfg legibility and move more defs there --- src/app.rs | 34 ++++-- src/cli.rs | 3 +- src/clock.rs | 17 --- src/config_bind.rs | 46 ++++---- src/config_view.rs | 93 ++++++++------- src/dialog.rs | 21 +--- src/tek.edn | 277 +++++++++++++-------------------------------- src/tek.rs | 9 +- 8 files changed, 182 insertions(+), 318 deletions(-) diff --git a/src/app.rs b/src/app.rs index 5197c086..4f4a0d48 100644 --- a/src/app.rs +++ b/src/app.rs @@ -228,8 +228,9 @@ fn get_opt_usize <'a> (state: &App, src: impl Language) -> Perhaps fn get_axis <'a> (_: &App, src: impl Language) -> Perhaps { eval_word(src, |word|Ok(match word { - ":x" => ControlAxis::X, - ":y" => ControlAxis::Y, + "X" => ControlAxis::X, "XFine" | "X2" => ControlAxis::XFine, + "Y" => ControlAxis::Y, "YFine" | "Y2" => ControlAxis::YFine, + "Z" => ControlAxis::Z, "ZFine" | "Z2" => ControlAxis::ZFine, _ => return err!("unknown axis {word}") @@ -459,7 +460,10 @@ impl App { /// let axis = tek::ControlAxis::X; /// ``` #[derive(Debug, Copy, Clone)] pub enum ControlAxis { - X, Y, Z, I + X, XFine, + Y, YFine, + Z, ZFine, + I, IFine, } #[tek_proc::commands(AxisCommand)] @@ -562,15 +566,21 @@ impl App { } #[allow(unused)] fn draw_debug (&self, to: &mut Tui) -> Drawn { - east( - format!("{}x{} ", - self.size.0.load(Relaxed), - self.size.1.load(Relaxed)), - format!("{}/{} {} ", - self.perf.used.load(Relaxed), - self.perf.window.load(Relaxed), - self.perf.clock.raw() / 10000000), - ).align_se().draw(to) + Split::Above.bar(0, + Split::West.bar(16, + format!("{}/{} {} ", + self.perf.used.load(Relaxed), + self.perf.window.load(Relaxed), + self.perf.clock.raw() / 10000000).align_e(), + format!("{}x{} ", + self.size.0.load(Relaxed), + self.size.1.load(Relaxed)).align_w(), + ).align_se(), + Split::East.bar(16, + format!("{}", self.modes.read()[0]), + format!("{}", self.modes.read()[0]) + ).align_sw() + ).draw(to) } } diff --git a/src/cli.rs b/src/cli.rs index fc679ad3..1110543c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -84,7 +84,8 @@ impl Action { exit.clone(), { #[allow(unused_mut)] - let mut app = App::new(Some(exit), sesh.init()?, config, ":menu"); + let mut app = App::new(Some(exit), sesh.init()?, config, "Menu"); + app.dialog = Dialog::welcome(); #[cfg(feature = "prof2")] { if trace { app.guard = Some({ diff --git a/src/clock.rs b/src/clock.rs index f43fc344..cf919b75 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -449,23 +449,6 @@ impl_time_unit!(Pulse); impl_time_unit!(Bpm); impl_time_unit!(LaunchSync); -/// ``` -/// let x = ""; -/// let _ = tek::view_transport(true, x.as_ref(), x.as_ref(), x.as_ref()); -/// let _ = tek::view_transport(false, x.as_ref(), x.as_ref(), x.as_ref()); -/// ``` -pub fn view_transport <'a> (play: bool, bpm: &str, beat: &str, time: &str) -> impl Draw { - let theme = ItemTheme::G[96]; - bg(Black, east!(above( - button_play_pause(play, false).align_w(), - east!( - field_h(theme, "BPM", bpm), - field_h(theme, "Beat", beat), - field_h(theme, "Time", time), - ).align_e().full_wh() - ))) -} - /// ``` /// let x = ""; /// let _ = tek::view_status(None, x.as_ref(), x.as_ref(), x.as_ref()); diff --git a/src/config_bind.rs b/src/config_bind.rs index 38c6f69c..243cfda5 100644 --- a/src/config_bind.rs +++ b/src/config_bind.rs @@ -12,27 +12,11 @@ impl Binds { let name = expr.head()?.ok_or("bind: missing name")?; let body = expr.tail()?.unwrap_or(""); binds.0.try_write().unwrap().insert(name.into(), { - let mut map = Bind::new(); + let mut map: Bind> = Bind::new(); body.each((), |_, item: &str|if matches!(item.expr().head(), Ok(Some("see"))) { - // TODO - Ok(()) + Binds::add_ref(&mut map, item) } else if let Ok(Some(_word)) = item.expr().head().word() { - let expr = item.expr()?; - let head = expr.head()?; - if let Some(event) = TuiKey::from_dsl(&head)?.to_crossterm() { - map.add(TuiEvent(event), Binding { - commands: [item.expr()?.tail()?.unwrap_or_default().into()].into(), - condition: None, - description: None, - source: None - }); - Ok(()) - } else if Some(":char") == item.expr()?.head()? { - // TODO - return Ok(()) - } else { - return err!("Binds::add: invalid key: {:?}", item.expr()?.head()?) - } + Binds::add_def(&mut map, item) } else { return err!("Binds::add: unexpected: {item:?}") })?; @@ -41,6 +25,30 @@ impl Binds { Ok(()) } + fn add_ref (_map: &mut Bind>, _item: &str) -> Usually<()> { + // TODO + Ok(()) + } + + fn add_def (map: &mut Bind>, item: &str) -> Usually<()> { + let expr = item.expr()?; + let head = expr.head()?; + if let Some(event) = TuiKey::from_dsl(&head)?.to_crossterm() { + map.add(TuiEvent(event), Binding { + commands: [item.expr()?.tail()?.unwrap_or_default().into()].into(), + condition: None, + description: None, + source: None + }); + Ok(()) + } else if Some(":char") == item.expr()?.head()? { + // TODO + Ok(()) + } else { + err!("Binds::add: invalid key: {:?}", item.expr()?.head()?) + } + } + pub fn clear (&self) { *self.0.write() = Default::default(); } diff --git a/src/config_view.rs b/src/config_view.rs index 2ad96110..dd1ed8ff 100644 --- a/src/config_view.rs +++ b/src/config_view.rs @@ -281,56 +281,55 @@ impl View { -> UsuallyDrawn + Send + Sync>>> { macro_rules! draw { - (|$state:ident|$body:expr)=>{Self::boxed(move|$state, to|$body.draw(to))} + (|$state:ident|$body:expr)=>{Self::boxed(move|$state, to|$body.draw(to))}; + ($const:expr)=>{Self::boxed(move|_, to|$const.draw(to))}; + ()=>{Self::boxed(move|_, __|Ok(None))}; } Ok(Arc::new(match word.split("/").next() { - //Some(":logo") => view_logo().draw(to), - Some(":meters") => match word.split("/").skip(1).next() { - Some("input") => Self::boxed(move|_, to|bg(Rgb(30, 30, 30), "Input Meters".align_s().full_h()).draw(to)), - Some("output") => Self::boxed(move|_, to|bg(Rgb(30, 30, 30), "Output Meters".align_s().full_h()).draw(to)), - _ => panic!() - }, - Some(":tracks") => match &word[(":tracks".len()+1)..] { - "" => Self::boxed(move|_, to|"TODO tracks".draw(to)), - - "names" => draw!(|app|app.project.view_track_names(app.color.clone())), - "names/count" => draw!(|app|app.project.view_track_names_count()), - "names/cells" => draw!(|app|app.project.view_track_names_cells()), - "names/add" => draw!(|app|app.project.view_track_names_add()), - - "devices" => draw!(|app|app.project.view_track_devices(app.color.clone())), - "devices/count" => draw!(|app|app.project.view_track_device_count()), - "devices/cells" => draw!(|app|app.project.view_track_device_cells(app.tracks_devices_height())), - "devices/add" => draw!(|app|app.project.view_track_device_add()), - - "inputs" => draw!(|app|app.project.view_track_inputs(app.color.clone())), - "inputs/count" => draw!(|app|app.project.view_track_input_count()), - "inputs/cells" => draw!(|app|app.project.view_track_input_cells(app.tracks_inputs_height())), - "inputs/add" => draw!(|app|app.project.view_track_input_add()), - - "outputs" => draw!(|app|app.project.view_track_outputs(app.color.clone(), 0)), - "outputs/count" => draw!(|app|app.project.view_track_output_count()), - "outputs/cells" => draw!(|app|app.project.view_track_output_cells()), - "outputs/add" => draw!(|app|app.project.view_track_output_add()), - - _ => panic!("unknown: {word}") - }, - Some(":scenes") => match word.split("/").skip(1).next() { - Some("clips") => draw!(|app|app.view_scenes_clips()), - Some("names") => draw!(|app|app.view_scenes_names()), - _ => panic!() - }, - Some(":templates") => draw!(|app|view_templates(app)), - Some(":browse/title") => draw!(|app|view_browse_title(app)), - Some(":device") => draw!(|app|view_device(app)), - Some(":dialog") => Self::boxed(move|state, to|draw_dialog(to, word.split("/").skip(1), state)), - Some(":sessions") => Self::boxed(move|_, to|view_sessions().draw(to)), - Some(":status") => Self::boxed(move|state, to|draw_status_bar(to, state)), - Some(":editor") => Self::boxed(move|_, to|"TODO Editor".draw(to)), - Some(":transport") => Self::boxed(move|_, to|view_transport(true, "", "", "").draw(to)), - Some(":debug") => Self::boxed(move|_, to|format!("[{:?}]", to.area()).exact_h(1).draw(to)), - Some(_) => Self::boxed(move|state, to|if let Some(view) = state.config.get_view(word.as_ref()) { + Some("Beat") => draw!(), + Some("Bpm") => draw!(), + Some("BrowseTitle") => draw!(|app|view_browse_title(app)), + Some("Debug") => Self::boxed(move|_, to|format!("[{:?}]", to.area()).exact_h(1).draw(to)), + Some("Device") => draw!(|app|view_device(app)), + Some("Menu") => draw!(|app|{ + if let Dialog::Menu(selected, items) = &app.dialog { + Some(iter_south(move||items.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).exact_h(2).align_x() + })).exact_w(20).align_x()) + } else { + None + } + }), + Some("Editor") => draw!("TODO editor"), + Some("MetersIn") => draw!(|___|bg(Rgb(30, 30, 30), "Input Meters".align_s().full_h())), + Some("MetersOut") => draw!(|___|bg(Rgb(30, 30, 30), "Output Meters".align_s().full_h())), + Some("ModeList") => draw!(|app|app.modes.read().get(0)), // TODO all + Some("ScenesClips") => draw!(|app|app.view_scenes_clips()), + Some("ScenesNames") => draw!(|app|app.view_scenes_names()), + Some("Sessions") => draw!(|___|view_sessions()), + Some("Templates") => draw!(|app|view_templates(app)), + Some("Time") => draw!(), + Some("Tracks") => draw!("TODO tracks"), + Some("TracksDevices") => draw!(|app|app.project.view_track_devices(app.color.clone())), + Some("TracksDevicesAdd") => draw!(|app|app.project.view_track_device_add()), + Some("TracksDevicesCells") => draw!(|app|app.project.view_track_device_cells(app.tracks_devices_height())), + Some("TracksDevicesCount") => draw!(|app|app.project.view_track_device_count()), + Some("TracksInputs") => draw!(|app|app.project.view_track_inputs(app.color.clone())), + Some("TracksInputsAdd") => draw!(|app|app.project.view_track_input_add()), + Some("TracksInputsCells") => draw!(|app|app.project.view_track_input_cells(app.tracks_inputs_height())), + Some("TracksInputsCount") => draw!(|app|app.project.view_track_input_count()), + Some("TracksNames") => draw!(|app|app.project.view_track_names(app.color.clone())), + Some("TracksNamesAdd") => draw!(|app|app.project.view_track_names_add()), + Some("TracksNamesCells") => draw!(|app|app.project.view_track_names_cells()), + Some("TracksNamesCount") => draw!(|app|app.project.view_track_names_count()), + Some("TracksOutputs") => draw!(|app|app.project.view_track_outputs(app.color.clone(), 0)), + Some("TracksOutputsAdd") => draw!(|app|app.project.view_track_output_add()), + Some("TracksOutputsCells") => draw!(|app|app.project.view_track_output_cells()), + Some("TracksOutputsCount") => draw!(|app|app.project.view_track_output_count()), + Some(_) => Self::boxed(move|state, to|if let Some(view) = state.config.get_view(word.as_ref()) { (view.render)(state, to) } else { fg(Color::Rgb(128, 32, 32), format!("undefined: {word:?}")).draw(to) diff --git a/src/dialog.rs b/src/dialog.rs index af13adc0..e399687e 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -55,25 +55,6 @@ pub fn get_dialog <'a> (_: &App, src: impl Language) -> Perhaps { Options, } -pub fn draw_dialog <'a, I: Debug + Iterator> (to: &mut Tui, mut frags: I, state: &App) - -> Drawn -{ - match frags.next() { - - Some("menu") => if let Dialog::Menu(selected, items) = &state.dialog { - Some(iter_south(move||items.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).exact_h(2).align_x() - })).exact_w(20).align_x()) - } else { - None - }.draw(to), - - _ => unimplemented!("draw_dialog: ({frags:?})"), - } -} - impl Dialog { /// ``` @@ -94,7 +75,7 @@ impl Dialog { }, AppCommand::Mode { command: ModeCommand::Reset { - modes: vec![":arranger".into()] + modes: vec!["Arranger".into()] } }, AppCommand::Tracks { diff --git a/src/tek.edn b/src/tek.edn index 63fe7fc6..66c5d694 100644 --- a/src/tek.edn +++ b/src/tek.edn @@ -1,207 +1,86 @@ -(view :logo (text tek )) +(mode Menu (name Main Menu) (info Welcome to Tek!) (keys Y Confirm) + (view (bar/s 2 Transport (bar/n 2 Status (align/c (bar/s 2 (align/x (bg (g 12) Logo)) Menu)))))) +(mode Transport (name Transport) (info JACK transport controller.) + (keys Clock Global) + (view Transport)) +(mode Arranger (name Arranger) (info Launch grid.) + (keys Global Clock Tracks Scenes Clip Launch Color History) + (view (bar/n 2 Status (bar/s 8 (bar/e 16 (align/nw Transport) + (bar/w 20 (bar/s 2 (bar/w 4 TracksOutputsAdd TracksOutputsCount) + (bar/s 2 (bar/w 4 TracksDevicesAdd TracksDevicesCount) + (bar/s 2 (bar/w 4 TracksNamesAdd TracksNamesCount) + (bar/w 4 TracksInputsAdd TracksInputsCount)))) + (align/x (bar/s 2 TracksOutputsCells + (bar/s 2 TracksDevicesCells + (bar/s 2 TracksNamesCells TracksInputsCells)))))) + (bar/w 20 (text) (bar/e 16 ScenesNames ScenesClips)))))) +(mode Sequencer (info MIDI sequencer.) + (keys Global Clock I IFine Y Page EditorView EditorAdd EditorDel) + (view (bsp/s (exact/h 1 Transport) (bsp/n (exact/h 1 Status) (fill/xy (bsp/a (fill/xy (align/e Pool)) Editor)))))) +(mode Sampler (info Sample player.) + (keys SamplerDirs SamplerRec SamplerPlay) + (view (bsp/s (exact/h 1 Transport) (bsp/n (exact/h 1 Status) (fill/xy SampleGrid))))) +(mode Groovebox (info Sequencer with sampler.) + (keys Global Clock Sampler I IFine Y Page EditorView EditorAdd EditorDel) + (view (bsp/w MetersOut (bsp/e MetersIn (bsp/w GrooveMeta GrooveEditor))))) -(view :browse (bsp/s - (pad/xy 3 1 :browse-title) - (fg (g 96) browser))) +(view Logo (text tek! 0.4.0 )) +(view Browse (bsp/s (pad/xy 3 1 BrowseTitle) (fg (g 96) browser))) +(view PortsOut (bsp/s (align/w (text L-AUDIO-OUT)) (bsp/e (text MIDI-OUT) (align/e (text AUDIO-OUT-R))))) +(view PortsIn (bsp/s (align/w (text L-AUDIO-IN)) (bsp/e (text MIDI-IN) (align/e (text AUDIO-IN-R))))) +(view GrooveMeta (fill/y (align/n (stack/s Pool MidiInsStatus MidiOutsStatus AudioInsStatus AudioOutsStatus)))) +(view GrooveEditor (bsp/n GrooveSample GrooveSequence)) +(view GrooveSample (exact/h SampleHeight (bsp/e (fill/y (exact/w 20 (align/nw SampleStatus))) SampleViewer))) +(view GrooveSequence (bsp/e (fill/y (align/n (bsp/s Status/v EditorStatus))) (bsp/e SamplesKeys Editor))) +(view Status (bar/s 1 (text Mode) ModeList)) +(view Transport (bg (g 0) (pad/x 1 (bar/e 4 PlayPause (bar/e 16 Bpm (bar/e 16 Beat Time)))))) -(mode :transport - (name Transport) - (info JACK transport controller.) - (keys :clock :global) - :transport) +(keys Global (@f1 (dialog Help)) + (@f2 (project new)) + (@f3 (dialog History)) + (@f6 (dialog :save)) + (@f8 (dialog :options)) + (@f9 (dialog :load)) + (@f10 (dialog :quit))) -(mode :menu - (name Menu) - (info Mode selector.) - (keys :axis/y :confirm) - (view - (bar/s 2 (pad/x 1 :transport) - (bar/n 2 :status - (align/c - (bar/s 2 (align/x (bg (g 12) :logo)) - :dialog/menu)))))) +(keys Back (@escape cancel)) +(keys Confirm (@enter confirm)) +(keys Page (@pgup page/up) (@pgdn page/down)) +(keys Delete (@delete delete) (@backspace delete/back)) +(keys History (@u (undo 1)) (@r (redo 1))) +(keys X (@left (axis (dec X))) (@right (axis (inc X)))) +(keys Y (@up (axis (dec Y))) (@down (axis (inc Y)))) +(keys Z (@minus (axis (dec Z))) (@equal (axis (inc Z)))) +(keys I (@comma (axis (dec I))) (@period (axis (inc Z)))) +(keys W (@openbracket (axis (dec W))) (@closebracket (axis (inc W)))) +(keys XFine (@shift/left (axis (dec XFine))) (@shift/right (axis (inc XFine)))) +(keys YFine (@shift/up (axis (dec YFine))) (@shift/down (axis (inc YFine)))) +(keys ZFine (@underscore (axis (dec ZFine))) (@plus (axis (inc ZFine)))) +(keys IFine (@lt (axis (dec IFine))) (@gt (axis (inc ZFine)))) +(keys WFine (@openbrace (axis (dec WFine))) (@closebrace (axis (inc WFine)))) -(keys :back (@escape cancel)) -(keys :confirm (@enter confirm)) -(keys :axis/y (@up (axis (dec :y))) - (@down (axis (inc :y)))) +(keys Clock (@space (clock/toggle 0)) (@shift/space (clock/toggle 0))) +(keys Scenes (@shift/S (scenes add)) (@s (scenes select)) (@up (scenes prev)) (@down (scenes next))) +(keys Tracks (@shift/T (tracks add)) (@t (tracks select)) (@left (tracks prev)) (@right (tracks next))) +(keys Clip (@l (toggle :loop)) (@tab (clip upsert) (edit toggle))) +(keys Color (@c (color))) +(keys Launch (@q (launch))) -(mode :arranger (name Arranger) (info Launch grid.) - (keys :clock :color :launch :scenes :tracks :clip :global :history :saveload) - (mode :editor (keys :editor)) - (mode :dialog (keys :dialog)) - (mode :message (keys :message)) - (mode :add-device (keys :add-device)) - (mode :browse (keys :browse)) - (mode :rename (keys :input)) - (mode :length (keys :rename)) - (mode :clip (keys :clip)) - (mode :track (keys :track)) - (mode :scene (keys :scene)) - (mode :mix (keys :mix)) - (view - (bar/n 2 :status - (bar/s 8 - (bar/e 16 (align/nw (pad/x 1 :transport)) - (bar/w 20 (bar/s 2 (bar/w 4 :tracks/outputs/add :tracks/outputs/count) - (bar/s 2 (bar/w 4 :tracks/devices/add :tracks/devices/count) - (bar/s 2 (bar/w 4 :tracks/names/add :tracks/names/count) - (bar/w 4 :tracks/inputs/add :tracks/inputs/count)))) - (align/x - (bar/s 2 :tracks/outputs/cells - (bar/s 2 :tracks/devices/cells - (bar/s 2 :tracks/names/cells - :tracks/inputs/cells)))))) - (bar/w 20 (text) - (bar/e 16 :scenes/names - :scenes/clips)))))) +(keys EditorView (see X XFine Z ZFine) (@z toggle :lock)) +(keys EditorAdd (@a editor/append :true) (@enter editor/append :false)) +(keys EditorDel (@del editor/delete/note) (@shift/del editor/delete/note)) -(keys :global - (@f1 (dialog :help)) - (@f2 (project new)) - (@f3 (dialog :history)) - (@f6 (dialog :save)) - (@f8 (dialog :options)) - (@f9 (dialog :load)) - (@f10 (dialog :quit))) +(keys Sequencer (see Color Launch) (@shift/I input/add) (@shift/O output/add)) -(keys :clock - (@space (clock/toggle 0)) - (@shift/space (clock/toggle 0))) +(keys SamplerRec (@r sampler/record/toggle SelectedSample) (@shift/R sampler/record/back)) +(keys SamplerPlay (@p sampler/play/sample SelectedSample) (@P sampler/stop/sample SelectedSample)) +(keys SamplerImpEx (@shift/f6 dialog :export/sample) (@shift/f9 dialog Import/sample)) +(keys SamplerDirs (@up sampler/select :sample/above) (@down sampler/select :sample/below) (@left sampler/select :sample/to/left) (@right sampler/select :sample/to/right)) -(keys :color - (@c (color))) - -(keys :launch - (@q (launch))) - -(keys :scenes - (@shift/S (scenes add)) - (@s (scenes select)) - (@up (scenes prev)) - (@down (scenes next))) - -(keys :tracks - (@shift/T (tracks add)) - (@t (tracks select)) - (@left (tracks prev)) - (@right (tracks next))) - -(keys :clip (see :color :launch :axis/z :axis/z2 :delete) - (@l (toggle :loop)) - (@tab (clip upsert) (edit toggle))) - -(view :ports/out - (bsp/s (align/w (text L-AUDIO-OUT)) - (bsp/e (text MIDI-OUT) - (align/e (text AUDIO-OUT-R))))) - -(view :ports/in - (bsp/s (align/w (text L-AUDIO-IN)) - (bsp/e (text MIDI-IN) - (align/e (text AUDIO-IN-R))))) - -(mode :sequencer (name Sequencer) (info MIDI sequencer.) - (keys :editor :clock :global) - (mode browse (keys :browse)) - (mode rename (keys :pool/rename)) - (mode length (keys :pool/length)) - (view - (bsp/s (exact/h 1 :transport) - (bsp/n (exact/h 1 :status) - (fill/xy (bsp/a (fill/xy (align/e :pool)) - :editor)))))) - -(mode :sampler (name Sampler) (info Sample player.) - (keys :sampler/directions :sampler/record :sampler/play) - (view - (bsp/s (exact/h 1 :transport) - (bsp/n (exact/h 1 :status) - (fill/xy :samples/grid))))) - -(mode :groovebox (name Groovebox) (info Sequencer with sampler.) - (keys :clock :editor :sampler :global) - (mode browse (keys :browse)) - (mode rename (keys :pool-rename)) - (mode length (keys :pool-length)) - (view - (bsp/w :meters/output - (bsp/e :meters/input - (bsp/w :groove/meta - :groove/editor))))) - -(view :groove/meta (fill/y (align/n (stack/s :midi-ins/status :midi-outs/status :audio-ins/status :audio-outs/status :pool)))) - -(view :groove/editor (bsp/n :groove/sample :groove/sequence)) - -(view :groove/sample (exact/h :h-sample-detail (bsp/e (fill/y (exact/w 20 (align/nw :sample-status))) :sample-viewer))) - -(view :groove/sequence (bsp/e (fill/y (align/n (bsp/s :status/v :editor-status))) (bsp/e :samples/keys :editor))) - -(keys :axis/x (@left dec :x) - (@right inc :x)) -(keys :axis/x2 (@shift/left dec :x2) - (@shift/right inc :x2)) -(keys :axis/y2 (@shift/up dec :y2) - (@shift/down inc :y2)) -(keys :axis/z (@minus dec :z) - (@equal inc :z)) -(keys :axis/z2 (@underscore dec :z2) - (@plus inc :z2)) -(keys :axis/i (@comma dec :i) - (@period inc :z)) -(keys :axis/i2 (@lt dec :i2) - (@gt inc :z2)) -(keys :axis/w (@openbracket dec :w) - (@closebracket inc :w)) -(keys :axis/w2 (@openbrace dec :w2) - (@closebrace inc :w2)) -(keys :focus) - -(keys :editor (see :axis/i :axis/i2 :axis/y - :page :editor/view :editor/add :editor/del)) -(keys :editor/view (see :axis/x :axis/x2 :axis/z :axis/z2) - (@z toggle :lock)) -(keys :editor/add (@a editor/append :true) - (@enter editor/append :false)) -(keys :editor/del (@del editor/delete/note) - (@shift/del editor/delete/note)) -(keys :sampler/record (@r sampler/record/toggle :sample/selected) - (@shift/R sampler/record/back)) -(keys :sampler/play (@p sampler/play/sample :sample/selected) - (@P sampler/stop/sample :sample/selected)) -(keys :sampler/import-export (@shift/f6 dialog :export/sample) - (@shift/f9 dialog :import/sample)) -(keys :sampler/directions (@up sampler/select :sample/above) - (@down sampler/select :sample/below) - (@left sampler/select :sample/to/left) - (@right sampler/select :sample/to/right)) -(keys :track (see :color :launch :axis/z :axis/z2 :delete) - (@r toggle :rec) - (@m toggle :mon) - (@p toggle :play) - (@P toggle :solo)) -(keys :scene (see :color :launch :axis/z :axis/z2 :delete)) -(keys :help (@f1 dialog :help)) -(keys :page (@pgup page/up) - (@pgdn page/down)) -(keys :delete (@delete delete) - (@backspace delete/back)) -(keys :input (see :axis/x :delete) (:char input)) -(keys :list (see :axis/y :confirm)) -(keys :length (see :axis/x :axis/y :confirm)) -(keys :browse (see :list :input :focus)) -(keys :history (@u undo 1) - (@r redo 1)) -(keys :saveload (@f6 dialog :save) - (@f9 dialog :load)) -(keys :sequencer (see :color :launch) - (@shift/I input/add) - (@shift/O output/add)) -(keys :pool (see :axis-y :axis-w :axis/z2 :color :delete) - (@n rename/begin) - (@t length/begin) - (@m import/begin) - (@x export/begin) - (@shift/A clip/add :after :new/clip) - (@shift/D clip/add :after :cloned/clip)) +(keys Track (see Color Launch Z ZFine Delete) (@r toggle :rec) (@m toggle :mon) (@p toggle :play) (@P toggle :solo)) +(keys Scene (see Color Launch Z ZFine Delete)) +(keys Input (see X Delete) (:char input)) +(keys List (see Y Confirm)) +(keys Length (see X Y Confirm)) +(keys Browse (see List Input)) +(keys Pool (see Y W ZFine Color Delete) (@n rename/begin) (@t length/begin) (@m import/begin) (@x export/begin) (@shift/A clip/add :after :newClip) (@shift/D clip/add :after :clonedClip)) diff --git a/src/tek.rs b/src/tek.rs index d7cb1679..bd2dfb92 100644 --- a/src/tek.rs +++ b/src/tek.rs @@ -78,13 +78,13 @@ fn main () -> Usually<()> { fn run_new_plain (config: Config) -> Usually<()> { let name = "tek"; tengri::Tui::run_main(Jack::new_run(name, move|jack|{ - let mode = ":menu"; + let mode = "Menu"; let title = "untitled!"; let bpm = 74.; let clock = Clock::new(&jack, Some(bpm))?; let tracks = []; let scenes = []; - Ok(App::new(None, Project::new( + let project = Project::new( &jack, title.into(), clock, @@ -96,6 +96,9 @@ fn run_new_plain (config: Config) -> Usually<()> { .chain(connect_audio_ins(&jack, &"R", &[], None)?.into_iter()), [].into_iter().chain(connect_audio_outs(&jack, &"L", &[], None)?.into_iter()) .chain(connect_audio_outs(&jack, &"R", &[], None)?.into_iter()), - ), config, mode)) + ); + let mut app = App::new(None, project, config, mode); + app.dialog = Dialog::welcome(); + Ok(app) })?) }