Files
reasampler/src/core/instrument/ui/sample_bands.h
T
daniel cfb53aade3 fix: close review findings on the velocity-curve deck and bipolar curves
Cancels the curve-node drag whenever the popup closes so Esc mid-drag can't alias the amp curve; generalizes CurveTarget routing to one switch; fixes stale/overstated comments; clamps a pre-v12 depth fold; adds deck-inertness and filter-fold test coverage.
2026-07-31 19:46:37 -04:00

67 lines
3.3 KiB
C++

#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.
inline constexpr int kEditorMinWidth = 840;
inline constexpr int kEditorMinHeight = 620;
// 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 = 52;
// 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