import React, { useState, useEffect, useRef } from "react"; import { Flex, Box, IconButton, Label } from "theme-ui"; import SelectMapButton from "./SelectMapButton"; import ExpandMoreIcon from "../../icons/ExpandMoreIcon"; import PanToolIcon from "../../icons/PanToolIcon"; import BrushToolIcon from "../../icons/BrushToolIcon"; import EraseToolIcon from "../../icons/EraseToolIcon"; import UndoIcon from "../../icons/UndoIcon"; import RedoIcon from "../../icons/RedoIcon"; import GridOnIcon from "../../icons/GridOnIcon"; import GridOffIcon from "../../icons/GridOffIcon"; import BlendOnIcon from "../../icons/BlendOnIcon"; import BlendOffIcon from "../../icons/BlendOffIcon"; import GestureOnIcon from "../../icons/GestureOnIcon"; import GestureOffIcon from "../../icons/GestureOffIcon"; import colors, { colorOptions } from "../../helpers/colors"; import MapMenu from "./MapMenu"; import EraseAllIcon from "../../icons/EraseAllIcon"; function MapControls({ onMapChange, onMapStateChange, currentMap, onToolChange, selectedTool, disabledTools, onUndo, onRedo, undoDisabled, redoDisabled, brushColor, onBrushColorChange, onEraseAll, useBrushGridSnapping, onBrushGridSnappingChange, useBrushBlending, onBrushBlendingChange, useBrushGesture, onBrushGestureChange, }) { const [isExpanded, setIsExpanded] = useState(false); const subMenus = { brush: ( {colorOptions.map((color) => ( onBrushColorChange(color)} aria-label={`Brush Color ${color}`} > {brushColor === color && ( )} ))} onBrushGridSnappingChange(!useBrushGridSnapping)} > {useBrushGridSnapping ? : } onBrushBlendingChange(!useBrushBlending)} > {useBrushBlending ? : } onBrushGestureChange(!useBrushGesture)} > {useBrushGesture ? : } ), erase: ( ), }; const [currentSubmenu, setCurrentSubmenu] = useState(null); const [currentSubmenuOptions, setCurrentSubmenuOptions] = useState({}); function handleToolClick(event, tool) { if (tool !== selectedTool) { onToolChange(tool); } else if (currentSubmenu) { setCurrentSubmenu(null); setCurrentSubmenuOptions({}); } else if (subMenus[tool]) { const toolRect = event.target.getBoundingClientRect(); setCurrentSubmenu(tool); setCurrentSubmenuOptions({ // Align the right of the submenu to the left of the tool and center vertically left: `${toolRect.left - 16}px`, top: `${toolRect.bottom - toolRect.height / 2}px`, style: { transform: "translate(-100%, -50%)" }, // Exclude this node from the sub menus auto close excludeNode: event.target, }); } } // Detect when a tool becomes disabled and switch to to the pan tool useEffect(() => { if (disabledTools.includes(selectedTool)) { onToolChange("pan"); } }, [selectedTool, disabledTools, onToolChange]); const divider = ( ); const expanedMenuRef = useRef(); return ( <> setIsExpanded(!isExpanded)} sx={{ transform: `rotate(${isExpanded ? "0" : "180deg"})`, display: "block", backgroundColor: "overlay", borderRadius: "50%", }} m={2} > {divider} handleToolClick(e, "pan")} sx={{ color: selectedTool === "pan" ? "primary" : "text" }} disabled={disabledTools.includes("pan")} > handleToolClick(e, "brush")} sx={{ color: selectedTool === "brush" ? "primary" : "text" }} disabled={disabledTools.includes("brush")} > handleToolClick(e, "erase")} sx={{ color: selectedTool === "erase" ? "primary" : "text" }} disabled={disabledTools.includes("erase")} > {divider} onUndo()} disabled={undoDisabled} > onRedo()} disabled={redoDisabled} > { setCurrentSubmenu(null); setCurrentSubmenuOptions({}); }} {...currentSubmenuOptions} > {currentSubmenu && subMenus[currentSubmenu]} ); } export default MapControls;