Skip to content

Commit 4075003

Browse files
committed
General purpose value node
1 parent ab34624 commit 4075003

File tree

9 files changed

+342
-95
lines changed

9 files changed

+342
-95
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,25 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
101101
description: Cow::Borrowed("Passes-through the input value without changing it. This is useful for rerouting wires for organization purposes."),
102102
properties: Some("identity_properties"),
103103
},
104+
DocumentNodeDefinition {
105+
identifier: "Value",
106+
category: "General",
107+
node_template: NodeTemplate {
108+
document_node: DocumentNode {
109+
implementation: DocumentNodeImplementation::proto("graphene_core::any::ValueNode"),
110+
manual_composition: Some(generic!(T)),
111+
inputs: vec![NodeInput::value(TaggedValue::None, false)],
112+
..Default::default()
113+
},
114+
persistent_node_metadata: DocumentNodePersistentMetadata {
115+
input_metadata: vec![("", "Value").into()],
116+
output_names: vec!["Out".to_string()],
117+
..Default::default()
118+
},
119+
},
120+
description: Cow::Borrowed("Returns the value stored in its input"),
121+
properties: Some("value_properties"),
122+
},
104123
// TODO: Auto-generate this from its proto node macro
105124
DocumentNodeDefinition {
106125
identifier: "Monitor",
@@ -2149,6 +2168,7 @@ fn static_node_properties() -> NodeProperties {
21492168
"monitor_properties".to_string(),
21502169
Box::new(|_node_id, _context| node_properties::string_properties("The Monitor node is used by the editor to access the data flowing through it.")),
21512170
);
2171+
map.insert("value_properties".to_string(), Box::new(node_properties::value_properties));
21522172
map
21532173
}
21542174

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ pub enum NodeGraphMessage {
147147
node_id: NodeId,
148148
alias: String,
149149
},
150+
SetReference {
151+
node_id: NodeId,
152+
reference: Option<String>,
153+
},
150154
SetToNodeOrLayer {
151155
node_id: NodeId,
152156
is_layer: bool,

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

Lines changed: 97 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,10 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
498498
log::error!("Could not get center of selected_nodes");
499499
return;
500500
};
501-
let center_of_selected_nodes_grid_space = IVec2::new((center_of_selected_nodes.x / 24. + 0.5).floor() as i32, (center_of_selected_nodes.y / 24. + 0.5).floor() as i32);
501+
let center_of_selected_nodes_grid_space = IVec2::new(
502+
(center_of_selected_nodes.x / GRID_SIZE as f64 + 0.5).floor() as i32,
503+
(center_of_selected_nodes.y / GRID_SIZE as f64 + 0.5).floor() as i32,
504+
);
502505
default_node_template.persistent_node_metadata.node_type_metadata = NodeTypePersistentMetadata::node(center_of_selected_nodes_grid_space - IVec2::new(3, 1));
503506
responses.add(DocumentMessage::AddTransaction);
504507
responses.add(NodeGraphMessage::InsertNode {
@@ -603,7 +606,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
603606
log::error!("Could not get network metadata in PointerDown");
604607
return;
605608
};
606-
609+
self.disconnecting = None;
607610
let click = ipp.mouse.position;
608611

609612
let node_graph_point = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_point2(click);
@@ -938,8 +941,9 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
938941
};
939942
responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: Some(wire_path) });
940943
}
941-
} else if self.disconnecting.is_some() {
942-
// Disconnecting with no upstream node, create new value node.
944+
}
945+
// Dragging from an exposed value input
946+
else if self.disconnecting.is_some() {
943947
let to_connector = network_interface.input_connector_from_click(ipp.mouse.position, selection_network_path);
944948
if let Some(to_connector) = &to_connector {
945949
let Some(input_position) = network_interface.input_position(to_connector, selection_network_path) else {
@@ -948,58 +952,12 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
948952
};
949953
self.wire_in_progress_to_connector = Some(input_position);
950954
}
951-
// Not hovering over a node input or node output, insert the node
952-
else {
953-
// Disconnect if the wire was previously connected to an input
954-
if let Some(disconnecting) = self.disconnecting.take() {
955-
let mut position = if let Some(to_connector) = self.wire_in_progress_to_connector { to_connector } else { point };
956-
// Offset to drag from center of node
957-
position = position - DVec2::new(24. * 3., 24.);
958-
959-
// Offset to account for division rounding error
960-
if position.x < 0. {
961-
position.x = position.x - 1.;
962-
}
963-
if position.y < 0. {
964-
position.y = position.y - 1.;
965-
}
966-
967-
let Some(input) = network_interface.take_input(&disconnecting, breadcrumb_network_path) else {
968-
return;
969-
};
970-
971-
let drag_start = DragStart {
972-
start_x: point.x,
973-
start_y: point.y,
974-
round_x: 0,
975-
round_y: 0,
976-
};
977-
978-
self.drag_start = Some((drag_start, false));
979-
self.node_has_moved_in_drag = false;
980-
self.update_node_graph_hints(responses);
981-
982-
let node_id = NodeId::new();
983-
responses.add(NodeGraphMessage::CreateNodeFromContextMenu {
984-
node_id: Some(node_id),
985-
node_type: "Identity".to_string(),
986-
xy: Some(((position.x / 24.) as i32, (position.y / 24.) as i32)),
987-
});
988-
989-
responses.add(NodeGraphMessage::SetInput {
990-
input_connector: InputConnector::node(node_id, 0),
991-
input,
992-
});
993-
994-
responses.add(NodeGraphMessage::CreateWire {
995-
output_connector: OutputConnector::Node { node_id, output_index: 0 },
996-
input_connector: disconnecting,
997-
});
998-
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![node_id] });
999-
// Update the frontend that the node is disconnected
1000-
responses.add(NodeGraphMessage::RunDocumentGraph);
1001-
responses.add(NodeGraphMessage::SendGraph);
1002-
}
955+
// Not hovering over a node input or node output, create the value node if alt is pressed
956+
else if ipp.keyboard.get(Key::Alt as usize) {
957+
self.preview_on_mouse_up = None;
958+
self.create_value_node(network_interface, point, breadcrumb_network_path, responses);
959+
} else {
960+
//TODO: Start creating wire
1003961
}
1004962
} else if let Some((drag_start, dragged)) = &mut self.drag_start {
1005963
if drag_start.start_x != point.x || drag_start.start_y != point.y {
@@ -1020,7 +978,10 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
1020978
}
1021979
}
1022980

