@@ -3,7 +3,7 @@ use super::document::utility_types::network_interface;
33use super :: spreadsheet:: SpreadsheetMessageHandler ;
44use super :: utility_types:: { PanelType , PersistentData } ;
55use crate :: application:: generate_uuid;
6- use crate :: consts:: DEFAULT_DOCUMENT_NAME ;
6+ use crate :: consts:: { DEFAULT_DOCUMENT_NAME , DEFAULT_STROKE_WIDTH } ;
77use crate :: messages:: animation:: TimingInformation ;
88use crate :: messages:: debug:: utility_types:: MessageLoggingVerbosity ;
99use crate :: messages:: dialog:: simple_dialogs;
@@ -12,6 +12,7 @@ use crate::messages::layout::utility_types::widget_prelude::*;
1212use crate :: messages:: portfolio:: document:: DocumentMessageContext ;
1313use crate :: messages:: portfolio:: document:: graph_operation:: utility_types:: TransformIn ;
1414use crate :: messages:: portfolio:: document:: node_graph:: document_node_definitions;
15+ use crate :: messages:: portfolio:: document:: node_graph:: document_node_definitions:: resolve_document_node_type;
1516use crate :: messages:: portfolio:: document:: utility_types:: clipboards:: { Clipboard , CopyBufferEntry , INTERNAL_CLIPBOARD_COUNT } ;
1617use crate :: messages:: portfolio:: document:: utility_types:: network_interface:: OutputConnector ;
1718use crate :: messages:: portfolio:: document:: utility_types:: nodes:: SelectedNodes ;
@@ -21,11 +22,14 @@ use crate::messages::prelude::*;
2122use crate :: messages:: tool:: common_functionality:: graph_modification_utils;
2223use crate :: messages:: tool:: utility_types:: { HintData , HintGroup , ToolType } ;
2324use crate :: node_graph_executor:: { ExportConfig , NodeGraphExecutor } ;
25+ use bezier_rs:: BezierHandles ;
2426use glam:: { DAffine2 , DVec2 } ;
2527use graph_craft:: document:: NodeId ;
2628use graph_craft:: document:: value:: TaggedValue ;
29+ use graphene_std:: Color ;
2730use graphene_std:: renderer:: Quad ;
2831use graphene_std:: text:: Font ;
32+ use graphene_std:: vector:: { HandleId , PointId , SegmentId , VectorData , VectorModificationType } ;
2933use std:: vec;
3034
3135#[ derive( ExtractField ) ]
@@ -576,6 +580,99 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
576580 }
577581 }
578582 }
583+ // Custom paste implementation for Path tool
584+ PortfolioMessage :: PasteSerializedVector { data } => {
585+ // If using Path tool then send the operation to Path tool
586+ if * current_tool == ToolType :: Path {
587+ responses. add ( PathToolMessage :: Paste { data } ) ;
588+ return ;
589+ }
590+
591+ // If not using Path tool, create new layers and add paths into those
592+ if let Some ( document) = self . active_document ( ) {
593+ let Ok ( data) = serde_json:: from_str :: < Vec < ( LayerNodeIdentifier , VectorData , DAffine2 ) > > ( & data) else {
594+ return ;
595+ } ;
596+
597+ let mut layers = Vec :: new ( ) ;
598+
599+ for ( _, new_vector, transform) in data {
600+ let Some ( node_type) = resolve_document_node_type ( "Path" ) else {
601+ error ! ( "Path node does not exist" ) ;
602+ continue ;
603+ } ;
604+ let nodes = vec ! [ ( NodeId ( 0 ) , node_type. default_node_template( ) ) ] ;
605+
606+ let parent = document. new_layer_parent ( false ) ;
607+
608+ let layer = graph_modification_utils:: new_custom ( NodeId :: new ( ) , nodes, parent, responses) ;
609+ layers. push ( layer) ;
610+
611+ // Adding the transform back into the layer
612+ responses. add ( GraphOperationMessage :: TransformSet {
613+ layer,
614+ transform,
615+ transform_in : TransformIn :: Local ,
616+ skip_rerender : false ,
617+ } ) ;
618+
619+ // Add default fill and stroke to the layer
620+ let fill_color = Color :: WHITE ;
621+ let stroke_color = Color :: BLACK ;
622+
623+ let fill = graphene_std:: vector:: style:: Fill :: solid ( fill_color. to_gamma_srgb ( ) ) ;
624+ responses. add ( GraphOperationMessage :: FillSet { layer, fill } ) ;
625+
626+ let stroke = graphene_std:: vector:: style:: Stroke :: new ( Some ( stroke_color. to_gamma_srgb ( ) ) , DEFAULT_STROKE_WIDTH ) ;
627+ responses. add ( GraphOperationMessage :: StrokeSet { layer, stroke } ) ;
628+
629+ // Create new point ids and add those into the existing vector data
630+ let mut points_map = HashMap :: new ( ) ;
631+ for ( point, position) in new_vector. point_domain . iter ( ) {
632+ let new_point_id = PointId :: generate ( ) ;
633+ points_map. insert ( point, new_point_id) ;
634+ let modification_type = VectorModificationType :: InsertPoint { id : new_point_id, position } ;
635+ responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
636+ }
637+
638+ // Create new segment ids and add the segments into the existing vector data
639+ let mut segments_map = HashMap :: new ( ) ;
640+ for ( segment_id, bezier, start, end) in new_vector. segment_bezier_iter ( ) {
641+ let new_segment_id = SegmentId :: generate ( ) ;
642+
643+ segments_map. insert ( segment_id, new_segment_id) ;
644+
645+ let handles = match bezier. handles {
646+ BezierHandles :: Linear => [ None , None ] ,
647+ BezierHandles :: Quadratic { handle } => [ Some ( handle - bezier. start ) , None ] ,
648+ BezierHandles :: Cubic { handle_start, handle_end } => [ Some ( handle_start - bezier. start ) , Some ( handle_end - bezier. end ) ] ,
649+ } ;
650+
651+ let points = [ points_map[ & start] , points_map[ & end] ] ;
652+ let modification_type = VectorModificationType :: InsertSegment { id : new_segment_id, points, handles } ;
653+ responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
654+ }
655+
656+ // Set G1 continuity
657+ for handles in new_vector. colinear_manipulators {
658+ let to_new_handle = |handle : HandleId | -> HandleId {
659+ HandleId {
660+ ty : handle. ty ,
661+ segment : segments_map[ & handle. segment ] ,
662+ }
663+ } ;
664+ let new_handles = [ to_new_handle ( handles[ 0 ] ) , to_new_handle ( handles[ 1 ] ) ] ;
665+ let modification_type = VectorModificationType :: SetG1Continuous { handles : new_handles, enabled : true } ;
666+ responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
667+ }
668+ }
669+
670+ responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
671+ responses. add ( Message :: Defer ( DeferMessage :: AfterGraphRun {
672+ messages : vec ! [ PortfolioMessage :: CenterPastedLayers { layers } . into( ) ] ,
673+ } ) ) ;
674+ }
675+ }
579676 PortfolioMessage :: CenterPastedLayers { layers } => {
580677 if let Some ( document) = self . active_document_mut ( ) {
581678 let viewport_bounds_quad_pixels = Quad :: from_box ( [ DVec2 :: ZERO , ipp. viewport_bounds . size ( ) ] ) ;
0 commit comments