mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-10-08 10:46:43 +02:00
improve cfg legibility and move more defs there
This commit is contained in:
parent
83c03f5a80
commit
8b96ddb411
8 changed files with 182 additions and 318 deletions
34
src/app.rs
34
src/app.rs
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
17
src/clock.rs
17
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<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());
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
277
src/tek.edn
277
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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})?)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue