Skip to content

Add draggable upstream nodes feature #1812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub enum NodeGraphMessage {
MoveSelectedNodes {
displacement_x: i32,
displacement_y: i32,
move_upstream: bool,
},
PasteNodes {
serialized_nodes: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ pub struct NodeGraphMessageHandler {
pub node_metadata: HashMap<NodeId, NodeMetadata>,
/// Cache for the bounding box around all nodes in node graph space.
pub bounding_box_subpath: Option<Subpath<PointId>>,
/// Index of selected node to be deselected on pointer up when shift clicking an already selected node
pub deselect_on_pointer_up: Option<usize>,
/// Adds the auto panning functionality to the node graph when dragging a node or selection box to the edge of the viewport.
auto_panning: AutoPanning,
}

Expand Down Expand Up @@ -473,7 +476,11 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
responses.add(NodeGraphMessage::RunDocumentGraph);
responses.add(NodeGraphMessage::SendGraph);
}
NodeGraphMessage::MoveSelectedNodes { displacement_x, displacement_y } => {
NodeGraphMessage::MoveSelectedNodes {
displacement_x,
displacement_y,
move_upstream,
} => {
let network_path = if selected_nodes.selected_nodes_ref().iter().any(|node_id| document_network.nodes.contains_key(node_id)) {
Vec::new()
} else {
Expand All @@ -484,7 +491,20 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
warn!("No network");
return;
};
for node_id in selected_nodes.selected_nodes(network).cloned().collect::<Vec<_>>() {
let mut nodes_to_move = selected_nodes.selected_nodes(network).cloned().collect::<HashSet<_>>();
if move_upstream {
for selected_node_id in selected_nodes.selected_nodes(network) {
let Some(selected_node) = network.nodes.get(selected_node_id) else {
log::error!("Could not get selected node from network");
continue;
};
// Only drag nodes that are children of the selected layer
if let Some(NodeInput::Node { node_id, .. }) = selected_node.inputs.get(1) {
nodes_to_move.extend(network.upstream_flow_back_from_nodes(vec![*node_id], FlowType::UpstreamFlow).map(|(_, node_id)| node_id))
};
}
}
for node_id in nodes_to_move {
if document_network.nested_network(&network_path).unwrap().exports_metadata.0 == node_id {
let network = document_network.nested_network_mut(&network_path).unwrap();
network.exports_metadata.1 += IVec2::new(displacement_x, displacement_y);
Expand Down Expand Up @@ -761,12 +781,11 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
modified_selected = true;

let index = updated_selected.iter().enumerate().find_map(|(i, node_id)| if *node_id == clicked_id { Some(i) } else { None });
// Remove from selection if already selected
if let Some(index) = index {
updated_selected.remove(index);
}
// Remove from selection (on PointerUp) if already selected
self.deselect_on_pointer_up = index;

// Add to selection if not already selected. Necessary in order to drag multiple nodes
else {
if index.is_none() {
updated_selected.push(clicked_id);
};
}
Expand Down Expand Up @@ -807,7 +826,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
}
self.box_selection_start = Some(UVec2::new(viewport_location.x.round().abs() as u32, viewport_location.y.round().abs() as u32));
}
// TODO: Alt+drag should move all upstream nodes as well
NodeGraphMessage::PointerMove { shift } => {
let Some(network) = document_network.nested_network(&self.network) else {
return;
Expand Down Expand Up @@ -899,6 +917,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
responses.add(NodeGraphMessage::MoveSelectedNodes {
displacement_x: graph_delta.x - drag_start.round_x,
displacement_y: graph_delta.y - drag_start.round_y,
move_upstream: ipp.keyboard.get(shift as usize),
});
drag_start.round_x = graph_delta.x;
drag_start.round_y = graph_delta.y;
Expand Down Expand Up @@ -943,6 +962,13 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
warn!("No network");
return;
};
if let Some(node_to_deselect) = self.deselect_on_pointer_up {
let mut new_selected_nodes = selected_nodes.selected_nodes_ref().clone();
new_selected_nodes.remove(node_to_deselect);
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: new_selected_nodes });
self.deselect_on_pointer_up = None;
}

// Disconnect if the wire was previously connected to an input
let viewport_location = ipp.mouse.position;
let point = node_graph_to_viewport.inverse().transform_point2(viewport_location);
Expand Down Expand Up @@ -2792,6 +2818,7 @@ impl Default for NodeGraphMessageHandler {
context_menu: None,
node_metadata: HashMap::new(),
bounding_box_subpath: None,
deselect_on_pointer_up: None,
auto_panning: Default::default(),
}
}
Expand Down
Loading