improve cfg legibility and move more defs there

This commit is contained in:
i do not exist 2026-09-20 14:17:28 +03:00
parent 83c03f5a80
commit 8b96ddb411
8 changed files with 182 additions and 318 deletions

View file

@ -228,8 +228,9 @@ fn get_opt_usize <'a> (state: &App, src: impl Language) -> Perhaps<Option<usize>
fn get_axis <'a> (_: &App, src: impl Language) -> Perhaps<ControlAxis> {
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<u16> {
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)
}
}

View file

@ -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({

View file

@ -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<Tui> {
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());

View file

@ -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<TuiEvent, Arc<str>> = 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<TuiEvent, Arc<str>>, _item: &str) -> Usually<()> {
// TODO
Ok(())
}
fn add_def (map: &mut Bind<TuiEvent, Arc<str>>, 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();
}

View file

@ -281,56 +281,55 @@ impl View<Tui, App> {
-> Usually<Arc<Box<dyn Fn(&App, &mut Tui)->Drawn<u16> + 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)

View file

@ -55,25 +55,6 @@ pub fn get_dialog <'a> (_: &App, src: impl Language) -> Perhaps<Dialog> {
Options,
}
pub fn draw_dialog <'a, I: Debug + Iterator<Item = &'a str>> (to: &mut Tui, mut frags: I, state: &App)
-> Drawn<u16>
{
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 {

View file

@ -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))

View file

@ -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)
})?)
}