SND · component library

The aGooey UI toolkit

Every graphic SND draws — knobs, faders, meters, LEDs, tactile keys, menus, modal dialogs, graph nodes, a keyboard, an XY pad, a step grid, a sequencer matrix — rendered here from the same shared paint vocabulary that powers snd::ui::retained, Dear ImGui compatibility, and the renderer-neutral draw::Surface path.

Try it —drag the knobs & faders (hold ⇧ Shift for 10× fine adjust), grab the XY handle, play the keys, click the switches and grid cells. The meter and the mod ring run on their own.
Accent

Knobs

paint::drawKnob · KnobStyle

Five hardware-oriented styles. Ring / Seq — the sequencer ring (Seq has flat, square-capped ends and no thumb dot). Synth — flat dished disc + track ring + value arc + pointer tick. Davies — moulded cap with a full tick ring. NxD — the scalloped case that rotates with the value, with a tick ring and bold pointer. Drag any knob up / down.

ring
Ring
seq
Seq · square ends
synth
Synth
davies
Davies
daviesface
Bob1 face · 0–10 scale + readout
nxd
NxD · scalloped
ringbi
Ring · bipolar
ringdis
disabled

Knob modulation ring

paint::drawKnobModRing · KnobMod

A second thin arc shows modulation depth from the value; the dot is the live modulated position. SND draws the overlay after any body — built-in styles or custom painters — then the focus ring, so modulated knobs keep one shared look. Drag the knobs — the LFO keeps riding the new value.

modknob
Ring · depth +0.30
modknob2
Davies · depth −0.25
modknob3
custom painter + mod

Randomise window

paint::drawKnobWindow · drawComboWindow · KnobWindow

Randomise fences: every control carries an independent {lo, hi, locked} window — an arc with two separately grabbable end dots over knobs, an index bracket under combos, and a padlock when locked out of RND. Draw + hit-test live in SND; the overlay mode and drag state stay with the caller. Drag an end dot (up / down on the knob, along the bracket on the combo) — click without dragging to lock.

ghostk
knob window · Seq ring
ghostc
combo bracket

Fader

paint::drawFader

Channel fader — centre rail, accent fill below the cap, cap brightens while grabbed. Drag a cap up / down — hold ⇧ Shift for 10× fine.

fader0
fader1
fader2
fader3

Toggle

paint::drawToggle

Sliding switch; the track lerps to the accent as the nub travels. Click to flip.

toggle
toggleon
toggleoff

Buttons

paint::drawButton · drawOutlineButton

The flat control button — SND's button for text labels, tabs and menu actions. The accent underline marks the selected one. Shown across its states:

default
hover
active
selected
disabled

Outline buttons are the quiet option: no fill and no resting border by default, with fill, text and border colours selectable per state.

no fill
hover border
active fill
selected
custom colours

Transport buttons

widgets::transportButton · paint::drawTransportGlyph

The building block of a transport bar: the outline-button chrome with a crisp vector transport glyph (drawn, not a font), picked by intent (Icon::Record, Play, Stop, Loop). The engaged fill marks the state — blue for play/cycle, and record goes red, its ring filling to a disc while armed. Fires on mouse-down for no-latency feel. Hover them.

record
recording
play
playing
loop
cycling

Segmented

snd::ui::segmented · paint::drawSegmented

A pill group of mutually exclusive options — mono/stereo, filter slope, A/B. One selection; Left/Right arrows move it when focused; equal-width segments sized to the widest label. Click a segment.

seg
3 options
segab
A / B
segdis
disabled

Glyph strip

snd::ui::glyphStrip · paint::drawGlyphStrip

Segmented with vector glyph keys instead of text — the synth oscillator-wave and LFO-shape selectors, drawn 1:1 from the Bob1 glyph geometry. Same binding and interaction as segmented; the speaker key is a plain transport toggle for the LFO audio-rate switch. Click a wave.

glyphosc
osc waves
glyphlfo
LFO shapes + S&H
speakerkey
audio-rate key

LED switch

snd::ui::ledSwitch · paint::drawLedSwitch

