S17 drop-and-load onto track FX button; S13 editor drop-accept (relay degraded)
S17: drag_out InstrumentDrop gesture + instrument_drop blob reusing the instrument's own serializer; bank_panel FX hover-track + add-VST/vst_chunk inject. S13 relay deferred (read-only bridge) — editor shows drop affordance.
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windowsx.h> // GET_X_LPARAM / GET_Y_LPARAM
|
||||
#include <shellapi.h> // DragAcceptFiles / DragQueryFile / DragFinish — S13 editor drop-accept
|
||||
|
||||
#include "wdltypes.h"
|
||||
#include "lice/lice.h"
|
||||
@@ -218,6 +219,12 @@ void ReaSamplerEditor::onSyncTimer() {
|
||||
refreshFromBank();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// S13: decay the drop-affordance banner so it auto-dismisses a few ticks after a drop.
|
||||
if (dropHintTicks_ > 0) {
|
||||
--dropHintTicks_;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -522,6 +529,10 @@ void ReaSamplerEditor::attachedToParent() {
|
||||
r.getWidth(), r.getHeight(), parent, nullptr, hInst, nullptr);
|
||||
if (childHwnd_) {
|
||||
SetWindowLongPtr(childHwnd_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
// S13: accept OS file drops on the editor window (WM_DROPFILES). The drop is NOT
|
||||
// ingested here (the relay is degraded — see onFilesDropped); accepting it lets us show
|
||||
// the "drop on the panel" affordance instead of the OS bouncing the drop silently.
|
||||
DragAcceptFiles(childHwnd_, TRUE);
|
||||
// Start the S9/S8 change-detection poll (UI thread). Tied to the child window's
|
||||
// lifetime — created here, killed in removedFromParent — so an instance whose editor
|
||||
// is closed does NOT poll (the editor-open-only cadence; see the handoff limitation).
|
||||
@@ -697,6 +708,19 @@ void ReaSamplerEditor::paint(HDC hdc) {
|
||||
paintBrowser(&bmp, w, h);
|
||||
}
|
||||
|
||||
// S13 (relay degraded): a transient banner flashed after a file was dropped ON THIS window.
|
||||
// It reiterates the shipped ingest gesture rather than swallowing the drop silently. Drawn
|
||||
// LAST so it overlays the mode content; decays via onSyncTimer (dropHintTicks_).
|
||||
if (dropHintTicks_ > 0) {
|
||||
const int bannerH = (std::min)(kTitleHeight + 8, h);
|
||||
Rect banner{0, bands.toggleZones.bottom, w, bands.toggleZones.bottom + bannerH};
|
||||
LICE_FillRect(&bmp, banner.left, banner.top, banner.width(), banner.height(),
|
||||
kColTabActiveBg, 1.0f, 0);
|
||||
drawTextCentered(&bmp, banner,
|
||||
"Dropped here isn't loaded yet - drop files onto the ReaSampler bank panel to add them.",
|
||||
kRgbText);
|
||||
}
|
||||
|
||||
BitBlt(hdc, 0, 0, w, h, bmp.getDC(), 0, 0, SRCCOPY);
|
||||
}
|
||||
|
||||
@@ -706,7 +730,16 @@ void ReaSamplerEditor::paintEmptyState(LICE_IBitmap* bmp, const Rect& area) {
|
||||
const char* msg = samples_.empty()
|
||||
? "No captures in this project yet - capture audio into the bank to play it here."
|
||||
: "No captures in this bank filter. Choose another bank tab above.";
|
||||
drawTextCentered(bmp, area, msg, kRgbDim);
|
||||
// Split the area so the primary line sits centered and the S13 ingest affordance sits just
|
||||
// below it. The affordance is the SHIPPED ingest gesture (drop onto the docked panel) — kept
|
||||
// discoverable here regardless of whether a drop ever lands on THIS window.
|
||||
Rect primary{area.left, area.top, area.right, area.top + area.height() / 2};
|
||||
Rect hint{area.left, primary.bottom, area.right, area.bottom};
|
||||
drawTextCentered(bmp, primary, msg, kRgbDim);
|
||||
drawTextCentered(bmp,
|
||||
hint,
|
||||
"To add a sample: drop a file onto the ReaSampler bank panel (the docked window).",
|
||||
kRgbDim);
|
||||
}
|
||||
|
||||
void ReaSamplerEditor::paintBrowser(LICE_IBitmap* bmp, int w, int h) {
|
||||
@@ -1559,6 +1592,20 @@ void ReaSamplerEditor::onSearchChar(unsigned int ch) {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void ReaSamplerEditor::onFilesDropped(int droppedCount) {
|
||||
// S13 relay DEGRADED. The instrument is a read-only bank consumer and the cross-artifact
|
||||
// ingest relay (editor drop -> extension) is not shipped (see the header note + the handoff
|
||||
// decision point), so we do NOT ingest the dropped files and — load-bearing — NEVER insert a
|
||||
// timeline item. Instead of silently swallowing the drop, flash a clear affordance pointing
|
||||
// at the shipped ingest gesture. dropHintTicks_ counts sync ticks (kSyncTimerIntervalMs
|
||||
// each); ~6 ticks keeps the banner up a few seconds, then onSyncTimer decays it to 0.
|
||||
(void)droppedCount; // count is informational; the banner text is drop-count-agnostic
|
||||
dropHintTicks_ = 6;
|
||||
#ifdef _WIN32
|
||||
invalidate();
|
||||
#endif
|
||||
}
|
||||
|
||||
LRESULT CALLBACK ReaSamplerEditor::wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
auto* self =
|
||||
@@ -1612,6 +1659,16 @@ LRESULT CALLBACK ReaSamplerEditor::wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
self->invalidate();
|
||||
}
|
||||
return 0;
|
||||
case WM_DROPFILES: {
|
||||
// S13 (relay degraded): count the dropped files and flash the affordance. We do NOT
|
||||
// read/ingest the paths (the instrument never ingests — the relay to the extension is
|
||||
// unshipped); DragQueryFile with 0xFFFFFFFF just returns the count for the banner.
|
||||
HDROP drop = reinterpret_cast<HDROP>(wParam);
|
||||
const UINT count = DragQueryFileW(drop, 0xFFFFFFFF, nullptr, 0);
|
||||
DragFinish(drop);
|
||||
if (self) self->onFilesDropped(static_cast<int>(count));
|
||||
return 0;
|
||||
}
|
||||
case WM_TIMER:
|
||||
if (self && wParam == kSyncTimerId) self->onSyncTimer();
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user