Compare commits

...

3 commits

Author SHA1 Message Date
daaa4f7bef filter help by current state
Some checks are pending
/ build (push) Waiting to run
2025-04-30 22:05:02 +03:00
9f30f77aee help: display all keybinds 2025-04-30 21:51:15 +03:00
9bc4e3fb5f delete track/scene 2025-04-30 20:30:55 +03:00
9 changed files with 71 additions and 63 deletions

View file

@ -1 +1 @@
(@r sampler record/begin :pitch) (@r sampler record/toggle :sample)

View file

@ -1,13 +1,13 @@
(@up select :sample-up) (@up sampler select :sample-up)
(@w select :sample-up) (@w sampler select :sample-up)
(@down select :sample-down) (@down sampler select :sample-down)
(@s select :sample-down) (@s sampler select :sample-down)
(@left select :sample-left) (@left sampler select :sample-left)
(@a select :sample-left) (@a sampler select :sample-left)
(@right select :sample-right) (@right sampler select :sample-right)
(@d select :sample-right) (@d sampler select :sample-right)
(@r record/toggle :sample) (@r sampler record/toggle :sample)

View file

@ -1,7 +1,7 @@
(@delete scene delete :scene)
(@q scene launch :scene) (@q scene launch :scene)
(@c scene color :scene) (@c scene color :scene)
(@comma scene prev) (@comma scene prev)
(@period scene next) (@period scene next)
(@lt scene swap-prev) (@lt scene swap-prev)
(@gt scene swap-next) (@gt scene swap-next)
(@delete scene delete)

View file

@ -1,11 +1,10 @@
(@delete track delete :track)
(@q track launch :track) (@q track launch :track)
(@c track color :track) (@c track color :track)
(@comma track prev) (@comma track prev)
(@period track next) (@period track next)
(@lt track swap-prev) (@lt track swap-prev)
(@gt track swap-next) (@gt track swap-next)
(@delete track delete)
(@r track rec) (@r track rec)
(@m track mon) (@m track mon)
(@p track play) (@p track play)

View file

@ -34,6 +34,9 @@ expose!([self: Tek]
handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.keys.command(self, input) { handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.keys.command(self, input) {
let undo = command.execute(self)?; let undo = command.execute(self)?;
if let Some(undo) = undo {
self.history.push(undo);
}
Some(true) Some(true)
} else { } else {
None None
@ -68,13 +71,15 @@ impose!([app: Tek]
(t, 0) => Self::Select(Selection::Track(t)), (t, 0) => Self::Select(Selection::Track(t)),
(0, s) => Self::Select(Selection::Scene(s)), (0, s) => Self::Select(Selection::Scene(s)),
(t, s) => Self::Select(Selection::Clip(t, s)) }))) (t, s) => Self::Select(Selection::Clip(t, s)) })))
(ClipCommand: (ClipCommand:
("edit" [a: MaybeClip] Some(Self::Edit(a.unwrap()))) ("edit" [a: MaybeClip] Some(Self::Edit(a.unwrap())))
("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemTheme::random()))) ("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemTheme::random())))
("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap()))) ("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap())))
("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap()))) ("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap())))
("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap()))) ("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap())))
("put" [a: usize, b: usize, c: MaybeClip] Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap())))) ("put" [a: usize, b: usize, c: MaybeClip] Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap())))
("delete" [a: usize, b: usize] Some(Self::Put(a.unwrap(), b.unwrap(), None))))
(InputCommand: (InputCommand:
("add" [] Some(Self::Add))) ("add" [] Some(Self::Add)))
@ -84,7 +89,7 @@ impose!([app: Tek]
(SceneCommand: (SceneCommand:
("add" [] Some(Self::Add)) ("add" [] Some(Self::Add))
("del" [a: usize] Some(Self::Del(0))) ("delete" [a: Option<usize>] Some(Self::Del(a.flatten().unwrap())))
("zoom" [a: usize] Some(Self::SetZoom(a.unwrap()))) ("zoom" [a: usize] Some(Self::SetZoom(a.unwrap())))
("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::G[128]))) ("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::G[128])))
("enqueue" [a: usize] Some(Self::Enqueue(a.unwrap()))) ("enqueue" [a: usize] Some(Self::Enqueue(a.unwrap())))
@ -95,7 +100,7 @@ impose!([app: Tek]
("size" [a: usize] Some(Self::SetSize(a.unwrap()))) ("size" [a: usize] Some(Self::SetSize(a.unwrap())))
("zoom" [a: usize] Some(Self::SetZoom(a.unwrap()))) ("zoom" [a: usize] Some(Self::SetZoom(a.unwrap())))
("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::random()))) ("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::random())))
("del" [a: usize] Some(Self::Del(a.unwrap()))) ("delete" [a: Option<usize>] Some(Self::Del(a.flatten().unwrap())))
("stop" [a: usize] Some(Self::Stop(a.unwrap()))) ("stop" [a: usize] Some(Self::Stop(a.unwrap())))
("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap()))) ("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap())))
("play" [] Some(Self::TogglePlay)) ("play" [] Some(Self::TogglePlay))

View file

