Refactor shortcuts into a central file and fix issue with caps lock
This commit is contained in:
parent
c77db06bce
commit
ad68aa7226
@ -42,6 +42,8 @@ import SubtractShapeAction from "../../actions/SubtractShapeAction";
|
||||
|
||||
import useSetting from "../../hooks/useSetting";
|
||||
|
||||
import shortcuts from "../../shortcuts";
|
||||
|
||||
function MapFog({
|
||||
map,
|
||||
shapes,
|
||||
@ -402,16 +404,20 @@ function MapFog({
|
||||
}, [toolSettings, drawingShape, onShapesCut, onShapesAdd, shapes]);
|
||||
|
||||
// Add keyboard shortcuts
|
||||
function handleKeyDown({ key }) {
|
||||
if (key === "Enter" && toolSettings.type === "polygon" && drawingShape) {
|
||||
function handleKeyDown(event) {
|
||||
if (
|
||||
shortcuts.fogFinishPolygon(event) &&
|
||||
toolSettings.type === "polygon" &&
|
||||
drawingShape
|
||||
) {
|
||||
finishDrawingPolygon();
|
||||
}
|
||||
if (key === "Escape" && drawingShape) {
|
||||
if (shortcuts.fogCancelPolygon(event) && drawingShape) {
|
||||
setDrawingShape(null);
|
||||
}
|
||||
// Remove last point from polygon shape if delete pressed
|
||||
if (
|
||||
(key === "Backspace" || key === "Delete") &&
|
||||
shortcuts.delete(event) &&
|
||||
drawingShape &&
|
||||
toolSettings.type === "polygon"
|
||||
) {
|
||||
|
@ -11,6 +11,8 @@ import { useKeyboard } from "../../contexts/KeyboardContext";
|
||||
|
||||
import Vector2 from "../../helpers/Vector2";
|
||||
|
||||
import shortcuts from "../../shortcuts";
|
||||
|
||||
function MapGridEditor({ map, onGridChange }) {
|
||||
const stageScale = useDebouncedStageScale();
|
||||
const mapWidth = useMapWidth();
|
||||
@ -166,20 +168,19 @@ function MapGridEditor({ map, onGridChange }) {
|
||||
}
|
||||
|
||||
function handleKeyDown(event) {
|
||||
const { key, shiftKey } = event;
|
||||
const nudgeAmount = shiftKey ? 2 : 0.5;
|
||||
if (key === "ArrowUp") {
|
||||
const nudgeAmount = event.shiftKey ? 2 : 0.5;
|
||||
if (shortcuts.gridNudgeUp(event)) {
|
||||
// Stop arrow up/down scrolling if overflowing
|
||||
event.preventDefault();
|
||||
nudgeGrid({ x: 0, y: -1 }, nudgeAmount);
|
||||
}
|
||||
if (key === "ArrowLeft") {
|
||||
if (shortcuts.gridNudgeLeft(event)) {
|
||||
nudgeGrid({ x: -1, y: 0 }, nudgeAmount);
|
||||
}
|
||||
if (key === "ArrowRight") {
|
||||
if (shortcuts.gridNudgeRight(event)) {
|
||||
nudgeGrid({ x: 1, y: 0 }, nudgeAmount);
|
||||
}
|
||||
if (key === "ArrowDown") {
|
||||
if (shortcuts.gridNudgeDown(event)) {
|
||||
event.preventDefault();
|
||||
nudgeGrid({ x: 0, y: 1 }, nudgeAmount);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ import { useMapStage } from "../../contexts/MapStageContext";
|
||||
import { GridProvider } from "../../contexts/GridContext";
|
||||
import { useKeyboard } from "../../contexts/KeyboardContext";
|
||||
|
||||
import shortcuts from "../../shortcuts";
|
||||
|
||||
function MapInteraction({
|
||||
map,
|
||||
mapState,
|
||||
@ -111,12 +113,12 @@ function MapInteraction({
|
||||
|
||||
function handleKeyDown(event) {
|
||||
// Change to move tool when pressing space
|
||||
if (event.key === " " && selectedToolId === "move") {
|
||||
if (shortcuts.move(event) && selectedToolId === "move") {
|
||||
// Stop active state on move icon from being selected
|
||||
event.preventDefault();
|
||||
}
|
||||
if (
|
||||
event.key === " " &&
|
||||
shortcuts.move(event) &&
|
||||
selectedToolId !== "move" &&
|
||||
!disabledControls.includes("move")
|
||||
) {
|
||||
@ -126,28 +128,28 @@ function MapInteraction({
|
||||
}
|
||||
|
||||
// Basic keyboard shortcuts
|
||||
if (event.key === "w" && !disabledControls.includes("move")) {
|
||||
if (shortcuts.moveTool(event) && !disabledControls.includes("move")) {
|
||||
onSelectedToolChange("move");
|
||||
}
|
||||
if (event.key === "d" && !disabledControls.includes("drawing")) {
|
||||
if (shortcuts.drawingTool(event) && !disabledControls.includes("drawing")) {
|
||||
onSelectedToolChange("drawing");
|
||||
}
|
||||
if (event.key === "f" && !disabledControls.includes("fog")) {
|
||||
if (shortcuts.fogTool(event) && !disabledControls.includes("fog")) {
|
||||
onSelectedToolChange("fog");
|
||||
}
|
||||
if (event.key === "m" && !disabledControls.includes("measure")) {
|
||||
if (shortcuts.measureTool(event) && !disabledControls.includes("measure")) {
|
||||
onSelectedToolChange("measure");
|
||||
}
|
||||
if (event.key === "q" && !disabledControls.includes("pointer")) {
|
||||
if (shortcuts.pointerTool(event) && !disabledControls.includes("pointer")) {
|
||||
onSelectedToolChange("pointer");
|
||||
}
|
||||
if (event.key === "n" && !disabledControls.includes("note")) {
|
||||
if (shortcuts.noteTool(event) && !disabledControls.includes("note")) {
|
||||
onSelectedToolChange("note");
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyUp(event) {
|
||||
if (event.key === " " && selectedToolId === "move") {
|
||||
if (shortcuts.move(event) && selectedToolId === "move") {
|
||||
onSelectedToolChange(previousSelectedToolRef.current);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ import Divider from "../../Divider";
|
||||
|
||||
import { useKeyboard } from "../../../contexts/KeyboardContext";
|
||||
|
||||
import shortcuts from "../../../shortcuts";
|
||||
|
||||
function DrawingToolSettings({
|
||||
settings,
|
||||
onSettingChange,
|
||||
@ -31,36 +33,26 @@ function DrawingToolSettings({
|
||||
disabledActions,
|
||||
}) {
|
||||
// Keyboard shotcuts
|
||||
function handleKeyDown({ key, ctrlKey, metaKey, shiftKey }) {
|
||||
if (key === "b") {
|
||||
function handleKeyDown(event) {
|
||||
if (shortcuts.drawBrush(event)) {
|
||||
onSettingChange({ type: "brush" });
|
||||
} else if (key === "p") {
|
||||
} else if (shortcuts.drawPaint(event)) {
|
||||
onSettingChange({ type: "paint" });
|
||||
} else if (key === "l") {
|
||||
} else if (shortcuts.drawLine(event)) {
|
||||
onSettingChange({ type: "line" });
|
||||
} else if (key === "r") {
|
||||
} else if (shortcuts.drawRect(event)) {
|
||||
onSettingChange({ type: "rectangle" });
|
||||
} else if (key === "c") {
|
||||
} else if (shortcuts.drawCircle(event)) {
|
||||
onSettingChange({ type: "circle" });
|
||||
} else if (key === "t") {
|
||||
} else if (shortcuts.drawTriangle(event)) {
|
||||
onSettingChange({ type: "triangle" });
|
||||
} else if (key === "e") {
|
||||
} else if (shortcuts.drawErase(event)) {
|
||||
onSettingChange({ type: "erase" });
|
||||
} else if (key === "o") {
|
||||
} else if (shortcuts.drawBlend(event)) {
|
||||
onSettingChange({ useBlending: !settings.useBlending });
|
||||
} else if (
|
||||
(key === "z" || key === "Z") &&
|
||||
(ctrlKey || metaKey) &&
|
||||
shiftKey &&
|
||||
!disabledActions.includes("redo")
|
||||
) {
|
||||
} else if (shortcuts.redo(event) && !disabledActions.includes("redo")) {
|
||||
onToolAction("mapRedo");
|
||||
} else if (
|
||||
key === "z" &&
|
||||
(ctrlKey || metaKey) &&
|
||||
!shiftKey &&
|
||||
!disabledActions.includes("undo")
|
||||
) {
|
||||
} else if (shortcuts.undo(event) && !disabledActions.includes("undo")) {
|
||||
onToolAction("mapUndo");
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import Divider from "../../Divider";
|
||||
|
||||
import { useKeyboard } from "../../../contexts/KeyboardContext";
|
||||
|
||||
import shortcuts from "../../../shortcuts";
|
||||
|
||||
function BrushToolSettings({
|
||||
settings,
|
||||
onSettingChange,
|
||||
@ -29,36 +31,26 @@ function BrushToolSettings({
|
||||
disabledActions,
|
||||
}) {
|
||||
// Keyboard shortcuts
|
||||
function handleKeyDown({ key, ctrlKey, metaKey, shiftKey }) {
|
||||
if (key === "p") {
|
||||
function handleKeyDown(event) {
|
||||
if (shortcuts.fogPolygon(event)) {
|
||||
onSettingChange({ type: "polygon" });
|
||||
} else if (key === "b") {
|
||||
} else if (shortcuts.fogBrush(event)) {
|
||||
onSettingChange({ type: "brush" });
|
||||
} else if (key === "t") {
|
||||
} else if (shortcuts.fogToggle(event)) {
|
||||
onSettingChange({ type: "toggle" });
|
||||
} else if (key === "e") {
|
||||
} else if (shortcuts.fogErase(event)) {
|
||||
onSettingChange({ type: "remove" });
|
||||
} else if (key === "l") {
|
||||
} else if (shortcuts.fogLayer(event)) {
|
||||
onSettingChange({ multilayer: !settings.multilayer });
|
||||
} else if (key === "f") {
|
||||
} else if (shortcuts.fogPreview(event)) {
|
||||
onSettingChange({ preview: !settings.preview });
|
||||
} else if (key === "c") {
|
||||
} else if (shortcuts.fogCut(event)) {
|
||||
onSettingChange({ useFogCut: !settings.useFogCut });
|
||||
} else if (key === "r") {
|
||||
} else if (shortcuts.fogRectangle(event)) {
|
||||
onSettingChange({ type: "rectangle" });
|
||||
} else if (
|
||||
(key === "z" || key === "Z") &&
|
||||
(ctrlKey || metaKey) &&
|
||||
shiftKey &&
|
||||
!disabledActions.includes("redo")
|
||||
) {
|
||||
} else if (shortcuts.redo(event) && !disabledActions.includes("redo")) {
|
||||
onToolAction("fogRedo");
|
||||
} else if (
|
||||
key === "z" &&
|
||||
(ctrlKey || metaKey) &&
|
||||
!shiftKey &&
|
||||
!disabledActions.includes("undo")
|
||||
) {
|
||||
} else if (shortcuts.undo(event) && !disabledActions.includes("undo")) {
|
||||
onToolAction("fogUndo");
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import normalizeWheel from "normalize-wheel";
|
||||
|
||||
import { useKeyboard, useBlur } from "../contexts/KeyboardContext";
|
||||
|
||||
import shortcuts from "../shortcuts";
|
||||
|
||||
const wheelZoomSpeed = -1;
|
||||
const touchZoomSpeed = 0.005;
|
||||
const minZoom = 0.1;
|
||||
@ -184,18 +186,14 @@ function useStageInteraction(
|
||||
}
|
||||
);
|
||||
|
||||
function handleKeyDown({ key, ctrlKey, metaKey }) {
|
||||
function handleKeyDown(event) {
|
||||
// TODO: Find better way to detect whether keyboard event should fire.
|
||||
// This one fires on all open stages
|
||||
if (preventInteraction) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
(key === "=" || key === "+" || key === "-" || key === "_") &&
|
||||
!ctrlKey &&
|
||||
!metaKey
|
||||
) {
|
||||
const pixelY = key === "=" || key === "+" ? -100 : 100;
|
||||
if (shortcuts.stageZoomIn(event) || shortcuts.stageZoomOut(event)) {
|
||||
const pixelY = shortcuts.stageZoomIn(event) ? -100 : 100;
|
||||
const newScale = Math.min(
|
||||
Math.max(
|
||||
stageScale +
|
||||
@ -219,13 +217,13 @@ function useStageInteraction(
|
||||
onStageScaleChange(newScale);
|
||||
}
|
||||
|
||||
if (key === "Shift") {
|
||||
if (shortcuts.stagePrecisionZoom(event)) {
|
||||
setZoomSpeed(0.25);
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyUp({ key }) {
|
||||
if (key === "Shift") {
|
||||
function handleKeyUp(event) {
|
||||
if (shortcuts.stagePrecisionZoom(event)) {
|
||||
setZoomSpeed(1);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ import { useMapData } from "../contexts/MapDataContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useKeyboard, useBlur } from "../contexts/KeyboardContext";
|
||||
|
||||
import shortcuts from "../shortcuts";
|
||||
|
||||
const defaultMapProps = {
|
||||
showGrid: false,
|
||||
snapToGrid: true,
|
||||
@ -345,17 +347,17 @@ function SelectMapModal({
|
||||
/**
|
||||
* Shortcuts
|
||||
*/
|
||||
function handleKeyDown({ key }) {
|
||||
function handleKeyDown(event) {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
if (key === "Shift") {
|
||||
if (shortcuts.selectRange(event)) {
|
||||
setSelectMode("range");
|
||||
}
|
||||
if (key === "Control" || key === "Meta") {
|
||||
if (shortcuts.selectMultiple(event)) {
|
||||
setSelectMode("multiple");
|
||||
}
|
||||
if (key === "Backspace" || key === "Delete") {
|
||||
if (shortcuts.delete(event)) {
|
||||
// Selected maps and none are default
|
||||
if (
|
||||
selectedMapIds.length > 0 &&
|
||||
@ -370,14 +372,14 @@ function SelectMapModal({
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyUp({ key }) {
|
||||
function handleKeyUp(event) {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
if (key === "Shift" && selectMode === "range") {
|
||||
if (shortcuts.selectRange(event) && selectMode === "range") {
|
||||
setSelectMode("single");
|
||||
}
|
||||
if ((key === "Control" || key === "Meta") && selectMode === "multiple") {
|
||||
if (shortcuts.selectMultiple(event) && selectMode === "multiple") {
|
||||
setSelectMode("single");
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import { useTokenData } from "../contexts/TokenDataContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useKeyboard, useBlur } from "../contexts/KeyboardContext";
|
||||
|
||||
import shortcuts from "../shortcuts";
|
||||
|
||||
function SelectTokensModal({ isOpen, onRequestClose }) {
|
||||
const { userId } = useAuth();
|
||||
const {
|
||||
@ -186,17 +188,17 @@ function SelectTokensModal({ isOpen, onRequestClose }) {
|
||||
/**
|
||||
* Shortcuts
|
||||
*/
|
||||
function handleKeyDown({ key }) {
|
||||
function handleKeyDown(event) {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
if (key === "Shift") {
|
||||
if (shortcuts.selectRange(event)) {
|
||||
setSelectMode("range");
|
||||
}
|
||||
if (key === "Control" || key === "Meta") {
|
||||
if (shortcuts.selectMultiple(event)) {
|
||||
setSelectMode("multiple");
|
||||
}
|
||||
if (key === "Backspace" || key === "Delete") {
|
||||
if (shortcuts.delete(event)) {
|
||||
// Selected tokens and none are default
|
||||
if (
|
||||
selectedTokenIds.length > 0 &&
|
||||
@ -210,14 +212,14 @@ function SelectTokensModal({ isOpen, onRequestClose }) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyUp({ key }) {
|
||||
function handleKeyUp(event) {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
if (key === "Shift" && selectMode === "range") {
|
||||
if (shortcuts.selectRange(event) && selectMode === "range") {
|
||||
setSelectMode("single");
|
||||
}
|
||||
if ((key === "Control" || key === "Meta") && selectMode === "multiple") {
|
||||
if (shortcuts.selectMultiple(event) && selectMode === "multiple") {
|
||||
setSelectMode("single");
|
||||
}
|
||||
}
|
||||
|
110
src/shortcuts.js
Normal file
110
src/shortcuts.js
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @param {KeyboardEvent} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasModifier(event) {
|
||||
return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key press without any modifiers and ignoring capitals
|
||||
* @param {KeyboardEvent} event
|
||||
* @param {string} key
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function singleKey(event, key) {
|
||||
return (
|
||||
!hasModifier(event) &&
|
||||
(event.key === key || event.key === key.toUpperCase())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Keyboard} event
|
||||
*/
|
||||
function undo(event) {
|
||||
const { key, ctrlKey, metaKey, shiftKey } = event;
|
||||
return (key === "z" || key === "Z") && (ctrlKey || metaKey) && !shiftKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Keyboard} event
|
||||
*/
|
||||
function redo(event) {
|
||||
const { key, ctrlKey, metaKey, shiftKey } = event;
|
||||
return (key === "z" || key === "Z") && (ctrlKey || metaKey) && shiftKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Keyboard} event
|
||||
*/
|
||||
function zoomIn(event) {
|
||||
const { key, ctrlKey, metaKey } = event;
|
||||
return (key === "=" || key === "+") && !ctrlKey && !metaKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Keyboard} event
|
||||
*/
|
||||
function zoomOut(event) {
|
||||
const { key, ctrlKey, metaKey } = event;
|
||||
return (key === "-" || key === "_") && !ctrlKey && !metaKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback shortcut
|
||||
* @param {KeyboardEvent} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {Object.<string, shortcut>}
|
||||
*/
|
||||
const shortcuts = {
|
||||
// Tools
|
||||
move: (event) => singleKey(event, " "),
|
||||
moveTool: (event) => singleKey(event, "w"),
|
||||
drawingTool: (event) => singleKey(event, "d"),
|
||||
fogTool: (event) => singleKey(event, "f"),
|
||||
measureTool: (event) => singleKey(event, "m"),
|
||||
pointerTool: (event) => singleKey(event, "q"),
|
||||
noteTool: (event) => singleKey(event, "n"),
|
||||
// Map editor
|
||||
gridNudgeUp: ({ key }) => key === "ArrowUp",
|
||||
gridNudgeLeft: ({ key }) => key === "ArrowLeft",
|
||||
gridNudgeRight: ({ key }) => key === "ArrowRight",
|
||||
gridNudgeDown: ({ key }) => key === "ArrowDown",
|
||||
// Drawing tool
|
||||
drawBrush: (event) => singleKey(event, "b"),
|
||||
drawPaint: (event) => singleKey(event, "p"),
|
||||
drawLine: (event) => singleKey(event, "l"),
|
||||
drawRect: (event) => singleKey(event, "r"),
|
||||
drawCircle: (event) => singleKey(event, "c"),
|
||||
drawTriangle: (event) => singleKey(event, "t"),
|
||||
drawErase: (event) => singleKey(event, "e"),
|
||||
drawBlend: (event) => singleKey(event, "o"),
|
||||
// Fog tool
|
||||
fogPolygon: (event) => singleKey(event, "p"),
|
||||
fogRectangle: (event) => singleKey(event, "r"),
|
||||
fogBrush: (event) => singleKey(event, "b"),
|
||||
fogToggle: (event) => singleKey(event, "t"),
|
||||
fogErase: (event) => singleKey(event, "e"),
|
||||
fogLayer: (event) => singleKey(event, "l"),
|
||||
fogPreview: (event) => singleKey(event, "f"),
|
||||
fogCut: (event) => singleKey(event, "c"),
|
||||
fogFinishPolygon: ({ key }) => key === "Enter",
|
||||
fogCancelPolygon: ({ key }) => key === "Escape",
|
||||
// Stage interaction
|
||||
stageZoomIn: zoomIn,
|
||||
stageZoomOut: zoomOut,
|
||||
stagePrecisionZoom: ({ key }) => key === "Shift",
|
||||
// Select
|
||||
selectRange: ({ key }) => key === "Shift",
|
||||
selectMultiple: ({ key }) => key === "Control" || key === "Meta",
|
||||
// Common
|
||||
undo,
|
||||
redo,
|
||||
delete: ({ key }) => key === "Backspace" || key === "Delete",
|
||||
};
|
||||
|
||||
export default shortcuts;
|
Loading…
Reference in New Issue
Block a user