Seperating the sequencer into multiple widgets.

This commit is contained in:
Johannes Findeisen 2026-11-06 21:39:38 +01:00
commit e664414796
23 changed files with 1455 additions and 914 deletions

View file

@ -65,6 +65,63 @@ commands and publish independent compiled snapshots. See GUI.md.
---
## Sequencer Widget Ownership
`SequencerWidget` is the master FLTK group. It owns the timeline coordinate
system, grid/background, selection, zoom, scrolling extent, expansion state,
shared edit hooks and gestures that cross tracks. Drawing and local input belong
to child widgets:
```mermaid
flowchart TD
S[SequencerWidget] --> R[SequencerRulerWidget]
S --> T[SequencerTrackWidget per track]
T --> H[SequencerTrackHeader]
H --> I[Fl_Choice instrument selector]
T --> C[SequencerClipWidget per clip]
T --> V[SequencerVelocityWidget]
```
FLTK groups own and destroy their children. The master's track index and each
track's clip index contain borrowed pointers; they do not independently delete
children. Views reconcile copied C metadata by stable IDs when edits, project
installation or drawing refresh the timeline. Surviving track views retain their
identity through reorder and undo; clips moved between tracks acquire a view
under their destination group. No child keeps a borrowed pointer into a C
project snapshot. Removed views are detached, hidden and scheduled with
`Fl::delete_widget`, allowing the current event handler to return safely.
A project replacement cancels captured gestures before refreshing the hierarchy.
The ruler handles seeking and loop selection. Track groups manage row layout;
headers handle disclosure/selection and own instrument controls. Clip widgets
draw notes or cached waveforms and start selection/move/trim gestures; the
master completes cross-track edits. Velocity children own MIDI/audio previews
and local point/bar hit testing. All mutations still use the master's
before-edit and changed callbacks, preserving C history, transport stopping and
plan publication. Instrument keyboard focus is handled before timeline shortcuts.
Implementation map:
| Files in `src/gui/` | Responsibility |
| --- | --- |
| `sequencer_widget.hpp/.cpp` | Master API, layout/reconciliation, shared selection, gestures and timeline overlays |
| `sequencer_track_widget.hpp/.cpp` | Track groups, pinned header groups and nested instrument selectors |
| `sequencer_clip_widget.hpp/.cpp` | Clip drawing and local selection/gesture initiation |
| `sequencer_velocity_widget.hpp/.cpp` | MIDI velocity bars and continuous audio gain envelopes, including preview state |
| `sequencer_ruler_widget.hpp/.cpp` | Bar/marker labels, loop display, seeking and loop gestures |
| `sequencer_commands.cpp` | Editing commands and dialogs exposed by the master |
| `sequencer_instruments.cpp` | Instrument catalog and selector callbacks |
| `sequencer_waveforms.cpp` | Shared control-thread waveform cache and waveform drawing |
| `sequencer_group_scope.hpp` | Restore FLTK's implicit parent around dynamic child construction |
`cmake/Gui.cmake` lists all implementation files explicitly in `xtc-gui`.
The hierarchy adds no dependency, C API, project format or audio-thread work.
GUI integration checks cover actual parent relationships, stable track views,
FLTK window-dispatched clip/velocity drags, cross-track movement, deferred
removal, project replacement during a captured gesture and undo/redo.
---
## Editable Graph and Canvas
Read-only C snapshots, monotonic node IDs, and a small set of C edit commands

View file

