diff --git a/src/vst/reasampler_editor.cpp b/src/vst/reasampler_editor.cpp index 9304835..2df9ed4 100644 --- a/src/vst/reasampler_editor.cpp +++ b/src/vst/reasampler_editor.cpp @@ -164,6 +164,7 @@ void ReaSamplerEditor::refreshFromBank() { samples_ = banksJson ? listSamples(*banksJson) : std::vector{}; banks_ = banksJson ? listBanks(*banksJson) : std::vector{}; selectedId_ = processor_->selectedSampleId(); + const auto prevZoneCount = static_cast(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(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 diff --git a/src/vst/reasampler_editor.h b/src/vst/reasampler_editor.h index eb8a3c0..9820d2d 100644 --- a/src/vst/reasampler_editor.h +++ b/src/vst/reasampler_editor.h @@ -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)