Cut core/instrument/ui comment bloat ~49% (comments only, zero code change)

This commit is contained in:
2026-07-29 20:48:39 -04:00
parent 1f24c4b095
commit ccd9968be1
21 changed files with 539 additions and 1043 deletions
+47 -76
View File
@@ -1,23 +1,16 @@
// browser_scroll.h — PURE scroll + type-to-filter geometry LAYERED over the S10
// capture_browser. NO VST3, NO REAPER, NO SWELL/LICE types at the boundary. The mirror of
// capture_browser / editor_geometry: the fiddly scroll-window + scrollbar-thumb + search-box
// arithmetic lives here, unit-tested outside the DAW, while the editor shell draws the
// clipped card window + the scrollbar + the search field and routes wheel/drag/keystrokes
// into these functions.
// browser_scroll.h — scroll + type-to-filter geometry layered over capture_browser. Mirror
// of capture_browser/editor_geometry; the shell draws the clipped card window, scrollbar,
// and search field, and routes wheel/drag/keystrokes into these functions.
//
// WHY IT EXISTS (S12). capture_browser (S10) lays out EVERY card top-down and the shell
// clips at the browser bottom — a bank longer than the panel runs off with no way to reach
// it (the S12 gap). This module adds the two things S12 layers over that stable geometry:
// * SCROLL — a vertical pixel offset into the card grid, with the max-offset clamp, the
// visible-row window, a scrollbar thumb rect, and the thumb-drag<->offset mapping so a
// wheel tick or a thumb drag reaches every card; and
// * SEARCH — a name-substring filter (case-insensitive) that narrows the drawn cards,
// COMPOSING with capture_browser's bank filter (the shell applies the bank filter first,
// then this search narrows within it) + the search-box rect the shell draws the field in.
// capture_browser lays out every card top-down and the shell clips at the browser bottom —
// a bank longer than the panel has no way to reach the rest. This module adds scroll (a
// vertical pixel offset with max-offset clamp, visible-row window, scrollbar thumb, and
// thumb-drag<->offset mapping) and search (a case-insensitive name-substring filter that
// composes with capture_browser's bank filter — the shell applies the bank filter first,
// then this search narrows within it).
//
// It holds NO card data and draws nothing — it knows only the browser layout (from
// capture_browser), COUNTS, and the scroll OFFSET the shell owns as transient UI state. It
// reuses capture_browser's BrowserLayout + the shared Rect (one geometry idiom).
// Holds no card data and draws nothing — knows only the browser layout, counts, and the
// scroll offset the shell owns as transient UI state.
#pragma once
@@ -28,96 +21,74 @@
namespace reasampler::instrument::ui {
// The width (px) of the vertical scrollbar gutter at the right edge of the grid. The shell
// draws the track + thumb here and hit-tests thumb grabs against scrollThumbRect. Exposed so
// the shell and tests agree. When the content fits (no scroll needed) the scrollbar is
// suppressed (scrollThumbRect returns empty) and the shell may reclaim the gutter.
// Width of the vertical scrollbar gutter at the grid's right edge. When content fits (no
// scroll needed), scrollThumbRect returns empty and the shell may reclaim the gutter.
inline constexpr int kScrollbarWidth = 10;
// The height (px) of the type-to-filter search box the shell draws ABOVE the tab strip (a
// thin band spanning the browser width). Exposed so the shell reserves the band and tests
// agree. capture_browser's tab strip + grid sit BELOW this band (the shell offsets the
// BrowserLayout it feeds to capture_browser by kSearchBoxHeight).
// Height of the type-to-filter search box the shell draws above the tab strip.
// capture_browser's tab strip + grid sit below this band.
inline constexpr int kSearchBoxHeight = 22;
// The total pixel HEIGHT the card grid needs to draw all `cardCount` cards at `layout`'s
// column count: the number of ROWS (ceil(cardCount / columns)) times the fixed cell height.
// Zero cards -> 0. Pure — the content extent the scroll offset ranges over.
// Total pixel height the card grid needs for `cardCount` cards at `layout`'s column
// count: rows (ceil(cardCount / columns)) times the fixed cell height.
int scrollContentHeight(const BrowserLayout& layout, int cardCount);
// The maximum scroll offset (px): content height minus the visible grid height, floored at 0.
// When the content fits within the grid this is 0 (nothing to scroll). Pure — the clamp
// ceiling for every offset the shell tracks.
// Maximum scroll offset: content height minus visible grid height, floored at 0.
int scrollMaxOffset(const BrowserLayout& layout, int cardCount);
// Clamp a proposed scroll offset into [0, scrollMaxOffset]. The shell clamps after every wheel
// tick / thumb drag so an over-scroll pins to an edge rather than showing past the last card
// or above the first. Pure.
// Clamps a proposed scroll offset into [0, scrollMaxOffset].
int clampScrollOffset(const BrowserLayout& layout, int cardCount, int proposedOffset);
// The half-open range of card INDICES [first, last) at least partially visible in the grid at
// scroll `offset`. The shell draws only these cards (the S12 clip window) rather than every
// card. `offset` is assumed pre-clamped (the shell clamps on input); a first past the last row
// yields an empty range (first==last==cardCount). Pure.
// Half-open range of card indices [first, last) at least partially visible at scroll
// `offset` (assumed pre-clamped). The shell draws only these cards.
struct VisibleRange {
int first = 0; // first card index drawn (inclusive)
int last = 0; // one past the last card index drawn (exclusive)
int first = 0;
int last = 0;
};
VisibleRange visibleCardRange(const BrowserLayout& layout, int cardCount, int offset);
// The cell rect of card `index` SHIFTED UP by the scroll offset, ready to draw (the shell
// still adds the browser sub-area origin). Equivalent to capture_browser::cardCellRect with
// the offset subtracted from top/bottom. Pure — the one place the offset applies to a card.
// Cell rect of card `index` shifted up by the scroll offset (the shell still adds the
// browser sub-area origin).
Rect scrolledCardCellRect(const BrowserLayout& layout, int index, int offset);
// The vertical scrollbar THUMB rect within the grid's right-edge gutter, sized proportional to
// the visible fraction (grid height / content height) and positioned proportional to the
// scroll offset. Returns an EMPTY rect when the content fits (no scroll needed) — the shell
// suppresses the scrollbar then. A minimum thumb height keeps a tiny thumb grabbable on a very
// long bank. Pure — the geometry the shell draws + hit-tests the thumb grab against.
// Vertical scrollbar thumb rect within the grid's right-edge gutter, sized proportional
// to the visible fraction and positioned proportional to the scroll offset. Empty when
// the content fits. A minimum thumb height keeps a tiny thumb grabbable on a long bank.
Rect scrollThumbRect(const BrowserLayout& layout, int cardCount, int offset);
// Map a thumb-drag to a scroll offset. Given the offset the thumb held at grab time
// (`startOffset`) and the vertical pixel delta since grab (`dyPixels`), returns the new
// (clamped) scroll offset: startOffset shifted by the delta scaled from thumb-track pixels to
// content pixels (a 1px thumb move covers content/track px of content). A degenerate track /
// fitting content pins to startOffset. Pure — the inverse of scrollThumbRect's position map.
// Maps a thumb-drag to a new (clamped) scroll offset: `startOffset` shifted by the pixel
// delta scaled from thumb-track pixels to content pixels. A degenerate track or fitting
// content pins to startOffset.
int thumbDragToOffset(const BrowserLayout& layout, int cardCount, int startOffset, int dyPixels);
// The search-box rect: a full-width band of height kSearchBoxHeight at the TOP of the browser
// area (above where capture_browser's tab strip draws). `w` is the browser sub-area width;
// the shell adds its origin. A zero/negative width yields an empty rect. Pure.
// Search-box rect: full-width band of height kSearchBoxHeight at the top of the browser
// area. `w` is the browser sub-area width; the shell adds its origin.
Rect searchBoxRect(int w);
// True iff `name` contains `query` as a case-insensitive ASCII substring. An EMPTY query
// matches everything (the no-filter identity). Matching is ASCII case-folded (the display
// names are ASCII until the Phase L type kit lands, mirroring the editor's other ASCII-only
// text). Pure — the single match predicate the shell's search narrow is built from.
// True iff `name` contains `query` as a case-insensitive ASCII substring. An empty query
// matches everything.
bool nameMatchesQuery(const std::string& name, const std::string& query);
// Narrow a list of display `names` to the INDICES whose name matches `query`, preserving
// order. An EMPTY query returns every index [0, names.size()) (the composition base so "bank
// filter, no search" == today's browser). Kept name-only (indices, not card structs) so this
// module stays free of the sample_map/bank_book chain — the shell owns the SampleChoice list
// and applies the bank filter FIRST, then feeds the surviving display names here (search
// narrows within the bank). Pure.
// Narrows a list of display `names` to the indices whose name matches `query`, preserving
// order. An empty query returns every index. Kept name-only (indices, not card structs)
// so this module stays free of the sample_map/bank_book chain — the shell applies the
// bank filter first, then feeds the surviving display names here.
std::vector<int> filterNameIndices(const std::vector<std::string>& names,
const std::string& query);
// --- The Browse-modal (S-VIEW-5) top-level regions (Q-W2v hoist, T2-06) -------
// --- Browse-modal top-level regions --------------------------------------------
//
// A title band with a Back button, the search box, the browser sub-area (tabs + card
// grid — layoutBrowser's origin), and a footer with Cancel / Load-confirm. The picker
// covers the full window (F3: full-window overlay). Draw + hit-test both derive from
// this single layout so they never drift. Homed here (not editor_geometry) because the
// search-box height feeds it — browser_scroll already owns the search/scroll geometry.
// covers the full window. Homed here (not editor_geometry) because the search-box
// height feeds it.
struct BrowseModal {
Rect title;
Rect back; // the "Back" title-band button
Rect search; // the type-to-filter box (absolute)
Rect content; // the browser sub-area (tabs + grid) — layoutBrowser's origin
Rect cancel; // footer Cancel
Rect confirm; // footer Load (confirm)
Rect back;
Rect search;
Rect content; // browser sub-area (tabs + grid) — layoutBrowser's origin
Rect cancel;
Rect confirm;
};
BrowseModal computeBrowseModal(int w, int h);