diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index 7fdebbc..4acdfb9 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -156,6 +156,7 @@ function Map({ disabledControls.push("move"); disabledControls.push("measure"); disabledControls.push("pointer"); + disabledControls.push("select"); } if (!allowFogDrawing) { disabledControls.push("fog"); diff --git a/src/components/map/MapControls.tsx b/src/components/map/MapControls.tsx index 7aef397..b8b8296 100644 --- a/src/components/map/MapControls.tsx +++ b/src/components/map/MapControls.tsx @@ -9,6 +9,7 @@ import SelectMapButton from "./SelectMapButton"; import FogToolSettings from "./controls/FogToolSettings"; import DrawingToolSettings from "./controls/DrawingToolSettings"; import PointerToolSettings from "./controls/PointerToolSettings"; +import SelectToolSettings from "./controls/SelectToolSettings"; import MoveToolIcon from "../../icons/MoveToolIcon"; import FogToolIcon from "../../icons/FogToolIcon"; @@ -19,8 +20,10 @@ import PointerToolIcon from "../../icons/PointerToolIcon"; import FullScreenIcon from "../../icons/FullScreenIcon"; import FullScreenExitIcon from "../../icons/FullScreenExitIcon"; import NoteToolIcon from "../../icons/NoteToolIcon"; +import SelectToolIcon from "../../icons/SelecToolIcon"; import useSetting from "../../hooks/useSetting"; + import { Map, MapTool, MapToolId } from "../../types/Map"; import { MapState } from "../../types/MapState"; import { @@ -29,6 +32,10 @@ import { } from "../../types/Events"; import { Settings } from "../../types/Settings"; +import { useKeyboard } from "../../contexts/KeyboardContext"; + +import shortcuts from "../../shortcuts"; + type MapControlsProps = { onMapChange: MapChangeEventHandler; onMapReset: MapResetEventHandler; @@ -39,7 +46,7 @@ type MapControlsProps = { toolSettings: Settings; onToolSettingChange: (change: Partial) => void; onToolAction: (actionId: string) => void; - disabledControls: string[]; + disabledControls: MapToolId[]; disabledSettings: Partial>; }; @@ -65,6 +72,12 @@ function MapContols({ icon: , title: "Move Tool (W)", }, + select: { + id: "select", + icon: , + title: "Select Tool (S)", + SettingsComponent: SelectToolSettings, + }, fog: { id: "fog", icon: , @@ -96,6 +109,7 @@ function MapContols({ }; const tools: MapToolId[] = [ "move", + "select", "fog", "drawing", "measure", @@ -209,7 +223,7 @@ function MapContols({ + change: Partial ) => onToolSettingChange({ [selectedToolId]: { @@ -225,6 +239,32 @@ function MapContols({ ); } + function handleKeyDown(event: KeyboardEvent) { + if (shortcuts.moveTool(event) && !disabledControls.includes("move")) { + onSelectedToolChange("move"); + } + if (shortcuts.selectTool(event) && !disabledControls.includes("select")) { + onSelectedToolChange("select"); + } + if (shortcuts.drawingTool(event) && !disabledControls.includes("drawing")) { + onSelectedToolChange("drawing"); + } + if (shortcuts.fogTool(event) && !disabledControls.includes("fog")) { + onSelectedToolChange("fog"); + } + if (shortcuts.measureTool(event) && !disabledControls.includes("measure")) { + onSelectedToolChange("measure"); + } + if (shortcuts.pointerTool(event) && !disabledControls.includes("pointer")) { + onSelectedToolChange("pointer"); + } + if (shortcuts.noteTool(event) && !disabledControls.includes("note")) { + onSelectedToolChange("note"); + } + } + + useKeyboard(handleKeyDown); + return ( <> ) => void; +}; + +function SelectToolSettings({ + settings, + onSettingChange, +}: SelectToolSettingsProps) { + // Keyboard shotcuts + function handleKeyDown(event: KeyboardEvent) { + if (shortcuts.selectPath(event)) { + onSettingChange({ type: "path" }); + } else if (shortcuts.selectRect(event)) { + onSettingChange({ type: "rectangle" }); + } + } + useKeyboard(handleKeyDown); + + const tools = [ + { + id: "lasso", + title: "Lasso (L)", + isSelected: settings.type === "path", + icon: , + }, + { + id: "rectangle", + title: "Rectangle (R)", + isSelected: settings.type === "rectangle", + icon: , + }, + ]; + + return ( + + + onSettingChange({ type: tool.id as SelectToolType }) + } + /> + + ); +} + +export default SelectToolSettings; diff --git a/src/icons/SelecToolIcon.tsx b/src/icons/SelecToolIcon.tsx new file mode 100644 index 0000000..12270ff --- /dev/null +++ b/src/icons/SelecToolIcon.tsx @@ -0,0 +1,16 @@ +function SelectToolIcon() { + return ( + + + + + ); +} + +export default SelectToolIcon; diff --git a/src/icons/SelectPathIcon.tsx b/src/icons/SelectPathIcon.tsx new file mode 100644 index 0000000..2fa81f0 --- /dev/null +++ b/src/icons/SelectPathIcon.tsx @@ -0,0 +1,16 @@ +function SelectPathIcon() { + return ( + + + + + ); +} + +export default SelectPathIcon; diff --git a/src/icons/SelectRectangleIcon.tsx b/src/icons/SelectRectangleIcon.tsx new file mode 100644 index 0000000..aa31296 --- /dev/null +++ b/src/icons/SelectRectangleIcon.tsx @@ -0,0 +1,16 @@ +function SelectRectangleIcon() { + return ( + + + + + ); +} + +export default SelectRectangleIcon; diff --git a/src/settings.ts b/src/settings.ts index 5d67c32..0ab5258 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -64,6 +64,11 @@ function loadVersions(settings: Settings) { ...prev, fog: { ...prev.fog, editOpacity: 0.5 }, })); + // v1.10.0 - Add select tool + settings.version(8, (prev: any) => ({ + ...prev, + select: { type: "path" }, + })); } export function getSettings() { diff --git a/src/shortcuts.ts b/src/shortcuts.ts index b8deaa1..925c159 100644 --- a/src/shortcuts.ts +++ b/src/shortcuts.ts @@ -41,9 +41,6 @@ function zoomOut(event: KeyboardEvent): boolean { type Shortcut = (event: KeyboardEvent) => boolean; -/** - * @type {Object.} - */ const shortcuts: Record = { // Tools move: (event) => singleKey(event, " "), @@ -78,6 +75,10 @@ const shortcuts: Record = { fogCut: (event) => singleKey(event, "c"), fogFinishPolygon: ({ key }) => key === "Enter", fogCancelPolygon: ({ key }) => key === "Escape", + // Select tool + selectTool: (event) => singleKey(event, "s"), + selectPath: (event) => singleKey(event, "l"), + selectRect: (event) => singleKey(event, "r"), // Stage interaction stageZoomIn: zoomIn, stageZoomOut: zoomOut, diff --git a/src/types/Map.ts b/src/types/Map.ts index cf45aa1..73ed57e 100644 --- a/src/types/Map.ts +++ b/src/types/Map.ts @@ -7,6 +7,7 @@ import { Grid } from "./Grid"; export type MapToolId = | "map" | "move" + | "select" | "fog" | "drawing" | "measure" diff --git a/src/types/Select.ts b/src/types/Select.ts new file mode 100644 index 0000000..61db77d --- /dev/null +++ b/src/types/Select.ts @@ -0,0 +1,24 @@ +import Konva from "konva"; +import { RectData, PointsData } from "./Drawing"; + +export type SelectToolType = "path" | "rectangle"; + +export type SelectToolSettings = { + type: SelectToolType; +}; + +export type BaseSelection = { + nodes: Konva.Node[]; +}; + +export type RectSelection = BaseSelection & { + data: RectData; + type: "rectangle"; +}; + +export type PathSelection = BaseSelection & { + data: PointsData; + type: "path"; +}; + +export type Selection = RectSelection | PathSelection; diff --git a/src/types/Settings.ts b/src/types/Settings.ts index 453a8d3..420dfd5 100644 --- a/src/types/Settings.ts +++ b/src/types/Settings.ts @@ -2,6 +2,7 @@ import { Duration } from "./Timer"; import { DrawingToolSettings } from "./Drawing"; import { FogToolSettings } from "./Fog"; import { PointerToolSettings } from "./Pointer"; +import { SelectToolSettings } from "./Select"; export type DrawingSettings = DrawingToolSettings; export type FogSettings = FogToolSettings & { @@ -22,6 +23,7 @@ export type MapSettings = { }; export type PointerSettings = PointerToolSettings; export type TimerSettings = Duration; +export type SelectSettings = SelectToolSettings; export type Settings = { dice: DiceSettings; @@ -31,4 +33,5 @@ export type Settings = { map: MapSettings; pointer: PointerSettings; timer: TimerSettings; + select: SelectSettings; };