diff --git a/CLAUDE.md b/CLAUDE.md index 041b645..3706a99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Repo identity and current state -The CMake project and binary are now named `reaper_reasampler`. This is **ReaSampler** — a per-project audio sample-bank capture tool. The MPE modules (`mpe_model`, `mpe_view`) have been removed. M0–M8 are complete (bank_model, peaks, capture offline+realtime, persist, bank_panel, insert, capture action family, RealtimeRecordBackend, tail T1+T2+T1-followons). Phase B multi-bank (B1–B5, B-cap), Phase D1/D2 Design View (D1–D5, D2-W1–W3-B), Phase V versioning/beta-channel (V1/V3, V4), M10 provenance + re-capture from source, Phase R Reclaim (R1–R3: prune-reconcile core, dry-run shell, guarded deletion + action + panel button), M11 in full (batch capture, action-button strip + keybinding labels, conform-on-insert verified-extant, native OS drag-out), Phase L wave 1 L1 (shared LICE drawing kit: `theme`/palette module, `component_geometry` geometry helpers, `draw_kit` shell, GDI DrawText retired in `bank_panel`), and Phase L wave 2 L2 (dock-panel layout redesign: `action_bar` pure task-grouped layout module, full M11-aware button inventory placed by task cluster, `bank_panel` redesigned through the L1 kit) have all landed. M9 slots deferred indefinitely. The *discipline* — pure REAPER-free testable core split from REAPER-facing shells — is **preserved** throughout. +The CMake project and binary are now named `reaper_reasampler`. This is **ReaSampler** — a per-project audio sample-bank capture tool. The MPE modules (`mpe_model`, `mpe_view`) have been removed. M0–M8 are complete (bank_model, peaks, capture offline+realtime, persist, bank_panel, insert, capture action family, RealtimeRecordBackend, tail T1+T2+T1-followons). Phase B multi-bank (B1–B5, B-cap), Phase D1/D2 Design View (D1–D5, D2-W1–W3-B), Phase V versioning/beta-channel (V1/V3, V4), M10 provenance + re-capture from source, Phase R Reclaim (R1–R3: prune-reconcile core, dry-run shell, guarded deletion + action + panel button), M11 in full (batch capture, action-button strip + keybinding labels, conform-on-insert verified-extant, native OS drag-out), Phase L L1 (shared LICE drawing kit: `theme`/palette module, `component_geometry` geometry helpers, `draw_kit` shell, GDI DrawText retired in `bank_panel`), Phase L L2 (dock-panel layout redesign: `action_bar` pure task-grouped layout module, full M11-aware button inventory placed by task cluster, `bank_panel` redesigned through the L1 kit), and Phase L L4 (dock-panel button layout enhancement: three-zone layout — top capture/placement/maintenance toolbar, bottom Design-View tagging/switching toolbar, footer narrow-toggle + Tail-button + Prune; `footer_bar` pure module + `footer_bar_tests`; `ActionCluster::Tagging`/`Switching` in `action_bar`) have all landed. M9 slots deferred indefinitely. The *discipline* — pure REAPER-free testable core split from REAPER-facing shells — is **preserved** throughout. CONTEXT.md is the authoritative spec and build roadmap. Read it first for any non-trivial task. Every REAPER API name cited there is correct-by-intent; verify argument order, types, and flag values against `vendor/reaper-sdk/sdk/reaper_plugin_functions.h` before use. @@ -45,6 +45,7 @@ Key targets (see CMakeLists.txt for the full list): | `theme_tests` | executable | Pure unit tests for `theme` — no REAPER, no DAW. | | `component_geometry_tests` | executable | Pure unit tests for `component_geometry` — no REAPER, no DAW. | | `action_bar_tests` | executable | Pure unit tests for `action_bar` — no REAPER, no DAW. | +| `footer_bar_tests` | executable | Pure unit tests for `footer_bar` — no REAPER, no DAW. | | `reaper_reasampler` | loadable module | The actual extension binary (`.dll` / `.dylib` / `.so`). | ### Beta channel build (Phase V, V4) @@ -88,12 +89,13 @@ There is no hot-reload. Copy the built binary into REAPER's `UserPlugins/` folde - `drag_out` — M11 pure OS drag-out module: gesture-boundary decision (internal drag becomes OS-bound when the pointer leaves the panel client rect), path-list assembly with dedupe and missing-file skip. No REAPER types at the boundary. - `theme` — Phase L pure palette module (L1): role→color mapping via one constants block (DS-2 revised — REAPER-grey neutral ladder: `bg/base #2b2b2b` / `bg/panel #333333` / `bg/cell #3a3a3a` / `line/hairline #4a4a4a` / `text/primary #dcdcdc` / `text/dim #a8a8a8`; three-accent pastel system: `accent/primary` pastel lime `#B0E098` = live/active/selected, `accent/secondary` pastel teal `#84D6D0` + `accent/tertiary` pastel purple `#C2AAE8` = categorical distinctions, `accent/hot` lighter lime = hover/drag feedback); `Role` enum carries the three accent roles; `roleColor`/`roleColorState` updated (Active/Dragging/Focus → primary accent); `spectralColor` is a pastel three-stop sweep anchored on the three accents (lime → teal → purple); WCAG contrast-floor helpers; full interaction-state color model. No LICE or REAPER types. - `component_geometry` — Phase L pure component geometry/hit-test helpers (L1): button/slider/list-row geometry + hover hit-test. No LICE or REAPER types. Mirror of `mode_switch`/`bank_grid`. -- `action_bar` — Phase L pure task-grouped action-bar layout/hit-test (L2): clusters (Capture / Placement / Maintenance), per-button label + keybinding micro sub-rects, whole-trailing-button overflow, point→index hit-test. No LICE or REAPER types. Mirror of `mode_switch`/`bank_grid`/`action_buttons`. +- `action_bar` — Phase L pure task-grouped action-bar layout/hit-test (L2 + L4): clusters (Capture / Placement / Maintenance / Tagging / Switching), per-button label + keybinding micro sub-rects, whole-trailing-button overflow, point→index hit-test. `ActionCluster::Tagging` and `ActionCluster::Switching` added in L4 for the bottom Design-View toolbar. No LICE or REAPER types. Mirror of `mode_switch`/`bank_grid`/`action_buttons`. +- `footer_bar` — Phase L pure footer layout/hit-test (L4): narrow `[Arrange|Design]` mode-toggle geometry + per-mode count label, Tail button, and Prune placement in the panel footer strip. No LICE or REAPER types. Mirror of `mode_switch` / `prune_button`. **REAPER-facing shells:** - `capture` — `ICaptureBackend` interface; `OfflineRenderBackend` (deterministic default) and `RealtimeRecordBackend`. Input: `CaptureRequest`. Output: finished file + populated `Sample` handed to `bank_model`. - `insert` — placement via `InsertMedia`; conform-to-project-tempo is an explicit opt-in flag, never silent stretching. -- `bank_panel` — docked LICE-drawn grid: thumbnails, audition, multi-select, keyboard navigation; a task-grouped action bar (L2) placing the full M11-aware button inventory by cluster (Capture / Placement / Maintenance) via the `action_bar` pure module, firing each action via `NamedCommandLookup` + `Main_OnCommand` and showing live keybinding labels via `kbd_getTextFromCmd`; prune button footer-set-apart; entire panel draws through the L1 kit by palette role with hover on interactive elements, single `KitColor→LICE_pixel` boundary via `draw_kit`; OS drag-out hook (M11) initiating an OS-level copy drag when the pointer leaves the panel client rect, via `drag_out` + `drag_out_win`. +- `bank_panel` — docked LICE-drawn grid: thumbnails, audition, multi-select, keyboard navigation; three-zone layout (L4): **top toolbar** = capture cluster (capture item, capture track, batch items, batch razor, capture RT) + placement cluster (insert, insert-conform) + maintenance cluster (re-capture, cancel-realtime) via `action_bar`, firing each action via `NamedCommandLookup` + `Main_OnCommand` and showing live keybinding labels via `kbd_getTextFromCmd`; **bottom toolbar** = Design View tagging + switching verbs (`ActionCluster::Tagging` / `ActionCluster::Switching`) firing the registered `VIEW_*` actions; **footer** = narrow `[Arrange|Design]` toggle · per-mode count · Tail button (cycles tail on click, proper kit button states) · set-apart `warn` Prune (rightmost) via `footer_bar`; entire panel draws through the L1 kit by palette role with hover on interactive elements, single `KitColor→LICE_pixel` boundary via `draw_kit`; OS drag-out hook (M11) initiating an OS-level copy drag when the pointer leaves the panel client rect, via `drag_out` + `drag_out_win`. - `persist` — project ext state (`SetProjExtState` / `GetProjExtState`, namespace `"reasampler"`) ↔ `BankBook` JSON (`"banks"` key) + `ViewModeModel` JSON (`"view_state"` key) + `TailSetting` JSON (`"tail_setting"` key) + `OwnedManifest` JSON (`"owned_files"` key) + writing-version stamp (`"version"` key, written via `stampVersion()` on every `saveToActiveProject()`); project-relative path resolution. A `projectconfig` hook (`BeginLoadProjectState(isUndo)`) triggers a deferred session reload on undo/redo so Ctrl-Z/redo visibly restores book/view/tail/manifest in-session. Hosts `ReaSamplerSession::pruneDryRun()` (read-only orphan enumeration via M4 project-relative resolution) and `pruneOrphanSet()` (full-set query for the R3 delete path); supplies `referencedPaths()` + `owned().paths()` to the `prune_reconcile` pure core. - `view` — Design View shell: reads the folder tree via `view_tree`, snapshots flag values before parking, drives hide + CPU-park on inactive-mode leaves (`B_SHOWINTCP`/`B_SHOWINMIXER`/`B_MAINSEND`/`I_FXEN` + per-FX offline) and derived visibility on parents; restores from snapshot. Never touches master or `B_MUTE`/`I_SOLO`. - `track_guid` — shared `MediaTrack*` → canonical GUID-string formatter; single source of truth for membership keys used by both the view shell and the actions layer. diff --git a/COMPLETED.md b/COMPLETED.md index bffd90e..b4f2e81 100644 --- a/COMPLETED.md +++ b/COMPLETED.md @@ -1306,3 +1306,45 @@ button remains footer-set-apart + `warn`-colored; grid stays the centerpiece. kit (chrome, buttons, tabs, grid cells, dividers) by palette role with hover on interactive elements; remaining GDI text retired; single `KitColor→LICE_pixel` boundary via the kit's `toLice` (now exposed in `draw_kit.h`). + +--- + +## L4 — dock-panel button layout enhancement +**Goal:** Re-home the `bank_panel`'s L2 button inventory around *frequency and intent* — +three-zone structure: top toolbar (capture + placement + maintenance), bottom toolbar (Design +View tagging + switching), footer (narrow mode toggle · Tail button · Prune). A layout +re-home of buttons that fire existing actions; no new actions, no capture/placement behavior +change, no touching the "capture ≠ placement" principle. Independent of L3. +CONTEXT.md §Phase L (L4 dock-panel button layout). Product framing: +`docs/product/visual-design-language.md` §L4. +**Verify (in DAW):** the top toolbar fires every capture + placement + maintenance action; the +bottom toolbar tags/untags selected tracks and switches/toggles Arrange/Design/show-both; the +footer shows a narrow `[Arrange|Design]` toggle at the left, a Tail button that cycles tail +on click with button states, and the Prune button set apart at the right in `warn`; every +surface draws through the L1 kit in the DS-2 grey+pastel palette; capture and placement still +never auto-insert (the buttons only fire the existing, unchanged actions). + +- [x] **Top toolbar**: capture cluster (capture item, capture track, batch items, batch razor, + capture RT) + placement cluster (insert, insert-conform) + maintenance cluster (re-capture, + cancel-realtime) moved from the L2 bottom bar to a top toolbar via `action_bar` row layout; + buttons fire existing actions unchanged — no auto-insert. +- [x] **Bottom toolbar**: Design View action family as buttons (tag / untag selected for mode, + activate Arrange, activate Design, toggle active mode, show-both) via `action_bar` + `ActionCluster::Tagging` + `ActionCluster::Switching`; fires existing registered Design View + actions. +- [x] **Footer toggle**: `[Arrange|Design]` segmented toggle shrunk to fit-its-text width and + moved to the footer left of Prune; per-mode count as a compact adjacent label. +- [x] **Footer Tail button**: Tail click-zone converted to a proper kit button (rest/hover/ + pressed states; click still cycles the tail setting). +- [x] **Footer order** (`[Arrange|Design]` · Tail · … · Prune `warn` set apart at the right); + pure footer-strip layout in new `footer_bar` module covered by CTest (`footer_bar_tests`). + +**Notes/decisions:** +- **Maintenance cluster restored to top toolbar** (Daniel's directive during L4 build): the + initial L4 spec described the top toolbar as "capture + placement" only; the landed + implementation includes re-capture and cancel-realtime in a Maintenance cluster on the same + top toolbar. CONTEXT.md and CLAUDE.md updated to reflect the actual layout. +- New pure module `src/footer_bar.{h,cpp}`: footer layout/hit-test (narrow mode toggle + + Tail button + Prune); no LICE or REAPER types. New CTest target `footer_bar_tests`. +- `action_bar` gained `ActionCluster::Tagging` and `ActionCluster::Switching` for the + bottom-toolbar Design View verb groups. diff --git a/CONTEXT.md b/CONTEXT.md index aee6601..6217116 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -1659,11 +1659,12 @@ or font decisions are re-opened here. **The new three-zone structure:** -- **Top toolbar = capture + placement.** The capture cluster (capture item, capture track, - batch items, batch razor, capture RT) and the placement cluster (insert, insert-conform) move - from the bottom L2 action bar to a **top** toolbar — the eye's first landing, matching the two - acts the tool exists for. Icon+label buttons with the keybinding as a `micro` sub-label (the - M11 keybinding-help convention), drawn through the kit. +- **Top toolbar = capture + placement + maintenance.** The capture cluster (capture item, + capture track, batch items, batch razor, capture RT), the placement cluster (insert, + insert-conform), and the maintenance cluster (re-capture, cancel-realtime) move from the + bottom L2 action bar to a **top** toolbar — the eye's first landing, matching the acts the + tool exists for. Icon+label buttons with the keybinding as a `micro` sub-label (the M11 + keybinding-help convention), drawn through the kit. - **Bottom toolbar = Design View tagging + switching.** The space the capture/placement buttons vacate holds the **Design View action family** as buttons: **tag / untag selected tracks for a mode, activate Arrange, activate Design, toggle active mode, show-both.** These are the @@ -1697,10 +1698,8 @@ editor (`IPlugView` LICE surface), the S6 embed strip, and the keyboard strip li Phase S, which is **not on dev yet** (it exists on the phase-s worktree). L3 cannot be built on dev until Phase S's editor/embed surfaces (≈ S1 / S6 / S10) merge to dev — **the Phase L team must not chase these files on dev; they are not there.** Until then L3 is a -planned, blocked point; L1 and L2 have landed, and **L4 (dock-panel button layout enhancement) -is the live, ungated extension-side Phase L work — it does not touch any Phase S surface, and -sequences after the in-flight palette revision merges to dev** (shared-`bank_panel` collision). -L4 is independent of the L3 gate. +planned, blocked point; L1, L2, and **L4 (dock-panel button layout enhancement) have all +landed**. L4 is independent of the L3 gate. **Coordination contract (load-bearing):** Phase S's S10–S13 build their interaction UX with the **current** drawing and **adopt the L1 kit when it is available — they are NOT gated on diff --git a/PLAN.md b/PLAN.md index 4ac41bc..cadc240 100644 --- a/PLAN.md +++ b/PLAN.md @@ -391,13 +391,14 @@ they merge (same gate posture as L3). > directions: `docs/product/visual-design-language.md`. When a point lands, doc-keeper > moves it to `COMPLETED.md`. > -> **L1 (shared LICE drawing kit — the foundation) and L2 (dock-panel layout redesign) -> have landed** — `theme`/palette module, `component_geometry` geometry/hit-test helpers, -> `draw_kit` shell, GDI `DrawText` retirement in `bank_panel` (L1); `action_bar` pure -> task-grouped layout module, full M11-aware button inventory placed by task cluster, -> `bank_panel` redesigned through the L1 kit (L2). See `COMPLETED.md`. **L3 and L4 remain** -> — L3 gated on Phase S landing on dev; L4 (dock-panel button layout enhancement) ungated and -> extension-side, sequencing after the in-flight palette revision merges to dev. +> **L1 (shared LICE drawing kit — the foundation), L2 (dock-panel layout redesign), and L4 +> (dock-panel button layout enhancement) have landed** — `theme`/palette module, +> `component_geometry` geometry/hit-test helpers, `draw_kit` shell, GDI `DrawText` retirement +> in `bank_panel` (L1); `action_bar` pure task-grouped layout module, full M11-aware button +> inventory placed by task cluster, `bank_panel` redesigned through the L1 kit (L2); three-zone +> layout (top capture/placement/maintenance toolbar, bottom Design-View toolbar, footer toggle + +> Tail button + Prune), `footer_bar` pure module, `ActionCluster::Tagging`/`Switching` in +> `action_bar` (L4). See `COMPLETED.md`. **L3 remains** — L3 gated on Phase S landing on dev. > > **This section is self-contained for a team without Phase S context.** Where a point > touches a Phase S surface (the VST editor, the embed strip, the keyboard strip), the @@ -474,85 +475,15 @@ work. state — never a pulse, per the speed constraint) as the signature surface; VST3 class UID unchanged. (Gated.) -## L4 — dock-panel button layout enhancement (ungated, extension-side) -**Goal:** Re-home the `bank_panel`'s L2 button inventory around *frequency and intent*, so the -two acts the tool exists for (capture, placement) sit at the **top** where the eye lands, the -Design View organize/switch verbs get a real button home at the **bottom**, and the footer -carries the small persistent controls (the Arrange|Design toggle, Tail, Prune) in a coherent -left-to-right order. This is a **layout re-home of buttons that fire existing actions** — no new -actions, no capture/placement behavior change, no touching the "capture ≠ placement" principle. -It is independent of L3 (which stays gated on Phase S); L4 is **ungated, extension-side only** -(the dock panel lives on dev). Product framing: `docs/product/visual-design-language.md` §L4 -(new) + CONTEXT.md §Phase L "L4 dock-panel button layout". - -The four layout moves (Daniel, 2026-07-26): -1. **Capture + placement clusters move to a TOP toolbar.** The capture cluster (capture item, - capture track, batch items, batch razor, capture RT) and the placement cluster (insert, - insert-conform) leave the current bottom L2 action bar and become a **top** toolbar — the - first thing the eye meets, matching their frequency and the tool's purpose. -2. **The bottom toolbar is repurposed for Design View tagging + switching.** In the space the - capture/placement buttons vacate, place the Design View action family as buttons: **tag / - untag selected tracks for a mode, activate Arrange, activate Design, toggle active mode, - show-both.** These are registered actions today (the Design View action family); L4 gives - them a button home in the bottom toolbar. -3. **The Arrange|Design segmented toggle shrinks and moves to the footer.** The large top - `[ Arrange | Design ]` segmented control shrinks to **just wide enough for its text - comfortably** and moves into the **footer, to the LEFT of the Prune button** (see footer - order below). The per-mode membership count travels with it (as a compact adjacent label). -4. **Tail becomes a real button.** The Tail footer affordance is a **click-zone** today - (clicking cycles the tail setting) — inconsistent with the other footer controls. Convert it - to a proper **button** drawn through the L1 kit like the others; click still cycles the tail - setting, but it now reads and behaves as a button (rest/hover/pressed states). - -**Footer affordance order (left → right):** `[Arrange|Design]` toggle · Tail button · … · -**Prune** (set apart at the right, `warn`). *Rationale:* the two view/session controls (mode -toggle, tail) group at the left as the "how this panel/capture behaves" cluster; Prune stays -isolated at the far right, visually separated and `warn`-colored, because it is the only -byte-deleting affordance and must never sit adjacent to a benign toggle where a mis-click is -cheap. Order reads left (benign, frequent) → right (destructive, rare). - -**Verify (in DAW):** the top toolbar fires every capture + placement action; the bottom toolbar -tags/untags selected tracks and switches/toggles Arrange/Design/show-both; the footer shows a -narrow `[Arrange|Design]` toggle at the left, a Tail button that cycles tail on click with -button states, and the Prune button set apart at the right in `warn`; every surface draws -through the L1 kit in the DS-2 grey+pastel palette; capture and placement still never -auto-insert (the buttons only fire the existing, unchanged actions). - -**Depends on:** L1 (the kit) + L2 (the landed layout + `action_bar` module). **Ungated by Phase -S** — extension-side (`bank_panel`) only. **Sequence AFTER the palette revision merges to dev** -— the in-flight DS-2 grey+pastel palette branch also reworks `bank_panel` heavily; landing L4 -concurrently would collide the same file. L4 begins once the palette revision is on dev. -**Pure/shell discipline (unchanged):** all new toolbar/footer layout math goes in pure -CTest-covered geometry modules — extend/mirror `action_bar` (toolbar row layout) and -`mode_switch` (the now-narrow footer toggle); `bank_grid`/`tab_strip` stay owners of their own -surfaces' hit-testing. The kit draws; geometry stays pure. - -- [ ] Top toolbar: re-home the capture cluster (item / track / batch items / batch razor / - capture RT) + placement cluster (insert / insert-conform) from the bottom L2 bar to a top - toolbar (pure row layout in `action_bar`; kit draw). Buttons fire the existing actions - unchanged — no auto-insert. -- [ ] Bottom toolbar: place the Design View action family as buttons (tag / untag selected for - mode, activate Arrange, activate Design, toggle active mode, show-both), firing the existing - registered Design View actions. -- [ ] Footer: shrink the `[ Arrange | Design ]` segmented toggle to fit-its-text width and move - it to the footer left of Prune (narrow-segment geometry in `mode_switch`); carry the per-mode - count as a compact adjacent label. -- [ ] Footer: convert the Tail click-zone into a proper kit button (rest/hover/pressed states; - click cycles the tail setting as today). -- [ ] Footer order: `[Arrange|Design]` · Tail · … · Prune (`warn`, set apart at the right); - pure footer-strip layout covered by CTest. - ## Phase L — sequencing ``` L1 (shared kit) ──► L2 (dock-panel layout redesign) [LANDED] ├─────────► L3 (VST editor + embed-strip restyle; GATED on Phase S landing on dev) - └─────────► L4 (dock-panel button layout enhancement; ungated, extension-side; - sequences AFTER the palette revision merges to dev) + └─────────► L4 (dock-panel button layout enhancement) [LANDED] Phase S (separate team, ungated): S-work builds with current drawing, adopts L1 when it lands. ``` -L1 and L2 have landed. L3 waits for Phase S to reach dev. L4 is ungated and extension-side but -sequences after the in-flight palette-revision branch merges to dev (both rework `bank_panel`). +L1, L2, and L4 have landed. L3 waits for Phase S to reach dev. Phase S feature work runs in parallel, ungated by Phase L. ## Phase L — must-verify-before-build @@ -570,11 +501,9 @@ Phase S feature work runs in parallel, ungated by Phase L. useful; keep hit-test geometry pure regardless. - **M11 button inventory (L2)** — resolved at L2 build: inventory taken against dev after M11 merged; all buttons placed by task cluster in the landed `action_bar` module. -- **L4 re-home surface (L4)** — resolved at L4 build against the **post-palette-revision** - `bank_panel`: confirm the landed `action_bar` row-layout module and the `mode_switch` - segmented-toggle geometry extend cleanly to a top toolbar + a narrow footer toggle, and that - the Design View action family's command ids are all live for the bottom-toolbar buttons. - **Do not build until the palette revision is on dev** (shared-file collision). +- **L4 re-home surface (L4)** — resolved at L4 build: three-zone layout confirmed against the + post-palette-revision `bank_panel`; `action_bar` extended with `ActionCluster::Tagging` + + `Switching`; new pure `footer_bar` module covers footer layout/hit-test. ---