96 lines
4.6 KiB
C++
96 lines
4.6 KiB
C++
// 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.
|
|
//
|
|
// 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).
|
|
//
|
|
// 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
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "core/instrument/ui/capture_browser.h" // BrowserLayout, cardCellRect, kBrowserCardHeight, Rect
|
|
|
|
namespace reasampler::instrument::ui {
|
|
|
|
// 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;
|
|
|
|
// 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;
|
|
|
|
// 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);
|
|
|
|
// Maximum scroll offset: content height minus visible grid height, floored at 0.
|
|
int scrollMaxOffset(const BrowserLayout& layout, int cardCount);
|
|
|
|
// Clamps a proposed scroll offset into [0, scrollMaxOffset].
|
|
int clampScrollOffset(const BrowserLayout& layout, int cardCount, int proposedOffset);
|
|
|
|
// 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;
|
|
int last = 0;
|
|
};
|
|
VisibleRange visibleCardRange(const BrowserLayout& layout, int cardCount, int offset);
|
|
|
|
// 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);
|
|
|
|
// 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);
|
|
|
|
// 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);
|
|
|
|
// 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.
|
|
bool nameMatchesQuery(const std::string& name, const std::string& query);
|
|
|
|
// 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);
|
|
|
|
// --- 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. Homed here (not editor_geometry) because the search-box
|
|
// height feeds it.
|
|
struct BrowseModal {
|
|
Rect title;
|
|
Rect back;
|
|
Rect search;
|
|
Rect content; // browser sub-area (tabs + grid) — layoutBrowser's origin
|
|
Rect cancel;
|
|
Rect confirm;
|
|
};
|
|
BrowseModal computeBrowseModal(int w, int h);
|
|
|
|
} // namespace reasampler::instrument::ui
|