Skip to content

Implement duplication of Alt-dragged layers within the Layers panel #2847

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

sneaxhuh
Copy link

@sneaxhuh sneaxhuh commented Jul 9, 2025

This PR introduces the ability to duplicate selected layers within the editor. Users can now duplicate layers by dragging them while holding the Alt key.

This includes:

Adding a new DuplicateSelectedLayers message.

Implementing the logic to copy and insert duplicated layers into the document.

Updating the frontend to detect the Alt key during drag operations and trigger the duplication.

Exposing the duplicateLayer function in the WASM API.

@sneaxhuh sneaxhuh marked this pull request as draft July 9, 2025 11:27
@Keavon Keavon force-pushed the master branch 4 times, most recently from ec51271 to e025103 Compare July 10, 2025 05:48
@sneaxhuh sneaxhuh marked this pull request as ready for review July 10, 2025 08:51
@sneaxhuh
Copy link
Author

Hi @Keavon , can you please review this. Thanks

@Keavon
Copy link
Member

Keavon commented Jul 14, 2025

Will do, no promises on when though. Still backlogged on code reviews.

@Keavon Keavon changed the title Add duplicate layer functionality Implement duplication of Alt-dragged layers within the Layers panel Jul 19, 2025
@sneaxhuh
Copy link
Author

@Keavon , just a gentle reminder

Comment on lines +656 to +689
if as_duplicate {
let mut all_new_ids = Vec::new();
let selected_layers = self.network_interface.selected_nodes().selected_layers(self.metadata()).collect::<Vec<_>>();

responses.add(DocumentMessage::DeselectAllLayers);
responses.add(DocumentMessage::AddTransaction);

for selected_layer in selected_layers {
let layer_node_id = selected_layer.to_node();

let mut copy_ids = HashMap::new();
copy_ids.insert(layer_node_id, NodeId(0));

self.network_interface
.upstream_flow_back_from_nodes(vec![layer_node_id], &[], network_interface::FlowType::LayerChildrenUpstreamFlow)
.enumerate()
.for_each(|(index, node_id)| {
copy_ids.insert(node_id, NodeId((index + 1) as u64));
});

let nodes: Vec<_> = self.network_interface.copy_nodes(&copy_ids, &[]).collect();
let new_ids: HashMap<_, _> = nodes.iter().map(|(id, _)| (*id, NodeId::new())).collect();
let layer = LayerNodeIdentifier::new_unchecked(new_ids[&NodeId(0)]);
all_new_ids.extend(new_ids.values().cloned());

responses.add(NodeGraphMessage::AddNodes { nodes, new_ids: new_ids.clone() });
responses.add(NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index });
}

responses.add(NodeGraphMessage::RunDocumentGraph);
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: all_new_ids });

return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have consolidated your new logic into the existing layer move message. Please see if you can further consolidate the logic to share code paths wherever possible. Because currently this just takes your duplicate-ish implementation and pastes it into here (followed by an early return; to avoid running the subsequent original non-duplication code paths).

Comment on lines +386 to +388
isDuplicating = event.altKey;
event.dataTransfer.dropEffect = isDuplicating ? "copy" : "move";
event.dataTransfer.effectAllowed = isDuplicating ? "copy" : "move";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please get this to update the cursor icon while dragging so the user can add or remove Alt any number of times during a drag and watch as the cursor updates, and the final state when the mouse drag is released becomes whether or not to duplicate. So the user can decide at the time of mouseup, not mousedown, whether to duplicate.

Copy link
Member

@Keavon Keavon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments.

@Keavon Keavon marked this pull request as draft July 26, 2025 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants