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
+28 -4
View File
@@ -1,7 +1,7 @@
// editor_paint_chrome.cpp — the CHROME band's painter: the toolbar row (product title +
// live readout, then the control run — preview, preview-velocity knob, Mono|Stereo, Browse)
// over the strip row, which the piano strip has to itself. Windows-only; all rects come from
// the pure sample_chrome interior and the pure keyboard_strip geometry.
// live readout, then the control run — preview, preview-velocity knob, Loop Off|On,
// Mono|Stereo, Browse) over the strip row, which the piano strip has to itself. Windows-only;
// all rects come from the pure sample_chrome interior and the pure keyboard_strip geometry.
#include "shell/instrument/reasampler_editor.h"
@@ -94,7 +94,8 @@ void drawRootKey(LICE_IBitmap* bmp, const Rect& area, const StripLayout& sl, int
} // namespace
void ReaSamplerEditor::paintChrome(LICE_IBitmap* bmp, const FaceLayout& fl, bool empty) {
void ReaSamplerEditor::paintChrome(LICE_IBitmap* bmp, const FaceLayout& fl, bool empty,
const SetupMarkers& marks) {
const ChromeRects& cr = fl.chrome;
fillSurface(bmp, toKitBox(cr.toolbar), Role::BgPanel, InteractionState::Rest);
@@ -211,6 +212,29 @@ void ReaSamplerEditor::paintChrome(LICE_IBitmap* bmp, const FaceLayout& fl, bool
}
}
// Loop Off | On. A two-segment toggle in the same primitive as Mono|Stereo because it is
// the same class of control: a playback mode of the loaded capture. Outside Gate both
// segments draw Disabled and neither accepts a click — the state is preserved, not cleared,
// so the return to Gate restores it.
{
const bool live = loopControlsLive();
const bool on = marks.hasLoop;
const auto segState = [&](bool active, HoverKind hk) {
if (!live) return InteractionState::Disabled;
if (active) return InteractionState::Active;
return isHovered(hk, -1) ? InteractionState::Hover : InteractionState::Rest;
};
const InteractionState offState = segState(!on, HoverKind::kLoopOff);
const InteractionState onState = segState(on, HoverKind::kLoopOn);
fillSurface(bmp, toKitBox(cr.loopOff), Role::BgCell, offState);
fillSurface(bmp, toKitBox(cr.loopOn), Role::BgCell, onState);
const Role dim = live ? Role::TextPrimary : Role::TextDim;
kitTextCentered(bmp, cr.loopOff, "Loop Off", kToolbarFont,
(live && !on) ? Role::BgBase : dim);
kitTextCentered(bmp, cr.loopOn, "Loop On", kToolbarFont,
(live && on) ? Role::BgBase : dim);
}
// Mono | Stereo output-mode toggle.
{
const bool isStereo = (channelMode_ == ChannelMode::Stereo);