Files
reasampler/src/bank_panel.h
T
daniel c33cb50632 Merge dev into phase-b-multibank (integrate parallel M7/8 + Phase D work before dev promotion)
# Conflicts:
#	CLAUDE.md
#	CMakeLists.txt
#	src/actions.cpp
#	src/bank_panel.cpp
#	src/persist.h
2026-07-25 23:30:44 -04:00

125 lines
6.9 KiB
C++

#pragma once
// bank_panel — the docked grid window (M5, Wave A). REAPER-facing shell: it owns
// a SWELL dialog docked via DockWindowAddEx, and paints the current project's
// bank as a grid of LICE-drawn waveform thumbnails. The panel itself NEVER inserts
// into the arrange or mutates the project/bank (CONTEXT.md §load-bearing
// principle). Audition / multi-select / keyboard nav are Wave B.
//
// The header is REAPER-free as practical: main.cpp drives the panel through these
// free functions, passing the live session so the panel reads the current bank.
// All SWELL / LICE / PCM_source use is confined to bank_panel.cpp. The pure
// layout math and cache keys live in bank_grid (unit-tested outside the DAW).
#include <string>
#include <vector>
#include "tail_control.h" // TailSetting — the panel's tail-mode toggle state
namespace reasampler {
class ReaSamplerSession;
// Wires the panel into main.cpp's lifecycle. Called once after the API pointers
// are loaded, BEFORE the toggle action is registered. `session` must outlive the
// panel (it is the extension-lifetime g_session). Stores the session pointer the
// panel reads on every repaint; does not create the window yet.
void bankPanelInit(ReaSamplerSession* session);
// Toggles the docked window: creates+docks it if hidden, hides+undocks it if
// shown. Bound to the "toggle bank panel" action. Safe to call before the first
// timer tick.
void bankPanelToggle();
// Whether the panel window is currently open/visible. Feeds the action's
// checked-state (toggleaction) so REAPER shows a tick next to the menu entry.
bool bankPanelIsOpen();
// The stable ids of the currently-selected samples, in bank (insertion) order.
// Empty when nothing is selected or the panel has never opened. This is the clean
// seam the `insert` action reads to know WHAT to place — it returns ids (not grid
// indices) so the caller resolves against the live bank and is unaffected by the
// panel's internal index bookkeeping. READ of panel state only; no mutation.
//
// Note: the panel's selection is cleared on a bank change (capture / project
// load), so a returned id always names a sample present in the current bank at
// the moment of the call; the caller still tolerates an absent id gracefully.
//
// Phase B4 (vertical split): the selection lives in whichever REGION the user last
// interacted with (the pool grid on top or a named-bank grid below), which is NOT
// necessarily the active/capture-target bank. The returned ids therefore name
// samples in the FOCUSED region's displayed bank — the bank the user visibly
// selected in. Pair with bankPanelSelectedSourceBankId() to know which bank those
// ids belong to (the move/copy source).
std::vector<std::string> bankPanelSelectedSampleIds();
// The bank id the current selection belongs to — the displayed bank of the region
// the user last interacted with (pool region -> the pool id; named-banks region ->
// the shown tab's bank id). This is the SOURCE bank for a move/copy of the current
// selection, and it is distinct from the active/capture-target bank (active ≠ shown).
// Returns the pool id when nothing is selected or the panel has never opened (a safe
// default source). READ of panel state only; no mutation.
std::string bankPanelSelectedSourceBankId();
// Requests a repaint if the bank changed since the last paint (generation bump).
// Cheap when nothing changed. Driven by the timer so a capture / project load is
// reflected without the panel diffing the bank itself.
void bankPanelRefresh();
// Notifies the panel that persist just (re)loaded a project's view model (membership +
// active mode). main.cpp calls this on the exact tick it drains persist's load signal
// and reapplies the active mode. It re-arms the new-content detector so the just-loaded
// project's PRE-EXISTING content is taken as the baseline (reported as nothing new),
// never diffed against the previously-open project and mass-tagged into the active mode.
// This coordinates the detector's project-identity signal with persist's authoritative
// (GUID-primary) one — the two can no longer diverge on a recycled ReaProject* address,
// which is what caused a project opened in Design to mis-tag its Arrange tracks. READ/
// arm of panel state only; no project or bank mutation.
void bankPanelNotifyProjectLoaded();
// The panel's current tail-mode setting (mode + Manual length), read by the plain
// CAPTURE_ITEM / CAPTURE_TRACK actions when building a CaptureRequest so a capture
// applies whatever the panel toggle is set to. Default None (exact bounds) — a
// capture with no explicit choice stays byte-identical to today. Extension-session
// setting: persists across project loads and panel open/close within a REAPER session;
// resets to None only when the extension unloads (fresh REAPER session). Project
// persistence across REAPER restarts is a noted follow-on.
// Safe to call before the panel has ever opened (returns the default). READ of panel
// state only; the toggle is mutated by a click inside the panel, never here.
TailSetting bankPanelTailSetting();
// The vertical-split full-height layout state (Phase B). The bank window splits
// vertically — pool on top, named-banks region below — and two toggles collapse the
// split: pool full-height (hide the named-banks region) and banks full-height (hide
// the pool). The two are mutually exclusive with the default (both regions shown),
// so one enum captures the whole state.
//
// This bit is B3-owned (the actions flip it); B4's panel RENDERS from it. It lives
// here beside the tail setting — the other session-level view-layout bit the panel
// reads — NOT in the persisted ReaSamplerSession: it is a UI-layout preference, not
// project state, so it must not travel with the .rpp. In-memory for the extension's
// lifetime; resets to Split on unload.
enum class BankPanelFullHeight {
Split, // default: pool region on top, named-banks region below
PoolOnly, // pool full-height — named-banks region hidden
BanksOnly, // banks full-height — pool region hidden
};
// The current full-height layout state (default Split). READ by B4's panel to decide
// which region(s) to draw. Safe before the panel has ever opened.
BankPanelFullHeight bankPanelFullHeight();
// Toggles pool full-height: Split <-> PoolOnly. From PoolOnly returns to Split; from
// either other state (Split or BanksOnly) enters PoolOnly. Bound to the "pool
// full-height" action. Requests a repaint so an open panel reflects the change.
void bankPanelToggledPoolFullHeight();
// Toggles banks full-height: Split <-> BanksOnly, symmetric to the pool toggle.
// Bound to the "banks full-height" action. Requests a repaint.
void bankPanelToggledBanksFullHeight();
// Tears the panel down on extension unload: destroys the window and releases any
// cached thumbnails / PCM handles. Mirror of bankPanelInit; safe if never opened.
void bankPanelShutdown();
} // namespace reasampler