From 8803cb4079b2fc24716b01b0dca97ec81ae840cb Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 5 Jul 2025 12:35:36 -0700 Subject: [PATCH] Identity from value input --- .../node_graph/node_graph_message_handler.rs | 63 +++++++++++++++++++ .../utility_types/network_interface.rs | 18 ++++++ 2 files changed, 81 insertions(+) diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index f28d9d4e11..6dd371e49c 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -994,6 +994,69 @@ impl<'a> MessageHandler> for NodeG }; responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: Some(wire_path) }); } + } else if self.disconnecting.is_some() { + // Disconnecting with no upstream node, create new value node. + let to_connector = network_interface.input_connector_from_click(ipp.mouse.position, selection_network_path); + if let Some(to_connector) = &to_connector { + let Some(input_position) = network_interface.input_position(to_connector, selection_network_path) else { + log::error!("Could not get input position for connector: {to_connector:?}"); + return; + }; + self.wire_in_progress_to_connector = Some(input_position); + } + // Not hovering over a node input or node output, insert the node + else { + // Disconnect if the wire was previously connected to an input + if let Some(disconnecting) = self.disconnecting.take() { + let mut position = if let Some(to_connector) = self.wire_in_progress_to_connector { to_connector } else { point }; + // Offset to drag from center of node + position = position - DVec2::new(24. * 3., 24.); + + // Offset to account for division rounding error + if position.x < 0. { + position.x = position.x - 1.; + } + if position.y < 0. { + position.y = position.y - 1.; + } + + let Some(input) = network_interface.take_input(&disconnecting, breadcrumb_network_path) else { + return; + }; + + let drag_start = DragStart { + start_x: point.x, + start_y: point.y, + round_x: 0, + round_y: 0, + }; + + self.drag_start = Some((drag_start, false)); + self.node_has_moved_in_drag = false; + self.update_node_graph_hints(responses); + + let node_id = NodeId::new(); + responses.add(NodeGraphMessage::CreateNodeFromContextMenu { + node_id: Some(node_id), + node_type: "Identity".to_string(), + xy: Some(((position.x / 24.) as i32, (position.y / 24.) as i32)), + }); + + responses.add(NodeGraphMessage::SetInput { + input_connector: InputConnector::node(node_id, 0), + input, + }); + + responses.add(NodeGraphMessage::CreateWire { + output_connector: OutputConnector::Node { node_id, output_index: 0 }, + input_connector: disconnecting, + }); + responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![node_id] }); + // Update the frontend that the node is disconnected + responses.add(NodeGraphMessage::RunDocumentGraph); + responses.add(NodeGraphMessage::SendGraph); + } + } } else if let Some((drag_start, dragged)) = &mut self.drag_start { if drag_start.start_x != point.x || drag_start.start_y != point.y { *dragged = true; diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface.rs b/editor/src/messages/portfolio/document/utility_types/network_interface.rs index 290247f621..18fbfbd274 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -501,6 +501,24 @@ impl NodeNetworkInterface { } } + pub fn take_input(&mut self, input_connector: &InputConnector, network_path: &[NodeId]) -> Option { + let Some(network) = self.network_mut(network_path) else { + log::error!("Could not get network in input_from_connector"); + return None; + }; + let input = match input_connector { + InputConnector::Node { node_id, input_index } => { + let Some(node) = network.nodes.get_mut(node_id) else { + log::error!("Could not get node {node_id} in input_from_connector"); + return None; + }; + node.inputs.get_mut(*input_index) + } + InputConnector::Export(export_index) => network.exports.get_mut(*export_index), + }; + input.map(|input| std::mem::replace(input, NodeInput::value(TaggedValue::None, true))) + } + /// Try and get the [`Type`] for any [`InputConnector`] based on the `self.resolved_types`. fn node_type_from_compiled(&mut self, input_connector: &InputConnector, network_path: &[NodeId]) -> Option<(Type, TypeSource)> { let (node_id, input_index) = match *input_connector {