diff --git a/input/index.ts b/input/index.ts index 9ed38f3..c2455b2 100644 --- a/input/index.ts +++ b/input/index.ts @@ -6,6 +6,7 @@ export { export type { CommandKeybind, GlobalKeybindConsumer, Keybind, KeybindEvent, KeybindMap } from "./keyboard"; export { handleKeybind, keybindFromEvent } from "./keyboard"; export { handleHistoryKey } from "./history"; +export { handleToolKey } from "./tool-keybinds"; export { findGroup, findLayerInfoInDocument, handleDeleteSelectionKey, resolveLayerDrop } from "./layers-panel"; export type { LayerDropTarget, LayerInfo } from "./layers-panel"; export { handleArtboardSelection } from "./selection"; diff --git a/input/tool-keybinds.ts b/input/tool-keybinds.ts new file mode 100644 index 0000000..50d2b06 --- /dev/null +++ b/input/tool-keybinds.ts @@ -0,0 +1,20 @@ +import { commandIds } from "@commands/ids"; +import type { Dispatch } from "@commands/dispatcher"; +import type { KeybindEvent } from "./keyboard"; + +const toolKeybinds = { + b: "brush", + e: "eraser", + p: "pan", + s: "select", +} as const; + +export function handleToolKey(options: { event: KeybindEvent; dispatch: Dispatch }): boolean { + if (options.event.altKey || options.event.ctrlKey || options.event.metaKey) return false; + + const tool = toolKeybinds[options.event.key.toLowerCase() as keyof typeof toolKeybinds]; + if (!tool) return false; + + options.dispatch(commandIds.toolSetActive, { tool }); + return true; +} diff --git a/view/App.tsx b/view/App.tsx index aed9b8a..7a90468 100644 --- a/view/App.tsx +++ b/view/App.tsx @@ -6,9 +6,10 @@ import { BottomControlsIsland } from "./BottomControlsIsland"; import { brushUnavailableHint } from "./canvas/brush"; import { CanvasViewport } from "./CanvasViewport"; import { LayersSheet } from "./LayersSheet"; +import { ShortcutsDisplay } from "./ShortcutsDisplay"; import { ToolOverlay } from "./ToolOverlay"; import { resolveTransformTargetBounds, selectedTransformTarget } from "@editor/transform-targets"; -import { handleDeleteSelectionKey, handleHistoryKey, keybindEventFromKeyboardEvent } from "@input/index"; +import { handleDeleteSelectionKey, handleHistoryKey, handleToolKey, keybindEventFromKeyboardEvent } from "@input/index"; import { useAppState } from "./useAppState"; import { downloadArtboardPng } from "./exportArtboardPng"; import { useImageImport } from "./useImageImport"; @@ -50,14 +51,23 @@ export function App({ app }: AppProps) { return; } - if (event.key.toLowerCase() === "l") { + const keybindEvent = keybindEventFromKeyboardEvent(event); + const toolConsumed = handleToolKey({ event: keybindEvent, dispatch: app.store.dispatch }); + if (toolConsumed) { + event.preventDefault(); + return; + } + + const key = event.key.toLowerCase(); + + if (key === "l") { setLayersOpen((open) => !open); event.preventDefault(); return; } const consumed = handleDeleteSelectionKey({ - event: keybindEventFromKeyboardEvent(event), + event: keybindEvent, selection: app.store.getState().editor.selection, dispatch: app.store.dispatch, }); @@ -115,6 +125,9 @@ export function App({ app }: AppProps) { dispatch={app.store.dispatch} /> +