import { Button } from '../ui/Button'; import { Panel } from '../ui/Panel'; import type { MachineRegistryEntry } from '../../modules/machines/schema'; import { DISPLAY_MODES, CROSS_SECTION_AXES } from '../../types/viewer'; import type { CrossSectionAxis, DisplayMode } from '../../types/viewer'; import { useViewerStore } from '../../store/viewerStore'; interface ControlPanelProps { machine: MachineRegistryEntry; } const displayModeLabels: Record = { solid: 'Solid', wireframe: 'Wireframe', xray: 'X-ray' }; const crossSectionLabels: Record = { none: 'None', x: 'X axis', y: 'Y axis', z: 'Z axis' }; export function ControlPanel({ machine }: ControlPanelProps) { const isPlaying = useViewerStore((state) => state.isPlaying); const rpm = useViewerStore((state) => state.rpm); const timeScale = useViewerStore((state) => state.timeScale); const cycleStepIndex = useViewerStore((state) => state.cycleStepIndex); const explodedDistance = useViewerStore((state) => state.explodedDistance); const displayMode = useViewerStore((state) => state.displayMode); const crossSectionAxis = useViewerStore((state) => state.crossSectionAxis); const crossSectionOffset = useViewerStore((state) => state.crossSectionOffset); const showAnnotations = useViewerStore((state) => state.showAnnotations); const togglePlayback = useViewerStore((state) => state.togglePlayback); const restartAnimation = useViewerStore((state) => state.restartAnimation); const stepCycle = useViewerStore((state) => state.stepCycle); const setRpm = useViewerStore((state) => state.setRpm); const setTimeScale = useViewerStore((state) => state.setTimeScale); const setExplodedDistance = useViewerStore((state) => state.setExplodedDistance); const setDisplayMode = useViewerStore((state) => state.setDisplayMode); const setCrossSectionAxis = useViewerStore((state) => state.setCrossSectionAxis); const setCrossSectionOffset = useViewerStore((state) => state.setCrossSectionOffset); const setShowAnnotations = useViewerStore((state) => state.setShowAnnotations); return (

Controls

Playback and display controls use the shared animation contract for every machine.

Playback

setRpm(Number(event.currentTarget.value))} step="10" type="range" value={rpm} />
setTimeScale(Number(event.currentTarget.value))} step="0.1" type="range" value={timeScale} />

Cycle step index: {cycleStepIndex}

Display

{DISPLAY_MODES.map((mode) => ( ))}
setExplodedDistance(Number(event.currentTarget.value))} step="0.05" type="range" value={explodedDistance} />
Annotations

Cross-section

setCrossSectionOffset(Number(event.currentTarget.value))} step="0.05" type="range" value={crossSectionOffset} />
); }