Retire the zone system: one capture = one parameter set, and re-seam the engine and Sample face into bands

This commit is contained in:
2026-07-30 07:15:54 -04:00
parent a689fb75eb
commit 8d4ccbf841
61 changed files with 5416 additions and 8008 deletions
+139
View File
@@ -0,0 +1,139 @@
// editor_paint_deck.cpp — the DECKS band's painter: the fenced control groups (AMP
// ENVELOPE / PITCH / PITCH ENV / VOICE / MASTER), their captions, the compact caption and
// row toggles, and the radial knobs with the label<->value swap on hover/drag.
// Windows-only; the deck's cell geometry is the pure knob_deck layout.
#include "shell/instrument/reasampler_editor.h"
#ifdef _WIN32
#include <string>
#include <vector>
#include "core/instrument/ui/knob_deck.h" // deck layout + kDeckKnobSize
#include "shell/instrument/editor_internal.h" // kit adapters + knob face + DeckGroup ids
#include "shell/instrument/reasampler_processor.h"
namespace reasampler::vst {
using namespace reasampler::ui; // kit vocabulary
using namespace reasampler::instrument::ui; // deck geometry
void ReaSamplerEditor::paintDeck(LICE_IBitmap* bmp, const FaceLayout& fl) {
const Rect& deckArea = fl.bands.decks;
if (deckArea.width <= 0 || deckArea.height <= 0) return;
const DeckLayout dl = layoutDeck(fl.deckDescs, deckArea.x, deckArea.y, deckArea.width);
const PlaySeconds& play = params_.play;
const bool isMono = (voiceMode_ == VoiceMode::Mono);
const LICE_pixel hairline = toLice(roleColor(Role::LineHairline));
// 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.
const auto drawToggle = [&](const DeckToggleLayout& t, const char* s0, const char* s1,
bool seg1Active, bool disabled) {
const bool hov = !disabled && isHovered(HoverKind::kControl, t.id);
const InteractionState st0 =
disabled ? InteractionState::Disabled
: (!seg1Active ? InteractionState::Active
: (hov ? InteractionState::Hover : InteractionState::Rest));
const InteractionState st1 =
disabled ? InteractionState::Disabled
: (seg1Active ? InteractionState::Active
: (hov ? InteractionState::Hover : InteractionState::Rest));
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));
kitTextCentered(bmp, t.seg1, s1, Font::Micro,
disabled ? Role::TextDim
: (seg1Active ? Role::BgBase : Role::TextPrimary));
};
// The knob's short name label (swapped for the live value during hover/drag — no third
// line, no permanent value clutter).
const auto knobName = [](ParamControl c) -> const char* {
switch (c) {
case ParamControl::kAttack: return "Attack";
case ParamControl::kHold: return "Hold";
case ParamControl::kDecay: return "Decay";
case ParamControl::kSustain: return "Sustain";
case ParamControl::kRelease: return "Release";
case ParamControl::kTrigFadeIn: return "Fade In";
case ParamControl::kTrigLength: return "Len %";
case ParamControl::kTrigFadeOut: return "Fade Out";
case ParamControl::kKeyTrack: return "Key Trk";
case ParamControl::kPitchEnvAttack: return "P.Att";
case ParamControl::kPitchEnvDecay: return "P.Dec";
case ParamControl::kPitchEnvDepth: return "P.Depth";
case ParamControl::kVoiceCount: return "Voices";
case ParamControl::kMasterGain: return "Gain";
default: return "";
}
};
for (const DeckGroupLayout& g : dl.groups) {
// The fence: a bg/panel box with a hairline border, caption micro-caps left.
fillSurface(bmp, toKitBox(g.box), Role::BgPanel, InteractionState::Rest);
LICE_DrawRect(bmp, g.box.x, g.box.y, g.box.width - 1, g.box.height - 1,
hairline, 1.0f, 0);
const char* caption = "";
switch (g.id) {
case kGroupAmpEnv: caption = "AMP ENVELOPE"; break;
case kGroupPitch: caption = "PITCH"; break;
case kGroupPitchEnv: caption = "PITCH ENV"; break;
case kGroupVoice: caption = "VOICE"; break;
case kGroupMaster: caption = "MASTER"; break;
default: break;
}
kitText(bmp, g.caption, caption, Font::Micro, Role::TextDim);
// 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)) {
case ParamControl::kPlayMode:
drawToggle(g.captionToggle, "Gate", "Trigger",
play.playMode == PlayMode::Trigger, false);
break;
case ParamControl::kPitchEngine:
drawToggle(g.captionToggle, "Varisp", "Presrv",
play.pitchEngine == PitchEngine::Preserve, false);
break;
case ParamControl::kPitchEnvEnable:
drawToggle(g.captionToggle, "Off", "On", play.pitchEnv.enabled, false);
break;
case ParamControl::kVoiceMode:
drawToggle(g.captionToggle, "Poly", "Mono", isMono, false);
break;
default: break;
}
}
// The row toggle (VOICE group's Retrig|Legato) — live only in Mono.
if (g.rowToggle.id >= 0) {
drawToggle(g.rowToggle, "Retrig", "Legato",
monoTrigger_ == MonoTrigger::Legato, !isMono);
}
// The knobs. PITCH ENV knobs draw Disabled (not hidden) while the envelope is off —
// stable geometry.
for (const DeckCellLayout& c : g.cells) {
if (c.id < 0) continue; // reserved blank cell (the Trigger face's two spares)
const bool disabled = (g.id == kGroupPitchEnv && !play.pitchEnv.enabled);
const bool dragging = (drag_ == DragKind::kDeckKnob && dragParamId_ == c.id);
const bool hov = !disabled && isHovered(HoverKind::kControl, c.id);
const InteractionState st =
disabled ? InteractionState::Disabled
: (dragging ? InteractionState::Dragging
: (hov ? InteractionState::Hover : InteractionState::Rest));
drawKnobFace(bmp, c.knob, deckControlNorm(c.id), st);
const std::string label = (dragging || hov)
? deckValueLabel(c.id)
: std::string(knobName(static_cast<ParamControl>(c.id)));
kitTextCentered(bmp, c.label, label.c_str(), Font::Micro, Role::TextDim);
}
}
}
} // namespace reasampler::vst
#endif // _WIN32