1023-
let mut graph_delta = IVec2::new(((point.x - drag_start.start_x) / 24.).round() as i32, ((point.y - drag_start.start_y) / 24.).round() as i32);
981+
let mut graph_delta = IVec2::new(
982+
((point.x - drag_start.start_x) / GRID_SIZE as f64).round() as i32,
983+
((point.y - drag_start.start_y) / GRID_SIZE as f64).round() as i32,
984+
);
1024985
let previous_round_x = drag_start.round_x;
1025986
let previous_round_y = drag_start.round_y;
1026987

@@ -1407,6 +1368,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
14071368
let document_bbox: [DVec2; 2] = viewport_bbox.map(|p| network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_point2(p));
14081369

14091370
let mut nodes = Vec::new();
1371+
14101372
for node_id in &self.frontend_nodes {
14111373
let Some(node_bbox) = network_interface.node_bounding_box(node_id, breadcrumb_network_path) else {
14121374
log::error!("Could not get bbox for node: {:?}", node_id);
@@ -1418,6 +1380,17 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
14181380
}
14191381
}
14201382

1383+
// Always send nodes with errors
1384+
for error in &self.node_graph_errors {
1385+
let Some((id, path)) = error.node_path.split_last() else {
1386+
log::error!("Could not get node path in error: {:?}", error);
1387+
continue;
1388+
};
1389+
if breadcrumb_network_path == path {
1390+
nodes.push(*id);
1391+
}
1392+
}
1393+
14211394
responses.add(FrontendMessage::UpdateVisibleNodes { nodes });
14221395
}
14231396
NodeGraphMessage::SendGraph => {
@@ -1456,7 +1429,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
14561429
input,
14571430
});
14581431
responses.add(PropertiesPanelMessage::Refresh);
1459-
if !(network_interface.reference(&node_id, selection_network_path).is_none() || input_index == 0) && network_interface.connected_to_output(&node_id, selection_network_path) {
1432+
if network_interface.connected_to_output(&node_id, selection_network_path) {
14601433
responses.add(NodeGraphMessage::RunDocumentGraph);
14611434
}
14621435
}
@@ -1538,6 +1511,9 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
15381511

