3440ddb268
On chunk-write failure, call TrackFX_Delete(track, fxIndex) to remove the just-added empty FX instance before returning false. Signature verified at reaper_plugin_functions.h:7236. Update the header comment from "leaves at most the added FX" to the new all-or-nothing contract.
58 lines
3.5 KiB
C++
58 lines
3.5 KiB
C++
#pragma once
|
|
// instrument_drop_win — the REAPER-facing shell half of S17 drop-and-load. The pure gesture
|
|
// decision lives in drag_out (DragGesture::InstrumentDrop) and the pure blob construction in
|
|
// instrument_drop; THIS is the platform shell that (a) resolves a screen point to a track +
|
|
// its TCP FX-button hotspot via REAPER's hit-test API, and (b) on release adds a ReaSampler
|
|
// 9000 instance to that track and injects the dragged capture as its component state.
|
|
//
|
|
// Compiled into the reaper_reasampler MODULE. REAPER-facing (GetThingFromPoint, TrackFX_*,
|
|
// Undo_*), so DAW-verified, not unit-tested; the pure decision + blob it drives are CTest'd.
|
|
//
|
|
// LOAD-BEARING (CONTEXT.md §Drop-and-load): this is an EXPLICIT user placement-of-the-player
|
|
// gesture — it adds a READER of the bank on a track and points it at one already-captured
|
|
// sample. It NEVER captures, NEVER writes the bank, and NEVER inserts a timeline item. The
|
|
// only writes are: a new FX instance on the target track + that instance's own component
|
|
// state — both REAPER-undoable, wrapped in one undo block so the whole gesture is one Ctrl-Z.
|
|
|
|
#include <string>
|
|
|
|
// Opaque REAPER track handle at the boundary so includers don't need the SDK. The SDK
|
|
// declares it as a class (reaper_plugin.h) — match that spelling so the mangled name agrees.
|
|
class MediaTrack;
|
|
|
|
namespace reasampler {
|
|
|
|
// The result of hit-testing a screen point during a live InstrumentDrop drag.
|
|
struct FxDropTarget {
|
|
MediaTrack* track = nullptr; // the track under the pointer (null if none / not a track)
|
|
bool overReaperUi = false; // the point is over REAPER's own window/UI at all
|
|
bool overFxHotspot = false; // specifically over this track's TCP FX-button/-chain region
|
|
|
|
// A valid drop target: a resolved track whose FX hotspot is under the pointer.
|
|
bool valid() const { return track != nullptr && overFxHotspot; }
|
|
};
|
|
|
|
// Hit-test a screen point (REAPER screen coords) to an FX drop target. Wraps
|
|
// GetThingFromPoint, whose info string tells us what was hit ("tcp"/"mcp" for a track panel,
|
|
// "fx_chain"/"fx_N" for the FX area/button). `overReaperUi` is the shell-supplied predicate
|
|
// the pure drag_out::decideGesture consumes (true when the point is over REAPER's own UI —
|
|
// i.e. GetThingFromPoint returned a track OR a recognizable non-track thing, false when the
|
|
// pointer has left REAPER entirely). `overFxHotspot` is true when the info string names the
|
|
// FX region specifically — the S17 "FX-button hotspot vs. whole TCP" question is resolved to
|
|
// the FX hotspot (the discoverable, unambiguous target), decided here from the SDK's own
|
|
// hit-test string rather than a home-grown geometry guess.
|
|
FxDropTarget resolveFxDropTarget(int screenX, int screenY);
|
|
|
|
// Perform the drop on `track`: add a fresh ReaSampler 9000 instance and inject `chunkBase64`
|
|
// (the instrument_drop::buildInstrumentDropChunk output) as its component state so it plays
|
|
// the dragged capture. `chunkBase64` is the base64 vst_chunk. Wraps the add + inject in one
|
|
// REAPER undo block (mirrors the bank-verb undo discipline). Returns true on success (the FX
|
|
// was added and the chunk written), false on any failure. All-or-nothing: if the chunk write
|
|
// fails after a successful add, the freshly-added FX instance is removed via TrackFX_Delete
|
|
// before returning false, leaving the track exactly as it was (no orphaned empty-state FX).
|
|
// NEVER inserts a timeline item; the ONLY mutations are the FX instance + its state, both
|
|
// undoable.
|
|
bool performInstrumentDrop(MediaTrack* track, const std::string& chunkBase64);
|
|
|
|
} // namespace reasampler
|