diff --git a/theatre/studio/src/Studio.ts b/theatre/studio/src/Studio.ts index bb21e3f..082e097 100644 --- a/theatre/studio/src/Studio.ts +++ b/theatre/studio/src/Studio.ts @@ -164,4 +164,12 @@ export class Studio { this.getStudioProject(core)!.sheet('Extension ' + extensionId), ) } + + undo() { + this._store.undo() + } + + redo() { + this._store.redo() + } } diff --git a/theatre/studio/src/StudioStore/StudioStore.ts b/theatre/studio/src/StudioStore/StudioStore.ts index 33bced4..8bdea33 100644 --- a/theatre/studio/src/StudioStore/StudioStore.ts +++ b/theatre/studio/src/StudioStore/StudioStore.ts @@ -257,4 +257,12 @@ export default class StudioStore { }, } } + + undo() { + this._reduxStore.dispatch(studioActions.historic.undo()) + } + + redo() { + this._reduxStore.dispatch(studioActions.historic.redo()) + } } diff --git a/theatre/studio/src/UIRoot/UIRoot.tsx b/theatre/studio/src/UIRoot/UIRoot.tsx index b16a7b5..ab254b6 100644 --- a/theatre/studio/src/UIRoot/UIRoot.tsx +++ b/theatre/studio/src/UIRoot/UIRoot.tsx @@ -10,6 +10,7 @@ import GlobalToolbar from '@theatre/studio/toolbars/GlobalToolbar/GlobalToolbar' import useRefAndState from '@theatre/studio/utils/useRefAndState' import {PortalContext} from 'reakit' import type {$IntentionalAny} from '@theatre/shared/utils/types' +import useKeyboardShortcuts from './useKeyboardShortcuts' const GlobalStyle = createGlobalStyle` :host { @@ -55,6 +56,7 @@ export default function UIRoot() { const [portalLayerRef, portalLayer] = useRefAndState( undefined as $IntentionalAny, ) + useKeyboardShortcuts() const inside = usePrism(() => { const visiblityState = val(studio.atomP.ahistoric.visibilityState) const initialised = val(studio.atomP.ephemeral.initialised) diff --git a/theatre/studio/src/UIRoot/useKeyboardShortcuts.ts b/theatre/studio/src/UIRoot/useKeyboardShortcuts.ts new file mode 100644 index 0000000..c80bd05 --- /dev/null +++ b/theatre/studio/src/UIRoot/useKeyboardShortcuts.ts @@ -0,0 +1,33 @@ +import {useEffect} from 'react' +import getStudio from '@theatre/studio/getStudio' +import {cmdIsDown} from '@theatre/studio/utils/keyboardUtils' + +export default function useKeyboardShortcuts() { + const studio = getStudio() + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.target && (e.target as HTMLElement).tagName === 'INPUT') { + return + } + + if (e.key === 'z' || e.key === 'Z' || e.code === 'KeyZ') { + if (cmdIsDown(e)) { + if (e.shiftKey === true) { + studio.redo() + } else { + studio.undo() + } + } + } else { + return + } + + e.preventDefault() + e.stopPropagation() + } + window.addEventListener('keydown', handleKeyDown) + return () => { + window.removeEventListener('keydown', handleKeyDown) + } + }, []) +}