The Bob1 ProphetSwitch: silkscreen label over a red lamp over the meaty tactile key. The lamp carries the state — the key only shows the press. Mini and full are the same widget at different sizes. Click the key.

ledswon
full · on
ledswmini
mini · off

Switch matrix

snd::ui::switchMatrix · paint::drawSwitchMatrix

Bob1's labelled option columns (filter MODEL / MODE / POLES): every option printed with a mini lamp, the active one lit red, radio-select. One column up to five options, two above. The binding is the selected index, exactly segmented's. Click an option.

swmatrix
one column
swmatrix2
two columns

Stepper

snd::ui::stepper · paint::drawStepper

The Bob1 nameplate [-] value [+] key pair (BEND, VOICES). Click a key or use Left/Right when focused; steps by the binding step and clamps to the range. Click - or +.

stepperw
BEND · 12 st

Cycle button

snd::ui::cycleButton · paint::drawCycleButton

A multi-state value button: click cycles the enum in place, right-click steps back — one control, no dropdown. Pips mark the position in the cycle, and the button is sized to the widest option so nothing jumps. Click / right-click.

cyc
filter slope
cyc2
rate multiplier

Animated & custom paint

animatedButton · ButtonPainter · KnobPainter · XYPadPainter · PatternCellPainter

Generation/action buttons can carry a subtle live sweep, while custom painter hooks let a consumer draw a knob, button, XY-pad, or pattern-grid-cell body without owning hit-testing, focus, keyboard, value mapping, or accessibility. SND draws the required focus treatment after the painter runs. The gradient knob and velocity cells below also use the shared drawGradientArc / drawGradientRect primitives.

animatedButton
custom ButtonPainter
custom
custom KnobPainter
gradknob
gradient-arc painter
velgrid
PatternCellPainter · velocity
puck
XYPadPainter · puck map

Tactile key

paint::drawTactileIconButton

The other button family — a hardware key for icon & tool buttons (transport, momentary/toggle tools), not text. Light-grey raised, presses into a soft off-white inset with the glyph lit in the accent. Press one. Text buttons stay on the flat style above — tactile isn't every button.

play
stop
tune
held
lucide

LED button

snd::ui::ledButton · paint::drawLedButton

The tactile key with an integrated status ring — record-arm, input monitor, transport latches. Latched buttons hold the inset face with the ring lit in the accent; arm pulses while pending. Click to latch / release.

ledrec
record · latched
ledarm
arm · blinking
ledmon
monitor · off

LED

paint::drawLed

Status lamp with a soft bloom when lit. Click to toggle.

ledblink
signal
ledon
on
ledoff
off

Meter

paint::drawMeter

Peak meter with the classic green / amber / red hardware zones and a peak-hold line. Vertical and horizontal — this is the one that runs on its own, on simulated program material.

meterL
L
meterR
R
meterH
bus · horizontal

Badge & section header

paint::drawBadge · drawSectionHeader

Small labels: a tinted pill and a dim caption with a trailing rule.

aGooey VST3 MIDI
header

List item

paint::drawListItem

Selectable row — the accent rail and tint mark the current selection while text stays aligned. Click a row.

Kick 909
Snare — rimshot
Hat closed
Clap

Value row & drag number

paint::drawValueRow · dragNumber

Compact readouts and horizontal drag values share the same value-row paint in immediate and retained modes. Drag numbers keep model state caller-owned; SND owns the row body, focus and fine-drag affordance.

Osc Pitch+7.00 st
Cutoff0.72
Voice Modepoly
Drive3.4 dB

Pattern grid

paint::drawPatternGrid

Step sequencer grid — lit cells in the accent, a checkered off-state on the beat. Click cells to toggle steps.

grid

XY pad

paint::drawXYPad

Two-axis control with a cross-hair and a lit handle. Drag anywhere in the pad.

xy

Envelope / Canvas

paint::drawEnvelope · retained Canvas

Breakpoint curves use the shared envelope painter. In retained mode this is the shape of a Canvas-backed editor: the node owns layout, focus, hit and semantic space while custom drawing owns the pixels. Drag a point.

