Skip to content

Commit bba771b

Browse files
authored
Add mitigation for inability to connect graph import directly to export by auto-inserting a Passthrough node (#3449)
insert passthrough
1 parent 9fc98cf commit bba771b

File tree

2 files changed

+55
-28
lines changed

2 files changed

+55
-28
lines changed

editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,30 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
203203
}
204204
NodeGraphMessage::CreateWire { output_connector, input_connector } => {
205205
// TODO: Add support for flattening NodeInput::Import exports in flatten_with_fns https://github.com/GraphiteEditor/Graphite/issues/1762
206-
if matches!(input_connector, InputConnector::Export(_)) && matches!(output_connector, OutputConnector::Import { .. }) {
207-
// We return early for now until this case becomes supported, then we can remove this
206+
if let (InputConnector::Export(_), OutputConnector::Import(_)) = (input_connector, output_connector) {
207+
let mid_point = (network_interface.get_output_center(&output_connector, breadcrumb_network_path).unwrap()
208+
+ network_interface.get_input_center(&input_connector, breadcrumb_network_path).unwrap())
209+
/ 2.;
210+
let node_template = Box::new(document_node_definitions::resolve_document_node_type("Passthrough").unwrap().default_node_template());
211+
212+
let node_id = NodeId::new();
213+
responses.add(NodeGraphMessage::InsertNode { node_id, node_template });
214+
responses.add(NodeGraphMessage::ShiftNodePosition {
215+
node_id,
216+
x: (mid_point.x / 24.) as i32,
217+
y: (mid_point.y / 24.) as i32,
218+
});
219+
let node_input_connector = InputConnector::node(node_id, 0);
220+
let node_output_connector = OutputConnector::node(node_id, 0);
221+
responses.add(NodeGraphMessage::CreateWire {
222+
output_connector,
223+
input_connector: node_input_connector,
224+
});
225+
responses.add(NodeGraphMessage::CreateWire {
226+
output_connector: node_output_connector,
227+
input_connector,
228+
});
229+
208230
return;
209231
}
210232
network_interface.create_wire(&output_connector, &input_connector, selection_network_path);
@@ -745,7 +767,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
745767
let clicked_input = network_interface.input_connector_from_click(click, selection_network_path);
746768
let clicked_output = network_interface.output_connector_from_click(click, selection_network_path);
747769
let network_metadata = network_interface.network_metadata(selection_network_path).unwrap();
748-
749770
// Create the add node popup on right click, then exit
750771
if right_click {
751772
// Abort dragging a node

editor/src/messages/portfolio/document/utility_types/network_interface.rs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,15 +2704,23 @@ impl NodeNetworkInterface {
27042704
log::error!("Could not get nested network_metadata in collect_frontend_click_targets");
27052705
return FrontendClickTargets::default();
27062706
};
2707-
network_metadata.persistent_metadata.node_metadata.keys().copied().collect::<Vec<_>>().into_iter().for_each(|node_id| {
2708-
if let (Some(import_export_click_targets), Some(node_click_targets)) = (self.import_export_ports(network_path).cloned(), self.node_click_targets(&node_id, network_path)) {
2707+
let nodes = network_metadata.persistent_metadata.node_metadata.keys().copied().collect::<Vec<_>>();
2708+
if let Some(import_export_click_targets) = self.import_export_ports(network_path).cloned() {
2709+
for port in import_export_click_targets.click_targets() {
2710+
if let ClickTargetType::Subpath(subpath) = port.target_type() {
2711+
connector_click_targets.push(subpath.to_bezpath().to_svg());
2712+
}
2713+
}
2714+
}
2715+
nodes.into_iter().for_each(|node_id| {
2716+
if let Some(node_click_targets) = self.node_click_targets(&node_id, network_path) {
27092717
let mut node_path = String::new();
27102718

27112719
if let ClickTargetType::Subpath(subpath) = node_click_targets.node_click_target.target_type() {
27122720
node_path.push_str(subpath.to_bezpath().to_svg().as_str())
27132721
}
27142722
all_node_click_targets.push((node_id, node_path));
2715-
for port in node_click_targets.port_click_targets.click_targets().chain(import_export_click_targets.click_targets()) {
2723+
for port in node_click_targets.port_click_targets.click_targets() {
27162724
if let ClickTargetType::Subpath(subpath) = port.target_type() {
27172725
connector_click_targets.push(subpath.to_bezpath().to_svg());
27182726
}
@@ -2879,19 +2887,18 @@ impl NodeNetworkInterface {
28792887
.collect::<Vec<_>>()
28802888
.iter()
28812889
.filter_map(|node_id| {
2882-
self.node_click_targets(node_id, network_path)
2883-
.and_then(|transient_node_metadata| {
2884-
transient_node_metadata
2885-
.port_click_targets
2886-
.clicked_input_port_from_point(point)
2887-
.map(|port| InputConnector::node(*node_id, port))
2888-
})
2889-
.or_else(|| {
2890-
self.import_export_ports(network_path)
2891-
.and_then(|import_export_ports| import_export_ports.clicked_input_port_from_point(point).map(InputConnector::Export))
2892-
})
2890+
self.node_click_targets(node_id, network_path).and_then(|transient_node_metadata| {
2891+
transient_node_metadata
2892+
.port_click_targets
2893+
.clicked_input_port_from_point(point)
2894+
.map(|port| InputConnector::node(*node_id, port))
2895+
})
28932896
})
28942897
.next()
2898+
.or_else(|| {
2899+
self.import_export_ports(network_path)
2900+
.and_then(|import_export_ports| import_export_ports.clicked_input_port_from_point(point).map(InputConnector::Export))
2901+
})
28952902
}
28962903

28972904
pub fn output_connector_from_click(&mut self, click: DVec2, network_path: &[NodeId]) -> Option<OutputConnector> {
@@ -2909,19 +2916,18 @@ impl NodeNetworkInterface {
29092916
nodes
29102917
.iter()
29112918
.filter_map(|node_id| {
2912-
self.node_click_targets(node_id, network_path)
2913-
.and_then(|transient_node_metadata| {
2914-
transient_node_metadata
2915-
.port_click_targets
2916-
.clicked_output_port_from_point(point)
2917-
.map(|output_index| OutputConnector::node(*node_id, output_index))
2918-
})
2919-
.or_else(|| {
2920-
self.import_export_ports(network_path)
2921-
.and_then(|import_export_ports| import_export_ports.clicked_output_port_from_point(point).map(OutputConnector::Import))
2922-
})
2919+
self.node_click_targets(node_id, network_path).and_then(|transient_node_metadata| {
2920+
transient_node_metadata
2921+
.port_click_targets
2922+
.clicked_output_port_from_point(point)
2923+
.map(|output_index| OutputConnector::node(*node_id, output_index))
2924+
})
29232925
})
29242926
.next()
2927+
.or_else(|| {
2928+
self.import_export_ports(network_path)
2929+
.and_then(|import_export_ports| import_export_ports.clicked_output_port_from_point(point).map(OutputConnector::Import))
2930+
})
29252931
}
29262932

29272933
pub fn input_position(&mut self, input_connector: &InputConnector, network_path: &[NodeId]) -> Option<DVec2> {

0 commit comments

Comments
 (0)