fix(editor): close curve popup on zone-count change; degenerate-rect guard + comment corrections

This commit is contained in:
2026-07-28 00:09:13 -04:00
parent 682c21509a
commit 40bcf0d56d
2 changed files with 15 additions and 8 deletions
+14 -7
View File
@@ -164,6 +164,7 @@ void ReaSamplerEditor::refreshFromBank() {
samples_ = banksJson ? listSamples(*banksJson) : std::vector<SampleChoice>{};
banks_ = banksJson ? listBanks(*banksJson) : std::vector<BankChoice>{};
selectedId_ = processor_->selectedSampleId();
const auto prevZoneCount = static_cast<int>(map_.zones.size());
map_ = processor_->performanceMap();
channelMode_ = processor_->channelMode();
voiceCount_ = processor_->voiceCount(); // Phase S voice-deck snapshot
@@ -174,9 +175,13 @@ void ReaSamplerEditor::refreshFromBank() {
// curve popup — the empty-state Sample face no longer draws it, and an open-but-invisible
// modal would swallow clicks.
if (selectedId_.empty() && map_.zones.empty()) curvePopupOpen_ = false;
// FB2: on the Zone surface the popup edits the SELECTED zone; if the refresh dropped the
// selection (the zones list shrank), close it rather than let it retarget another zone.
if (view_ == View::kZone && selectedZone_ < 0) curvePopupOpen_ = false;
// FB2: on the Zone surface the popup edits the SELECTED zone; close it if the zones list
// shrank (selectedZone_ past-end), OR if the zone count changed at all — a mid-list
// deletion leaves selectedZone_ in range but now naming a DIFFERENT zone (silent retarget).
if (view_ == View::kZone && curvePopupOpen_) {
const auto newZoneCount = static_cast<int>(map_.zones.size());
if (selectedZone_ < 0 || newZoneCount != prevZoneCount) curvePopupOpen_ = false;
}
// Drop a filter that names a bank no longer present.
if (!activeFilterBankId_.empty()) {
bool found = false;
@@ -877,7 +882,7 @@ constexpr int kPad = 8;
// cluster's and the Zone panel's (the inline Zone box is retired). The INSET keeps node handles
// + the pick radius inside the border so an endpoint at amp 0/1 stays grabbable — the ONE
// curveBoxFromRect grammar the popup derives its mapping box through.
constexpr int kVelCurveInset = 14; // border -> mapping-box inset: caption band (~12px) + 2px gap
constexpr int kVelCurveInset = 14; // border -> mapping-box inset: keeps endpoint handles + pick radius inside the border
constexpr int kCurveDragOffMargin = 24; // release beyond box+margin -> drag-off delete
// The r11 cluster's fixed right-anchored run (left -> right: Preview button, the radial
@@ -996,9 +1001,10 @@ Rect zonesControlPanel(const Rect& content) {
// FB2 (R11-F2 parity): the Zone panel's per-zone controls render as the SAME knob deck the
// Sample face uses. The deck lays out from the panel top (top-anchored — the Zone panel reads
// top-down, unlike the Sample face's bottom-anchored band), with a column at the panel's right
// reserved for the mini curve-preview button so a deck row can never collide with it (the pure
// knob_deck wrap keeps whole groups inside availWidth). Both draw + hit-test derive from these
// two formulas so they never drift.
// reserved for the mini curve-preview button so no deck row starts inside it (layoutDeck places
// the first group of each row unconditionally; collision avoidance relies on the available
// width margin in practice). Both draw + hit-test derive from these two formulas so they never
// drift.
Rect zonesDeckArea(const Rect& content) {
const Rect panel = zonesControlPanel(content);
return Rect{panel.left, panel.top, panel.right - kCurveBtnSize - kPad, panel.bottom};
@@ -1544,6 +1550,7 @@ void ReaSamplerEditor::paintKnobDeck(LICE_IBitmap* bmp, const Rect& deckArea,
void ReaSamplerEditor::paintCurveButton(LICE_IBitmap* bmp, const Rect& r,
const PerformanceZone& zone) {
if (r.width() <= 0 || r.height() <= 0) return;
// The mini curve-preview button (r11/FB2 — shared by the Sample cluster and the Zone
// panel): a hairline-bordered bg/cell square with the zone's live velocity curve traced
// in miniature (no node markers at this scale). Hover lifts it; it draws ACTIVE
+1 -1
View File
@@ -143,7 +143,7 @@ private:
kPreview, // the Sample-view preview-trigger button
kAddZone, // the "+ Add Zone" button
kDeleteZone, // the "Delete" zone button
kControl, // a param-panel control row / deck element (index = control id)
kControl, // a knob-deck element (index = control id)
kCurveNode, // a velocity-curve control point (index = point index, S-VIEW-10)
kVelKnob, // the cluster preview-velocity radial knob (r11)
kCurveButton, // the cluster mini curve-preview button (r11 — opens the popup)