import hotkeys, { HotkeysEvent } from 'hotkeys-js'; import { isMac } from '@/functions/platform'; import { MaybePromise } from 'rollup'; export enum HotkeyScope { MCAD_MENU = 'mcad_menu', PRIMARY = 'primary', MEASUREMENT_MENU = 'measurement_menu', ANNOTATION_MENU = 'annotation_menu', ANNOTATION_TOOLS = 'annotation_tools', MEASUREMENT_TOOLS = 'measurement_tools', // NAVIGATION_DRAWER = 'navigation_drawer' } // Always Windows keys. Mac keys will be generated at runtime. export enum Hotkeys { CTRL_SHIFT_A = 'ctrl+shift+a', CTRL_SHIFT_C = 'ctrl+shift+c', CTRL_SHIFT_D = 'ctrl+shift+d', CTRL_SHIFT_DEL = 'ctrl+shift+del', CTRL_SHIFT_E = 'ctrl+shift+e', CTRL_SHIFT_F = 'ctrl+shift+f', CTRL_SHIFT_G = 'ctrl+shift+g', CTRL_SHIFT_H = 'ctrl+shift+h', CTRL_SHIFT_L = 'ctrl+shift+l', CTRL_SHIFT_M = 'ctrl+shift+m', CTRL_SHIFT_P = 'ctrl+shift+p', CTRL_SHIFT_Q = 'ctrl+shift+q', CTRL_SHIFT_R = 'ctrl+shift+r', CTRL_SHIFT_S = 'ctrl+shift+s', CTRL_SHIFT_V = 'ctrl+shift+v', CTRL_SHIFT_PLUS = 'ctrl+shift++', CTRL_SHIFT_MINUS = 'ctrl+shift+-', CTRL_SHIFT_SPACE = 'ctrl+shift+space', ALT_A = 'alt+a', ALT_H = 'alt+h', ALT_D = 'alt+d', ALT_M = 'alt+m', ALT_E = 'alt+e', ALT_F = 'alt+f', } function generateHotkey(...params: Array) { return params.map(String).join(','); } type HotkeyDefinition = { [key in Hotkeys]?: (event: any, handler: any) => MaybePromise; }; // Vitest not liking us testing defaultfunctions with object modifiers /* v8 ignore start -- @preserve */ export function defineHotkeys( scope: HotkeyScope, definition: HotkeyDefinition, ) { const keys = transformHotkeysMac(Object.values(Object.keys(definition))); hotkeys( generateHotkey(keys), scope, (event: KeyboardEvent, handler: HotkeysEvent) => hotKeyHandler(definition, event, handler), ); hotkeys.setScope(scope); } /* v8 ignore stop -- @preserve */ export function defaultHotkeys(definition: HotkeyDefinition) { const keys = transformHotkeysMac(Object.values(Object.keys(definition))); hotkeys(generateHotkey(keys), (event: KeyboardEvent, handler: HotkeysEvent) => hotKeyHandler(definition, event, handler), ); } function hotKeyHandler( definition: HotkeyDefinition, event: KeyboardEvent, handler: HotkeysEvent, ) { event.preventDefault(); const key = handler.key as Hotkeys; const method = definition[ key.replace('command', 'ctrl').replace('option', 'alt') as Hotkeys ]; if (method) { method(event, handler); } } export function resetScope(scope: HotkeyScope) { hotkeys.deleteScope(scope); hotkeys.setScope(HotkeyScope.PRIMARY); } /* v8 ignore start -- @preserve */ function transformHotkeysMac(keys: string[]): string[] { if (isMac()) return keys.map((key) => key.replace('ctrl', 'command').replace('alt', 'option'), ); return keys; } /* v8 ignore stop -- @preserve */