#pragma once // drag_out_win — the OS/COM initiation half of native OS drag-out: hands a resolved // existing-file path list to the OS's drag-drop machinery so the user can drop bank // samples into Explorer / another app / another DAW. The pure gesture-boundary // decision + path-list assembly live in drag_out.*. // // COPY-ONLY is STRUCTURAL on Windows: DoDragDrop's effect mask is DROPEFFECT_COPY // alone — MOVE is never offered, so no target can pull a file out of the bank folder // (only prune deletes bank bytes). macOS/Linux route through SWELL's file-list drag, // which exposes no per-source effect mask, so there the copy-only guarantee rests on // SWELL's copy semantics rather than an explicit mask. // // NON-DESTRUCTIVE: initiating a drag reads nothing but the path list; a cancelled or // failed drag mutates no sample/index/selection. #include #include struct HWND__; // avoid dragging windows.h into every includer; the shell casts as needed. namespace reasampler { // `absolutePaths` must already be resolved/existing/de-duped (drag_out::assemblePathList // output). No-op when empty. BLOCKING on Windows: OLE DoDragDrop runs its own modal // message loop until drop/cancel. Returns true iff the drop was accepted // (DROPEFFECT_COPY); the return is advisory — a failed drag surfaces no error. bool initiateDragOut(HWND__* panelHwnd, const std::vector& absolutePaths); // Side-effect-free readiness probe for initiateDragOut. Call BEFORE tearing down internal drag // state — an OS that isn't ready (OLE unavailable, HDROP build failure) must not consume the // gesture like an empty payload would. Windows re-runs the OLE-init + HDROP checks and frees the // probe HGLOBAL immediately; SWELL exposes no probe, so macOS/Linux reduces to the non-empty check. bool canInitiateDragOut(const std::vector& absolutePaths); } // namespace reasampler