15391512
responses.add(NodeGraphMessage::SendWires);
15401513
}
1514+
NodeGraphMessage::SetReference { node_id, reference } => {
1515+
network_interface.set_reference(&node_id, breadcrumb_network_path, reference);
1516+
}
15411517
NodeGraphMessage::SetToNodeOrLayer { node_id, is_layer } => {
15421518
if is_layer && !network_interface.is_eligible_to_be_layer(&node_id, selection_network_path) {
15431519
return;
@@ -2217,6 +2193,69 @@ impl NodeGraphMessageHandler {
22172193
}
22182194
}
22192195

2196+
fn create_value_node(&mut self, network_interface: &mut NodeNetworkInterface, point: DVec2, breadcrumb_network_path: &[NodeId], responses: &mut VecDeque<Message>) {
2197+
let Some(disconnecting) = self.disconnecting.take() else {
2198+
log::error!("To connector must be initialized to create a value node");
2199+
return;
2200+
};
2201+
let Some(mut position) = self.wire_in_progress_to_connector.take() else {
2202+
log::error!("To connector must be initialized to create a value node");
2203+
return;
2204+
};
2205+
// Offset node insertion 3 grid spaces left and 1 grid space up so the center of the node is dragged
2206+
position = position - DVec2::new(GRID_SIZE as f64 * 3., GRID_SIZE as f64);
2207+
2208+
// Offset to account for division rounding error and place the selected node to the top left of the input
2209+
if position.x < 0. {
2210+
position.x = position.x - 1.;
2211+
}
2212+
if position.y < 0. {
2213+
position.y = position.y - 1.;
2214+
}
2215+
2216+
let Some(mut input) = network_interface.take_input(&disconnecting, breadcrumb_network_path) else {
2217+
return;
2218+
};
2219+
2220+
match &mut input {
2221+
NodeInput::Value { exposed, .. } => *exposed = false,
2222+
_ => return,
2223+
}
2224+
2225+
let drag_start = DragStart {
2226+
start_x: point.x,
2227+
start_y: point.y,
2228+
round_x: 0,
2229+
round_y: 0,
2230+
};
2231+
2232+
self.drag_start = Some((drag_start, false));
2233+
self.node_has_moved_in_drag = false;
2234+
self.update_node_graph_hints(responses);
2235+
2236+
let node_id = NodeId::new();
2237+
responses.add(NodeGraphMessage::CreateNodeFromContextMenu {
2238+
node_id: Some(node_id),
2239+
node_type: "Value".to_string(),
2240+
xy: Some(((position.x / GRID_SIZE as f64) as i32, (position.y / GRID_SIZE as f64) as i32)),
2241+
add_transaction: false,
2242+
});
2243+
2244+
responses.add(NodeGraphMessage::SetInput {
2245+
input_connector: InputConnector::node(node_id, 0),
2246+
input,
2247+
});
2248+
2249+
responses.add(NodeGraphMessage::CreateWire {
2250+
output_connector: OutputConnector::Node { node_id, output_index: 0 },
2251+
input_connector: disconnecting,
2252+
});
2253+
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![node_id] });
2254+
// Update the frontend that the node is disconnected
2255+
responses.add(NodeGraphMessage::RunDocumentGraph);
2256+
responses.add(NodeGraphMessage::SendGraph);
2257+
}
2258+
22202259
fn collect_wires(&mut self, network_interface: &mut NodeNetworkInterface, graph_wire_style: GraphWireStyle, breadcrumb_network_path: &[NodeId]) -> Vec<WirePathUpdate> {
22212260
let mut added_wires = network_interface
22222261
.node_graph_input_connectors(breadcrumb_network_path)

0 commit comments

Comments
 (0)