Merge pull request #320 from grovebit/range-shortcuts

Make the Zoom Preset, Waveform Zoom and Clip Rating keys work; add Commands Focus 1–5 and N
This commit is contained in:
Brandon Thomas authored and GitHub committed 2026-10-13 04:43:26 -04:00
commit 50b0f68363
2 files changed
+86

No files matched your search

+23
View File
@@ -188,6 +188,20 @@ fn fixed(app: &mut SoundApp, key: Key, m: Modifiers, mac: bool) -> bool {
}
true
}
// The registry's key families "Cmd+Alt+[ / ]", "Cmd+Alt+0-5" and "Cmd+Ctrl+1-5", which `parse` can't read.
Key::OpenBracket | Key::CloseBracket if mods_match(Modifiers::COMMAND | Modifiers::ALT, m, mac) => {
let factor = if key == Key::CloseBracket { 2.0 } else { 0.5 };
let _ = app.run("view.waveform_zoom", json!({"factor": factor}));
true
}
Key::Num0 | Key::Num1 | Key::Num2 | Key::Num3 | Key::Num4 | Key::Num5 if mods_match(Modifiers::COMMAND | Modifiers::ALT, m, mac) => {
let _ = app.run("clip.rating", json!({"rating": digit(key)}));
true
}
Key::Num1 | Key::Num2 | Key::Num3 | Key::Num4 | Key::Num5 if mods_match(Modifiers::COMMAND | Modifiers::CTRL, m, mac) => {
let _ = app.run("view.zoom_preset", json!({"preset": digit(key)}));
true
}
Key::ArrowUp | Key::ArrowDown if m.ctrl && !m.shift => {
let id = if key == Key::ArrowUp { "edit.extend_selection_up" } else { "edit.extend_selection_down" };
let _ = app.run(id, json!({}));
@@ -245,6 +259,11 @@ fn commands_focus(app: &mut SoundApp, key: Key, shift: bool) -> bool {
Key::C => "edit.copy",
Key::V => "edit.paste",
Key::Z => "edit.undo",
Key::N => "options.insertion_follows_playback",
Key::Num1 | Key::Num2 | Key::Num3 | Key::Num4 | Key::Num5 => {
let _ = app.run("view.zoom_preset", json!({"preset": digit(key)}));
return true;
}
Key::P => {
move_selection_track(app, -1);
return true;
@@ -289,6 +308,10 @@ fn tab_clip(app: &mut SoundApp, back: bool) {
}
}
fn digit(key: Key) -> u8 {
key.name().parse().unwrap_or(0)
}
/// Shortcut text for display. The registry stores macOS-style strings ("Cmd+N"); off macOS the Cmd
/// modifier is the Ctrl key. Mac-only Control chords ("Cmd+Ctrl+S") have no key there, so they show nothing.
pub fn shortcut_label(s: &str, mac: bool) -> String {
+63
View File
@@ -0,0 +1,63 @@
//! Shortcuts written as key families ("Cmd+Ctrl+1-5", "Cmd+Alt+0-5", "Cmd+Alt+[ / ]") fire, and Commands Focus
//! has Pro Tools' 1–5 zoom presets and N for Insertion Follows Playback.
use egui::os::OperatingSystem;
use egui::{Key, Modifiers};
use serde_json::json;
use soundcraft_ui_egui::{Services, SoundApp, shortcuts};
const MAC_CMD: Modifiers = Modifiers { mac_cmd: true, command: true, ..Modifiers::NONE };
const PC_CTRL: Modifiers = Modifiers { ctrl: true, command: true, ..Modifiers::NONE };
const OSES: [(OperatingSystem, Modifiers); 3] =
[(OperatingSystem::Mac, MAC_CMD), (OperatingSystem::Windows, PC_CTRL), (OperatingSystem::Nix, PC_CTRL)];
fn press(ctx: &egui::Context, app: &mut SoundApp, key: Key, modifiers: Modifiers) {
let events = [true, false].map(|pressed| egui::Event::Key { key, physical_key: None, pressed, repeat: false, modifiers }).to_vec();
ctx.run_ui(egui::RawInput { events, ..Default::default() }, |ui| shortcuts::handle(app, ui.ctx())).textures_delta.clear();
}
fn rig(os: OperatingSystem) -> (egui::Context, SoundApp) {
let ctx = egui::Context::default();
ctx.set_os(os);
(ctx, SoundApp::new(soundcraft_engine::demo::demo_engine(), None, Services::default()))
}
#[test]
fn cmd_alt_brackets_zoom_waveforms_and_cmd_alt_digits_rate_clips() {
for (os, cmd) in OSES {
let (ctx, mut app) = rig(os);
let cmd_alt = Modifiers { alt: true, ..cmd };
press(&ctx, &mut app, Key::CloseBracket, cmd_alt);
press(&ctx, &mut app, Key::CloseBracket, cmd_alt);
press(&ctx, &mut app, Key::OpenBracket, cmd_alt);
assert_eq!(app.engine.session().edit.zoom.waveform_zoom, 2.0, "{os:?}");
let kick = app.engine.session().track_by_name("Kick").unwrap().clips()[0].id;
app.engine.execute("edit.select", &json!({"clips": [kick.0]})).unwrap();
press(&ctx, &mut app, Key::Num4, cmd_alt);
assert_eq!(app.engine.session().find_clip(kick).unwrap().1.rating, 4, "{os:?}");
press(&ctx, &mut app, Key::Num9, cmd_alt);
assert_eq!(app.engine.session().find_clip(kick).unwrap().1.rating, 4, "{os:?}: 9 is outside 0-5");
}
}
#[test]
fn cmd_ctrl_digits_recall_zoom_presets_on_macos() {
let (ctx, mut app) = rig(OperatingSystem::Mac);
press(&ctx, &mut app, Key::Num2, Modifiers { ctrl: true, ..MAC_CMD });
assert_eq!(app.engine.session().edit.zoom.samples_per_px, 256.0);
press(&ctx, &mut app, Key::Num6, Modifiers { ctrl: true, ..MAC_CMD });
assert_eq!(app.engine.session().edit.zoom.samples_per_px, 256.0, "6 is outside 1-5");
}
#[test]
fn commands_focus_digits_recall_zoom_presets_and_n_toggles_insertion_follows_playback() {
for (os, _) in OSES {
let (ctx, mut app) = rig(os);
app.engine.execute("options.keyboard_focus", &json!({"focus": "commands"})).unwrap();
let follows = app.engine.session().edit.insertion_follows_playback;
press(&ctx, &mut app, Key::Num5, Modifiers::NONE);
press(&ctx, &mut app, Key::N, Modifiers::NONE);
let edit = &app.engine.session().edit;
assert_eq!((edit.zoom.samples_per_px, edit.insertion_follows_playback), (16384.0, !follows), "{os:?}");
}
}