import { useControls, useDebug, useSettings, type TouchMode, } from "./SettingsProvider"; import { MissionSelect } from "./MissionSelect"; import { useEffect, useState, useRef, RefObject } from "react"; import { CopyCoordinatesButton } from "./CopyCoordinatesButton"; import { LoadDemoButton } from "./LoadDemoButton"; import { useDemoRecording } from "./DemoProvider"; import { FiInfo, FiSettings } from "react-icons/fi"; import { Camera } from "three"; import styles from "./InspectorControls.module.css"; export function InspectorControls({ missionName, missionType, onChangeMission, onOpenMapInfo, isTouch, cameraRef, }: { missionName: string; missionType: string; onChangeMission: ({ missionName, missionType, }: { missionName: string; missionType: string; }) => void; onOpenMapInfo: () => void; isTouch: boolean | null; cameraRef: RefObject; }) { const { fogEnabled, setFogEnabled, fov, setFov, audioEnabled, setAudioEnabled, animationEnabled, setAnimationEnabled, } = useSettings(); const { speedMultiplier, setSpeedMultiplier, touchMode, setTouchMode } = useControls(); const { debugMode, setDebugMode } = useDebug(); const demoRecording = useDemoRecording(); const isDemoLoaded = demoRecording != null; const [settingsOpen, setSettingsOpen] = useState(false); const dropdownRef = useRef(null); const buttonRef = useRef(null); const focusAreaRef = useRef(null); // Focus the panel when it opens. useEffect(() => { if (settingsOpen) { dropdownRef.current?.focus(); } }, [settingsOpen]); const handleDropdownBlur = (e: React.FocusEvent) => { const relatedTarget = e.relatedTarget as Node | null; if (relatedTarget && focusAreaRef.current?.contains(relatedTarget)) { return; } setSettingsOpen(false); }; // Close on Escape and return focus to the gear button. const handlePanelKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Escape") { setSettingsOpen(false); buttonRef.current?.focus(); } }; return (
e.stopPropagation()} onPointerDown={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()} >
{ setFogEnabled(event.target.checked); }} />
{ setAudioEnabled(event.target.checked); }} />
{ setAnimationEnabled(event.target.checked); }} />
{ setDebugMode(event.target.checked); }} />
{isDemoLoaded ? null : (
setFov(parseInt(event.target.value))} /> {fov}
)} {isDemoLoaded ? null : (
setSpeedMultiplier(parseFloat(event.target.value)) } />
)}
{isTouch && (
{" "}
)}
); }