@@ -7,6 +7,7 @@ use crate::messages::debug::utility_types::MessageLoggingVerbosity;
7
7
use crate :: messages:: dialog:: simple_dialogs;
8
8
use crate :: messages:: frontend:: utility_types:: FrontendDocumentDetails ;
9
9
use crate :: messages:: layout:: utility_types:: widget_prelude:: * ;
10
+ use crate :: messages:: portfolio:: document:: graph_operation:: utility_types:: TransformIn ;
10
11
use crate :: messages:: portfolio:: document:: node_graph:: document_node_definitions:: resolve_document_node_type;
11
12
use crate :: messages:: portfolio:: document:: utility_types:: clipboards:: { Clipboard , CopyBufferEntry , INTERNAL_CLIPBOARD_COUNT } ;
12
13
use crate :: messages:: portfolio:: document:: utility_types:: nodes:: SelectedNodes ;
@@ -15,6 +16,7 @@ use crate::messages::preferences::SelectionMode;
15
16
use crate :: messages:: prelude:: * ;
16
17
use crate :: messages:: tool:: utility_types:: { HintData , HintGroup , ToolType } ;
17
18
use crate :: node_graph_executor:: { ExportConfig , NodeGraphExecutor } ;
19
+ use graphene_core:: renderer:: Quad ;
18
20
19
21
use bezier_rs:: Subpath ;
20
22
use glam:: IVec2 ;
@@ -888,22 +890,42 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
888
890
if let Some ( document) = self . active_document ( ) {
889
891
if let Ok ( data) = serde_json:: from_str :: < Vec < CopyBufferEntry > > ( & data) {
890
892
let parent = document. new_layer_parent ( false ) ;
891
-
892
- let mut added_nodes = false ;
893
-
894
- for entry in data. into_iter ( ) . rev ( ) {
895
- if !added_nodes {
896
- responses. add ( DocumentMessage :: DeselectAllLayers ) ;
897
- responses. add ( DocumentMessage :: AddTransaction ) ;
898
- added_nodes = true ;
893
+ let mut transform = document. metadata ( ) . document_to_viewport ;
894
+
895
+ // Check parent bounds first since children will be pasted at same position
896
+ if let Some ( parent_bounds) = document. metadata ( ) . bounding_box_document ( parent) {
897
+ let viewport_bounds = Quad :: from_box_at_zero ( ipp. viewport_bounds . size ( ) ) ;
898
+ let quad = transform * Quad :: from_box ( parent_bounds) ;
899
+
900
+ transform. translation = ( viewport_bounds. center ( ) - quad. center ( ) ) . round ( ) + quad. center ( ) ;
901
+ let centering_transform = quad. 0 . into_iter ( ) . all ( |point| !viewport_bounds. contains ( point) ) . then_some ( transform) ;
902
+
903
+ let mut added_nodes = false ;
904
+
905
+ for entry in data. into_iter ( ) . rev ( ) {
906
+ if !added_nodes {
907
+ responses. add ( DocumentMessage :: DeselectAllLayers ) ;
908
+ responses. add ( DocumentMessage :: AddTransaction ) ;
909
+ added_nodes = true ;
910
+ }
911
+
912
+ document. load_layer_resources ( responses) ;
913
+ let new_ids: HashMap < _ , _ > = entry. nodes . iter ( ) . map ( |( id, _) | ( * id, NodeId :: new ( ) ) ) . collect ( ) ;
914
+ let layer = LayerNodeIdentifier :: new_unchecked ( new_ids[ & NodeId ( 0 ) ] ) ;
915
+ responses. add ( NodeGraphMessage :: AddNodes { nodes : entry. nodes , new_ids } ) ;
916
+ responses. add ( NodeGraphMessage :: MoveLayerToStack { layer, parent, insert_index : 0 } ) ;
917
+
918
+ if let Some ( transform) = centering_transform {
919
+ responses. add ( GraphOperationMessage :: TransformSet {
920
+ layer,
921
+ transform,
922
+ transform_in : TransformIn :: Viewport ,
923
+ skip_rerender : false ,
924
+ } ) ;
925
+ }
899
926
}
900
- document. load_layer_resources ( responses) ;
901
- let new_ids: HashMap < _ , _ > = entry. nodes . iter ( ) . map ( |( id, _) | ( * id, NodeId :: new ( ) ) ) . collect ( ) ;
902
- let layer = LayerNodeIdentifier :: new_unchecked ( new_ids[ & NodeId ( 0 ) ] ) ;
903
- responses. add ( NodeGraphMessage :: AddNodes { nodes : entry. nodes , new_ids } ) ;
904
- responses. add ( NodeGraphMessage :: MoveLayerToStack { layer, parent, insert_index : 0 } ) ;
927
+ responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
905
928
}
906
- responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
907
929
}
908
930
}
909
931
}
0 commit comments