From 9c3ca57c14458018dd79c6784a585bf346b579a2 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 5 May 2024 01:22:31 -0700 Subject: [PATCH] Fix duplicate selection when holding alt and dragging with select tool --- .../document/document_message_handler.rs | 14 ++--- .../graph_operation_message.rs | 1 + .../graph_operation_message_handler.rs | 4 +- .../utility_types/document_metadata.rs | 2 +- .../portfolio/portfolio_message_handler.rs | 11 ++-- .../tool/tool_messages/select_tool.rs | 58 +++++++++---------- 6 files changed, 44 insertions(+), 46 deletions(-) diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index a5db05a00c..1d4a6b6303 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -279,7 +279,7 @@ impl MessageHandler> for DocumentMessag } DocumentMessage::DuplicateSelectedLayers => { let parent = self.new_layer_parent(false); - let calculated_insert_index = self.get_calculated_insert_index(parent); + let calculated_insert_index = DocumentMessageHandler::get_calculated_insert_index(&self.metadata, &self.selected_nodes, parent); responses.add(DocumentMessage::StartTransaction); responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal }); @@ -412,7 +412,7 @@ impl MessageHandler> for DocumentMessag }); } - let calculated_insert_index = self.get_calculated_insert_index(parent); + let calculated_insert_index = DocumentMessageHandler::get_calculated_insert_index(&self.metadata, &self.selected_nodes, parent); let folder_id = NodeId(generate_uuid()); responses.add(GraphOperationMessage::NewCustomLayer { @@ -1298,17 +1298,17 @@ impl DocumentMessageHandler { .unwrap_or_else(|| self.metadata().active_artboard()) } - fn get_calculated_insert_index(&self, parent: LayerNodeIdentifier) -> isize { + pub fn get_calculated_insert_index(metadata: &DocumentMetadata, selected_nodes: &SelectedNodes, parent: LayerNodeIdentifier) -> isize { parent - .children(self.metadata()) + .children(metadata) .enumerate() .find_map(|(index, direct_child)| { - if self.selected_nodes.selected_layers(self.metadata()).any(|selected| selected == direct_child) { + if selected_nodes.selected_layers(metadata).any(|selected| selected == direct_child) { return Some(index as isize); } - for descendant in direct_child.descendants(self.metadata()) { - if self.selected_nodes.selected_layers(self.metadata()).any(|selected| selected == descendant) { + for descendant in direct_child.descendants(metadata) { + if selected_nodes.selected_layers(metadata).any(|selected| selected == descendant) { return Some(index as isize); } } diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs index 180482660d..725a6857d8 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs @@ -21,6 +21,7 @@ use glam::{DAffine2, DVec2, IVec2}; pub enum GraphOperationMessage { AddNodesAsChild { nodes: HashMap, + new_ids: HashMap, parent: LayerNodeIdentifier, insert_index: isize, }, diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs index d0bfd2c8d3..da9dd1bba5 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs @@ -37,9 +37,7 @@ impl MessageHandler> for Gr } = data; match message { - GraphOperationMessage::AddNodesAsChild { nodes, parent, insert_index } => { - let new_ids: HashMap<_, _> = nodes.iter().map(|(&id, _)| (id, NodeId(generate_uuid()))).collect(); - + GraphOperationMessage::AddNodesAsChild { nodes, new_ids, parent, insert_index } => { let shift = nodes .get(&NodeId(0)) .and_then(|node| { diff --git a/editor/src/messages/portfolio/document/utility_types/document_metadata.rs b/editor/src/messages/portfolio/document/utility_types/document_metadata.rs index 4341e5e026..5ee5c29fc5 100644 --- a/editor/src/messages/portfolio/document/utility_types/document_metadata.rs +++ b/editor/src/messages/portfolio/document/utility_types/document_metadata.rs @@ -100,7 +100,7 @@ impl DocumentMetadata { let mut layer_path = layer.ancestors(self).collect::>(); layer_path.reverse(); - if !include_self || !self.is_artboard(layer) && !self.is_folder(layer) { + if !include_self || !self.is_artboard(layer) { layer_path.pop(); } diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 6fbc45175d..4fa4837ad3 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -383,12 +383,9 @@ impl MessageHandler> for PortfolioMes let paste = |entry: &CopyBufferEntry, responses: &mut VecDeque<_>| { if self.active_document().is_some() { trace!("Pasting into folder {parent:?} as index: {insert_index}"); - - responses.add(GraphOperationMessage::AddNodesAsChild { - nodes: entry.clone().nodes, - parent, - insert_index, - }); + let nodes = entry.clone().nodes; + let new_ids: HashMap<_, _> = nodes.iter().map(|(&id, _)| (id, NodeId(generate_uuid()))).collect(); + responses.add(GraphOperationMessage::AddNodesAsChild { nodes, new_ids, parent, insert_index }); } }; @@ -408,8 +405,10 @@ impl MessageHandler> for PortfolioMes for entry in data.into_iter().rev() { document.load_layer_resources(responses); + let new_ids: HashMap<_, _> = entry.nodes.iter().map(|(&id, _)| (id, NodeId(generate_uuid()))).collect(); responses.add(GraphOperationMessage::AddNodesAsChild { nodes: entry.nodes, + new_ids, parent, insert_index: -1, }); diff --git a/editor/src/messages/tool/tool_messages/select_tool.rs b/editor/src/messages/tool/tool_messages/select_tool.rs index 99582a8910..f2d36dc75f 100644 --- a/editor/src/messages/tool/tool_messages/select_tool.rs +++ b/editor/src/messages/tool/tool_messages/select_tool.rs @@ -15,7 +15,7 @@ use crate::messages::tool::common_functionality::pivot::Pivot; use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnappedPoint}; use crate::messages::tool::common_functionality::transformation_cage::*; -use graph_craft::document::{NodeId, NodeNetwork}; +use graph_craft::document::{DocumentNode, NodeId, NodeNetwork}; use graphene_core::renderer::Quad; use std::fmt; @@ -315,23 +315,6 @@ impl SelectToolData { let Some(layer) = layer_ancestors.last().copied() else { continue }; let Some(parent) = layer.parent(&document.metadata) else { continue }; - // Copy the layer - let node = layer.to_node(); - let Some(node) = document.network().nodes.get(&node).and_then(|node| node.inputs.first()).and_then(|input| input.as_node()) else { - continue; - }; - - let nodes = NodeGraphMessageHandler::copy_nodes( - document.network(), - &document - .network() - .upstream_flow_back_from_nodes(vec![node], graph_craft::document::FlowType::UpstreamFlow) - .enumerate() - .map(|(index, (_, node_id))| (node_id, NodeId(index as u64))) - .collect(), - ) - .collect(); - // Moves the layer back to its starting position. responses.add(GraphOperationMessage::TransformChange { layer, @@ -340,17 +323,34 @@ impl SelectToolData { skip_rerender: true, }); - let id = NodeId(generate_uuid()); - let insert_index = -1; - let layer = LayerNodeIdentifier::new_unchecked(id); - responses.add(GraphOperationMessage::NewCustomLayer { - id, - nodes, - parent, - insert_index, - alias: String::new(), - }); - new_dragging.push(layer); + // Copy the layer + let mut copy_ids = HashMap::new(); + let node = layer.to_node(); + copy_ids.insert(node, NodeId(0 as u64)); + if let Some(input_node) = document + .network() + .nodes + .get(&node) + .and_then(|node| if node.is_layer { node.inputs.get(1) } else { node.inputs.get(0) }) + .and_then(|input| input.as_node()) + { + document + .network() + .upstream_flow_back_from_nodes(vec![input_node], graph_craft::document::FlowType::UpstreamFlow) + .enumerate() + .for_each(|(index, (_, node_id))| { + copy_ids.insert(node_id, NodeId((index + 1) as u64)); + }); + }; + let nodes: HashMap = NodeGraphMessageHandler::copy_nodes(document.network(), ©_ids).collect(); + + let insert_index = DocumentMessageHandler::get_calculated_insert_index(&document.metadata, &document.selected_nodes, parent); + + let new_ids: HashMap<_, _> = nodes.iter().map(|(&id, _)| (id, NodeId(generate_uuid()))).collect(); + + let layer_id = new_ids.get(&NodeId(0)).expect("Node Id 0 should be a layer").clone(); + responses.add(GraphOperationMessage::AddNodesAsChild { nodes, new_ids, parent, insert_index }); + new_dragging.push(LayerNodeIdentifier::new_unchecked(layer_id)); } let nodes = new_dragging.iter().map(|layer| layer.to_node()).collect(); responses.add(NodeGraphMessage::SelectedNodesSet { nodes });