feat(S8): ingest through the bank — capture/import/drop into bank + assign to active instance

This commit is contained in:
2026-07-26 21:29:13 -04:00
parent bf1bf5283c
commit 8074e21057
11 changed files with 1009 additions and 6 deletions
+40
View File
@@ -61,6 +61,7 @@
#include "draw_kit.h" // kit text() over cached AA fonts — retires GDI DrawText (L1)
#include "footer_bar.h" // pure footer LEFT-group layout: toggle + count + Tail button (L4)
#include "guid_diff.h" // GuidBaseline — new-content detection (D2 Wave 2)
#include "ingest.h" // ingestDroppedFiles — S8 drop-onto-panel ingest
#include "item_read.h" // itemGuid / itemLaneName — shared item-read seam (D2 W3-B)
#include "lane_keys.h" // managed/manual lane heuristic (D2 Wave 2)
#include "mode_enable.h" // opposite-mode tag-button enablement predicate (pure, L5)
@@ -82,6 +83,7 @@
#ifdef _WIN32
#include <windows.h>
#include <windowsx.h> // GET_X_LPARAM / GET_Y_LPARAM (SWELL supplies them on mac/linux)
#include <shellapi.h> // DragAcceptFiles / DragQueryFile / DragFinish — S8 drop ingest
#else
#include <pthread.h>
#endif
@@ -3075,8 +3077,35 @@ void handleRightClick(int x, int y) {
// --- Dialog proc + docking ----------------------------------------------------
// Decodes a WM_DROPFILES HDROP into the dropped file paths (absolute, OS-native) and hands
// them to the S8 ingest path. Multi-file drop: ingestDroppedFiles imports all and assigns
// the first. Always DragFinish's the HDROP (frees the shell-allocated drop buffer) on every
// path. DragQueryFile(hDrop, 0xFFFFFFFF, ...) returns the file count; then each path is
// queried by index. Both Win32 and SWELL expose DragQueryFile/DragFinish with this contract.
void handleDropFiles(HDROP hDrop) {
std::vector<std::string> paths;
const UINT count = DragQueryFile(hDrop, 0xFFFFFFFF, nullptr, 0);
paths.reserve(count);
for (UINT i = 0; i < count; ++i) {
// Query the required length first (excludes the NUL), then read into a sized buffer.
const UINT len = DragQueryFile(hDrop, i, nullptr, 0);
if (len == 0) continue;
std::vector<char> buf(static_cast<std::size_t>(len) + 1, '\0');
DragQueryFile(hDrop, i, buf.data(), static_cast<UINT>(buf.size()));
std::string p(buf.data());
if (!p.empty()) paths.push_back(std::move(p));
}
DragFinish(hDrop);
if (!paths.empty()) ingestDroppedFiles(paths);
}
WDL_DLGRET dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_DROPFILES:
// S8 drop-onto-panel ingest: OS file drop on the docked panel HWND -> import
// into the active bank + assign the first. wParam is the HDROP.
handleDropFiles(reinterpret_cast<HDROP>(wParam));
return 0;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
@@ -3172,6 +3201,17 @@ void openPanel() {
DockWindowActivate(g_panel.hwnd);
g_panel.open = true;
// S8: accept OS file drops on the panel HWND (WM_DROPFILES routes to handleDropFiles).
// DragAcceptFiles is a native Win32 shell call (shellapi.h); SWELL does NOT expose it,
// so the opt-in is Windows-only here. The primary/shipped platform is Windows (the VST3
// instrument the drop assigns to is Windows-only, D5); a mac/linux drop-registration
// surface is out of scope for this dispatch. WM_DROPFILES handling itself uses
// DragQueryFile/DragFinish, which SWELL DOES provide, so a drop delivered by other means
// would still ingest — only the accept opt-in is gated.
#ifdef _WIN32
DragAcceptFiles(g_panel.hwnd, TRUE);
#endif
registerAccel();
reconcileShownBank();