docs: 1.0 documentation restructure
Split root CLAUDE.md into 19 per-directory files scoped to their source area. Roll v0 history into docs/ARCHIVE.md; retire CONTEXT.md, CONTEXT-ARCHIVE.md, PLAN.md, COMPLETED.md. Move plan docs under docs/. Rescue 9 live deferrals into docs/TODO.md.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
# src/core/ui — pure UI geometry, palette, and interaction-decision modules
|
||||
|
||||
## Scope
|
||||
|
||||
Pure, REAPER-free UI geometry, palette, and interaction-decision modules shared by
|
||||
the extension's docked bank panel and the VST3 instrument's editor/embed surfaces:
|
||||
layout math, hit-testing, hover/drag-gesture-precedence decisions, and the
|
||||
role-based color palette. Does **not** include: the actual LICE drawing (`draw_kit`
|
||||
lives in `shell/panel`; the editor's own paint code lives in `shell/instrument`),
|
||||
REAPER/SWELL window or dialog mechanics, or the DAW-side Design View flag
|
||||
application (`shell/view`).
|
||||
|
||||
## Invariants
|
||||
|
||||
Look-and-feel — visual design language (Phase L) (settled decisions, 2026-07-26;
|
||||
L7 sub-pass, 2026-07-27):
|
||||
|
||||
- **DS-1 — toolkit discipline.** Draw with LICE + reused WDL/vwnd pieces directly;
|
||||
external frameworks (iPlug2/JUCE/VSTGUI) are rejected. "**Caution, not a ban:**
|
||||
keep hit-test **geometry** in pure CTest-covered modules — do not import vwnd's
|
||||
retained-mode object model wholesale (its controls own their hit-test internally,
|
||||
which would move geometry into untestable shell code and undercut the pure/shell
|
||||
split)." This directory is that pure-geometry seam.
|
||||
- **DS-2 — palette is role-based, not hardcoded hue**, in one constants block
|
||||
(`theme`): `bg/base`, `bg/panel`, `bg/cell`, `line/hairline`, `text/primary`,
|
||||
`text/dim`, `accent/primary`, `accent/secondary`, `accent/tertiary`,
|
||||
`accent/hot`, `warn`. Neutral ladder sits in REAPER's mid-grey theme family
|
||||
(`bg/base` ≈ `#2b2b2b`, `bg/panel` ≈ `#333333`, `bg/cell` ≈ `#3a3a3a`,
|
||||
`line/hairline` ≈ `#4a4a4a`, `text/primary` ≈ `#dcdcdc`, `text/dim` ≈
|
||||
`~#a0a0a0`+), elevation-ladder discipline (base < panel < cell by a few %,
|
||||
micro-gradient + inner highlight/shadow carry elevation, not hard borders).
|
||||
Three pastel accents carry categorical meaning: **primary (pastel lime) =
|
||||
live/active/selected**, secondary (pastel teal) + tertiary (pastel purple) =
|
||||
supporting categorical distinctions (kinds, not intensity). `warn` (red/amber)
|
||||
is reserved **only** for byte-deleting or clip states (prune, delete).
|
||||
- **WCAG-floor discipline (tight pairs to re-verify on any palette change):**
|
||||
`text/dim` on `bg/panel`/`bg/cell` is the classic mid-grey-on-mid-grey floor
|
||||
failure — must clear AA 4.5:1 body text. The three pastels as state
|
||||
indicators/active fills on `bg/cell` have a shrunken contrast cushion
|
||||
(~6:1–7:1, still clears 3:1 but re-check on any hue nudge). Body text on a
|
||||
pastel fill is a tight AA 4.5:1 pair. Take the most pastel value that still
|
||||
clears the floor, approached from the soft side, never re-saturated toward
|
||||
neon "to be safe."
|
||||
- **"Speed is the selling point" — a design constraint on this geometry, not
|
||||
just the draw layer.** Sub-frame hover/press/drag feedback must repaint
|
||||
immediately on the input message. **No decorative animation** — no
|
||||
tweens/fades/pulses; the only permitted motion is a level/meter readout
|
||||
following audio directly. Any glow/bloom state is a static drawn state, never
|
||||
a pulse.
|
||||
- **Precision/invariant implications (Phase L does not change these):** "the
|
||||
pure/shell split holds" — all layout/hit-test stays in pure CTest-covered
|
||||
geometry modules; the kit's *draw* half is shell, its *geometry* half is pure,
|
||||
even where a WDL piece is reused. Look-and-feel work never touches capture,
|
||||
placement, or bank data ownership.
|
||||
- **L7 drag-gesture precedence is a pure decision helper.** The rule — leave
|
||||
client rect → OS drag-out; else drop on a tab/other bank → move/copy; else
|
||||
same-bank grid → reorder-to-slot (empty slot = place, occupied + no modifier =
|
||||
insert-before-and-shift, occupied + Alt = replace) — is "encoded in a pure
|
||||
decision helper (mirror `drag_out::decideGesture`)"; the shell only reads live
|
||||
pointer/focus/client-rect/modifier state and calls it, then maps the resolved
|
||||
gesture to a cursor via `SetCursor`. No cue or precedence logic belongs in the
|
||||
shell.
|
||||
|
||||
## Modules
|
||||
|
||||
- `rect` (`core/ui`, header-only) — the ONE concrete pixel rectangle (Q-W1): XYWH storage + `right()`/`bottom()`/`ltrb()`/`contains()`, replacing 12+ byte-identical role structs (`ButtonRect`/`FooterRect`/`CellRect`/`KitBox`/…) and the VST side's separate LTRB `Rect`; every prior role name survives as a `using` alias at its old site (e.g. `editor_geometry::Rect`).
|
||||
- `bank_grid` — REAPER-free grid layout, selection, keyboard-nav, and thumbnail-cache-key logic for the docked bank panel.
|
||||
- `tab_strip` — REAPER-free scrollable tab-strip layout + hit-test for the named-banks strip.
|
||||
- `prune_button` — pure layout/hit-test for the `bank_panel` footer Prune button.
|
||||
- `drag_out` — pure OS drag-out module: gesture-boundary decision and path-list assembly. The `InstrumentDrop` gesture signals that the shell should execute an instrument-drop rather than a file-copy drag.
|
||||
- `theme` — pure palette module: role→color mapping, REAPER-grey neutral ladder + three-accent pastel system, WCAG contrast-floor helpers.
|
||||
- `component_geometry` — pure button/slider/list-row geometry + hover hit-test helpers.
|
||||
- `action_bar` — pure task-grouped action-bar layout/hit-test: clusters (Capture / Placement / Maintenance / Tagging / Switching).
|
||||
- `footer_bar` — pure footer layout/hit-test: `[Arrange|Design]` mode-toggle geometry, Tail button, and Prune placement.
|
||||
- `overflow_menu` — pure overflow-menu-button geometry/reserve/hit-test for the top-toolbar More (⋯) button.
|
||||
- `mode_enable` — pure opposite-mode enablement predicate: given the active mode, computes per-button live/disabled state for the four Item/Track × Arrange/Design tag buttons.
|
||||
- `tooltip` — pure tooltip placement + prefix-strip: strips the `ReaSampler:` display prefix from the registered action phrase; width clamped to the client rect.
|
||||
- `card_drag` — pure drag-gesture precedence + slot hit-test: leave-client → OS drag-out; other-bank → move/copy; same-bank → reorder / Alt-over-occupied → replace.
|
||||
- `card_meta` — pure card-metadata formatters: bars.beats.subdivisions and seconds.milliseconds; blank when the sample is unstamped.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- The WCAG contrast-floor pairs above are real math in `theme`'s tests, not a
|
||||
visual eyeball check — any new hue or role needs its own contrast-floor
|
||||
assertion.
|
||||
- `card_drag`'s precedence order must stay a pure decision helper mirroring
|
||||
`drag_out::decideGesture` — don't let a shell reimplement gesture precedence
|
||||
ad hoc; the cursor-cue mapping in the shell must stay a thin lookup over the
|
||||
pure result.
|
||||
- `rect`'s prior role names survive only as `using` aliases at their old call
|
||||
sites — changing `rect.h` itself ripples across every directory that aliases
|
||||
it (e.g. `editor_geometry::Rect`); check all alias sites, not just this one.
|
||||
Reference in New Issue
Block a user