env

Keyboard

paint::drawKeyboard

Playable range — white and black keys light in the accent. Click / drag across the keys to play.

keys

Sequencer matrix

MatrixGridGeometry · SequencerMatrix · GhostFence

Retained audio-editor primitives for sequencers and table editors: shared matrix geometry, continuous bars, gate cells, route cells, band spans, playhead, selections, drag preview, help labels, and pass-through ghost fences. Drag rows in the matrix.

matrix
Measured geometry

One object returns row, gutter, cell, and playhead rects for paint, hit-test, and semantics.

Row policies

Continuous bars interpolate across skipped columns; gate and route rows drag-paint.

Overlays

GhostFence, Help, Playhead, Selection, and DragPreview draw above rows without stealing input by default.

aGooey render surface

snd::ui::retained · draw::Surface · GlWindow

aGooey is the retained UI path: stable nodes, layout, focus, events, dirty state, semantic snapshots, and renderer-neutral painting. The C++ namespace remains snd::ui::retained; the public drawing seam is snd::ui::draw::Surface.

Pure retained GL

GlWindow renders retained trees without a Dear ImGui context.

Shared paint

Immediate compatibility and aGooey use the same palette, focus rings, icons, and control geometry.

Headless proof

RecordingSurface records operations for tests without pretending to be visual QA.

Semantics

Controls publish roles, names, values, checked/disabled state, actions, and virtual children for spatial surfaces.

fillRectstrokeRecttextimagebezierCubicpolylineGradientpushClipmeasureText

Modal dialogs

modalOverlay · modalDialog · alertDialog · confirmDialog

Retained blocking overlays with dim, blank, or no visual backdrop, centred dialog chrome or custom panel content, real button children, Escape policy, Tab focus trap, inert background input, and Dialog/Alert semantics.

graph surface
module list
transport
meter bank
pattern grid
value rows

Delete module?

This removes the module and its cables. Background controls are inert until Cancel, Confirm, Escape, or the configured scrim policy resolves the dialog.

Graph surface

widgets::graphSurface · drawGraphGrid · drawCable · drawModuleBox

Retained graph surfaces own pan/zoom, grid/backdrop, selection, cables, module chrome, ports, hit regions, anchored context menus, keyboard traversal, and virtual semantic children. The caller owns graph data and mutations.

graphNeo
Neo skin · grid backdrop · cable preview
graphAurora
Aurora backdrop · selected module · ports

Text field & value field

widgets::textField · widgets::valueField

Pure retained text editing: caret, selection, keyboard editing, semantic value text, and caller-owned strings. Value fields use the same compact row language as drag numbers when editing numeric values.

oscillator.name = "sub fold"
Gain-6.0 dB
Modelatch

Scroll view & splitter

widgets::scrollView · widgets::splitter

Retained layout primitives for real tool surfaces: scroll views keep content clipped with semantic children intact, and splitters bind to caller-owned proportions so panes rebuild from app state.

Device Aready
Oscillator2 outs
Filtermod
Delaysync
Recorderarmed
InspectorNode controls, meters, actions.
GraphSurface, cables, modules.

Icon catalogue

Material · Apache-2.0  /  Lucide · ISC

Every embedded icon selector from snd/icons.h. Material glyphs work inline with ICON_MD_*; Lucide glyphs use ICON_LC_* with iconFontLucide(). Search by selector, display name, or codepoint.

SND vector icon buttons · snd::ui::Icon
viPlay
Icon::Play
viStop
Icon::Stop
viRecord
Icon::Record
viStart
Icon::SkipToStart
viEnd
Icon::SkipToEnd
viLoop
Icon::Loop
viWaveform
Icon::Waveform
viSpectrum
Icon::Spectrum
viFollow
Icon::Follow
Rendered from the SND toolkit: controls trace snd::ui::paint geometry, icons come from third_party/fonts, and new retained surfaces draw through snd::ui::draw::Surface. aGooey is the preferred retained path; Dear ImGui remains the compatibility layer for existing immediate-mode hosts.