#pragma once // drag_out_win — the OS/COM initiation half of native OS drag-out (Milestone 11). The pure // gesture-boundary decision and path-list assembly live in drag_out.*; THIS is the platform // shell that hands a resolved, existing-file path list to the operating system's drag-drop // machinery so the user can drop bank samples into Explorer / another app / another DAW. // // ONE seam, platform-forked inside the .cpp: // * Windows (primary — Daniel's target): OLE DoDragDrop with a minimal IDataObject // carrying CF_HDROP (absolute paths, double-null-terminated wide list) and a minimal // IDropSource. COPY-ONLY is STRUCTURAL: the IDataObject offers DROPEFFECT_COPY and the // effect mask passed to DoDragDrop is DROPEFFECT_COPY alone — MOVE is never offered, so // no target can pull the bank file out of the bank folder (invariant #1: a move would // delete bank bytes, and per the Phase R boundary ONLY prune deletes files). // * macOS/Linux (SWELL): SWELL_InitiateDragDropOfFileList (verified present in // vendor/WDL/WDL/swell/swell-functions.h) behind the same seam. SWELL's file-list drag // is a copy-style file drag; it exposes no per-source effect mask the way OLE does, so // the copy-only guarantee there rests on SWELL's copy semantics rather than an explicit // mask — noted honestly, not faked. Windows is where the mask control is exact. // // NON-DESTRUCTIVE (invariant #2): initiating a drag reads nothing but the path list and // mutates no sample / index / selection. A cancelled or failed drag changes nothing — the // OS layer here neither writes ext-state nor touches the book. #include #include struct HWND__; // avoid dragging windows.h into every includer; the shell casts as needed. namespace reasampler { // Initiates a native OS drag-out of `absolutePaths` (already resolved, existing, de-duped — // the pure drag_out::assemblePathList output) from the panel window `panelHwnd`. COPY-ONLY; // see the header note. A no-op when the path list is empty (nothing draggable — the caller // checks this too, but the guard is repeated here so a direct call is safe). // // BLOCKING on Windows: OLE DoDragDrop runs its own modal message loop until the drop or // cancel, then returns — the caller's gesture state should be reset AFTER this returns. // Returns true if a drop was accepted (DROPEFFECT_COPY), false on cancel / failure / // empty input. The return is advisory (a failed drag is visible by nothing happening — // the caller does not surface an error, per the brief's no-console-output constraint). bool initiateDragOut(HWND__* panelHwnd, const std::vector& absolutePaths); } // namespace reasampler