Add Alt+drag layer duplication to the Layers panel (#4216)

* Add Alt+drag layer duplication to the Layers panel

* Code review
This commit is contained in:
Keavon Chambers
2026-06-08 21:08:16 -07:00
committed by GitHub
parent 04bca4a877
commit bc1f63ccc6
4 changed files with 123 additions and 28 deletions
+7 -3
View File
@@ -349,6 +349,7 @@
if (distance > DRAG_THRESHOLD) {
internalDragState.active = true;
dragInPanel = true;
layerToClipUponClick = undefined;
const layer = internalDragState.listing.entry;
if (!$nodeGraph.selected.includes(layer.id)) {
@@ -381,7 +382,7 @@
}
}
function draggingPointerUp() {
function draggingPointerUp(e: PointerEvent) {
if (internalDragState?.active && dragDropTarget) {
// Ensure the dragged layer is part of the selection, matching the move-in-tree behavior
if (!$nodeGraph.selected.includes(internalDragState.layerId)) selectLayer(internalDragState.listing, false, false);
@@ -393,9 +394,12 @@
} else if (internalDragState?.active && draggingData) {
const { select, insertParentId, insertIndex } = draggingData;
// Commit the move
// Ensure the dragged layer is part of the selection before committing
select?.();
editor.moveLayerInTree(insertParentId, insertIndex);
// Holding Alt drops a duplicate of the selection at the target instead of moving the originals
if (e.altKey) editor.duplicateLayerInTree(insertParentId, insertIndex);
else editor.moveLayerInTree(insertParentId, insertIndex);
// Prevent the subsequent click event from processing
justFinishedDrag = true;
+12
View File
@@ -756,6 +756,18 @@ impl EditorWrapper {
self.dispatch(message);
}
/// Duplicate the selected layers, placing the copies within the given folder at the given index.
/// If the folder is `None`, they are inserted into the document root.
/// If the insert index is `None`, they are inserted at the start of the folder.
#[wasm_bindgen(js_name = duplicateLayerInTree)]
pub fn duplicate_layer_in_tree(&self, insert_parent_id: Option<u64>, insert_index: Option<usize>) {
let message = DocumentMessage::DuplicateSelectedLayersTo {
parent: insert_parent_id.map(NodeId).map(LayerNodeIdentifier::new_unchecked).unwrap_or_default(),
insert_index: insert_index.unwrap_or_default(),
};
self.dispatch(message);
}
/// Set the name for the layer
#[wasm_bindgen(js_name = setLayerName)]
pub fn set_layer_name(&self, id: u64, name: String) {