instrument: latch the note done at the read-head run-off, fit the migrated fades, and lift the curve dial and overlay selection into pure modules
This commit is contained in:
@@ -3,8 +3,9 @@
|
||||
// descriptors the Sample face carries: the signal-flow group order (pitch -> filter -> amp),
|
||||
// the Filter group's contents, the wrapped deck height at the editor's floor width and its fit
|
||||
// inside the floor window, the hit-test reaching the new filter controls, the bipolar knob
|
||||
// law's inverse pair, and the commit-tier routing — which controls are live, and which drags
|
||||
// take the live tier.
|
||||
// law's inverse pair, the commit-tier routing — which controls are live, and which drags take
|
||||
// the live tier — and the overlay-selection state machine (exclusivity, the none resting state,
|
||||
// and which selections are inert).
|
||||
|
||||
#include "../src/core/instrument/ui/deck_groups.h"
|
||||
#include "../src/core/instrument/ui/sample_bands.h"
|
||||
@@ -341,7 +342,66 @@ static void testOnlyALiveControlsDragTakesTheLiveTier() {
|
||||
CHECK(!liveCommitFor(LiveDragKind::kOther, static_cast<int>(DeckParam::kFilterCutoff)));
|
||||
}
|
||||
|
||||
// --- The overlay selection state machine ---------------------------------------
|
||||
|
||||
static int radio(DeckParam p) { return static_cast<int>(p); }
|
||||
|
||||
// EXCLUSIVITY: picking another deck's radio switches to it outright — two envelopes can never
|
||||
// be overlay-active at once, whatever the previous selection was.
|
||||
static void testOverlaySelectionIsExclusiveAcrossTheThreeEnvelopeDecks() {
|
||||
const OverlayEnv states[] = {OverlayEnv::kNone, OverlayEnv::kAmp, OverlayEnv::kPitch,
|
||||
OverlayEnv::kFilter};
|
||||
for (OverlayEnv from : states) {
|
||||
if (from != OverlayEnv::kAmp) {
|
||||
CHECK(nextOverlaySelection(from, radio(DeckParam::kAmpEnvSelect)) == OverlayEnv::kAmp);
|
||||
}
|
||||
if (from != OverlayEnv::kPitch) {
|
||||
CHECK(nextOverlaySelection(from, radio(DeckParam::kPitchEnvSelect)) ==
|
||||
OverlayEnv::kPitch);
|
||||
}
|
||||
if (from != OverlayEnv::kFilter) {
|
||||
CHECK(nextOverlaySelection(from, radio(DeckParam::kFilterEnvSelect)) ==
|
||||
OverlayEnv::kFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// kNone is a RESTING STATE the user can get back to: clicking the active radio clears it.
|
||||
static void testClickingTheActiveOverlayRadioClearsToNone() {
|
||||
CHECK(nextOverlaySelection(OverlayEnv::kAmp, radio(DeckParam::kAmpEnvSelect)) ==
|
||||
OverlayEnv::kNone);
|
||||
CHECK(nextOverlaySelection(OverlayEnv::kPitch, radio(DeckParam::kPitchEnvSelect)) ==
|
||||
OverlayEnv::kNone);
|
||||
CHECK(nextOverlaySelection(OverlayEnv::kFilter, radio(DeckParam::kFilterEnvSelect)) ==
|
||||
OverlayEnv::kNone);
|
||||
}
|
||||
|
||||
// A control that is not one of the three radios selects nothing and clears nothing.
|
||||
static void testANonRadioIdLeavesTheOverlaySelectionAlone() {
|
||||
CHECK(overlayEnvForRadio(radio(DeckParam::kFilterCutoff)) == OverlayEnv::kNone);
|
||||
CHECK(overlayEnvForRadio(-1) == OverlayEnv::kNone);
|
||||
CHECK(nextOverlaySelection(OverlayEnv::kFilter, radio(DeckParam::kFilterCutoff)) ==
|
||||
OverlayEnv::kFilter);
|
||||
CHECK(nextOverlaySelection(OverlayEnv::kAmp, 9999) == OverlayEnv::kAmp);
|
||||
}
|
||||
|
||||
// An overlay whose deck group is switched OFF is inert, matching the drawn-but-dead knobs on
|
||||
// the same params: a node drag must not reach a value the knob refuses.
|
||||
static void testOverlayIsInertExactlyWhenItsGroupToggleIsOff() {
|
||||
CHECK(overlayEnvInert(OverlayEnv::kPitch, /*pitchEnv=*/false, /*filter=*/true));
|
||||
CHECK(!overlayEnvInert(OverlayEnv::kPitch, true, true));
|
||||
CHECK(overlayEnvInert(OverlayEnv::kFilter, true, /*filter=*/false));
|
||||
CHECK(!overlayEnvInert(OverlayEnv::kFilter, true, true));
|
||||
// Amp has no enable toggle, so it is never inert; kNone draws nothing to grab.
|
||||
CHECK(!overlayEnvInert(OverlayEnv::kAmp, false, false));
|
||||
CHECK(!overlayEnvInert(OverlayEnv::kNone, false, false));
|
||||
}
|
||||
|
||||
int main() {
|
||||
testOverlaySelectionIsExclusiveAcrossTheThreeEnvelopeDecks();
|
||||
testClickingTheActiveOverlayRadioClearsToNone();
|
||||
testANonRadioIdLeavesTheOverlaySelectionAlone();
|
||||
testOverlayIsInertExactlyWhenItsGroupToggleIsOff();
|
||||
testEveryDeckControlIsClassifiedLiveOrReloading();
|
||||
testOnlyALiveControlsDragTakesTheLiveTier();
|
||||
testDeckReadsPitchThenFilterThenAmpLeftToRight();
|
||||
|
||||
Reference in New Issue
Block a user