Retire the zone system: one capture = one parameter set, and re-seam the engine and Sample face into bands
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
// editor_paint_chrome.cpp — the CHROME band's painter: the toolbar row (product title +
|
||||
// live readout + Browse) and the control row (root/piano strip with its root marker, the
|
||||
// preview trigger, the preview-velocity knob cell, the curve-preview button, and the
|
||||
// Mono|Stereo toggle). Windows-only; all rects come from the pure sample_chrome interior.
|
||||
|
||||
#include "shell/instrument/reasampler_editor.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include "core/instrument/ui/knob_deck.h" // kDeckKnobSize (the shared knob square)
|
||||
#include "core/version/app_version.h" // vstPluginName (channel-derived title band)
|
||||
#include "shell/instrument/editor_internal.h" // kit adapters + knob face / spectral strip / root marker
|
||||
#include "shell/instrument/reasampler_processor.h"
|
||||
|
||||
namespace reasampler::vst {
|
||||
|
||||
using namespace reasampler::ui; // kit vocabulary
|
||||
using namespace reasampler::instrument::ui; // chrome geometry + keyboard strip
|
||||
using namespace reasampler::instrument::map; // SampleRefs / findRef (title readout fallback)
|
||||
|
||||
void ReaSamplerEditor::paintChrome(LICE_IBitmap* bmp, const FaceLayout& fl, bool empty) {
|
||||
const ChromeRects& cr = fl.chrome;
|
||||
|
||||
// Toolbar: product name + live readout. The beta channel gets no distinct accent; the
|
||||
// channel-derived vstPluginName is the only beta-vs-stable signal.
|
||||
std::string title = version::vstPluginName();
|
||||
if (processor_ && processor_->bridge().isConnected()) {
|
||||
// The instance's own loaded state outranks bank availability (the bank is a browser
|
||||
// source, not the instrument's identity) — a self-contained instance names its sound
|
||||
// (refs displayName fallback) even when the bank snapshot is empty.
|
||||
if (!selectedId_.empty())
|
||||
title += " [" + sampleLabel(samples_, processor_->sampleRefs(), selectedId_) + "]";
|
||||
else if (samples_.empty()) title += " [bank empty]";
|
||||
else title += " [pick a capture]";
|
||||
} else {
|
||||
title += " [host: no bridge]";
|
||||
}
|
||||
drawTitleBand(bmp, cr.toolbar, title);
|
||||
|
||||
// Browse: the picker. When nothing is loaded it is the empty state's dominant
|
||||
// call-to-action — draw it Active (accent-primary) so it reads as "start here".
|
||||
{
|
||||
const KitButtonBox box{toKitBox(cr.navBrowse)};
|
||||
const InteractionState st = empty ? InteractionState::Active
|
||||
: (isHovered(HoverKind::kNavBrowse, -1) ? InteractionState::Hover
|
||||
: InteractionState::Rest);
|
||||
drawButton(bmp, box, "Browse", st, /*warn=*/false);
|
||||
}
|
||||
|
||||
// The control row draws only once a capture is loaded — with nothing picked there is no
|
||||
// root, no preview and no channel decision to make.
|
||||
if (empty || cr.controls.empty()) return;
|
||||
|
||||
fillSurface(bmp, toKitBox(cr.controls), Role::BgPanel, InteractionState::Rest);
|
||||
|
||||
// Root strip: the full 128-key spectral band with the root marked. The loaded capture
|
||||
// responds across the whole strip, repitched from that root.
|
||||
if (cr.rootStrip.width > 0) {
|
||||
drawSpectralStrip(bmp, cr.rootStrip);
|
||||
const StripLayout sl = layoutStrip(cr.rootStrip.width, cr.rootStrip.height);
|
||||
drawRootMarker(bmp, cr.rootStrip, sl, effectiveRoot());
|
||||
}
|
||||
|
||||
// Preview-trigger button (fires the loaded capture at root through the live voice engine).
|
||||
{
|
||||
const KitButtonBox box{toKitBox(cr.preview)};
|
||||
const InteractionState st = (previewingNote_ >= 0) ? InteractionState::Active
|
||||
: (isHovered(HoverKind::kPreview, -1) ? InteractionState::Hover
|
||||
: InteractionState::Rest);
|
||||
drawButton(bmp, box, "Preview", st, /*warn=*/false);
|
||||
}
|
||||
|
||||
// Preview velocity: a radial knob cell (the deck cell grammar), bound to the same
|
||||
// persisted previewVelocity seam. Label swaps to the live value during hover/drag.
|
||||
{
|
||||
const bool dragging = (drag_ == DragKind::kDeckKnob && dragParamId_ == -2);
|
||||
const bool hov = isHovered(HoverKind::kVelKnob, -1);
|
||||
const InteractionState st = dragging ? InteractionState::Dragging
|
||||
: (hov ? InteractionState::Hover
|
||||
: InteractionState::Rest);
|
||||
drawKnobFace(bmp, cr.velKnob, previewVelocity01(), st);
|
||||
if (dragging || hov) {
|
||||
char buf[8];
|
||||
snprintf(buf, sizeof(buf), "%d",
|
||||
static_cast<int>(previewVelocity01() * 127.0 + 0.5));
|
||||
kitTextCentered(bmp, cr.velLabel, buf, Font::Micro, Role::TextDim);
|
||||
} else {
|
||||
kitTextCentered(bmp, cr.velLabel, "Vel", Font::Micro, Role::TextDim);
|
||||
}
|
||||
}
|
||||
|
||||
// The mini curve-preview button: opens the popup editor.
|
||||
paintCurveButton(bmp, cr.curveBtn);
|
||||
|
||||
// Mono | Stereo output-mode toggle.
|
||||
{
|
||||
const bool isStereo = (channelMode_ == ChannelMode::Stereo);
|
||||
const InteractionState monoState = !isStereo ? InteractionState::Active
|
||||
: (isHovered(HoverKind::kChanMono, -1) ? InteractionState::Hover
|
||||
: InteractionState::Rest);
|
||||
const InteractionState stereoState = isStereo ? InteractionState::Active
|
||||
: (isHovered(HoverKind::kChanStereo, -1) ? InteractionState::Hover
|
||||
: InteractionState::Rest);
|
||||
fillSurface(bmp, toKitBox(cr.chanMono), Role::BgCell, monoState);
|
||||
fillSurface(bmp, toKitBox(cr.chanStereo), Role::BgCell, stereoState);
|
||||
kitTextCentered(bmp, cr.chanMono, "Mono", Font::Label,
|
||||
!isStereo ? Role::BgBase : Role::TextPrimary);
|
||||
kitTextCentered(bmp, cr.chanStereo, "Stereo", Font::Label,
|
||||
isStereo ? Role::BgBase : Role::TextPrimary);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace reasampler::vst
|
||||
|
||||
#endif // _WIN32
|
||||
Reference in New Issue
Block a user