fix(zone-view): Add Zone seeds narrow octave range so new zones survive reconcile
This commit is contained in:
@@ -1943,10 +1943,13 @@ void ReaSamplerEditor::onMouseDown(int x, int y) {
|
|||||||
Rect addR{content.left + pad, content.top + 4, content.left + pad + 96,
|
Rect addR{content.left + pad, content.top + 4, content.left + pad + 96,
|
||||||
content.top + 4 + 20};
|
content.top + 4 + 20};
|
||||||
if (contains(addR, x, y)) {
|
if (contains(addR, x, y)) {
|
||||||
// Add a full-keyboard zone for the picked capture (or the first visible sample as a
|
// Add a narrow default zone for the picked capture (or the first visible sample as a
|
||||||
// sensible seed). No pick -> nothing to add. If a full-keyboard zone for the seed id
|
// sensible seed). No pick -> nothing to add. If a full-keyboard zone for the seed id
|
||||||
// already exists, select it rather than appending a duplicate (mirrors the upsert the
|
// already exists (pre-fix bleed survivor), select it rather than appending a duplicate
|
||||||
// root-marker drag path already performs, preventing overlapping identical zones).
|
// (mirrors the upsert the root-marker drag path already performs).
|
||||||
|
// NARROW DEFAULT: seed [root-6, root+5] (one octave centred on the bank root, clamped
|
||||||
|
// to [0,127]) so the new zone is immediately "authored" (narrow) and survives
|
||||||
|
// reconcileSingleCaptureZones without being treated as a Sample-face full-range zone.
|
||||||
std::string seed = !selectedId_.empty() ? selectedId_
|
std::string seed = !selectedId_.empty() ? selectedId_
|
||||||
: (!visible_.empty() ? visible_.front().id : std::string());
|
: (!visible_.empty() ? visible_.front().id : std::string());
|
||||||
if (seed.empty()) return;
|
if (seed.empty()) return;
|
||||||
@@ -1958,10 +1961,17 @@ void ReaSamplerEditor::onMouseDown(int x, int y) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Look up the seed's root note from the browser list (absent root defaults to 60).
|
||||||
|
int seedRoot = 60;
|
||||||
|
for (const SampleChoice& sc : samples_) {
|
||||||
|
if (sc.id == seed) { if (sc.rootNote.has_value()) seedRoot = *sc.rootNote; break; }
|
||||||
|
}
|
||||||
|
const int lo = (std::max)(0, seedRoot - 6);
|
||||||
|
const int hi = (std::min)(127, seedRoot + 5);
|
||||||
PerformanceZone z;
|
PerformanceZone z;
|
||||||
z.sampleId = seed;
|
z.sampleId = seed;
|
||||||
z.lowNote = 0;
|
z.lowNote = lo;
|
||||||
z.highNote = 127;
|
z.highNote = hi;
|
||||||
map_.zones.push_back(z);
|
map_.zones.push_back(z);
|
||||||
selectedZone_ = static_cast<int>(map_.zones.size()) - 1;
|
selectedZone_ = static_cast<int>(map_.zones.size()) - 1;
|
||||||
commitAndReload();
|
commitAndReload();
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ tresult PLUGIN_API ReaSamplerProcessor::setState(IBStream* state) {
|
|||||||
// editor shows is the sample the engine plays" for already-affected projects; authored
|
// editor shows is the sample the engine plays" for already-affected projects; authored
|
||||||
// Zone-view maps (any narrow key range) pass through untouched.
|
// Zone-view maps (any narrow key range) pass through untouched.
|
||||||
PerformanceMap restored = cs.map;
|
PerformanceMap restored = cs.map;
|
||||||
reconcileSingleCaptureZones(restored, cs.selectionId);
|
reconcileSingleCaptureZones(restored, cs.selectionId); // bool return ignored: setPerformanceMap + reloadFromBank run unconditionally on load
|
||||||
setPerformanceMap(restored);
|
setPerformanceMap(restored);
|
||||||
// S8: restore the last-consumed assignment generation so a re-open does not re-apply a
|
// S8: restore the last-consumed assignment generation so a re-open does not re-apply a
|
||||||
// stale assign_request (the user may have manually changed the selection after the assign).
|
// stale assign_request (the user may have manually changed the selection after the assign).
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ struct PerformanceMap {
|
|||||||
// authorship; first-match order is load-bearing there — untouched, false. The Sample
|
// authorship; first-match order is load-bearing there — untouched, false. The Sample
|
||||||
// face never creates a narrow zone, so a narrow zone proves deliberate multi-zone intent.
|
// face never creates a narrow zone, so a narrow zone proves deliberate multi-zone intent.
|
||||||
// * else (every zone full-range — the map is purely Sample-face-shaped): keep only the
|
// * else (every zone full-range — the map is purely Sample-face-shaped): keep only the
|
||||||
// first zone bound to `selectedId` (its params survive a return to that sample); drop
|
// first zone bound to `selectedId` (the selection's own params are not reset); drop
|
||||||
// the rest. A selection with no zone yet empties the map (the shell then plays the
|
// the rest. A selection with no zone yet empties the map (the shell then plays the
|
||||||
// selection via the Tier-0 fast path with product defaults).
|
// selection via the Tier-0 fast path with product defaults).
|
||||||
// Returns true iff the map changed (the caller republishes + reloads on true).
|
// Returns true iff the map changed (the caller republishes + reloads on true).
|
||||||
|
|||||||
Reference in New Issue
Block a user