instrument: spline EGs — hard points on the one shared spline, a drawn contour per envelope beside its staged state, payload v13

This commit is contained in:
2026-07-31 21:33:59 -04:00
parent f115904e4f
commit e44bd42dd9
33 changed files with 1739 additions and 364 deletions
+26 -15
View File
@@ -30,13 +30,16 @@ void ReaSamplerEditor::paintDeck(LICE_IBitmap* bmp, const FaceLayout& fl) {
// One compact-toggle draw (the Mono/Stereo segment grammar at Micro scale). Disabled
// segments draw inert so the dependency (Retrig|Legato needs Mono) reads at a glance.
// `seg0Disabled` disables ONE segment: Gate is unselectable while an EG is drawn, but
// Trigger — the mode it is stuck in — must still read as the live choice.
const auto drawToggle = [&](const DeckToggleLayout& t, const char* s0, const char* s1,
bool seg1Active, bool disabled) {
bool seg1Active, bool disabled, bool seg0Disabled = false) {
const bool hov = !disabled && isHovered(HoverKind::kControl, t.id);
const bool d0 = disabled || seg0Disabled;
const InteractionState st0 =
disabled ? InteractionState::Disabled
: (!seg1Active ? InteractionState::Active
: (hov ? InteractionState::Hover : InteractionState::Rest));
d0 ? InteractionState::Disabled
: (!seg1Active ? InteractionState::Active
: (hov ? InteractionState::Hover : InteractionState::Rest));
const InteractionState st1 =
disabled ? InteractionState::Disabled
: (seg1Active ? InteractionState::Active
@@ -44,12 +47,13 @@ void ReaSamplerEditor::paintDeck(LICE_IBitmap* bmp, const FaceLayout& fl) {
fillSurface(bmp, toKitBox(t.seg0), Role::BgCell, st0);
fillSurface(bmp, toKitBox(t.seg1), Role::BgCell, st1);
kitTextCentered(bmp, t.seg0, s0, Font::Micro,
disabled ? Role::TextDim
: (!seg1Active ? Role::BgBase : Role::TextPrimary));
d0 ? Role::TextDim
: (!seg1Active ? Role::BgBase : Role::TextPrimary));
kitTextCentered(bmp, t.seg1, s1, Font::Micro,
disabled ? Role::TextDim
: (seg1Active ? Role::BgBase : Role::TextPrimary));
};
const bool anySpline = splineActive(play);
// The knob's short name label (swapped for the live value during hover/drag — no third
// line, no permanent value clutter).
@@ -132,25 +136,32 @@ void ReaSamplerEditor::paintDeck(LICE_IBitmap* bmp, const FaceLayout& fl) {
}
}
// The compact caption toggle (right-anchored in the caption row, never full-width).
if (g.captionToggle.id >= 0) {
switch (static_cast<ParamControl>(g.captionToggle.id)) {
// The compact caption toggles (right-anchored in the caption row, never full-width).
for (const DeckToggleLayout* tp : {&g.captionToggle, &g.captionToggle2}) {
if (tp->id < 0) continue;
const DeckToggleLayout& t = *tp;
switch (static_cast<ParamControl>(t.id)) {
case ParamControl::kPlayMode:
drawToggle(g.captionToggle, "Gate", "Trigger",
play.playMode == PlayMode::Trigger, false);
drawToggle(t, "Gate", "Trigger", play.playMode == PlayMode::Trigger, false,
/*seg0Disabled=*/anySpline);
break;
case ParamControl::kPitchEngine:
drawToggle(g.captionToggle, "Varisp", "Presrv",
drawToggle(t, "Varisp", "Presrv",
play.pitchEngine == PitchEngine::Preserve, false);
break;
case ParamControl::kPitchEnvEnable:
drawToggle(g.captionToggle, "Off", "On", play.pitchEnv.enabled, false);
drawToggle(t, "Off", "On", play.pitchEnv.enabled, false);
break;
case ParamControl::kVoiceMode:
drawToggle(g.captionToggle, "Poly", "Mono", isMono, false);
drawToggle(t, "Poly", "Mono", isMono, false);
break;
case ParamControl::kFilterEnable:
drawToggle(g.captionToggle, "Off", "On", play.filter.enabled, false);
drawToggle(t, "Off", "On", play.filter.enabled, false);
break;
case ParamControl::kAmpEnvMode:
case ParamControl::kPitchEnvMode:
case ParamControl::kFilterEnvMode:
drawToggle(t, "Stg", "Spl", deckControlNorm(t.id) > 0.5, false);
break;
default: break;
}