1
0
Fork 0
forked from hanez/xtc
xtc/docs/GUI.md

214 lines
13 KiB
Markdown

# GUI guidelines
Use FLTK/C++ for windows, menus, dialogs, and the event loop. Keep all audio
engine and project-domain logic in C.
Main views:
- Sequencer: tracks, clips, ruler, playhead, selection, zoom and scrolling.
- Mixer: channels, faders, pan, mute/solo and meters.
- Modular graph: nodes, ports, connections, validation feedback.
- Transport: play/stop/record, tempo, meter, loop and position.
Use custom-drawn widgets where ordinary controls are not a good fit: timeline,
waveforms, piano roll, mixer strips and graph canvas. Keep drawing separate
from project mutation. Never call FLTK from the audio thread.
Visual direction: compact, high-contrast, restrained dark interface. Avoid
excessive animation and modal configuration. Recreate broad usability ideas,
not energyXT's exact artwork or proprietary resources.
## Phase 3 shell
The shell opens JACK on startup through `xtc_backend.h`. It never accesses
backend structures, processes samples, or calls JACK itself. Graph domain
data is owned by opaque C objects, manipulated only through the C API. All backend control calls run on the GUI thread; FLTK is never called
from an audio callback. No server is started and no audio ports are connected
by the GUI. The initially empty graph produces silence.
- **Play / F5:** start the engine. **Stop / F8:** deactivate it. **Pause / F7:** hold playback. **Space:** toggle Play/Stop.
**To start / Home:** stop and seek to zero. Pause/Home are disabled while recording.
These advance/pause the sample-counted playhead; imported audio clips play through their graph source.
- **Reconnect / F6:** close the old client and open a fresh stopped client.
Use this after server loss or sample-rate changes. A failed close preserves
the handle and reports the failure instead of opening another client.
- **View menu / Ctrl+1, Ctrl+2, Ctrl+3:** switch between sequencer, mixer and
modular graph. Tabs provide the same view switching. Mixer, graph and sequencer editors are described below.
- **File / Quit / Ctrl+Q** or the window close button: close the backend and
synchronize audio callbacks before hiding/destroying widgets. A failed close
leaves the window open for a retry. New/Open/Save actions are described below. About identifies the development milestone and version.
The indicator shows disconnected, ready, running, server lost, format changed
or process-error states. The status line shows rate, actual block size, mono
layout, processed block count, xruns and process result. Command errors remain
visible until a successful control action; periodic refresh does not erase them.
A GUI-owned 100 ms timer reads atomic snapshots and collects retired plans.
Label text changes only when needed. The timer is removed before successful
close and again by the window destructor. No GUI locks are held across control
calls. Operations such as opening JACK can briefly block the GUI; there is no
worker/control-thread framework in this initial shell.
MainWindow owns the backend handle and FLTK owns the window's children. The
destructor also attempts cleanup on exceptional event-loop exit; if JACK close
itself fails then, it reports to stderr and retains the callback context until
process exit. Normal close/reconnect paths permit retry and release ownership
only after successful close. The entry point catches C++ exceptions before
process exit. Backend operations return C error codes throughout.
Tests: `make test-gui` runs real widgets/callbacks/timers against a fake C backend
under Xvfb, including control errors, startup without JACK, partially initialized
handles, server/format notifications, view switching, retrying close, and timer
removal. `make test-gui-jack` additionally requires a running JACK-compatible
server, tests repeated start/stop, reconnect and active-client close, and creates
no routes. Physical playback is outside this shell. See BUILD.md and the
integration test README for sanitizer limitations and keyboard smoke results.
## Phase 4 modular editor
Open **Modular Graph** or press **Ctrl+3**. Add oscillator (440 Hz), gain (0.10),
pass-through meter or output nodes with the toolbar. Their parameters are fixed
presets in this milestone and are drawn on each node; parameter editing and
live meter display are not implemented. Connect oscillator → gain → meter →
output for a simple test chain. No sound reaches hardware until ports are
explicitly connected outside the GUI. Output nodes are required to render;
isolated sources and an empty graph produce silence.
Drag a node body/title to move it. Drag a circular output port to an input port
to connect. Click a node or wire to select it (yellow outline/wire), then press
Delete/Backspace or **Delete selection**. Deleting a node deletes its incident
wires. Escape cancels a drag preview. Canvas scrollbars pan the view; positions
are retained across edits/reconnect but not across application restart. There
is no graph zoom, multiselection or external hardware routing UI. Semantic
graph edits participate in project undo/redo; layout does not. The default
project supports 64 nodes; auto-layout can grow the scrollable canvas.
Every semantic action becomes a C graph command. The window owns a C project containing the graph
handle and publishes the C-created candidate through the backend. Cycle,
invalid-direction, duplicate connection, missing-port, capacity and backend
failures are shown below the canvas; failed edits leave the graph unchanged.
Capacity feedback distinguishes the possible node limit/pending edit condition
and allows retry. Editing while stopped replaces the prepared plan without
starting playback. Editing with a disconnected startup backend stays local
until reconnect. A lost or changed live backend requires reconnect before
further semantic edits. Moving/selecting nodes does not touch the engine.
The graph state line distinguishes offline, prepared, queued and active states.
Queued explicitly means the drawing represents the next submitted graph while
the engine finishes the previous plan. The 100 ms GUI timer observes audio
adoption revisions and then shows active. Graphs are not edited in place on the
audio thread. There is no automatic retry/hidden edit queue; users retry a
rejected capacity edit. Plan replacement can reset oscillator phase and is not
crossfaded. Render validation and active replacement tests are described in
tests/integration/README.md.
## Phase 5 projects and sequencer
File/New (Ctrl+N), Open (Ctrl+O), Save (Ctrl+S), and Save As
(Ctrl+Shift+S) use native file dialogs and the C persistence API. New/Open/Quit
offer Cancel/Discard when semantic edits are unsaved; save first to retain them.
Save As confirms overwrites. The title marks unsaved changes. Failed loads and
backend submissions retain the old document. Loading parses before stopping
audio; installing a valid candidate stops and resets transport before compiling
and submitting. A later failure can leave the retained document stopped at zero.
Opening/New resets graph layout; graph positions are not saved. See PROJECT_FORMAT.md.
Sequencer offers Add track, Add region, Delete region/track, Zoom +/-. Select a
track header to add a one-bar region there at the cursor. Select a region to
delete it; deleting a selected track cascades to its regions. Delete also works
with canvas focus. Drag a region body to move it in time or between tracks;
drag either edge to trim within its original source bounds. Edits commit on
release with 1/16-note snapping; Escape cancels. There is no drag preview, undo,
multiselection, rename or tempo editor yet. Overlapping regions are permitted.
The scrollable canvas expands to cover the arrangement plus a margin; zoom
ranges from 24 to 384 pixels/quarter. Names, tempo and 4/4 meter are drawn.
A ruler click seeks while stopped (or positions the cursor when disconnected).
The 100 ms GUI refresh converts the backend's actual sample counter to ticks;
it never integrates wall-clock time. Play resumes and Stop pauses. Reconnect,
New and Open reset position. Add region creates silent metadata; imported WAV clips play through the
audio source node (Phase 6 below). MIDI clips and notes are described below. The C model
supports a constant tempo; a tempo map and scheduler are future work.
Tests cover C-model/persistence boundaries, GUI move/trim gestures and zoom,
save/reopen, failed load/submission rollback, sample-derived cursor updates,
and live JACK playhead advance/pause.
## Phase 6 audio workflow
Use File/Import WAV (Ctrl+I) to add an audio clip at the playhead on the selected
track, or on a new Audio track. Record (Shift+F5) chooses a WAV destination and
captures JACK input until Stop finalizes and adds the take. No input routes are
created automatically. Save after Stop; the project references the external WAV.
Import creates an Audio clips graph source and output route if the source is
absent. Modular Graph offers Add audio source for explicit routing through gain
or meter nodes. All tracks currently share one mono timeline mix. Arrangement
edits stop playback; graph edits remain live outside recording. During recording,
edits, file actions, reconnect and close require Stop first.
Open/Play reports missing, unreadable or unsupported assets, preserving their
regions as silence. The backend status shows the unique issue count. Select a
clip and use File/Relink selected audio to choose another path; Play validates
the replacement. Playback uses preloaded immutable samples; imports and loads
can block the GUI while reading, but never the audio callback.
See AUDIO_FILES.md for supported WAV formats, memory limits, musical placement,
recording overflow/partial-take recovery, external asset portability and the
software-only acceptance tests. Waveform drawing, input monitoring, recording
latency compensation and per-track graph inserts are not implemented.
Per-track gain/pan/mute/solo is available in Phase 8 below.
## Phase 7 piano roll
Add MIDI clip creates a one-bar clip on the selected/first existing track at the
cursor. Select it and choose Piano roll (View/Piano roll, Ctrl+4). Click to draw,
drag a body to move pitch/time, drag its right edge to resize, and right-click
or Delete to remove. Notes use source ticks with 1/16 snapping; trimmed source
content is retained. Edits stop transport and are blocked during audio recording.
Panic/F9 silences held notes; Record continues to mean WAV audio capture.
Modular Graph offers Add instrument for explicit routing. Status includes MIDI
drops. See MIDI.md for voice limits, unsupported messages and live input routing.
## Phase 8 mixer and editing
Mixer (Ctrl+2) now has a selectable track strip, gain/pan controls, mute/solo,
Output L/R peaks and editable gain/pan automation lanes. Mixer edits stop
playback. Click the lane to add/replace points, right-click near a point to
remove, and change First tick to navigate. Ctrl+Z, Ctrl+Shift+Z and Ctrl+Y undo
and redo up to 32 project edits; New/Open resets history. M/S and arrow keys
provide mixer shortcuts. See MIXER.md for exact controls, history rollback,
stereo port routing, automation semantics and prototype limits.
## Phase 11 minimal composition workflow
[WORKFLOW.md](WORKFLOW.md) walks through creating, arranging, saving, closing,
reopening and playing MIDI/audio with the GUI. New/Open select Sequencer;
Ctrl+3 still opens the modular graph. Stop retains its established position-hold
behavior and finalizes recording; explicit Pause retains position without
finalizing a take (and is refused during recording). Home stops and returns to
zero. Failed candidate installation now refreshes the actual backend state
even when the previous document is retained.
`make test-workflow` uses a live JACK-compatible backend and Xvfb, with exact
stereo render comparisons across destruction/recreation of the GUI and live
playhead/meter/transport checks. `test-gui` covers stop/seek failure and recording
guards. No project files need manual editing for this workflow.
## Phase 12 timing and transitions
The GUI enables 5 ms source boundaries and master start/stop ramps. Ordinary
Pause/Stop now request a fade and show “stopping” until the timer collects its
acknowledgement and deactivates JACK. Recording Stop, Home, fault handling and
project installation retain immediate semantics. See
[AUDIO_QUALITY.md](AUDIO_QUALITY.md) for timing, overload/denormal behavior, latency
limits, test commands and the pending human-listening checklist.
## Phase 23 routing refinement
Graph selection now reports edge counts, output reachability and external-input
fallback. Direction arrows, role colors, incident-wire highlighting and no-output
badges help inspect routes. View / Arrange graph by signal flow (L) is a layout
command; Edit / Insert unity gain in selected wire (I) is one undoable graph edit.
Left/Right selects nodes; Tab retains ordinary focus navigation. See [ROUTING.md](ROUTING.md) for summing, stereo-lane,
cycle, live publication and deferred grouping/template semantics.