Move measurement options to map settings

This commit is contained in:
Mitchell McCaffrey
2021-02-10 19:59:15 +11:00
parent 19def8cdb0
commit 96298e8943
15 changed files with 153 additions and 210 deletions

View File

@@ -8,7 +8,6 @@ import SelectMapButton from "./SelectMapButton";
import FogToolSettings from "./controls/FogToolSettings";
import DrawingToolSettings from "./controls/DrawingToolSettings";
import MeasureToolSettings from "./controls/MeasureToolSettings";
import PointerToolSettings from "./controls/PointerToolSettings";
import PanToolIcon from "../../icons/PanToolIcon";
@@ -61,7 +60,6 @@ function MapContols({
id: "measure",
icon: <MeasureToolIcon />,
title: "Measure Tool (M)",
SettingsComponent: MeasureToolSettings,
},
pointer: {
id: "pointer",

View File

@@ -14,14 +14,14 @@ import { getRelativePointerPosition } from "../../helpers/konva";
import useGridSnapping from "../../hooks/useGridSnapping";
function MapMeasure({ map, selectedToolSettings, active }) {
function MapMeasure({ map, active }) {
const {
stageScale,
mapWidth,
mapHeight,
interactionEmitter,
} = useMapInteraction();
const { gridCellNormalizedSize, gridStrokeWidth } = useGrid();
const { grid, gridCellNormalizedSize, gridStrokeWidth } = useGrid();
const mapStageRef = useMapStage();
const [drawingShapeData, setDrawingShapeData] = useState(null);
const [isBrushDown, setIsBrushDown] = useState(false);
@@ -45,7 +45,7 @@ function MapMeasure({ map, selectedToolSettings, active }) {
return { multiplier: 1, unit: "", digits: 0 };
}
const measureScale = parseToolScale(active && selectedToolSettings.scale);
const measureScale = parseToolScale(active && grid.measurement.scale);
const snapPositionToGrid = useGridSnapping();
@@ -95,7 +95,7 @@ function MapMeasure({ map, selectedToolSettings, active }) {
Vector2.divide(points[1], gridCellNormalizedSize),
precision
),
selectedToolSettings.type
grid.measurement.type
);
setDrawingShapeData({
length,

View File

@@ -23,6 +23,18 @@ const gridTypeSettings = [
{ value: "hexHorizontal", label: "Hex Horizontal" },
];
const gridSquareMeasurementTypeSettings = [
{ value: "chebyshev", label: "Chessboard (D&D 5e)" },
{ value: "alternating", label: "Alternating Diagonal (D&D 3.5e)" },
{ value: "euclidean", label: "Euclidean" },
{ value: "manhattan", label: "Manhattan" },
];
const gridHexMeasurementTypeSettings = [
{ value: "manhattan", label: "Manhattan" },
{ value: "euclidean", label: "Euclidean" },
];
function MapSettings({
map,
mapState,
@@ -69,11 +81,41 @@ function MapSettings({
}
function handleGridTypeChange(option) {
let grid = { ...map.grid, type: option.value };
const type = option.value;
let grid = {
...map.grid,
type,
measurement: {
...map.grid.measurement,
type: type === "square" ? "chebyshev" : "manhattan",
},
};
grid.inset = getGridUpdatedInset(grid, map.width, map.height);
onSettingsChange("grid", grid);
}
function handleGridMeasurementTypeChange(option) {
const grid = {
...map.grid,
measurement: {
...map.grid.measurement,
type: option.value,
},
};
onSettingsChange("grid", grid);
}
function handleGridMeasurementScaleChange(event) {
const grid = {
...map.grid,
measurement: {
...map.grid.measurement,
scale: event.target.value,
},
};
onSettingsChange("grid", grid);
}
function getMapSize() {
let size = 0;
if (map.quality === "original") {
@@ -131,42 +173,77 @@ function MapSettings({
<Flex
mt={2}
mb={mapEmpty || map.type === "default" ? 2 : 0}
sx={{ alignItems: "flex-end" }}
sx={{ flexDirection: "column" }}
>
<Box mb={1} sx={{ width: "50%" }}>
<Label mb={1}>Grid Type</Label>
<Select
isDisabled={mapEmpty || map.type === "default"}
options={gridTypeSettings}
value={
!mapEmpty &&
gridTypeSettings.find((s) => s.value === map.grid.type)
}
onChange={handleGridTypeChange}
isSearchable={false}
/>
</Box>
<Flex sx={{ width: "50%", flexDirection: "column" }} ml={2}>
<Label>
<Checkbox
checked={!mapEmpty && map.showGrid}
disabled={mapEmpty || map.type === "default"}
onChange={(e) =>
onSettingsChange("showGrid", e.target.checked)
<Flex sx={{ alignItems: "flex-end" }}>
<Box mb={1} sx={{ width: "50%" }}>
<Label mb={1}>Grid Type</Label>
<Select
isDisabled={mapEmpty || map.type === "default"}
options={gridTypeSettings}
value={
!mapEmpty &&
gridTypeSettings.find((s) => s.value === map.grid.type)
}
onChange={handleGridTypeChange}
isSearchable={false}
/>
Draw Grid
</Label>
<Label>
<Checkbox
checked={!mapEmpty && map.snapToGrid}
disabled={mapEmpty || map.type === "default"}
onChange={(e) =>
onSettingsChange("snapToGrid", e.target.checked)
</Box>
<Flex sx={{ width: "50%", flexDirection: "column" }} ml={2}>
<Label>
<Checkbox
checked={!mapEmpty && map.showGrid}
disabled={mapEmpty || map.type === "default"}
onChange={(e) =>
onSettingsChange("showGrid", e.target.checked)
}
/>
Draw Grid
</Label>
<Label>
<Checkbox
checked={!mapEmpty && map.snapToGrid}
disabled={mapEmpty || map.type === "default"}
onChange={(e) =>
onSettingsChange("snapToGrid", e.target.checked)
}
/>
Snap to Grid
</Label>
</Flex>
</Flex>
<Flex sx={{ alignItems: "flex-end" }}>
<Box my={2} sx={{ width: "50%" }}>
<Label mb={1}>Grid Measurement</Label>
<Select
isDisabled={mapEmpty || map.type === "default"}
options={
map && map.grid.type === "square"
? gridSquareMeasurementTypeSettings
: gridHexMeasurementTypeSettings
}
value={
!mapEmpty &&
gridSquareMeasurementTypeSettings.find(
(s) => s.value === map.grid.measurement.type
)
}
onChange={handleGridMeasurementTypeChange}
isSearchable={false}
/>
Snap to Grid
</Label>
</Box>
<Box mb={1} mx={2} sx={{ flexGrow: 1 }}>
<Label htmlFor="gridMeasurementScale">Grid Scale</Label>
<Input
name="gridMeasurementScale"
value={`${map && map.grid.measurement.scale}`}
onChange={handleGridMeasurementScaleChange}
disabled={mapEmpty || map.type === "default"}
min={1}
my={1}
autoComplete="off"
/>
</Box>
</Flex>
</Flex>
{!mapEmpty && map.type !== "default" && (

View File

@@ -1,86 +0,0 @@
import React from "react";
import { Flex, Input, Text } from "theme-ui";
import ToolSection from "./ToolSection";
import MeasureChebyshevIcon from "../../../icons/MeasureChebyshevIcon";
import MeasureEuclideanIcon from "../../../icons/MeasureEuclideanIcon";
import MeasureManhattanIcon from "../../../icons/MeasureManhattanIcon";
import MeasureAlternatingIcon from "../../../icons/MeasureAlternatingIcon";
import Divider from "../../Divider";
import { useKeyboard } from "../../../contexts/KeyboardContext";
function MeasureToolSettings({ settings, onSettingChange }) {
// Keyboard shortcuts
function handleKeyDown({ key }) {
if (key === "g") {
onSettingChange({ type: "chebyshev" });
} else if (key === "l") {
onSettingChange({ type: "euclidean" });
} else if (key === "c") {
onSettingChange({ type: "manhattan" });
} else if (key === "a") {
onSettingChange({ type: "alternating" });
}
}
useKeyboard(handleKeyDown);
const tools = [
{
id: "chebyshev",
title: "Grid Distance (G)",
isSelected: settings.type === "chebyshev",
icon: <MeasureChebyshevIcon />,
},
{
id: "alternating",
title: "Alternating Diagonal Distance (A)",
isSelected: settings.type === "alternating",
icon: <MeasureAlternatingIcon />,
},
{
id: "euclidean",
title: "Line Distance (L)",
isSelected: settings.type === "euclidean",
icon: <MeasureEuclideanIcon />,
},
{
id: "manhattan",
title: "City Block Distance (C)",
isSelected: settings.type === "manhattan",
icon: <MeasureManhattanIcon />,
},
];
return (
<Flex sx={{ alignItems: "center" }}>
<ToolSection
tools={tools}
onToolClick={(tool) => onSettingChange({ type: tool.id })}
/>
<Divider vertical />
<Text as="label" variant="body2" sx={{ fontSize: "16px" }} p={1}>
Scale:
</Text>
<Input
p={1}
pl={0}
sx={{
width: "40px",
border: "none",
":focus": {
outline: "none",
},
lineHeight: 1.2,
}}
value={settings.scale}
onChange={(e) => onSettingChange({ scale: e.target.value })}
autoComplete="off"
/>
</Flex>
);
}
export default MeasureToolSettings;