import { h } from 'preact'; import { useState } from 'preact/hooks'; import type { Interface, Widget, SignalRef } from './lib/types'; import TextView from './widgets/TextView'; import TextLabel from './widgets/TextLabel'; import Gauge from './widgets/Gauge'; import BarH from './widgets/BarH'; import BarV from './widgets/BarV'; import Led from './widgets/Led'; import MultiLed from './widgets/MultiLed'; import SetValue from './widgets/SetValue'; import Button from './widgets/Button'; import PlotWidget from './widgets/PlotWidget'; import ImageWidget from './widgets/ImageWidget'; import LinkWidget from './widgets/LinkWidget'; import ContextMenu from './ContextMenu'; const COMPONENTS: Record = { textview: TextView, textlabel: TextLabel, gauge: Gauge, barh: BarH, barv: BarV, led: Led, multiled: MultiLed, setvalue: SetValue, button: Button, plot: PlotWidget, image: ImageWidget, link: LinkWidget, }; interface CtxState { visible: boolean; x: number; y: number; signal: SignalRef | null; } interface Props { iface: Interface | null; onNavigate?: (interfaceId: string) => void; timeRange?: { start: string; end: string } | null; } export default function Canvas({ iface, onNavigate, timeRange }: Props) { const [ctxMenu, setCtxMenu] = useState({ visible: false, x: 0, y: 0, signal: null, }); function onCtxMenu(e: MouseEvent, widget: Widget) { e.preventDefault(); e.stopPropagation(); setCtxMenu({ visible: true, x: e.clientX, y: e.clientY, signal: widget.signals[0] ?? null }); } if (!iface) { return (

Select an interface from the left panel, or import one.

); } return (
{iface.widgets.map(widget => { const Comp = COMPONENTS[widget.type]; return Comp ? onCtxMenu(e, widget)} onNavigate={onNavigate} timeRange={timeRange} /> : (
onCtxMenu(e, widget)} > {widget.type}
); })}
setCtxMenu(c => ({ ...c, visible: false }))} />
); }