feat(bank_panel): B4 vertical-split UI — LICE tab strip, id-keyed bank ops, move/copy drag

Pool grid on top, LICE-drawn named-banks tab strip below with overflow-scroll
(new pure tab_strip seam, unit-tested). Full-height toggles, unmistakable
active-bank readout distinct from the shown tab, tab context menu
(activate/rename/delete/evacuate/create) with rich confirm-on-non-empty-delete,
and move/copy via menu + drag with drop-highlighting. Fold-in: deserialize
auto-disambiguates duplicate folded bank names instead of rejecting the book.
This commit is contained in:
2026-07-25 14:37:57 -04:00
parent 88af39e036
commit a67a2f9479
10 changed files with 1769 additions and 457 deletions
+9 -8
View File
@@ -531,12 +531,13 @@ void doBankActivatePool() {
ShowConsoleMsg("ReaSampler: active bank -> \"Pool\".\n");
}
// Move or copy the panel's selected samples from the ACTIVE bank into a named
// destination bank (prompted by display name). The panel grid shows the active bank,
// so its selection ids are members of the active bank — that is the source. Both are
// Move or copy the panel's selected samples into a named destination bank (prompted
// by display name). The SOURCE is the bank the selection lives in — the focused
// region's displayed bank (bankPanelSelectedSourceBankId), which under B4's vertical
// split is NOT necessarily the active/capture-target bank (active ≠ shown). Both are
// index-only (files never relocate); move removes the source entry, copy retains it;
// both observe destination collapse-by-hash (bank_book). B4's "move to bank" menu will
// drive moveSample/copySample directly with a menu-chosen destination — this bindable
// both observe destination collapse-by-hash (bank_book). B4's "move to bank" menu
// drives moveSample/copySample directly with a menu-chosen destination — this bindable
// form is the same operation with a text-prompt destination.
void doBankTransferSelected(bool copy) {
const std::vector<std::string> selected = bankPanelSelectedSampleIds();
@@ -554,9 +555,9 @@ void doBankTransferSelected(bool copy) {
ShowConsoleMsg(("ReaSampler: no bank named \"" + destName + "\".\n").c_str());
return;
}
// Source = the active bank (what the panel grid shows). Pass ids by value — no
// BankIndex& is cached across the loop's mutations.
const std::string srcId = g_session->book().activeBankId();
// Source = the bank the selection lives in (the focused region's displayed bank).
// Pass ids by value — no BankIndex& is cached across the loop's mutations.
const std::string srcId = bankPanelSelectedSourceBankId();
if (srcId == destId) {
ShowConsoleMsg("ReaSampler: source and destination are the same bank.\n");
return;