Allow the Pen tool to connect layers by their endpoints, merging into a single layer (#2076)

* Merge vector data layers

* Fix early return

* Fix layer space multiplication error

* Recalculate positions when changing layer space

* Add transform node

* Remove pen tool layer state
This commit is contained in:
adamgerhant
2024-11-01 12:19:46 -07:00
committed by GitHub
parent 018e9839f8
commit c7b08246c2
8 changed files with 229 additions and 33 deletions
@@ -1,7 +1,7 @@
use super::transform_utils;
use super::utility_types::ModifyInputsContext;
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface};
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface, OutputConnector};
use crate::messages::portfolio::document::utility_types::nodes::CollapsedLayers;
use crate::messages::prelude::*;
@@ -95,14 +95,7 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for Gr
}
}
GraphOperationMessage::SetUpstreamToChain { layer } => {
let Some(first_chain_node) = network_interface
.upstream_flow_back_from_nodes(
vec![layer.to_node()],
&[],
crate::messages::portfolio::document::utility_types::network_interface::FlowType::HorizontalFlow,
)
.nth(1)
else {
let Some(OutputConnector::Node { node_id: first_chain_node, .. }) = network_interface.upstream_output_connector(&InputConnector::node(layer.to_node(), 1), &[]) else {
return;
};
@@ -37,6 +37,10 @@ pub enum NodeGraphMessage {
output_connector: OutputConnector,
input_connector: InputConnector,
},
ConnectUpstreamOutputToInput {
downstream_input: InputConnector,
input_connector: InputConnector,
},
Cut,
DeleteNodes {
node_ids: Vec<NodeId>,
@@ -70,6 +74,10 @@ pub enum NodeGraphMessage {
parent: LayerNodeIdentifier,
insert_index: usize,
},
MoveNodeToChainStart {
node_id: NodeId,
parent: LayerNodeIdentifier,
},
PasteNodes {
serialized_nodes: String,
},
@@ -210,6 +210,16 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
});
responses.add(NodeGraphMessage::SendGraph);
}
NodeGraphMessage::ConnectUpstreamOutputToInput { downstream_input, input_connector } => {
let Some(upstream_node) = network_interface.upstream_output_connector(&downstream_input, selection_network_path) else {
log::error!("Failed to find upstream node for downstream_input");
return;
};
responses.add(NodeGraphMessage::CreateWire {
output_connector: upstream_node,
input_connector,
});
}
NodeGraphMessage::Cut => {
responses.add(NodeGraphMessage::Copy);
responses.add(NodeGraphMessage::DeleteSelectedNodes { delete_children: true });
@@ -323,6 +333,9 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index } => {
network_interface.move_layer_to_stack(layer, parent, insert_index, selection_network_path);
}
NodeGraphMessage::MoveNodeToChainStart { node_id, parent } => {
network_interface.move_node_to_chain_start(&node_id, parent, selection_network_path);
}
NodeGraphMessage::PasteNodes { serialized_nodes } => {
let data = match serde_json::from_str::<Vec<(NodeId, NodeTemplate)>>(&serialized_nodes) {
Ok(d) => d,
@@ -88,6 +88,10 @@ impl DocumentMetadata {
self.upstream_transforms.get(&node_id).copied().map(|(_, transform)| transform).unwrap_or(DAffine2::IDENTITY)
}
pub fn downstream_transform_to_document(&self, layer: LayerNodeIdentifier) -> DAffine2 {
self.document_to_viewport.inverse() * self.downstream_transform_to_viewport(layer)
}
pub fn downstream_transform_to_viewport(&self, layer: LayerNodeIdentifier) -> DAffine2 {
if layer == LayerNodeIdentifier::ROOT_PARENT {
return self.transform_to_viewport(layer);
@@ -4894,6 +4894,32 @@ impl NodeNetworkInterface {
self.create_wire(&OutputConnector::node(*node_id, 0), &InputConnector::node(parent.to_node(), 1), network_path);
self.set_chain_position(node_id, network_path);
} else {
// TODO: Implement a more robust horizontal shift system when inserting a node into a chain.
// This should be done by breaking the chain and shifting the sole dependents for each node upstream of the insertion.
// Before inserting the node, shift the layer right 7 units so that all sole dependents are also shifted
// let input_connector = InputConnector::node(parent.to_node(), 0);
// let old_upstream = self.upstream_output_connector(&input_connector, network_path);
// This also needs to disconnect from the downstream layer
// self.disconnect_input(&input_connector, network_path);
// let Some(selected_nodes) = self.selected_nodes_mut(network_path) else {
// log::error!("Could not get selected nodes in move_layer_to_stack");
// return;
// };
// let old_selected_nodes = selected_nodes.replace_with(vec![parent.to_node()]);
// for _ in 0..7 {
// self.shift_selected_nodes(Direction::Left, false, network_path);
// }
// // Grip drag it back to the right
// for _ in 0..7 {
// self.shift_selected_nodes(Direction::Right, true, network_path);
// }
// let _ = self.selected_nodes_mut(network_path).unwrap().replace_with(old_selected_nodes);
// if let Some(old_upstream) = old_upstream {
// self.create_wire(&old_upstream, &input_connector, network_path);
// }
// Insert the node in the gap and set the upstream to a chain
self.insert_node_between(node_id, &InputConnector::node(parent.to_node(), 1), 0, network_path);
self.force_set_upstream_to_chain(node_id, network_path);
}