// drag_out — pure implementation. See drag_out.h. NO REAPER / SWELL / OS / vendor. #include "drag_out.h" #include namespace reasampler { namespace { // Half-open point-in-rect (matches the panel's other hit-tests: [x, x+w) x [y, y+h)). bool insideClient(int px, int py, const PanelClientRect& c) { return px >= c.x && px < c.x + c.width && py >= c.y && py < c.y + c.height; } } // namespace DragGesture decideGesture(int px, int py, const PanelClientRect& client, const DragState& state) { if (!state.dragging || !state.hasArmedSamples) return DragGesture::None; if (insideClient(px, py, client)) return DragGesture::Internal; // Outside the client rect (M11 boundary), refined by S17: a SINGLE-capture drag that is // still over REAPER's own UI is an instrument drop (heading for a track's FX button); // anything else (a multi-capture payload, or the pointer off REAPER entirely) is the // unchanged M11 OS drag-out. if (state.singleCapture && state.overReaperUi) return DragGesture::InstrumentDrop; return DragGesture::OsDrag; } PathList assemblePathList(const std::vector& resolved) { PathList out; std::unordered_set seen; seen.reserve(resolved.size()); for (const ResolvedSample& s : resolved) { if (s.absolutePath.empty()) { // shell could not resolve it ++out.skippedUnresolved; continue; } if (!s.fileExists) { // stale index entry, file gone ++out.skippedMissing; continue; } if (!seen.insert(s.absolutePath).second) { // already emitted this path ++out.skippedDuplicate; continue; } out.paths.push_back(s.absolutePath); } return out; } } // namespace reasampler