@ -120,6 +120,11 @@ cmake --build build --target analyze
cmake --build build --target quality-preview builtin-preview
```
The `xtc-gui` target explicitly includes the sequencer master, track/header,
clip, velocity and ruler implementations, plus command, instrument and waveform
support files. See the [component map](ARCHITECTURE.md#sequencer-widget-ownership)
when adding GUI sources; update `cmake/Gui.cmake` alongside new implementation files.
Each registered root test also has a `test-NAME` build target (for example
`test-core`, `test-gui`, `test-track-fx`). `test-builtins` aliases `test-builtin`.
`gui` builds the optional main application. Preview targets write WAVs below the

View file

@ -148,6 +148,25 @@ 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.
### Sequencer components
The sequencer is a master `Fl_Group` containing a ruler and one group per track.
Each track contains clip widgets, a velocity lane, and a pinned header group
with its instrument selector. Local drawing and input live with those children;
the master coordinates selection, scrolling, zoom and cross-track edits.
See [widget ownership and source files](ARCHITECTURE.md#sequencer-widget-ownership)
for the implementation map and lifetime rules.
Click the small track-header arrow to expand a track downward. MIDI tracks
expose note velocity bars (1–127); drag a cap to edit a note. Audio tracks expose
the saved track-gain envelope (0–400%): click at any timeline position to add a
point, drag vertically to adjust it, or right-click a cap to remove it. Audio
positions ignore the snap grid. Escape cancels a preview; undo/redo restores
committed edits. Instrument selectors retain their own keyboard focus.
Expansion is temporary view state; audio gain points are shared with the mixer
and saved with the project. This component refactor preserves the existing
workflow and project format.
---
## Audio Workflow

View file

@ -216,6 +216,9 @@ xtc/
└── build/ # generated; do not commit
```
The implemented sequencer now uses nested track, header, clip, velocity and
ruler widgets; see the [current source and ownership map](ARCHITECTURE.md#sequencer-widget-ownership).
Keep C and C++ files clearly separated. C headers exposed to C++ must use
`extern "C"` guards.

View file

@ -3656,6 +3656,55 @@ and inspection of the actual [audio envelope capture](../screenshots/audio-veloc
---
## Phase 111 — Sequencer Master and Child Widgets
### Goal
Split the sequencer GUI into focused components. Keep `SequencerWidget` as the
master with real nested FLTK track, header, clip, velocity and ruler widgets,
preserving current editing behavior, the C domain boundary and saved projects.
### Tasks and acceptance criteria
- [x] Make the master own ruler and track groups; each track owns its header,
instrument selector, clip widgets and velocity lane through FLTK ownership.
- [x] Move child drawing and local input into dedicated track/header, clip,
velocity and ruler implementation files. Keep shared coordinates, selection,
scrolling and cross-track gesture completion in the master.
- [x] Extract editing commands/dialogs, instrument support and waveform caching
into separate source files and register them explicitly in CMake.
- [x] Reconcile views by stable C IDs, preserving surviving track identity through
reorder/undo and moving clip views into the destination track hierarchy.
- [x] Cancel gestures on project replacement and defer removed widget deletion
until event handlers can return; preserve instrument focus and shortcuts.
- [x] Exercise real parent/child membership, cross-track movement, velocity edits,
undo/redo, removal and project replacement through GUI integration tests,
including FLTK window-level event dispatch.
- [x] Update the architecture/component map, GUI guide, build guidance, README
and integration-test documentation.
### Implementation status
Implemented on 2026-11-06. The master now delegates track/header, clip, velocity
and ruler drawing/input to child classes; commands and support code are separate
translation units. See [the ownership and source map](ARCHITECTURE.md#sequencer-widget-ownership).
FLTK owns the hierarchy; indexes and captured-gesture pointers are borrowed.
Child views hold copied C metadata rather than pointers into project snapshots.
Removed children are detached/hidden and deleted through FLTK's deferred queue.
The master remains the single selection and edit/publication coordinator.
No dependency, core API, persistence or intended visual/workflow change is
introduced. Existing screenshots continue to describe the same interface.
Validation: the warning-enabled CMake build succeeds, all 55 existing CTests
pass, and the added `gui-sequencer` hierarchy/dispatched-gesture check passes.
The final build's main GUI and focused hierarchy tests were also rerun successfully.
The focused hierarchy/lifetime test passes Clang ASan/UBSan with leak detection
disabled for the unsanitized system FLTK library. Both audio-envelope captures
remain pixel-identical to the existing gallery. Physical hardware qualification
is unaffected.
---
## Recommended Execution Order
Reorder the phases when the audit reveals a blocking dependency. Do not mark a