From 80b711296b21d8e3ed93d2b579f3db956f44a7c4 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Wed, 24 Jun 2020 18:05:33 +1000 Subject: [PATCH] Added keyboard shortcuts to drawing and remaining fog tools --- src/components/map/MapFog.js | 46 ++++++++++++---- src/components/map/MapInteraction.js | 35 +++++++++---- .../map/controls/DrawingToolSettings.js | 46 +++++++++++++++- .../map/controls/FogToolSettings.js | 52 ++++++++++++++++++- 4 files changed, 158 insertions(+), 21 deletions(-) diff --git a/src/components/map/MapFog.js b/src/components/map/MapFog.js index 563f282..14c4bce 100644 --- a/src/components/map/MapFog.js +++ b/src/components/map/MapFog.js @@ -122,7 +122,7 @@ function MapFog({ if (subtract) { shapeData = { id: drawingShape.id, type: drawingShape.type }; } else { - shapeData = drawingShape; + shapeData = { ...drawingShape, color: "black" }; } const shape = { ...shapeData, @@ -259,7 +259,7 @@ function MapFog({ data: data, }); } else { - onShapeAdd({ ...drawingShape, data: data }); + onShapeAdd({ ...drawingShape, data: data, color: "black" }); } setDrawingShape(null); @@ -267,26 +267,52 @@ function MapFog({ // Add keyboard shortcuts useEffect(() => { - const mapStage = mapStageRef.current; - - function handleKeyDown(event) { + function handleKeyDown({ key }) { if ( - event.key === "Enter" && + key === "Enter" && selectedToolSettings.type === "polygon" && drawingShape ) { finishDrawingPolygon(); } - if (event.key === "Escape" && drawingShape) { + if (key === "Escape" && drawingShape) { setDrawingShape(null); } + if (key === "Alt" && drawingShape) { + updateShapeColor(); + } } - mapStage.container().addEventListener("keydown", handleKeyDown); + function handleKeyUp({ key }) { + if (key === "Alt" && drawingShape) { + updateShapeColor(); + } + } + + function updateShapeColor() { + setDrawingShape((prevShape) => { + if (!prevShape) { + return; + } + return { + ...prevShape, + color: selectedToolSettings.useFogSubtract ? "black" : "red", + }; + }); + } + + interactionEmitter.on("keyDown", handleKeyDown); + interactionEmitter.on("keyUp", handleKeyUp); return () => { - mapStage.container().removeEventListener("keydown", handleKeyDown); + interactionEmitter.off("keyDown", handleKeyDown); + interactionEmitter.off("keyUp", handleKeyUp); }; - }, [finishDrawingPolygon, mapStageRef, drawingShape, selectedToolSettings]); + }, [ + finishDrawingPolygon, + interactionEmitter, + drawingShape, + selectedToolSettings, + ]); function handleShapeOver(shape, isDown) { if (shouldHover && isDown) { diff --git a/src/components/map/MapInteraction.js b/src/components/map/MapInteraction.js index 104d825..903c379 100644 --- a/src/components/map/MapInteraction.js +++ b/src/components/map/MapInteraction.js @@ -127,7 +127,7 @@ function MapInteraction({ isInteractingWithCanvas.current = event.target === mapLayerRef.current.getCanvas()._canvas; }, - onDrag: ({ delta, xy, first, last, pinching }) => { + onDrag: ({ delta, first, last, pinching }) => { if ( preventMapInteraction || pinching || @@ -166,6 +166,27 @@ function MapInteraction({ stageHeightRef.current = height; } + function handleKeyDown(event) { + // Change to pan tool when pressing space + if (event.key === " " && selectedToolId === "pan") { + // Stop active state on pan icon from being selected + event.preventDefault(); + } + if (event.key === " " && selectedToolId !== "pan") { + event.preventDefault(); + previousSelectedToolRef.current = selectedToolId; + onSelectedToolChange("pan"); + } + interactionEmitter.emit("keyDown", event); + } + + function handleKeyUp(event) { + if (event.key === " " && selectedToolId === "pan") { + onSelectedToolChange(previousSelectedToolRef.current); + } + interactionEmitter.emit("keyUp", event); + } + function getCursorForTool(tool) { switch (tool) { case "pan": @@ -200,14 +221,6 @@ function MapInteraction({ interactionEmitter, }; - // Enable keyboard interaction for map stage container - useEffect(() => { - const container = mapStageRef.current.container(); - container.tabIndex = 1; - container.style.outline = "none"; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - return ( { + function handleKeyDown({ key, ctrlKey, metaKey, shiftKey }) { + if (key === "b") { + onSettingChange({ type: "brush" }); + } else if (key === "p") { + onSettingChange({ type: "paint" }); + } else if (key === "r") { + onSettingChange({ type: "rectangle" }); + } else if (key === "c") { + onSettingChange({ type: "circle" }); + } else if (key === "t") { + onSettingChange({ type: "triangle" }); + } else if (key === "e") { + onSettingChange({ type: "erase" }); + } else if (key === "o") { + onSettingChange({ useBlending: !settings.useBlending }); + } else if ( + key === "z" && + (ctrlKey || metaKey) && + shiftKey && + !disabledActions.includes("redo") + ) { + onToolAction("mapRedo"); + } else if ( + key === "z" && + (ctrlKey || metaKey) && + !shiftKey && + !disabledActions.includes("undo") + ) { + onToolAction("mapUndo"); + } + } + + interactionEmitter.on("keyDown", handleKeyDown); + return () => { + interactionEmitter.off("keyDown", handleKeyDown); + }; + }); + // Change to brush if on erase and it gets disabled useEffect(() => { if (settings.type === "erase" && disabledActions.includes("erase")) { diff --git a/src/components/map/controls/FogToolSettings.js b/src/components/map/controls/FogToolSettings.js index 2a583bc..06d35a2 100644 --- a/src/components/map/controls/FogToolSettings.js +++ b/src/components/map/controls/FogToolSettings.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useContext, useEffect } from "react"; import { Flex } from "theme-ui"; import EdgeSnappingToggle from "./EdgeSnappingToggle"; @@ -16,12 +16,62 @@ import RedoButton from "./RedoButton"; import Divider from "../../Divider"; +import MapInteractionContext from "../../../contexts/MapInteractionContext"; + function BrushToolSettings({ settings, onSettingChange, onToolAction, disabledActions, }) { + const { interactionEmitter } = useContext(MapInteractionContext); + + // Keyboard shortcuts + useEffect(() => { + function handleKeyDown({ key, ctrlKey, metaKey, shiftKey }) { + if (key === "Alt") { + onSettingChange({ useFogSubtract: !settings.useFogSubtract }); + } else if (key === "p") { + onSettingChange({ type: "polygon" }); + } else if (key === "b") { + onSettingChange({ type: "brush" }); + } else if (key === "t") { + onSettingChange({ type: "toggle" }); + } else if (key === "r") { + onSettingChange({ type: "remove" }); + } else if (key === "s") { + onSettingChange({ useEdgeSnapping: !settings.useEdgeSnapping }); + } else if ( + key === "z" && + (ctrlKey || metaKey) && + shiftKey && + !disabledActions.includes("redo") + ) { + onToolAction("fogRedo"); + } else if ( + key === "z" && + (ctrlKey || metaKey) && + !shiftKey && + !disabledActions.includes("undo") + ) { + onToolAction("fogUndo"); + } + } + + function handleKeyUp({ key }) { + if (key === "Alt") { + onSettingChange({ useFogSubtract: !settings.useFogSubtract }); + } + } + + interactionEmitter.on("keyDown", handleKeyDown); + interactionEmitter.on("keyUp", handleKeyUp); + return () => { + interactionEmitter.off("keyDown", handleKeyDown); + interactionEmitter.off("keyUp", handleKeyUp); + }; + }); + return (