mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
184 lines
6.6 KiB
Rust
184 lines
6.6 KiB
Rust
//! Handling of input events.
|
|
|
|
use crate::*;
|
|
|
|
handle!{
|
|
App |self, e| {
|
|
if handle_modal(e)? {
|
|
return Ok(true)
|
|
}
|
|
Ok(if self.entered {
|
|
handle_focused(self, e)?
|
|
|| handle_keymap(self, e, KEYMAP_GLOBAL)?
|
|
|| handle_keymap(self, e, crate::control::KEYMAP_FOCUS)?
|
|
} else {
|
|
handle_keymap(self, e, KEYMAP_GLOBAL)?
|
|
|| handle_keymap(self, e, crate::control::KEYMAP_FOCUS)?
|
|
|| handle_focused(self, e)?
|
|
})
|
|
}
|
|
}
|
|
|
|
fn handle_modal (e: &AppEvent) -> Usually<bool> {
|
|
let mut handled = false;
|
|
let mut close = false;
|
|
if let Some(ref mut modal) = *MODAL.lock().unwrap() {
|
|
if modal.handle(e)? {
|
|
handled = true;
|
|
if modal.exited() {
|
|
close = true;
|
|
}
|
|
};
|
|
}
|
|
if close {
|
|
*MODAL.lock().unwrap() = None;
|
|
}
|
|
Ok(handled)
|
|
}
|
|
|
|
fn handle_focused (state: &mut App, e: &AppEvent) -> Usually<bool> {
|
|
unimplemented!()
|
|
//match state.section {
|
|
//AppFocus::Transport => state.transport.handle(e),
|
|
//AppFocus::Arranger => state.arranger.sequencer_mut().map(|s|s.handle(e)),
|
|
//AppFocus::Sequencer => state.arranger.sequencer_mut().map(|s|s.handle(e)),
|
|
//AppFocus::Chain => Ok(false)[>if state.entered {
|
|
//handle_device(state, e)? ||
|
|
//handle_keymap(state, e, crate::control::KEYMAP_CHAIN)?
|
|
//} else {
|
|
//handle_keymap(state, e, crate::control::KEYMAP_CHAIN)? || handle_device(state, e)?
|
|
//})*/
|
|
//}
|
|
}
|
|
|
|
fn handle_device (state: &mut App, e: &AppEvent) -> Usually<bool> {
|
|
state.mixer.track()
|
|
.and_then(|track|track.device_mut())
|
|
.map(|mut device|device.handle(e))
|
|
.transpose()
|
|
.map(|x|x.unwrap_or(false))
|
|
}
|
|
|
|
/// Global key bindings.
|
|
pub const KEYMAP_GLOBAL: &'static [KeyBinding<App>] = keymap!(App {
|
|
[Char(' '), NONE, "play_toggle", "play or pause", |app: &mut App| {
|
|
app.transport.toggle_play()?;
|
|
Ok(true)
|
|
}],
|
|
[Char('r'), NONE, "record_toggle", "toggle recording", |app: &mut App| {
|
|
app.arranger.track_mut().map(|t|t.toggle_record());
|
|
Ok(true)
|
|
}],
|
|
[Char('o'), NONE, "overdub_toggle", "toggle overdub", |app: &mut App| {
|
|
app.arranger.track_mut().map(|t|t.toggle_overdub());
|
|
Ok(true)
|
|
}],
|
|
[Char('m'), NONE, "monitor_toggle", "toggle monitor", |app: &mut App| {
|
|
app.arranger.track_mut().map(|t|t.toggle_monitor());
|
|
Ok(true)
|
|
}],
|
|
[Char('+'), NONE, "quant_inc", "quantize coarser", |app: &mut App| {
|
|
app.transport.quant = Note::next(app.transport.quant);
|
|
Ok(true)
|
|
}],
|
|
[Char('_'), NONE, "quant_dec", "quantize finer", |app: &mut App| {
|
|
app.transport.quant = Note::prev(app.transport.quant);
|
|
Ok(true)
|
|
}],
|
|
[Char('='), NONE, "zoom_in", "show fewer ticks per block", |app: &mut App| {
|
|
app.arranger.sequencer_mut().map(|s|s.time_axis.scale_mut(&Note::prev));
|
|
Ok(true)
|
|
}],
|
|
[Char('-'), NONE, "zoom_out", "show more ticks per block", |app: &mut App| {
|
|
app.arranger.sequencer_mut().map(|s|s.time_axis.scale_mut(&Note::next));
|
|
Ok(true)
|
|
}],
|
|
[Char('x'), NONE, "extend", "double the current clip", |app: &mut App| {
|
|
app.arranger.phrase().map(|x|x.write().unwrap()).map(|mut phrase|{
|
|
let mut notes = phrase.notes.clone();
|
|
notes.extend_from_slice(&mut phrase.notes);
|
|
phrase.notes = notes;
|
|
phrase.length = phrase.length * 2;
|
|
});
|
|
//app.arranger.show_phrase()?;
|
|
Ok(true)
|
|
}],
|
|
[Char('l'), NONE, "loop_toggle", "toggle looping", |_app: &mut App| {
|
|
// TODO: This toggles the loop flag for the clip under the cursor.
|
|
Ok(true)
|
|
}],
|
|
[Char('['), NONE, "loop_start_dec", "move loop start back", |_app: &mut App| {
|
|
// TODO: This moves the loop start to the previous quant.
|
|
Ok(true)
|
|
}],
|
|
[Char(']'), NONE, "loop_start_inc", "move loop start forward", |_app: &mut App| {
|
|
// TODO: This moves the loop start to the next quant.
|
|
Ok(true)
|
|
}],
|
|
[Char('{'), NONE, "loop_end_dec", "move loop end back", |_app: &mut App| {
|
|
// TODO: This moves the loop end to the previous quant.
|
|
Ok(true)
|
|
}],
|
|
[Char('}'), NONE, "loop_end_inc", "move loop end forward", |_app: &mut App| {
|
|
// TODO: This moves the loop end to the next quant.
|
|
Ok(true)
|
|
}],
|
|
[Char('a'), CONTROL, "scene_add", "add a new scene", |app: &mut App| {
|
|
app.arranger.scene_add(None)?;
|
|
Ok(true)
|
|
}],
|
|
[Char('t'), CONTROL, "track_add", "add a new track", |app: &mut App| {
|
|
app.arranger.track_add(None)?;
|
|
Ok(true)
|
|
}],
|
|
});
|
|
|
|
/// Generic key bindings for views that support focus.
|
|
pub const KEYMAP_FOCUS: &'static [KeyBinding<App>] = keymap!(App {
|
|
[Char(';'), NONE, "command", "open command palette", |_: &mut App| {
|
|
*MODAL.lock().unwrap() = Some(Box::new(HelpModal::new()));
|
|
Ok(true)
|
|
}],
|
|
[Tab, NONE, "focus_next", "focus next area", focus_next],
|
|
[Tab, SHIFT, "focus_prev", "focus previous area", focus_prev],
|
|
[Esc, NONE, "focus_exit", "unfocus", |app: &mut App|{
|
|
app.entered = false;
|
|
app.transport.entered = app.entered;
|
|
//app.arranger.entered = app.entered;
|
|
app.arranger.sequencer_mut().map(|s|s.entered = app.entered);
|
|
Ok(true)
|
|
}],
|
|
[Enter, NONE, "focus_enter", "activate item at cursor", |app: &mut App|{
|
|
app.entered = true;
|
|
app.transport.entered = app.entered;
|
|
//app.arranger.entered = app.entered;
|
|
app.arranger.sequencer_mut().map(|s|s.entered = app.entered);
|
|
Ok(true)
|
|
}],
|
|
});
|
|
|
|
pub fn focus_next (app: &mut App) -> Usually<bool> {
|
|
app.section.next();
|
|
app.transport.focused = app.section == AppFocus::Transport;
|
|
app.transport.entered = app.entered;
|
|
//app.arranger.focused = app.section == AppFocus::Arranger;
|
|
//app.arranger.entered = app.entered;
|
|
app.arranger.sequencer_mut().map(|s|{
|
|
s.focused = app.section == AppFocus::Sequencer;
|
|
s.entered = app.entered;
|
|
});
|
|
Ok(true)
|
|
}
|
|
|
|
pub fn focus_prev (app: &mut App) -> Usually<bool> {
|
|
app.section.prev();
|
|
app.transport.focused = app.section == AppFocus::Transport;
|
|
app.transport.entered = app.entered;
|
|
//app.arranger.focused = app.section == AppFocus::Arranger;
|
|
//app.arranger.entered = app.entered;
|
|
app.arranger.sequencer_mut().map(|s|{
|
|
s.focused = app.section == AppFocus::Sequencer;
|
|
s.entered = app.entered;
|
|
});
|
|
Ok(true)
|
|
}
|