Add select tool settings and icons

This commit is contained in:
Mitchell McCaffrey 2021-07-19 10:56:14 +10:00
parent 0113b07ac4
commit 621014bff2
12 changed files with 191 additions and 25 deletions

View File

@ -156,6 +156,7 @@ function Map({
disabledControls.push("move"); disabledControls.push("move");
disabledControls.push("measure"); disabledControls.push("measure");
disabledControls.push("pointer"); disabledControls.push("pointer");
disabledControls.push("select");
} }
if (!allowFogDrawing) { if (!allowFogDrawing) {
disabledControls.push("fog"); disabledControls.push("fog");

View File

@ -9,6 +9,7 @@ import SelectMapButton from "./SelectMapButton";
import FogToolSettings from "./controls/FogToolSettings"; import FogToolSettings from "./controls/FogToolSettings";
import DrawingToolSettings from "./controls/DrawingToolSettings"; import DrawingToolSettings from "./controls/DrawingToolSettings";
import PointerToolSettings from "./controls/PointerToolSettings"; import PointerToolSettings from "./controls/PointerToolSettings";
import SelectToolSettings from "./controls/SelectToolSettings";
import MoveToolIcon from "../../icons/MoveToolIcon"; import MoveToolIcon from "../../icons/MoveToolIcon";
import FogToolIcon from "../../icons/FogToolIcon"; import FogToolIcon from "../../icons/FogToolIcon";
@ -19,8 +20,10 @@ import PointerToolIcon from "../../icons/PointerToolIcon";
import FullScreenIcon from "../../icons/FullScreenIcon"; import FullScreenIcon from "../../icons/FullScreenIcon";
import FullScreenExitIcon from "../../icons/FullScreenExitIcon"; import FullScreenExitIcon from "../../icons/FullScreenExitIcon";
import NoteToolIcon from "../../icons/NoteToolIcon"; import NoteToolIcon from "../../icons/NoteToolIcon";
import SelectToolIcon from "../../icons/SelecToolIcon";
import useSetting from "../../hooks/useSetting"; import useSetting from "../../hooks/useSetting";
import { Map, MapTool, MapToolId } from "../../types/Map"; import { Map, MapTool, MapToolId } from "../../types/Map";
import { MapState } from "../../types/MapState"; import { MapState } from "../../types/MapState";
import { import {
@ -29,6 +32,10 @@ import {
} from "../../types/Events"; } from "../../types/Events";
import { Settings } from "../../types/Settings"; import { Settings } from "../../types/Settings";
import { useKeyboard } from "../../contexts/KeyboardContext";
import shortcuts from "../../shortcuts";
type MapControlsProps = { type MapControlsProps = {
onMapChange: MapChangeEventHandler; onMapChange: MapChangeEventHandler;
onMapReset: MapResetEventHandler; onMapReset: MapResetEventHandler;
@ -39,7 +46,7 @@ type MapControlsProps = {
toolSettings: Settings; toolSettings: Settings;
onToolSettingChange: (change: Partial<Settings>) => void; onToolSettingChange: (change: Partial<Settings>) => void;
onToolAction: (actionId: string) => void; onToolAction: (actionId: string) => void;
disabledControls: string[]; disabledControls: MapToolId[];
disabledSettings: Partial<Record<keyof Settings, string[]>>; disabledSettings: Partial<Record<keyof Settings, string[]>>;
}; };
@ -65,6 +72,12 @@ function MapContols({
icon: <MoveToolIcon />, icon: <MoveToolIcon />,
title: "Move Tool (W)", title: "Move Tool (W)",
}, },
select: {
id: "select",
icon: <SelectToolIcon />,
title: "Select Tool (S)",
SettingsComponent: SelectToolSettings,
},
fog: { fog: {
id: "fog", id: "fog",
icon: <FogToolIcon />, icon: <FogToolIcon />,
@ -96,6 +109,7 @@ function MapContols({
}; };
const tools: MapToolId[] = [ const tools: MapToolId[] = [
"move", "move",
"select",
"fog", "fog",
"drawing", "drawing",
"measure", "measure",
@ -209,7 +223,7 @@ function MapContols({
<Settings <Settings
settings={toolSettings[selectedToolId]} settings={toolSettings[selectedToolId]}
onSettingChange={( onSettingChange={(
change: Partial<Settings["fog" | "drawing" | "pointer"]> change: Partial<Settings["fog" | "drawing" | "pointer" | "select"]>
) => ) =>
onToolSettingChange({ onToolSettingChange({
[selectedToolId]: { [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 ( return (
<> <>
<Flex <Flex

View File

@ -135,26 +135,6 @@ function MapInteraction({
previousSelectedToolRef.current = selectedToolId; previousSelectedToolRef.current = selectedToolId;
onSelectedToolChange("move"); onSelectedToolChange("move");
} }
// Basic keyboard shortcuts
if (shortcuts.moveTool(event) && !disabledControls.includes("move")) {
onSelectedToolChange("move");
}
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");
}
} }
function handleKeyUp(event: KeyboardEvent) { function handleKeyUp(event: KeyboardEvent) {

View File

@ -0,0 +1,63 @@
import { Flex } from "theme-ui";
import {
SelectToolSettings as SelectToolSettingsType,
SelectToolType,
} from "../../../types/Select";
import { useKeyboard } from "../../../contexts/KeyboardContext";
import ToolSection from "./ToolSection";
import shortcuts from "../../../shortcuts";
import RectIcon from "../../../icons/SelectRectangleIcon";
import PathIcon from "../../../icons/SelectPathIcon";
type SelectToolSettingsProps = {
settings: SelectToolSettingsType;
onSettingChange: (change: Partial<SelectToolSettingsType>) => 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: <PathIcon />,
},
{
id: "rectangle",
title: "Rectangle (R)",
isSelected: settings.type === "rectangle",
icon: <RectIcon />,
},
];
return (
<Flex sx={{ alignItems: "center" }}>
<ToolSection
tools={tools}
onToolClick={(tool) =>
onSettingChange({ type: tool.id as SelectToolType })
}
/>
</Flex>
);
}
export default SelectToolSettings;

View File

@ -0,0 +1,16 @@
function SelectToolIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="currentcolor"
>
<rect fill="none" height="24" width="24" />
<path d="M12 3c4.95 0 9 2.835 9 6.34 0 2.953-2.871 5.435-6.75 6.141v-.253c0-.535-.09-1.051-.261-1.531 3.006-.543 5.211-2.292 5.211-4.357 0-2.5-3.222-4.528-7.2-4.528S4.8 6.84 4.8 9.34c0 1.078.603 2.074 1.611 2.853-.396.444-.711.96-.909 1.54C3.954 12.592 3 11.043 3 9.34 3 5.835 7.05 3 12 3m-2.25 9.058c1.737 0 3.15 1.422 3.15 3.17 0 1.72-1.35 3.125-3.06 3.17-.189.326-.378.906.207 1.522 1.053 1.086 3.105-.87 5.904-.879 1.836-.01 3.276.235 3.276.235s.945.118.846.97c-.099.842-.954.842-.954.842-.342-.036-1.692-.353-3.321-.263-1.629.082-2.475.662-3.294.915-.81.254-2.385.625-3.834-.58-1.197-.987-.756-2.662-.567-3.215A3.22 3.22 0 016.6 15.228c0-1.748 1.413-3.17 3.15-3.17m0 1.811c-.747 0-1.35.607-1.35 1.359s.603 1.358 1.35 1.358c.747 0 1.35-.606 1.35-1.358 0-.752-.603-1.359-1.35-1.359z" />
</svg>
);
}
export default SelectToolIcon;

View File

@ -0,0 +1,16 @@
function SelectPathIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="currentcolor"
>
<rect fill="none" height="24" width="24" />
<path d="M12 3c4.95 0 9 2.835 9 6.34 0 2.953-2.871 5.435-6.75 6.141v-.253c0-.535-.09-1.051-.261-1.531 3.006-.543 5.211-2.292 5.211-4.357 0-2.5-3.222-4.528-7.2-4.528S4.8 6.84 4.8 9.34c0 1.078.603 2.074 1.611 2.853-.396.444-.711.96-.909 1.54C3.954 12.592 3 11.043 3 9.34 3 5.835 7.05 3 12 3m-2.25 9.058c1.737 0 3.15 1.422 3.15 3.17 0 1.72-1.35 3.125-3.06 3.17-.189.326-.378.906.207 1.522 1.053 1.086 3.105-.87 5.904-.879 1.836-.01 3.276.235 3.276.235s.945.118.846.97c-.099.842-.954.842-.954.842-.342-.036-1.692-.353-3.321-.263-1.629.082-2.475.662-3.294.915-.81.254-2.385.625-3.834-.58-1.197-.987-.756-2.662-.567-3.215A3.22 3.22 0 016.6 15.228c0-1.748 1.413-3.17 3.15-3.17m0 1.811c-.747 0-1.35.607-1.35 1.359s.603 1.358 1.35 1.358c.747 0 1.35-.606 1.35-1.358 0-.752-.603-1.359-1.35-1.359z" />
</svg>
);
}
export default SelectPathIcon;

View File

@ -0,0 +1,16 @@
function SelectRectangleIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 0 24 24"
width="24"
fill="currentcolor"
>
<rect fill="none" height="24" width="24" />
<path d="M17,5h-2V3h2V5z M19,9h2V7h-2V9z M19,13h2v-2h-2V13z M11,21h2v-2h-2V21z M7,5h2V3H7V5z M3,17h2v-2H3V17z M5,21v-2H3 C3,20.1,3.9,21,5,21z M19,3v2h2C21,3.9,20.1,3,19,3z M11,5h2V3h-2V5z M3,9h2V7H3V9z M7,21h2v-2H7V21z M3,13h2v-2H3V13z M3,5h2V3 C3.9,3,3,3.9,3,5z M18.71,17.29l1.44-1.44c0.32-0.32,0.09-0.85-0.35-0.85H16c-0.55,0-1,0.45-1,1v3.79c0,0.45,0.54,0.67,0.85,0.35 l1.44-1.44l2,2c0.39,0.39,1.02,0.39,1.41,0c0.39-0.39,0.39-1.02,0-1.41L18.71,17.29z" />
</svg>
);
}
export default SelectRectangleIcon;

View File

@ -64,6 +64,11 @@ function loadVersions(settings: Settings) {
...prev, ...prev,
fog: { ...prev.fog, editOpacity: 0.5 }, fog: { ...prev.fog, editOpacity: 0.5 },
})); }));
// v1.10.0 - Add select tool
settings.version(8, (prev: any) => ({
...prev,
select: { type: "path" },
}));
} }
export function getSettings() { export function getSettings() {

View File

@ -41,9 +41,6 @@ function zoomOut(event: KeyboardEvent): boolean {
type Shortcut = (event: KeyboardEvent) => boolean; type Shortcut = (event: KeyboardEvent) => boolean;
/**
* @type {Object.<string, shortcut>}
*/
const shortcuts: Record<string, Shortcut> = { const shortcuts: Record<string, Shortcut> = {
// Tools // Tools
move: (event) => singleKey(event, " "), move: (event) => singleKey(event, " "),
@ -78,6 +75,10 @@ const shortcuts: Record<string, Shortcut> = {
fogCut: (event) => singleKey(event, "c"), fogCut: (event) => singleKey(event, "c"),
fogFinishPolygon: ({ key }) => key === "Enter", fogFinishPolygon: ({ key }) => key === "Enter",
fogCancelPolygon: ({ key }) => key === "Escape", fogCancelPolygon: ({ key }) => key === "Escape",
// Select tool
selectTool: (event) => singleKey(event, "s"),
selectPath: (event) => singleKey(event, "l"),
selectRect: (event) => singleKey(event, "r"),
// Stage interaction // Stage interaction
stageZoomIn: zoomIn, stageZoomIn: zoomIn,
stageZoomOut: zoomOut, stageZoomOut: zoomOut,

View File

@ -7,6 +7,7 @@ import { Grid } from "./Grid";
export type MapToolId = export type MapToolId =
| "map" | "map"
| "move" | "move"
| "select"
| "fog" | "fog"
| "drawing" | "drawing"
| "measure" | "measure"

24
src/types/Select.ts Normal file
View File

@ -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;

View File

@ -2,6 +2,7 @@ import { Duration } from "./Timer";
import { DrawingToolSettings } from "./Drawing"; import { DrawingToolSettings } from "./Drawing";
import { FogToolSettings } from "./Fog"; import { FogToolSettings } from "./Fog";
import { PointerToolSettings } from "./Pointer"; import { PointerToolSettings } from "./Pointer";
import { SelectToolSettings } from "./Select";
export type DrawingSettings = DrawingToolSettings; export type DrawingSettings = DrawingToolSettings;
export type FogSettings = FogToolSettings & { export type FogSettings = FogToolSettings & {
@ -22,6 +23,7 @@ export type MapSettings = {
}; };
export type PointerSettings = PointerToolSettings; export type PointerSettings = PointerToolSettings;
export type TimerSettings = Duration; export type TimerSettings = Duration;
export type SelectSettings = SelectToolSettings;
export type Settings = { export type Settings = {
dice: DiceSettings; dice: DiceSettings;
@ -31,4 +33,5 @@ export type Settings = {
map: MapSettings; map: MapSettings;
pointer: PointerSettings; pointer: PointerSettings;
timer: TimerSettings; timer: TimerSettings;
select: SelectSettings;
}; };