Add synthetic array (waveform) DSP support + UX improvements

Adds full array/waveform support through the synthetic DSP engine: a
dsp.Sample value model (scalar or []float64), array ops (index, slice,
sum, mean, min, max, length, fft) with an in-tree radix-2 FFT, and static
type propagation (OpOutputType) that the editor mirrors to colour wires by
data type and flag invalid wirings. Stateful filters and lua stay
scalar-only. Adds a waveform plot mode (x-vs-index trace).

Also: errored-node hover reasons, S/N add-signal/add-node HUD shortcuts in
the synthetic editor, and view-mode widgets that blend with the canvas
background (chrome kept in edit mode).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino Ferrari
2026-06-20 17:06:55 +02:00
parent 446de7f1ee
commit f7f297c3df
18 changed files with 1470 additions and 57 deletions
+79
View File
@@ -375,6 +375,23 @@ body {
/* width/height set inline from interface dimensions */
}
/* View mode: widgets shed their card chrome (border/background/shadow) so they
blend with the canvas background. Edit mode (EditCanvas) keeps the chrome so
widgets stay visible and selectable. Internal elements (gauge arc, bar track,
plot chart, inputs) keep their own styling. */
.canvas-view-bare .textview,
.canvas-view-bare .gauge,
.canvas-view-bare .barh,
.canvas-view-bare .barv,
.canvas-view-bare .led-widget,
.canvas-view-bare .multiled-widget,
.canvas-view-bare .setvalue,
.canvas-view-bare .plot-widget {
background: transparent;
border-color: transparent;
box-shadow: none;
}
/* ── TextLabel widget ──────────────────────────────────────────────────────── */
.textlabel {
@@ -1248,6 +1265,12 @@ body {
.flow-wire-selected { stroke: #ef4444; stroke-width: 2.5; }
.flow-wire-pending { stroke: #3b82f6; stroke-dasharray: 5 4; }
/* Synthetic-editor data-type wire colouring (scoped to .synth-graph so the
Logic / ControlLogic editors that share .flow-wire are unaffected). Scalar
keeps the default slate; array (waveform) signals are purple. */
.synth-graph .flow-wire.synth-wire-array { stroke: #a855f7; }
.synth-graph .flow-wire.synth-wire-array:hover { stroke: #c084fc; }
/* Node block */
.flow-node {
position: absolute;
@@ -2002,8 +2025,64 @@ body {
display: flex;
flex-direction: column;
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
position: relative;
}
/* Quick-add HUD (S = signal, N = node) */
.synth-hud-backdrop {
position: absolute;
inset: 0;
background: rgba(10, 14, 22, 0.45);
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 12vh;
z-index: 20;
}
.synth-hud {
width: 26rem;
max-width: 80%;
background: #1a1f2e;
border: 1px solid #3a4660;
border-radius: 8px;
box-shadow: 0 12px 40px rgba(0,0,0,0.55);
display: flex;
flex-direction: column;
overflow: hidden;
}
.synth-hud-input {
border: none;
border-bottom: 1px solid #2d3748;
background: #0f1117;
color: #e2e8f0;
font-size: 0.9rem;
padding: 0.6rem 0.75rem;
outline: none;
}
.synth-hud-list {
max-height: 18rem;
overflow-y: auto;
display: flex;
flex-direction: column;
}
.synth-hud-item {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 0.5rem;
padding: 0.4rem 0.75rem;
background: none;
border: none;
color: #e2e8f0;
font-size: 0.85rem;
text-align: left;
cursor: pointer;
}
.synth-hud-item:hover { background: #243049; }
.synth-hud-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.synth-hud-item-meta { color: #64748b; font-size: 0.72rem; flex-shrink: 0; }
.synth-hud-empty { padding: 0.6rem 0.75rem; }
.wizard-header {
display: flex;
align-items: center;