mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-28 07:58:12 +08:00
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:
+2
-9
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user