65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
import { RemoveAnimationKeysCommand, RemoveAnimationTracksCommand } from '../core/commands/animationCommands';
|
||
import { RemoveFrameCommand } from '../core/commands/frameCommands';
|
||
import { ui } from '../ui';
|
||
import { confirmDeleteAsset, createContainer, removeGraphSelection, removeObjects } from './actions';
|
||
import type { EditorState } from './state';
|
||
|
||
export interface ShortcutActions {
|
||
play(): void;
|
||
stop(): void;
|
||
togglePause(): void;
|
||
}
|
||
|
||
/**
|
||
* Global keyboard shortcuts (see the wiki page "Keyboard"). Text fields keep their own key handling;
|
||
* these only run when no focused widget consumed the key.
|
||
*/
|
||
export function installShortcuts(state: EditorState, actions: ShortcutActions): void {
|
||
ui().focus.globalHandlers.push((event) => {
|
||
const mod = event.ctrlKey || event.metaKey;
|
||
const key = event.key.toLowerCase();
|
||
if (event.key === 'Escape' && state.mode === 'play') {
|
||
actions.stop();
|
||
return true;
|
||
}
|
||
if (mod && key === 'z') {
|
||
if (event.shiftKey) state.redo();
|
||
else state.undo();
|
||
return true;
|
||
}
|
||
if (mod && key === 'y') {
|
||
state.redo();
|
||
return true;
|
||
}
|
||
if (mod && key === 'g') {
|
||
const s = state.selection;
|
||
if (s?.kind === 'object') createContainer(state, s.holderId, s.objectIds);
|
||
return true;
|
||
}
|
||
if (event.key === 'Delete' || event.key === 'Backspace') {
|
||
const s = state.selection;
|
||
if (s?.kind === 'object') removeObjects(state, s.holderId, s.objectIds);
|
||
else if (s?.kind === 'node') removeGraphSelection(state, s.assetId, s.nodeIds, s.annotationIds);
|
||
else if (s?.kind === 'frame') state.execute(new RemoveFrameCommand(s.assetId, s.frameId));
|
||
else if (s?.kind === 'annotation') removeGraphSelection(state, s.assetId, [], s.annotationIds);
|
||
// The keys when some are picked, else the row itself – like a frame of a texture.
|
||
else if (s?.kind === 'track')
|
||
state.execute(
|
||
s.keys.length > 0
|
||
? new RemoveAnimationKeysCommand(s.assetId, s.keys)
|
||
: new RemoveAnimationTracksCommand(s.assetId, [s.trackId]),
|
||
);
|
||
else if (s?.kind === 'asset') confirmDeleteAsset(state, s.assetId);
|
||
return s !== null;
|
||
}
|
||
// Ctrl+Enter starts play and then holds/resumes it. A plain letter would be taken away from
|
||
// the game, which owns the keyboard while playing.
|
||
if (mod && event.key === 'Enter') {
|
||
if (state.mode === 'edit') actions.play();
|
||
else actions.togglePause();
|
||
return true;
|
||
}
|
||
return false;
|
||
});
|
||
}
|