From 3a7d1938b6c03af518ca38cc64e6374f5f3f713a Mon Sep 17 00:00:00 2001 From: Adesh Gupta <148623820+4adex@users.noreply.github.com> Date: Sat, 1 Mar 2025 13:14:13 +0530 Subject: [PATCH] Make Ctrl+D duplication interleave each layer like Alt+drag duplication already does (#2328) Fixed order of layers on Ctrl D Co-authored-by: Keavon Chambers --- .../document/document_message_handler.rs | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 99f4ab12..2f7c0557 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1,7 +1,6 @@ use super::node_graph::document_node_definitions; use super::node_graph::utility_types::Transform; use super::overlays::utility_types::Pivot; -use super::utility_types::clipboards::Clipboard; use super::utility_types::error::EditorError; use super::utility_types::misc::{GroupFolderType, SnappingOptions, SnappingState, SNAP_FUNCTIONS_FOR_BOUNDING_BOXES, SNAP_FUNCTIONS_FOR_PATHS}; use super::utility_types::network_interface::{self, NodeNetworkInterface, TransactionStatus}; @@ -16,7 +15,7 @@ use crate::messages::portfolio::document::overlays::grid_overlays::{grid_overlay use crate::messages::portfolio::document::properties_panel::utility_types::PropertiesPanelMessageHandlerData; use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier}; use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis, PTZ}; -use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector}; +use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, NodeTemplate}; use crate::messages::portfolio::document::utility_types::nodes::RawBuffer; use crate::messages::portfolio::utility_types::PersistentData; use crate::messages::prelude::*; @@ -355,17 +354,46 @@ impl MessageHandler> for DocumentMessag } } DocumentMessage::DuplicateSelectedLayers => { - let parent = self.new_layer_parent(false); - let calculated_insert_index = - DocumentMessageHandler::get_calculated_insert_index(self.network_interface.document_metadata(), &self.network_interface.selected_nodes(&[]).unwrap(), parent); - responses.add(DocumentMessage::AddTransaction); - responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal }); - responses.add(PortfolioMessage::PasteIntoFolder { - clipboard: Clipboard::Internal, - parent, - insert_index: calculated_insert_index, + + let mut new_dragging = Vec::new(); + let mut layers = self.network_interface.shallowest_unique_layers(&[]).collect::>(); + + layers.sort_by_key(|layer| { + let Some(parent) = layer.parent(self.metadata()) else { return usize::MAX }; + DocumentMessageHandler::get_calculated_insert_index(self.metadata(), &SelectedNodes(vec![layer.to_node()]), parent) }); + + for layer in layers.into_iter().rev() { + let Some(parent) = layer.parent(self.metadata()) else { continue }; + + // Copy the layer + let mut copy_ids = HashMap::new(); + let node_id = layer.to_node(); + copy_ids.insert(node_id, NodeId(0)); + + self.network_interface + .upstream_flow_back_from_nodes(vec![layer.to_node()], &[], FlowType::LayerChildrenUpstreamFlow) + .enumerate() + .for_each(|(index, node_id)| { + copy_ids.insert(node_id, NodeId((index + 1) as u64)); + }); + + let nodes = self.network_interface.copy_nodes(©_ids, &[]).collect::>(); + + let insert_index = DocumentMessageHandler::get_calculated_insert_index(self.metadata(), &SelectedNodes(vec![layer.to_node()]), parent); + + let new_ids: HashMap<_, _> = nodes.iter().map(|(id, _)| (*id, NodeId::new())).collect(); + + let layer_id = *new_ids.get(&NodeId(0)).expect("Node Id 0 should be a layer"); + let layer = LayerNodeIdentifier::new_unchecked(layer_id); + new_dragging.push(layer); + responses.add(NodeGraphMessage::AddNodes { nodes, new_ids }); + responses.add(NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index }); + } + let nodes = new_dragging.iter().map(|layer| layer.to_node()).collect(); + responses.add(NodeGraphMessage::SelectedNodesSet { nodes }); + responses.add(NodeGraphMessage::RunDocumentGraph); } DocumentMessage::EnterNestedNetwork { node_id } => { self.breadcrumb_network_path.push(node_id);