fix: S12 R2 — marker-drag sets selectedZone_, ADSR rate-resolve, gateAdsr doc
Marker drag now sets selectedZone_ so single-capture controls stay reachable. Lifted/default ADSR rescales nominal 44100-Hz frame counts by sampleRate/44100 via adsrNeedsRateResolve; v4-authored zones skip rescale. gateAdsr documented vestigial.
This commit is contained in:
@@ -269,32 +269,31 @@ ReaSamplerEditor::SetupMarkers ReaSamplerEditor::pickedMarkers(std::int64_t fram
|
||||
return m;
|
||||
}
|
||||
|
||||
void ReaSamplerEditor::upsertPickedOverride(const SetupMarkers& m) {
|
||||
int ReaSamplerEditor::upsertPickedOverride(const SetupMarkers& m) {
|
||||
// Find-or-append the zone for selectedId_ and write the loop/start override fields.
|
||||
// The bank intrinsic is NEVER written (read-only bank consumer, D-B). selectedId_ must
|
||||
// be non-empty; callers are responsible for that guard.
|
||||
// Returns the zone index (0-based) so callers can update selectedZone_.
|
||||
SampleLoop loop;
|
||||
loop.hasLoop = m.hasLoop;
|
||||
loop.start = m.loopStart;
|
||||
loop.end = m.loopEnd;
|
||||
bool found = false;
|
||||
for (PerformanceZone& z : map_.zones) {
|
||||
for (int i = 0; i < static_cast<int>(map_.zones.size()); ++i) {
|
||||
PerformanceZone& z = map_.zones[static_cast<std::size_t>(i)];
|
||||
if (z.sampleId == selectedId_) {
|
||||
z.loopOverride = loop;
|
||||
z.startPoint = m.start;
|
||||
found = true;
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
PerformanceZone z;
|
||||
z.sampleId = selectedId_;
|
||||
z.lowNote = 0;
|
||||
z.highNote = 127;
|
||||
z.loopOverride = loop;
|
||||
z.startPoint = m.start;
|
||||
map_.zones.push_back(z);
|
||||
}
|
||||
PerformanceZone z;
|
||||
z.sampleId = selectedId_;
|
||||
z.lowNote = 0;
|
||||
z.highNote = 127;
|
||||
z.loopOverride = loop;
|
||||
z.startPoint = m.start;
|
||||
map_.zones.push_back(z);
|
||||
return static_cast<int>(map_.zones.size()) - 1;
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -1322,6 +1321,14 @@ void ReaSamplerEditor::onMouseDown(int x, int y) {
|
||||
dragParamPanel_ = panel;
|
||||
dragStartMap_ = map_;
|
||||
applyControl(id, z.play, valueAtPoint(r.control, x), 0);
|
||||
// An explicit ADSR slider touch commits a rate-resolved value (the slider
|
||||
// maps 0..1 -> editor-domain frames at kEnvTimeMaxFrames, not nominal 44100-Hz
|
||||
// counts). Mark the zone as no longer needing rate-resolve so buildZonedKeymap
|
||||
// does not re-rescale the value at reload time.
|
||||
if (id >= static_cast<int>(ParamControl::kAttack) &&
|
||||
id <= static_cast<int>(ParamControl::kRelease)) {
|
||||
z.adsrNeedsRateResolve = false;
|
||||
}
|
||||
invalidate(); // live feedback; commit on WM_LBUTTONUP
|
||||
}
|
||||
break;
|
||||
@@ -1352,9 +1359,18 @@ void ReaSamplerEditor::onMouseMove(int x, int y) {
|
||||
// zone over the whole keyboard) and round-trips through the v3 component state; the
|
||||
// zone becomes visible if the user opens the Zones panel. Upsert by the picked id so a
|
||||
// repeated drag edits the same zone rather than stacking duplicates.
|
||||
// Upsert the root override on the picked id; track the zone index so the control panel
|
||||
// stays visible after the zone is materialized on the single-capture face (fix: without
|
||||
// setting selectedZone_ here, selectedZone_==-1 with a non-empty map hides controls).
|
||||
bool found = false;
|
||||
for (PerformanceZone& z : map_.zones) {
|
||||
if (z.sampleId == selectedId_) { z.rootOverride = note; found = true; break; }
|
||||
for (int i = 0; i < static_cast<int>(map_.zones.size()); ++i) {
|
||||
PerformanceZone& z = map_.zones[static_cast<std::size_t>(i)];
|
||||
if (z.sampleId == selectedId_) {
|
||||
z.rootOverride = note;
|
||||
selectedZone_ = i;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
PerformanceZone z;
|
||||
@@ -1363,6 +1379,7 @@ void ReaSamplerEditor::onMouseMove(int x, int y) {
|
||||
z.highNote = 127;
|
||||
z.rootOverride = note;
|
||||
map_.zones.push_back(z);
|
||||
selectedZone_ = static_cast<int>(map_.zones.size()) - 1;
|
||||
}
|
||||
invalidate(); // live feedback; the commit lands on WM_LBUTTONUP
|
||||
return;
|
||||
@@ -1407,8 +1424,10 @@ void ReaSamplerEditor::onMouseMove(int x, int y) {
|
||||
if (m.start > frames - 1) m.start = frames - 1;
|
||||
|
||||
// Upsert the override on the picked id (mirror of the root-marker path); commit lands on
|
||||
// release, this is live feedback.
|
||||
upsertPickedOverride(m);
|
||||
// release, this is live feedback. Set selectedZone_ so the control panel stays visible
|
||||
// after the zone is materialized (fix: without this, selectedZone_==-1 with a non-empty
|
||||
// map hides controls after the first marker drag on the single-capture face).
|
||||
selectedZone_ = upsertPickedOverride(m);
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user