Loop: an explicit enable, four named marks with grabbable caps, and the crossfade painted where it is actually heard

hasLoop becomes user-owned with the gestures as shortcuts onto it; no format change. START uses overlay/trace, not accent/primary, which is the waveform's own fill.
This commit is contained in:
2026-08-02 05:18:53 -04:00
parent ef59265e7a
commit a7c3c7a828
26 changed files with 1190 additions and 191 deletions
+21 -2
View File
@@ -1,6 +1,6 @@
// editor_input_chrome.cpp — the CHROME band's input: the Browse nav, the preview trigger,
// the preview-velocity knob grab, the channel toggle, and the piano strip's root grab plus
// its live drag. Windows-only.
// the preview-velocity knob grab, the loop enable, the channel toggle, and the piano strip's
// root grab plus its live drag. Windows-only.
#include "shell/instrument/reasampler_editor.h"
@@ -73,6 +73,21 @@ bool ReaSamplerEditor::mouseDownChrome(const FaceLayout& fl, int x, int y) {
invalidate();
return true;
}
// The loop enable. Inert (not hidden) outside Gate: that refusal comes from the engine and
// no click can talk it out of it — unlike the user's own off, which the marks themselves
// still offer to reverse.
if (loopControlsLive()) {
if (contains(cr.loopOff, x, y)) {
setLoopEnabled(false);
invalidate();
return true;
}
if (contains(cr.loopOn, x, y)) {
setLoopEnabled(true);
invalidate();
return true;
}
}
if (contains(cr.chanMono, x, y)) {
channelMode_ = ChannelMode::Mono;
processor_->setChannelMode(ChannelMode::Mono);
@@ -146,6 +161,10 @@ ReaSamplerEditor::HoverTarget ReaSamplerEditor::hoverChrome(const FaceLayout& fl
if (contains(cr.bake, x, y)) return {HoverKind::kBake, -1};
if (contains(cr.preview, x, y)) return {HoverKind::kPreview, -1};
if (contains(cr.velCell, x, y)) return {HoverKind::kVelKnob, -1};
if (loopControlsLive()) {
if (contains(cr.loopOff, x, y)) return {HoverKind::kLoopOff, -1};
if (contains(cr.loopOn, x, y)) return {HoverKind::kLoopOn, -1};
}
if (contains(cr.chanMono, x, y)) return {HoverKind::kChanMono, -1};
if (contains(cr.chanStereo, x, y)) return {HoverKind::kChanStereo, -1};
if (!cr.rootStrip.empty()) {