Bake window derives itself: %-knob fold, declick pad, Gate held to exhaustion, preview velocity; Hold is the one knob a loop needs

This commit is contained in:
2026-08-01 20:26:04 -04:00
parent d3894dae6d
commit 19aeb92775
36 changed files with 1040 additions and 274 deletions
@@ -10,6 +10,7 @@
#include <cstdio>
#include <string>
#include "core/instrument/note/musical_division.h" // divisionLabel (the Hold readout)
#include "core/instrument/ui/keyboard_strip.h" // StripLayout / keyRect / noteName
#include "core/instrument/ui/knob_deck.h" // kDeckKnobSize (the shared knob square)
#include "core/ui/tooltip.h" // computeTooltip (shared placement math)
@@ -145,6 +146,22 @@ void ReaSamplerEditor::paintChrome(LICE_IBitmap* bmp, const FaceLayout& fl, bool
drawButton(bmp, box, "Bake", st, /*warn=*/false);
}
// Bake Hold: the note length the bake holds the gate for. Drawn ONLY while the window
// cannot be derived without it — every other dialed sound bakes with no user input, and a
// control that did nothing there would read as one that did.
if (bakeHoldNeeded_) {
const bool dragging = (drag_ == DragKind::kDeckKnob && dragParamId_ == kBakeHoldKnobId);
const bool hov = isHovered(HoverKind::kHoldKnob, -1);
const InteractionState st = dragging ? InteractionState::Dragging
: (hov ? InteractionState::Hover
: InteractionState::Rest);
drawKnobFace(bmp, cr.holdKnob, bakeHoldNorm(), st);
const std::string label = dragging || hov
? instrument::note::divisionLabel(params_.bakeHold)
: std::string("Hold");
kitTextCentered(bmp, cr.holdLabel, label.c_str(), Font::Micro, Role::TextDim);
}
// Preview-trigger button (fires the loaded capture at root through the live voice engine).
// A drawn play triangle rather than a label or an embedded image: it inherits the button's
// own foreground role, so it stays legible in every interaction state at no build cost.