fix: close review findings on spline EGs — engine, codec, and popup/overlay UI grammar
Live pitch depth, Gate/Spline enable-rule agreement, inert kTrigLength, NaN wire guards, hard-flag-tail corruption no longer wipes the record, RT/cold spline tie-break, retired alt-click, marker-shadow fix, plus new test coverage.
This commit is contained in:
@@ -31,17 +31,16 @@ bool ReaSamplerEditor::mouseDownWaveform(const FaceLayout& fl, int x, int y) {
|
||||
if (frames <= 0) return false;
|
||||
const OverlayArea overlay = waveformOverlayArea(fl.bands.waveform);
|
||||
|
||||
// A drawn EG's own point actions come first, for the same reason the staged nodes do —
|
||||
// they sit on top of the markers. Its ADD, which any empty-space click satisfies, is held
|
||||
// back until after the markers below, or a spline overlay would make them unreachable.
|
||||
// A drawn EG's contour is evaluated below, AFTER the markers: pointAtPixel's pick radius
|
||||
// has no box check of its own, so a coincident contour node would otherwise shadow a
|
||||
// marker's own dedicated grab rect (the loop-crossfade tab most sharply, since it is the
|
||||
// ONLY affordance at zero crossfade) — marker reachability wins on any pixel overlap. The
|
||||
// staged envelope-node pass just below is unaffected (its own, longer-standing ordering).
|
||||
const DeckEnableState gates = deckEnableState();
|
||||
const bool splineLive = overlayIsSpline() && overlayEnvEnabled(overlayEnv_, gates);
|
||||
const SplineGesture gesture = (GetKeyState(VK_CONTROL) & 0x8000) != 0
|
||||
? SplineGesture::kControlLeft
|
||||
: SplineGesture::kLeft;
|
||||
if (splineLive && splineOverlayClick(overlay, x, y, gesture, /*addOnEmptySpace=*/false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Envelope nodes first (they sit on top of the markers), then the wave markers. With no
|
||||
// envelope overlay-active — or with its deck group's enable toggle off, which makes the
|
||||
@@ -83,6 +82,11 @@ bool ReaSamplerEditor::mouseDownWaveform(const FaceLayout& fl, int x, int y) {
|
||||
beginMarkerDrag(static_cast<WaveMarker>(hit), m, frames, x);
|
||||
return true;
|
||||
}
|
||||
// No marker wanted the click: a drawn EG's own node grab/toggle (never add — empty space is
|
||||
// tried last, below).
|
||||
if (splineLive && splineOverlayClick(overlay, x, y, gesture, /*addOnEmptySpace=*/false)) {
|
||||
return true;
|
||||
}
|
||||
// Nothing else wanted the click: now the drawn contour may take the empty space.
|
||||
if (splineLive) return splineOverlayClick(overlay, x, y, gesture, /*addOnEmptySpace=*/true);
|
||||
return false;
|
||||
@@ -92,7 +96,15 @@ bool ReaSamplerEditor::splineOverlayClick(const OverlayArea& waveArea, int x, in
|
||||
SplineGesture gesture, bool addOnEmptySpace) {
|
||||
const VelocityCurve::Box box = splineOverlayBox(waveArea);
|
||||
VelocityCurve& contour = splineFor(overlayEnv_);
|
||||
const SplineEdit edit = resolveSplineEdit(contour, box, gesture, x, y);
|
||||
SplineEdit edit = resolveSplineEdit(contour, box, gesture, x, y);
|
||||
// resolveSplineEdit's outside-box grab/delete/toggle allowance (pointAtPixel's radius has
|
||||
// no box check of its own) was designed for the popup's inset ring; the overlay box has NO
|
||||
// inset (splineOverlayBox), so honoring it here would extend the grab halo 6px into the
|
||||
// inter-band pad. kAdd already requires in-box (resolveSplineEdit's own check).
|
||||
if (edit.kind != SplineEditKind::kNone && edit.kind != SplineEditKind::kAdd &&
|
||||
!(x >= box.left && x < box.left + box.width && y >= box.top && y < box.top + box.height)) {
|
||||
edit = SplineEdit{};
|
||||
}
|
||||
if (edit.kind == SplineEditKind::kAdd && !addOnEmptySpace) return false;
|
||||
switch (edit.kind) {
|
||||
case SplineEditKind::kNone:
|
||||
@@ -125,6 +137,10 @@ bool ReaSamplerEditor::splineOverlayClick(const OverlayArea& waveArea, int x, in
|
||||
drag_ = DragKind::kSplineNode;
|
||||
curvePointIndex_ = index;
|
||||
dragStartCurve_ = contour; // AFTER the add — resolvePointDrag's delta base
|
||||
// The release-time drag-off-delete bound (onMouseUp), matching the popup's kCurveNode use
|
||||
// of the same field — the two spline surfaces share one drag-off grammar, not just the
|
||||
// click grammar.
|
||||
dragCurveRect_ = waveArea.rect;
|
||||
dragStartX_ = x;
|
||||
dragStartY_ = y;
|
||||
invalidate(); // live feedback; the commit lands on WM_LBUTTONUP
|
||||
|
||||
Reference in New Issue
Block a user