xtc/docs/GUI.md

64 lines
3.7 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, creates domain objects, or calls JACK
itself. 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. With no graph submitted, the running backend produces silence.
- **Play / F5:** start the engine. **Stop / F8:** deactivate it. **Space:** toggle.
These are engine controls, not timeline playback or transport positioning.
- **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. Editors remain clearly
labeled placeholders; no project editing is implied.
- **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. Unsupported New/Open/Save actions are
visibly disabled. 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.