From fc304ac3490b369d5c5e110d6ac9cfcd4d186f81 Mon Sep 17 00:00:00 2001 From: Xiaohan-Tian <157918347+Xiaohan-Tian@users.noreply.github.com> Date: Mon, 4 May 2026 16:53:48 -0700 Subject: [PATCH] feat: added a shortcut `E` to open/close piano roll --- src/hooks/useGlobalKeyboardHandler.ts | 58 ++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/hooks/useGlobalKeyboardHandler.ts b/src/hooks/useGlobalKeyboardHandler.ts index 101274d..63d6e7a 100644 --- a/src/hooks/useGlobalKeyboardHandler.ts +++ b/src/hooks/useGlobalKeyboardHandler.ts @@ -8,13 +8,14 @@ import { selectAllNotesInActiveRegion } from '../util/selectionUtil'; import { KGCore } from '../core/KGCore'; import { KGMidiInput } from '../core/midi-input/KGMidiInput'; import { KGMidiRegion } from '../core/region/KGMidiRegion'; +import { showAlert } from '../util/dialogUtil'; /** * Global keyboard handler for copy/paste, undo/redo, play/pause, and save operations * Handles keyboard shortcuts defined in the configuration */ export const useGlobalKeyboardHandler = () => { - const { undo, redo, setStatus, isPlaying, startPlaying, stopTransport, toggleLoop, projectName, savedProjectName, setSavedProjectName, setProjectName, isRecording, startRecording, stopRecording, activeRegionId, selectedRegionIds, setActiveRegionId, setShowPianoRoll } = useProjectStore(); + const { undo, redo, setStatus, isPlaying, startPlaying, stopTransport, toggleLoop, projectName, savedProjectName, setSavedProjectName, setProjectName, isRecording, startRecording, stopRecording, activeRegionId, selectedRegionIds, setActiveRegionId, setShowPianoRoll, showPianoRoll, openMidiPianoRoll, openSpectrogramViewer } = useProjectStore(); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { @@ -193,6 +194,37 @@ export const useGlobalKeyboardHandler = () => { return; } + // Check for edit/view shortcut (E) — open piano roll for MIDI, spectrogram for audio + if (event.key.toLowerCase() === 'e' && !event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) { + event.preventDefault(); + if (showPianoRoll) { + setShowPianoRoll(false); + return; + } + const candidateId = activeRegionId ?? (selectedRegionIds[0] ?? null); + if (!candidateId) { + void showAlert('Please select a region to open the editor.'); + return; + } + const tracks = KGCore.instance().getCurrentProject().getTracks(); + let foundMidi = false; + let foundAudio = false; + for (const track of tracks) { + const region = track.getRegions().find(r => r.getId() === candidateId); + if (region) { + if (region instanceof KGMidiRegion) foundMidi = true; + else foundAudio = true; + break; + } + } + if (foundMidi) { + openMidiPianoRoll(candidateId); + } else if (foundAudio) { + openSpectrogramViewer(candidateId); + } + return; + } + // Check for save shortcut if (saveShortcut && matchesKeyboardShortcut(event, saveShortcut)) { event.preventDefault(); @@ -216,5 +248,27 @@ export const useGlobalKeyboardHandler = () => { return () => { document.removeEventListener('keydown', handleKeyDown, { capture: true }); }; - }, [undo, redo, setStatus, isPlaying, startPlaying, stopTransport, toggleLoop, projectName, savedProjectName, setSavedProjectName, setProjectName, isRecording, startRecording, stopRecording, activeRegionId, selectedRegionIds, setActiveRegionId, setShowPianoRoll]); // Include dependencies for store actions + }, [ + undo, + redo, + setStatus, + isPlaying, + startPlaying, + stopTransport, + toggleLoop, + projectName, + savedProjectName, + setSavedProjectName, + setProjectName, + isRecording, + startRecording, + stopRecording, + activeRegionId, + selectedRegionIds, + setActiveRegionId, + setShowPianoRoll, + showPianoRoll, + openMidiPianoRoll, + openSpectrogramViewer, + ]); // Include dependencies for store actions };