Fix duplicate selection when holding Alt and dragging with Select tool (#1739)

Fix duplicate selection when holding alt and dragging with select tool
This commit is contained in:
adamgerhant
2024-05-06 18:33:58 -07:00
committed by GitHub
parent 1fca813797
commit 14262e1527
6 changed files with 44 additions and 46 deletions
@@ -279,7 +279,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
} }
DocumentMessage::DuplicateSelectedLayers => { DocumentMessage::DuplicateSelectedLayers => {
let parent = self.new_layer_parent(false); 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(DocumentMessage::StartTransaction);
responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal }); responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal });
@@ -412,7 +412,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> 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()); let folder_id = NodeId(generate_uuid());
responses.add(GraphOperationMessage::NewCustomLayer { responses.add(GraphOperationMessage::NewCustomLayer {
@@ -1298,17 +1298,17 @@ impl DocumentMessageHandler {
.unwrap_or_else(|| self.metadata().active_artboard()) .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 parent
.children(self.metadata()) .children(metadata)
.enumerate() .enumerate()
.find_map(|(index, direct_child)| { .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); return Some(index as isize);
} }
for descendant in direct_child.descendants(self.metadata()) { for descendant in direct_child.descendants(metadata) {
if self.selected_nodes.selected_layers(self.metadata()).any(|selected| selected == descendant) { if selected_nodes.selected_layers(metadata).any(|selected| selected == descendant) {
return Some(index as isize); return Some(index as isize);
} }
} }
@@ -21,6 +21,7 @@ use glam::{DAffine2, DVec2, IVec2};
pub enum GraphOperationMessage { pub enum GraphOperationMessage {
AddNodesAsChild { AddNodesAsChild {
nodes: HashMap<NodeId, DocumentNode>, nodes: HashMap<NodeId, DocumentNode>,
new_ids: HashMap<NodeId, NodeId>,
parent: LayerNodeIdentifier, parent: LayerNodeIdentifier,
insert_index: isize, insert_index: isize,
}, },
@@ -37,9 +37,7 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for Gr
} = data; } = data;
match message { match message {
GraphOperationMessage::AddNodesAsChild { nodes, parent, insert_index } => { GraphOperationMessage::AddNodesAsChild { nodes, new_ids, parent, insert_index } => {
let new_ids: HashMap<_, _> = nodes.iter().map(|(&id, _)| (id, NodeId(generate_uuid()))).collect();
let shift = nodes let shift = nodes
.get(&NodeId(0)) .get(&NodeId(0))
.and_then(|node| { .and_then(|node| {
@@ -100,7 +100,7 @@ impl DocumentMetadata {
let mut layer_path = layer.ancestors(self).collect::<Vec<_>>(); let mut layer_path = layer.ancestors(self).collect::<Vec<_>>();
layer_path.reverse(); layer_path.reverse();
if !include_self || !self.is_artboard(layer) && !self.is_folder(layer) { if !include_self || !self.is_artboard(layer) {
layer_path.pop(); layer_path.pop();
} }
@@ -383,12 +383,9 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
let paste = |entry: &CopyBufferEntry, responses: &mut VecDeque<_>| { let paste = |entry: &CopyBufferEntry, responses: &mut VecDeque<_>| {
if self.active_document().is_some() { if self.active_document().is_some() {
trace!("Pasting into folder {parent:?} as index: {insert_index}"); trace!("Pasting into folder {parent:?} as index: {insert_index}");
let nodes = entry.clone().nodes;
responses.add(GraphOperationMessage::AddNodesAsChild { let new_ids: HashMap<_, _> = nodes.iter().map(|(&id, _)| (id, NodeId(generate_uuid()))).collect();
nodes: entry.clone().nodes, responses.add(GraphOperationMessage::AddNodesAsChild { nodes, new_ids, parent, insert_index });
parent,
insert_index,
});
} }
}; };
@@ -408,8 +405,10 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
for entry in data.into_iter().rev() { for entry in data.into_iter().rev() {
document.load_layer_resources(responses); document.load_layer_resources(responses);
let new_ids: HashMap<_, _> = entry.nodes.iter().map(|(&id, _)| (id, NodeId(generate_uuid()))).collect();
responses.add(GraphOperationMessage::AddNodesAsChild { responses.add(GraphOperationMessage::AddNodesAsChild {
nodes: entry.nodes, nodes: entry.nodes,
new_ids,
parent, parent,
insert_index: -1, insert_index: -1,
}); });
@@ -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::snapping::{self, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnappedPoint};
use crate::messages::tool::common_functionality::transformation_cage::*; 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 graphene_core::renderer::Quad;
use std::fmt; use std::fmt;
@@ -315,23 +315,6 @@ impl SelectToolData {
let Some(layer) = layer_ancestors.last().copied() else { continue }; let Some(layer) = layer_ancestors.last().copied() else { continue };
let Some(parent) = layer.parent(&document.metadata) 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. // Moves the layer back to its starting position.
responses.add(GraphOperationMessage::TransformChange { responses.add(GraphOperationMessage::TransformChange {
layer, layer,
@@ -340,17 +323,34 @@ impl SelectToolData {
skip_rerender: true, skip_rerender: true,
}); });
let id = NodeId(generate_uuid()); // Copy the layer
let insert_index = -1; let mut copy_ids = HashMap::new();
let layer = LayerNodeIdentifier::new_unchecked(id); let node = layer.to_node();
responses.add(GraphOperationMessage::NewCustomLayer { copy_ids.insert(node, NodeId(0 as u64));
id, if let Some(input_node) = document
nodes, .network()
parent, .nodes
insert_index, .get(&node)
alias: String::new(), .and_then(|node| if node.is_layer { node.inputs.get(1) } else { node.inputs.get(0) })
}); .and_then(|input| input.as_node())
new_dragging.push(layer); {
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<NodeId, DocumentNode> = NodeGraphMessageHandler::copy_nodes(document.network(), &copy_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(); let nodes = new_dragging.iter().map(|layer| layer.to_node()).collect();
responses.add(NodeGraphMessage::SelectedNodesSet { nodes }); responses.add(NodeGraphMessage::SelectedNodesSet { nodes });