1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2025-present FERS Contributors (see AUTHORS.md).
4import { useState } from 'react';
20} from '@mui/material';
22import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
23import CenterFocusStrongIcon from '@mui/icons-material/CenterFocusStrong';
24import TravelExploreIcon from '@mui/icons-material/TravelExplore';
25import VideocamIcon from '@mui/icons-material/Videocam';
26import VideocamOffIcon from '@mui/icons-material/VideocamOff';
27import TuneIcon from '@mui/icons-material/Tune';
28import CloseIcon from '@mui/icons-material/Close';
29import { useScenarioStore, VisualizationLayers } from '@/stores/scenarioStore';
31// TODO: users should be able to drag the view controls button or pane to relocate it in the preview area. It should dynamically determine whether to expand upwards or downwards depending on whether it is opening from the bottom of the preview area or the top of the preview area.
33export default function ViewControls() {
42 } = useScenarioStore();
44 const [expanded, setExpanded] = useState(true);
46 // Helper to determine if we are following the currently selected item
48 viewControlAction.type === 'follow' &&
49 viewControlAction.targetId === selectedItemId;
51 const handleToggle = (key: keyof VisualizationLayers) => {
57 <Tooltip title="Open View Controls" placement="right">
65 justifyContent: 'center',
70 <IconButton onClick={() => setExpanded(true)} size="small">
71 <TuneIcon fontSize="small" />
85 flexDirection: 'column',
88 backgroundColor: 'background.paper',
91 {/* 1. Header & Camera Controls (Always Visible) */}
97 justifyContent: 'space-between',
98 bgcolor: 'action.hover',
100 borderColor: 'divider',
103 <Stack direction="row" spacing={1}>
104 <Tooltip title="Frame Scene">
105 <IconButton size="small" onClick={frameScene}>
106 <TravelExploreIcon fontSize="small" />
109 <Tooltip title="Focus on Selected">
115 focusOnItem(selectedItemId)
117 disabled={!selectedItemId}
120 <CenterFocusStrongIcon fontSize="small" />
126 isFollowing ? 'Stop Following' : 'Follow Selected'
134 toggleFollowItem(selectedItemId)
136 disabled={!selectedItemId}
137 color={isFollowing ? 'secondary' : 'default'}
142 color: isFollowing ? 'white' : 'inherit',
151 <VideocamIcon fontSize="small" />
153 <VideocamOffIcon fontSize="small" />
159 <IconButton size="small" onClick={() => setExpanded(false)}>
160 <CloseIcon fontSize="small" />
164 {/* 2. Scrollable Settings Area */}
165 <Box sx={{ overflowY: 'auto', p: 0 }}>
166 {/* SECTION: SCENE OBJECTS */}
167 <Accordion defaultExpanded disableGutters elevation={0}>
168 <AccordionSummary expandIcon={<ExpandMoreIcon />}>
169 <Typography variant="subtitle2">
173 <AccordionDetails sx={{ pt: 0, pb: 2 }}>
174 <Stack spacing={0.5}>
179 checked={visibility.showPlatforms}
181 handleToggle('showPlatforms')
186 <Typography variant="body2">
191 <Collapse in={visibility.showPlatforms}>
196 flexDirection: 'column',
204 visibility.showPlatformLabels
214 <Typography variant="caption">
223 checked={visibility.showAxes}
225 handleToggle('showAxes')
230 <Typography variant="caption">
240 visibility.showVelocities
250 <Typography variant="caption">
260 visibility.showPatterns
263 handleToggle('showPatterns')
268 <Typography variant="caption">
278 visibility.showBoresights
288 <Typography variant="caption">
296 <Divider sx={{ my: 1 }} />
302 checked={visibility.showMotionPaths}
304 handleToggle('showMotionPaths')
309 <Typography variant="body2">
320 {/* SECTION: RF LINKS */}
321 <Accordion defaultExpanded disableGutters elevation={0}>
322 <AccordionSummary expandIcon={<ExpandMoreIcon />}>
323 <Typography variant="subtitle2">RF Links</Typography>
325 <AccordionDetails sx={{ pt: 0 }}>
326 <Stack spacing={0.5}>
331 checked={visibility.showLinks}
333 handleToggle('showLinks')
338 <Typography variant="body2">
343 <Collapse in={visibility.showLinks}>
350 visibility.showLinkLabels
360 <Typography variant="body2">
367 color="text.secondary"
368 sx={{ mt: 1, display: 'block' }}
376 flexDirection: 'column',
384 visibility.showLinkMonostatic
394 <Typography variant="caption">
404 visibility.showLinkIlluminator
408 'showLinkIlluminator'
414 <Typography variant="caption">
415 Bistatic (Illuminator)
424 visibility.showLinkScattered
434 <Typography variant="caption">
444 visibility.showLinkDirect
454 <Typography variant="caption">
455 Direct (Interference)