Add Design View phase spec (Phase D), parallel to capture roadmap

CONTEXT.md: additive Design View technical spec section.
PLAN.md: additive Phase D (D1-D5) milestone breakdown.
docs/product/design-view.md: product framing, N-mode reasoning,
screenset differentiation, design-direction calls.
This commit is contained in:
2026-07-22 19:55:23 -04:00
parent a9ba532f07
commit 06256f05e9
3 changed files with 580 additions and 0 deletions
+98
View File
@@ -126,3 +126,101 @@ landed milestone.
`int64_t → int` via `static_cast` without a range check; integers that fit
in int64 but exceed `INT_MAX` are implementation-defined. Hardening candidate
— add bounds check before the cast when integer-field validation is in scope.
---
# Phase D — Design View (parallel to the M0M11 capture roadmap)
> **Separate phase namespace.** The M-numbers belong to the capture pillar
> (M0M11, M4 in flight). Design View is an orthogonal feature on its own track,
> so it uses a **lettered** namespace (D1, D2, …) rather than extending the M-line.
> This keeps the two roadmaps from colliding on numbering and reads correctly:
> Phase D is not "the twelfth capture step," it's a different pillar. Authoritative
> spec: **CONTEXT.md §Design View**. Product framing: `docs/product/design-view.md`.
> When a point lands, doc-keeper moves it to `COMPLETED.md`.
## D1 — view_model (pure)
**Goal:** REAPER-free mode registry + membership index + folder-tree-aware
visibility derivation + parking/restore planner + JSON round-trip. The heart of the
phase; mirror of `bank_model`. CONTEXT.md §Design View (Module architecture — pure).
**Verify:** CTest green. N-mode model (not a boolean); Arrange + Design seeded.
Restore-planner round-trip (snapshot → park → restore) returns every driven flag to
its captured value. Parent-derivation correct against a supplied folder tree.
JSON round-trip lossless across modes + membership + show-both + snapshots + active
mode.
- [ ] Mode registry: ordered (id, display name, ordinal); Arrange + Design seeded;
add/query more modes (prove N-mode, not binary).
- [ ] Membership index: `GUID → { mode ids }` + per-track show-both flag;
add / remove / retag / query; untagged = Arrange.
- [ ] Folder-tree-aware visibility derivation: given a supplied parent↔child tree +
active mode, compute the visible set (active leaves, derived-visible parents,
show-both leaves, master always in).
- [ ] Parking/restore planner: emit exact (track, flag, value) op-lists for park and
restore from active mode + snapshot record.
- [ ] JSON round-trip: modes + membership + show-both + snapshots + active mode.
- [ ] Tests: N-mode add/query; parent follows tagged leaf (multi-mode parent);
restore-round-trip returns snapshot values (never hardcoded "on"); show-both leaf
never parked; unknown/stale GUID tolerated; JSON lossless.
## D2 — view shell (apply flags in the DAW)
**Goal:** Read the folder tree and drive REAPER flags per the planner.
CONTEXT.md §Design View (view shell, REAPER API surface).
**Verify (in DAW):** Toggling active mode hides + parks inactive leaves
(`B_SHOWINTCP`/`B_SHOWINMIXER`/`B_MAINSEND`/`I_FXEN` + per-FX offline) and restores
active ones from snapshot. **Master untouched. `B_MUTE`/`I_SOLO` untouched.**
Untagged tracks untouched. Parents follow their tagged descendants.
- [ ] Build parent↔child tree from `I_FOLDERDEPTH`; feed to `view_model`.
- [ ] Snapshot prior flag values (`GetMediaTrackInfo_Value`) before parking.
- [ ] Apply park/restore ops (`SetMediaTrackInfo_Value` for the four flags;
`TrackFX_GetCount` + per-FX `TrackFX_SetOffline`). Verify flag names/signatures.
- [ ] GUID resolution: `GetTrackGUID` / `guidToString` / `stringToGuid` (never index).
- [ ] Review gate: no path touches master visibility or `B_MUTE`/`I_SOLO`, or any
untagged track's owned flags.
## D3 — persist slice (view state ↔ project ext state)
**Goal:** Serialize the view section into the `"reasampler"` namespace alongside the
bank; reapply the active mode on project open. CONTEXT.md §Design View (persist).
**Verify (in DAW):** Membership + active mode + snapshots survive Save / Save As /
close+reopen; on open, the active mode's visibility + processing is reapplied.
Saved-while-parked project restores parked tracks from persisted snapshots (not to a
guessed "on").
- [ ] Serialize/deserialize the view section under `"reasampler"` (shared blob,
distinct section from the bank index).
- [ ] Reapply active mode on project open (rebuild tree, run the planner).
- [ ] Confirm survival across Save / Save As; snapshot durability across
save-while-parked.
## D4 — actions
**Goal:** Bindable action set for the mode workflow. CONTEXT.md §Design View
(actions). **Verify (in DAW):** Each action registered (bindable in Actions list);
toggle + mode-jumps MIDI-bindable; tag/untag acts on the current track selection.
- [ ] Toggle active mode (cycle; extensible to cycle-all for >2 modes).
- [ ] Activate mode: Arrange / Activate mode: Design (direct jumps).
- [ ] Tag selected tracks → Design / → Arrange; Untag selected (= → Arrange).
- [ ] Show-both for selected tracks (toggle).
- [ ] Register each (`command_id`/`gaccel`/`hookcommand`); toggle + jumps MIDI-bindable.
## D5 — in-window toggle affordance (UI)
**Goal:** The segmented mode switch in the ReaSampler / bank_panel window header.
CONTEXT.md §Design View (UI). **Verify (in DAW):** Segmented control shows current
mode (lit segment), one click flips modes via the D4 toggle action, per-mode
membership count visible, offlined-FX caveat surfaced as a tooltip.
- [ ] Segmented mode switch `[ Arrange | Design ]` in the window header; active lit.
- [ ] Wire the switch to the toggle/activate actions from D4.
- [ ] Per-mode membership count display.
- [ ] Offlined-FX re-init caveat as a tooltip on the switch.
## Phase D open questions
- **Snapshot durability across save-while-parked** — persisted here by decision;
lean alternative is force-restore-to-Arrange on save (product notes item 4).
(touches D3)
- **Reconcile on delete/restructure** — tagged leaf deleted or folder restructured
while parked leaves a stale GUID; ignore-and-prune on next toggle/open.
(touches D1/D2)
- **Screenset coexistence** — Design View drives the same flags a screenset recall
would; confirm last-writer-wins is not surprising. (touches D2)