fix: Ctrl+click+drag copies pre-toggle selection, not post-toggle
Ctrl+click toggle selection THEN drag started -> selIds.has(itemId) returned false because the item was just removed from snapshot. Fix: snapshot selectedItemIds BEFORE toggle, pass to pendingDrag. Drag always copies the original group; toggle is only visual.
This commit is contained in:
+10
-13
@@ -1084,14 +1084,14 @@ const WaveformLane = ({
|
||||
e.stopPropagation();
|
||||
if (e.ctrlKey) {
|
||||
// Ctrl+Click: toggle selection only, never start drag immediately
|
||||
var ctrlWasSelected = selectedItemIds && selectedItemIds.has(hitItem.id);
|
||||
if (ctrlWasSelected) {
|
||||
var preToggleSnapshot = selectedItemIds ? new Set(selectedItemIds) : new Set();
|
||||
if (selectedItemIds && selectedItemIds.has(hitItem.id)) {
|
||||
if (onDeselectItem) onDeselectItem(hitItem.id);
|
||||
} else if (onAddToSelection) {
|
||||
onAddToSelection(hitItem.id);
|
||||
}
|
||||
// Store pending drag so mousemove can start copy-drag
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, hitItem.type, hitItem.id, time - hitItem.start, e.nativeEvent || e, ctrlWasSelected);
|
||||
// Store pre-toggle snapshot so drag copies the ORIGINAL group
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, hitItem.type, hitItem.id, time - hitItem.start, e.nativeEvent || e, preToggleSnapshot);
|
||||
} else {
|
||||
// No modifier: start drag immediately (single or multi move)
|
||||
if (onSectionItemDragStart) onSectionItemDragStart(track.id, hitItem.type, hitItem.id, time - hitItem.start, false);
|
||||
@@ -1151,15 +1151,15 @@ const WaveformLane = ({
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (e.ctrlKey) {
|
||||
// Ctrl+Click: toggle selection, store pending drag
|
||||
// Ctrl+Click: toggle selection, store pending drag w/ pre-toggle snapshot
|
||||
var clipCanonicalId = clickedClip.id === 'default' ? 'default_' + track.id : clickedClip.id;
|
||||
var ctrlClipSelected = selectedItemIds && selectedItemIds.has(clipCanonicalId);
|
||||
if (ctrlClipSelected) {
|
||||
var clipPreToggleSnapshot = selectedItemIds ? new Set(selectedItemIds) : new Set();
|
||||
if (selectedItemIds && selectedItemIds.has(clipCanonicalId)) {
|
||||
if (onDeselectItem) onDeselectItem(clipCanonicalId);
|
||||
} else if (onAddToSelection) {
|
||||
onAddToSelection(clipCanonicalId);
|
||||
}
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, 'clip', clipCanonicalId, time - clickedClip.startTime, e.nativeEvent || e, ctrlClipSelected);
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, 'clip', clipCanonicalId, time - clickedClip.startTime, e.nativeEvent || e, clipPreToggleSnapshot);
|
||||
} else {
|
||||
// Alt+Click: move immediately
|
||||
if (onClipDragStart) onClipDragStart(track.id, clickedClip.id, time - clickedClip.startTime, false);
|
||||
@@ -11666,11 +11666,8 @@ const App = () => {
|
||||
return next;
|
||||
});
|
||||
};
|
||||
const handleSetPendingDrag = (trackId, itemType, itemId, clickOffset, e, wasAlreadySelected) => {
|
||||
var snap = new Set(selectedItemIds);
|
||||
if (wasAlreadySelected) snap.delete(itemId);
|
||||
else snap.add(itemId);
|
||||
pendingDragRef.current = { trackId, itemType, itemId, clickOffset, startX: e.clientX, startY: e.clientY, selectedIds: snap };
|
||||
const handleSetPendingDrag = (trackId, itemType, itemId, clickOffset, e, preToggleSnapshot) => {
|
||||
pendingDragRef.current = { trackId, itemType, itemId, clickOffset, startX: e.clientX, startY: e.clientY, selectedIds: preToggleSnapshot || new Set(selectedItemIds) };
|
||||
};
|
||||
|
||||
// ── Sweep Select ──
|
||||
|
||||
Reference in New Issue
Block a user