#pragma once // sample_bands.h — THE band-stack allocator for the Sample face: the one module that owns // the editor's vertical inventory. Three bands, top to bottom — CHROME (toolbar + control // row), WAVEFORM (elastic, sized to hold two stacked channel lanes), DECKS (the knob-deck // row). Everything else in the editor fills a band it is handed; nothing else allocates // vertical space, so a band's owner can re-lay its interior without moving its neighbours. #include "core/instrument/ui/editor_geometry.h" // Rect namespace reasampler::instrument::ui { // Shared outer inset every band honours horizontally. inline constexpr int kPad = 8; // The editor's client-area floor, which IS its default size: the band stack is laid out for // exactly this, and there is no scroll, so anything smaller pushes the deck band off the // window bottom (computeSampleBands' waveform-floor-wins degrade). Growing is fine — the // waveform band is the elastic one. Both the enforced minimum and the opening rect read this. // // The width is a LITERAL here on purpose, though it is derived from knob_deck's width budget: // this allocator is deliberately independent of the deck (it takes deckHeight as a parameter // for exactly that reason), so the derivation is asserted in test_deck_groups.cpp — the one // place that already includes both headers — rather than coded as an include edge. inline constexpr int kEditorMinWidth = 1190; inline constexpr int kEditorMinHeight = 680; // The hard ceiling the floor above may not exceed; the window itself still grows freely above // it. A window fact, sibling of kEditorMinWidth/kEditorMinHeight, not a deck one — moved here // from knob_deck.h for that reason. The gap to the floor (today: 90px) is the deck's whole // width budget, spent once; the identity is asserted in test_deck_groups.cpp, the one place // that already includes both this header and knob_deck.h. inline constexpr int kEditorCeilingWidth = 1280; // Chrome band: the toolbar row (title + nav) stacked over the control row (piano strip, // preview, velocity knob, channel toggle). sample_chrome partitions it. inline constexpr int kTitleHeight = 26; inline constexpr int kChromeRowHeight = 64; // Waveform band floor: two stacked lanes plus the seam between them. The band never shrinks // below this — a window too short for it clips the bands beneath instead, so the waveform // stays a usable two-lane surface at every size. inline constexpr int kLaneMinHeight = 74; inline constexpr int kLaneGap = 2; inline constexpr int kWaveformMinHeight = 2 * kLaneMinHeight + kLaneGap; // Vertical seam between adjacent bands. inline constexpr int kBandGap = 4; // The vertical inventory. Bands never overlap and are returned top-to-bottom; a band may be // empty() on a degenerate window, in which case its owner draws and hit-tests nothing. struct SampleBands { Rect chrome; // full width: toolbar row + control row Rect waveform; // kPad-inset, elastic, >= kWaveformMinHeight Rect decks; // kPad-inset, bottom-anchored, height `deckHeight` }; // Divide a (w x h) client area into the three bands. `deckHeight` is the knob deck's own // wrapped height (from knob_deck) — the only interior measurement the allocator needs, so // the deck band is exactly as tall as its content. Pure. SampleBands computeSampleBands(int w, int h, int deckHeight); // The waveform band's two channel lanes: L above R, separated by kLaneGap. In mono only // `upper` is populated (it takes the whole band) and `lower` is empty — a mono capture has // no second lane to draw, and overlays that ride the waveform draw ONCE across the whole // band in either mode, never per lane. struct WaveformLanes { Rect upper; Rect lower; // empty() in mono }; // A RESOLVED lane-split decision, not "is the instrument in stereo mode" — a mono source // stays Single even in stereo mode (dual-mono, no second channel to draw). Only // waveformSurface (waveform_view) folds the source channel count in; a bare bool here would // let a caller pass isStereoMode straight through and skip that check. enum class LaneSplit { Single, Stereo }; WaveformLanes waveformLanes(const Rect& waveform, LaneSplit split); } // namespace reasampler::instrument::ui