// sample_bands.cpp — see sample_bands.h. Pure math; no host types. #include "core/instrument/ui/sample_bands.h" #include namespace reasampler::instrument::ui { SampleBands computeSampleBands(int w, int h, int deckHeight) { const int cw = std::max(0, w); const int ch = std::max(0, h); const int deckH = std::max(0, deckHeight); SampleBands b; const int chromeH = std::min(kTitleHeight + kChromeRowHeight, ch); b.chrome = Rect::ltrb(0, 0, cw, chromeH); // Decks are bottom-anchored so the deck row sits on the window edge at any height; the // waveform absorbs whatever is left. When that leaves less than the two-lane floor the // FLOOR WINS and the deck band is pushed past the window bottom (clipped) rather than // squeezing the waveform into an unreadable sliver. int deckTop = ch - kPad - deckH; int waveTop = chromeH + kBandGap; int waveBottom = deckTop - kBandGap; if (waveBottom - waveTop < kWaveformMinHeight) { waveBottom = waveTop + kWaveformMinHeight; deckTop = waveBottom + kBandGap; } b.waveform = Rect::ltrb(kPad, waveTop, std::max(kPad, cw - kPad), waveBottom); b.decks = Rect::ltrb(kPad, deckTop, std::max(kPad, cw - kPad), deckTop + deckH); return b; } WaveformLanes waveformLanes(const Rect& waveform, LaneSplit split) { WaveformLanes lanes; if (waveform.empty()) return lanes; if (split == LaneSplit::Single) { lanes.upper = waveform; // one lane; `lower` stays empty return lanes; } // Split the usable height evenly, giving the seam to the gap. An odd remainder goes to // the upper (left) lane so the two lanes never disagree about the seam row. const int usable = std::max(0, waveform.height - kLaneGap); const int lowerH = usable / 2; const int upperH = usable - lowerH; const int upperBottom = waveform.y + upperH; lanes.upper = Rect::ltrb(waveform.x, waveform.y, waveform.right(), upperBottom); lanes.lower = Rect::ltrb(waveform.x, upperBottom + kLaneGap, waveform.right(), waveform.bottom()); return lanes; } } // namespace reasampler::instrument::ui