@@ -62,6 +62,9 @@ pub struct NodeGraphMessageHandler {
62
62
pub node_metadata : HashMap < NodeId , NodeMetadata > ,
63
63
/// Cache for the bounding box around all nodes in node graph space.
64
64
pub bounding_box_subpath : Option < Subpath < PointId > > ,
65
+ /// Index of selected node to be deselected on pointer up when shift clicking an already selected node
66
+ pub deselect_on_pointer_up : Option < usize > ,
67
+ /// Adds the auto panning functionality to the node graph when dragging a node or selection box to the edge of the viewport.
65
68
auto_panning : AutoPanning ,
66
69
}
67
70
@@ -473,7 +476,11 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
473
476
responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
474
477
responses. add ( NodeGraphMessage :: SendGraph ) ;
475
478
}
476
- NodeGraphMessage :: MoveSelectedNodes { displacement_x, displacement_y } => {
479
+ NodeGraphMessage :: MoveSelectedNodes {
480
+ displacement_x,
481
+ displacement_y,
482
+ move_upstream,
483
+ } => {
477
484
let network_path = if selected_nodes. selected_nodes_ref ( ) . iter ( ) . any ( |node_id| document_network. nodes . contains_key ( node_id) ) {
478
485
Vec :: new ( )
479
486
} else {
@@ -484,7 +491,20 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
484
491
warn ! ( "No network" ) ;
485
492
return ;
486
493
} ;
487
- for node_id in selected_nodes. selected_nodes ( network) . cloned ( ) . collect :: < Vec < _ > > ( ) {
494
+ let mut nodes_to_move = selected_nodes. selected_nodes ( network) . cloned ( ) . collect :: < HashSet < _ > > ( ) ;
495
+ if move_upstream {
496
+ for selected_node_id in selected_nodes. selected_nodes ( network) {
497
+ let Some ( selected_node) = network. nodes . get ( selected_node_id) else {
498
+ log:: error!( "Could not get selected node from network" ) ;
499
+ continue ;
500
+ } ;
501
+ // Only drag nodes that are children of the selected layer
502
+ if let Some ( NodeInput :: Node { node_id, .. } ) = selected_node. inputs . get ( 1 ) {
503
+ nodes_to_move. extend ( network. upstream_flow_back_from_nodes ( vec ! [ * node_id] , FlowType :: UpstreamFlow ) . map ( |( _, node_id) | node_id) )
504
+ } ;
505
+ }
506
+ }
507
+ for node_id in nodes_to_move {
488
508
if document_network. nested_network ( & network_path) . unwrap ( ) . exports_metadata . 0 == node_id {
489
509
let network = document_network. nested_network_mut ( & network_path) . unwrap ( ) ;
490
510
network. exports_metadata . 1 += IVec2 :: new ( displacement_x, displacement_y) ;
@@ -761,12 +781,11 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
761
781
modified_selected = true ;
762
782
763
783
let index = updated_selected. iter ( ) . enumerate ( ) . find_map ( |( i, node_id) | if * node_id == clicked_id { Some ( i) } else { None } ) ;
764
- // Remove from selection if already selected
765
- if let Some ( index) = index {
766
- updated_selected. remove ( index) ;
767
- }
784
+ // Remove from selection (on PointerUp) if already selected
785
+ self . deselect_on_pointer_up = index;
786
+
768
787
// Add to selection if not already selected. Necessary in order to drag multiple nodes
769
- else {
788
+ if index . is_none ( ) {
770
789
updated_selected. push ( clicked_id) ;
771
790
} ;
772
791
}
@@ -807,7 +826,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
807
826
}
808
827
self . box_selection_start = Some ( UVec2 :: new ( viewport_location. x . round ( ) . abs ( ) as u32 , viewport_location. y . round ( ) . abs ( ) as u32 ) ) ;
809
828
}
810
- // TODO: Alt+drag should move all upstream nodes as well
811
829
NodeGraphMessage :: PointerMove { shift } => {
812
830
let Some ( network) = document_network. nested_network ( & self . network ) else {
813
831
return ;
@@ -899,6 +917,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
899
917
responses. add ( NodeGraphMessage :: MoveSelectedNodes {
900
918
displacement_x : graph_delta. x - drag_start. round_x ,
901
919
displacement_y : graph_delta. y - drag_start. round_y ,
920
+ move_upstream : ipp. keyboard . get ( shift as usize ) ,
902
921
} ) ;
903
922
drag_start. round_x = graph_delta. x ;
904
923
drag_start. round_y = graph_delta. y ;
@@ -943,6 +962,13 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
943
962
warn ! ( "No network" ) ;
944
963
return ;
945
964
} ;
965
+ if let Some ( node_to_deselect) = self . deselect_on_pointer_up {
966
+ let mut new_selected_nodes = selected_nodes. selected_nodes_ref ( ) . clone ( ) ;
967
+ new_selected_nodes. remove ( node_to_deselect) ;
968
+ responses. add ( NodeGraphMessage :: SelectedNodesSet { nodes : new_selected_nodes } ) ;
969
+ self . deselect_on_pointer_up = None ;
970
+ }
971
+
946
972
// Disconnect if the wire was previously connected to an input
947
973
let viewport_location = ipp. mouse . position ;
948
974
let point = node_graph_to_viewport. inverse ( ) . transform_point2 ( viewport_location) ;
@@ -2792,6 +2818,7 @@ impl Default for NodeGraphMessageHandler {
2792
2818
context_menu : None ,
2793
2819
node_metadata : HashMap :: new ( ) ,
2794
2820
bounding_box_subpath : None ,
2821
+ deselect_on_pointer_up : None ,
2795
2822
auto_panning : Default :: default ( ) ,
2796
2823
}
2797
2824
}
0 commit comments