m6-move-copy-swap.md 4.0 KB

M6: move, copy, swap

Branch: m6-move-copy-swap → main

What changed

Pads can be moved, copied and swapped, across banks:

  • Dragging a filled pad onto an empty pad moves it; onto a filled pad swaps the two; holding Alt copies (onto a filled pad: copy and replace). The target cell shows a dashed outline for move/swap and a solid one for copy.
  • Dragging over a bank letter switches the grid to that bank, so a pad can be dropped on another bank's pads.
  • Move to pad / Copy to pad buttons open a picker (bank and pad, with each pad's sample shown): the keyboard route to the same three actions. Move onto a filled pad becomes Swap, as with dragging.
  • Dragging pads inside the window doesn't interfere with dropping WAV files from Explorer: the Wails runtime only handles drags that carry files.

Recorded-notes warning (build plan M6, format doc section 3). Notes point at a slot, not a sample, so they stay where they are. Before any move, swap or copy that changes what a pad with notes will play, a dialog lists each such pad and what its notes will play afterwards. Pads without notes get no dialog. Copying onto a filled pad also asks first. Pads with notes show a notes badge in the grid and a note in the settings panel.

Load (brought forward from M8). M6's done-when needs a project with notes, and only the device makes those, so the app needs Load now. Load opens a .xpj (the name comes from the file, samples from its _[ProjectData] folder) and reports firmware or version warnings. New and Load ask before discarding unsaved changes. M8 keeps missing-file badges, the window-close prompt and the other guard rails.

Go service: MovePad, CopyPad, SwapPads, Load (dialog) and LoadPath. The Dialogs interface gains OpenProject.

Fix after the first laptop test: the picker's Move/Copy button did nothing (step 7). The click handler closed the dialog before reading the dialog's choice. Closing clears ui.picker, and Svelte 5 props are live, so the following picker.from threw inside an async handler, which nothing reported. The handler now reads the choice first. transfer also shows any unexpected error in the banner instead of failing silently.

Testing

On the server: go vet and go test ./... pass. New service tests cover move/copy/swap across banks (tuning carried, sample shared, move onto a filled pad, out-of-range slot), and Load: cancelled dialog, DemoFile (name, 6 samples, notes on A01–A04 only, preview URL, 2 sequences), and a bad file keeping the current project.

bajdev's laptop run (2026-11-11): steps 1–6 and 8 passed; step 7 failed and is fixed above. Re-run step 7. The frontend is untested here (no Node). On the laptop (create C:\temp\m6 first):

  1. npm run check in frontend: 0 errors, 0 warnings.
  2. wails3 dev, Load testdata\device\DemoFile.xpj. A01–A04 show notes; B01 and B02 don't. Pads play when clicked.
  3. Move across banks, with a warning: drag A01 over the C bank letter (the grid switches to bank C) and drop on C01. A dialog says A01 has notes that will play nothing. Cancel: nothing changes. Do it again and confirm: C01 has the kick, A01 is empty.
  4. No warning without notes: Alt-drag B01 to bank D, pad D05. It copies with no dialog; B01 is unchanged.
  5. Swap: drag A02 onto B02. A dialog lists A02's notes; confirm. A02 and B02 have swapped.
  6. Rename to UiMoves, Export to folder C:\temp\m6. Then:

    go run ./cmd/mpckit-cli -load testdata\device\DemoFile.xpj -name CliMoves -out C:\temp\m6 -move "A1:C1" -copy "B1:D5" -swap "A2:B2"
    go run ./tools/xpjdiff C:\temp\m6\UiMoves.xpj C:\temp\m6\CliMoves.xpj
    

    prints identical. (M6 done-when: all three across banks.)

  7. Buttons: select C01, Copy to pad → bank A, pad A03 (shows the hat): the button reads "Copy and replace". The warning lists A03's notes. Move to pad onto an empty pad moves it.

  8. Unsaved changes: after any edit, New asks to discard; Cancel keeps the project.