Ψ-W1-T4: resolve drop targets per move, not once — every surface gets a defined outcome, a cue, and no silent no-op

This commit is contained in:
2026-08-01 19:43:37 -04:00
parent 8bf6841f7b
commit fe3ac79ab5
17 changed files with 842 additions and 398 deletions
+9 -12
View File
@@ -12,7 +12,7 @@
#include <vector>
#include "core/version/app_version.h" // vstPluginName() — the CHANNEL-correct FX name (stable/beta pairing)
#include "core/wire/instrument_drop.h" // infoNamesFxHotspot — the PURE, unit-tested hotspot classifier
#include "core/wire/instrument_drop.h" // classifyReaperSurface — the PURE, unit-tested classifier
#include "reaper_plugin.h"
@@ -33,7 +33,7 @@ using version::vstPluginName;
using wire::decideDropOutcome;
using wire::DropAttempt;
using wire::DropOutcome;
using wire::infoNamesFxHotspot;
using wire::classifyReaperSurface;
namespace {
@@ -76,17 +76,14 @@ std::filesystem::path writeTempPreset(const std::vector<std::uint8_t>& bytes) {
} // namespace
FxDropTarget resolveFxDropTarget(int screenX, int screenY) {
FxDropTarget out;
DropProbe probeDropTarget(int screenX, int screenY) {
DropProbe out;
char info[256] = {0};
// A non-empty info OR a non-null track means the point is over REAPER's own UI;
// a null track with empty info means the pointer has left REAPER entirely.
MediaTrack* track = GetThingFromPoint(screenX, screenY, info, sizeof(info));
out.track = track;
out.overReaperUi = (track != nullptr) || (info[0] != '\0');
// The hotspot is either the FX chain/floating window ("fx_*") OR the FX-button family of
// the track/mixer panel ("tcp.fx*"/"mcp.fx*"). The pure classifier owns the rule.
out.overFxHotspot = (track != nullptr) && infoNamesFxHotspot(info);
// GetThingFromPoint may return a null track together with a valid info string (its own
// doc-comment says so), so the track and the surface are two independent facts and both
// are reported. The pure classifier owns every token rule.
out.track = GetThingFromPoint(screenX, screenY, info, sizeof(info));
out.surface = classifyReaperSurface(info, out.track != nullptr);
return out;
}