@ -53,7 +53,7 @@ pub struct Tek {
// Modal overlay // Modal overlay
pub modal: Option<Modal>, pub modal: Option<Modal>,
// Input keymap // Input keymap
pub keys: InputMap<'static, Self, TekCommand, TuiIn, SourceIter<'static>> pub keys: InputMap<'static, Self, TekCommand, TuiIn, TokenIter<'static>>
} }
impl Tek { impl Tek {

View file

@ -41,21 +41,23 @@ impl Tek {
Bsp::s(Tui::bold(true, "tek!"), Bsp::s("", Map::south(1, options, option))) Bsp::s(Tui::bold(true, "tek!"), Bsp::s("", Map::south(1, options, option)))
} }
fn view_modal_help (&self) -> impl Content<TuiOut> { fn view_modal_help (&self) -> impl Content<TuiOut> + use<'_> {
let bindings = ||TokenIter::new(include_str!("../../../config/keys_groovebox.edn")) let bindings = ||self.keys.layers.iter()
.filter_map(|a|(a.0)(self).then_some(a.1))
.flat_map(|a|a)
.filter_map(|x|if let Value::Exp(_, iter)=x.value{ .filter_map(|x|if let Value::Exp(_, iter)=x.value{
Some(iter) Some(iter)
} else { } else {
None None
}); });
let binding = |mut binding: TokenIter, _|Bsp::e( let binding = |mut binding: TokenIter, _|Bsp::e(
Tui::bold(true, Tui::fg(Color::Rgb(255,192,0), if let Some(Token { Fixed::x(15, Align::w(Tui::bold(true, Tui::fg(Color::Rgb(255,192,0), if let Some(Token {
value: Value::Sym(key), .. value: Value::Sym(key), ..
}) = binding.next() { }) = binding.next() {
Some(key.to_string()) Some(key.to_string())
} else { } else {
None None
})), })))),
Bsp::e(" ", Tui::fg(Color::Rgb(255,255,255), if let Some(Token { Bsp::e(" ", Tui::fg(Color::Rgb(255,255,255), if let Some(Token {
value: Value::Key(command), .. value: Value::Key(command), ..
}) = binding.next() { }) = binding.next() {
@ -64,8 +66,7 @@ impl Tek {
None None
})), })),
); );
let layer = Map::south(1, bindings, binding); Bsp::s(Tui::bold(true, "Help"), Bsp::s("", Map::south(1, bindings, binding)))
Bsp::s(Tui::bold(true, "Help"), Bsp::s("", layer))
} }
pub fn view_status (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_status (&self) -> impl Content<TuiOut> + use<'_> {

View file

@ -120,33 +120,36 @@ impl Cli {
}), }),
keys: match mode { keys: match mode {
LaunchMode::Sampler => InputMap::default() LaunchMode::Sampler => InputMap::default()
.layer(SourceIter(include_str!("../../config/keys_global.edn"))) .layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_sampler.edn"))), .layer(SourceIter(include_str!("../../config/keys_sampler.edn")).into()),
LaunchMode::Clock => InputMap::default() LaunchMode::Clock => InputMap::default()
.layer(SourceIter(include_str!("../../config/keys_global.edn"))) .layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_clock.edn"))), .layer(SourceIter(include_str!("../../config/keys_clock.edn")).into()),
LaunchMode::Sequencer => InputMap::default() LaunchMode::Sequencer => InputMap::default()
.layer(SourceIter(include_str!("../../config/keys_global.edn"))) .layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_editor.edn"))) .layer(SourceIter(include_str!("../../config/keys_editor.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_clock.edn"))) .layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_sequencer.edn"))), .layer(SourceIter(include_str!("../../config/keys_sequencer.edn")).into()),
LaunchMode::Groovebox => InputMap::default() LaunchMode::Groovebox => InputMap::default()
.layer(SourceIter(include_str!("../../config/keys_global.edn"))) .layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_editor.edn"))) .layer(SourceIter(include_str!("../../config/keys_editor.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_clock.edn"))) .layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_sequencer.edn"))) .layer(SourceIter(include_str!("../../config/keys_sequencer.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_groovebox.edn"))), .layer(SourceIter(include_str!("../../config/keys_groovebox.edn")).into()),
LaunchMode::Arranger {..} => InputMap::default() LaunchMode::Arranger {..} => InputMap::default()
.layer(SourceIter(include_str!("../../config/keys_global.edn"))) .layer(SourceIter(include_str!("../../config/keys_global.edn")).into())
.layer_if( .layer_if(|state: &Tek|state.is_editing(),
|state: &Tek|state.is_editing(), SourceIter(include_str!("../../config/keys_editor.edn")).into())
SourceIter(include_str!("../../config/keys_editor.edn"))) .layer_if(|state: &Tek|state.selected.is_clip()&&!state.is_editing(),
.layer(SourceIter(include_str!("../../config/keys_clock.edn"))) SourceIter(include_str!("../../config/keys_clip.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_arranger.edn"))) .layer_if(|state: &Tek|state.selected.is_track()&&!state.is_editing(),
.layer(SourceIter(include_str!("../../config/keys_clip.edn"))) SourceIter(include_str!("../../config/keys_track.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_track.edn"))) .layer_if(|state: &Tek|state.selected.is_scene()&&!state.is_editing(),
.layer(SourceIter(include_str!("../../config/keys_scene.edn"))) SourceIter(include_str!("../../config/keys_scene.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_mix.edn"))), .layer_if(|state: &Tek|state.selected.is_mix()&&!state.is_editing(),
SourceIter(include_str!("../../config/keys_mix.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_clock.edn")).into())
.layer(SourceIter(include_str!("../../config/keys_arranger.edn")).into()),
_ => todo!("{mode:?}"), _ => todo!("{mode:?}"),
}, },
pool: match mode { pool: match mode {

2
deps/tengri vendored

@ -1 +1 @@
Subproject commit 4ec51d5b694c14ccf617ec4538da04089b17ab92 Subproject commit 44ebe17c665b3a65e7a3a0020eff290093fc7ed2