1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2025-present FERS Contributors (see AUTHORS.md).
12} from '@mui/material';
13import { Antenna, useScenarioStore } from '@/stores/scenarioStore';
14import { FileInput, NumberField } from './InspectorControls';
16interface AntennaInspectorProps {
20export function AntennaInspector({ item }: AntennaInspectorProps) {
21 const previewError = useScenarioStore(
22 (state) => state.antennaPreviewErrors[item.id]
24 const { updateItem, setAntennaPattern } = useScenarioStore.getState();
25 const handleChange = (path: string, value: unknown) =>
26 updateItem(item.id, path, value);
29 <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
36 onChange={(e) => handleChange('name', e.target.value)}
38 <FormControl fullWidth size="small">
39 <InputLabel>Pattern</InputLabel>
46 e.target.value as Antenna['pattern']
50 <MenuItem value="isotropic">Isotropic</MenuItem>
51 <MenuItem value="sinc">Sinc</MenuItem>
52 <MenuItem value="gaussian">Gaussian</MenuItem>
53 <MenuItem value="squarehorn">Square Horn</MenuItem>
54 <MenuItem value="parabolic">Parabolic</MenuItem>
55 <MenuItem value="xml">XML</MenuItem>
56 <MenuItem value="file">File (H5)</MenuItem>
61 value={item.efficiency}
62 onChange={(v) => handleChange('efficiency', v)}
65 label="Mesh Scale Multiplier"
66 value={item.meshScale ?? null}
67 onChange={(v) => handleChange('meshScale', v)}
69 {previewError && <Alert severity="error">{previewError}</Alert>}
71 {item.pattern === 'sinc' && (
75 value={item.alpha ?? null}
76 onChange={(v) => handleChange('alpha', v)}
80 value={item.beta ?? null}
81 onChange={(v) => handleChange('beta', v)}
85 value={item.gamma ?? null}
86 onChange={(v) => handleChange('gamma', v)}
90 {item.pattern === 'gaussian' && (
94 value={item.azscale ?? null}
95 onChange={(v) => handleChange('azscale', v)}
98 label="Elevation Scale"
99 value={item.elscale ?? null}
100 onChange={(v) => handleChange('elscale', v)}
104 {(item.pattern === 'squarehorn' ||
105 item.pattern === 'parabolic') && (
109 value={item.diameter ?? null}
110 onChange={(v) => handleChange('diameter', v)}
113 label="Design Frequency (Hz)"
114 value={item.design_frequency ?? null}
115 onChange={(v) => handleChange('design_frequency', v)}
120 {(item.pattern === 'xml' || item.pattern === 'file') && (
122 {/* TODO: Support authoring antenna XML in-app. That requires a real editor flow plus UI/store/schema
123 changes for antenna asset contents, rather than treating XML antennas as opaque filename-only assets. */}
126 value={item.filename}
127 onChange={(v) => handleChange('filename', v)}
130 name: 'Antenna Pattern',
132 item.pattern === 'xml' ? ['xml'] : ['h5'],
134 { name: 'All Files', extensions: ['*'] },