@@ -690,25 +690,9 @@ impl PenToolData {
690
690
self . handle_end = None ;
691
691
692
692
let tolerance = crate :: consts:: SNAP_POINT_TOLERANCE ;
693
- if let Some ( ( layer, point, position) ) = should_extend ( document, viewport, tolerance, selected_nodes. selected_layers ( document. metadata ( ) ) , preferences) {
694
- // Perform extension of an existing path
695
- let in_segment = if self . modifiers . lock_angle { self . end_point_segment } else { None } ;
696
- self . add_point ( LastPoint {
697
- id : point,
698
- pos : position,
699
- in_segment,
700
- handle_start : position,
701
- } ) ;
702
- responses. add ( NodeGraphMessage :: SelectedNodesSet { nodes : vec ! [ layer. to_node( ) ] } ) ;
703
- self . next_point = position;
704
- self . next_handle_start = position;
705
- let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
706
- let segment = vector_data. all_connected ( point) . collect :: < Vec < _ > > ( ) . first ( ) . map ( |s| s. segment ) ;
707
-
708
- if self . modifiers . lock_angle {
709
- self . set_lock_angle ( & vector_data, point, segment) ;
710
- }
711
-
693
+ let extension_choice = should_extend ( document, viewport, tolerance, selected_nodes. selected_layers ( document. metadata ( ) ) , preferences) ;
694
+ if let Some ( ( layer, point, position) ) = extension_choice {
695
+ self . extend_existing_path ( document, layer, point, position, responses) ;
712
696
return ;
713
697
}
714
698
@@ -759,6 +743,64 @@ impl PenToolData {
759
743
responses. add ( PenToolMessage :: AddPointLayerPosition { layer, viewport } ) ;
760
744
}
761
745
746
+ /// Perform extension of an existing path
747
+ fn extend_existing_path ( & mut self , document : & DocumentMessageHandler , layer : LayerNodeIdentifier , point : PointId , position : DVec2 , responses : & mut VecDeque < Message > ) {
748
+ let vector_data = document. network_interface . compute_modified_vector ( layer) ;
749
+ let ( handle_start, in_segment) = if let Some ( vector_data) = & vector_data {
750
+ vector_data
751
+ . segment_bezier_iter ( )
752
+ . find_map ( |( segment_id, bezier, start, end) | {
753
+ let is_end = point == end;
754
+ let is_start = point == start;
755
+ if !is_end && !is_start {
756
+ return None ;
757
+ }
758
+
759
+ let handle = match bezier. handles {
760
+ BezierHandles :: Cubic { handle_start, handle_end, .. } => {
761
+ if is_start {
762
+ handle_start
763
+ } else {
764
+ handle_end
765
+ }
766
+ }
767
+ BezierHandles :: Quadratic { handle } => handle,
768
+ _ => return None ,
769
+ } ;
770
+ Some ( ( segment_id, is_end, handle) )
771
+ } )
772
+ . map ( |( segment_id, is_end, handle) | {
773
+ let mirrored_handle = position * 2. - handle;
774
+ let in_segment = if is_end { Some ( segment_id) } else { None } ;
775
+ ( mirrored_handle, in_segment)
776
+ } )
777
+ . unwrap_or_else ( || ( position, None ) )
778
+ } else {
779
+ ( position, None )
780
+ } ;
781
+
782
+ let in_segment = if self . modifiers . lock_angle { self . end_point_segment } else { in_segment } ;
783
+
784
+ self . add_point ( LastPoint {
785
+ id : point,
786
+ pos : position,
787
+ in_segment,
788
+ handle_start,
789
+ } ) ;
790
+
791
+ responses. add ( NodeGraphMessage :: SelectedNodesSet { nodes : vec ! [ layer. to_node( ) ] } ) ;
792
+
793
+ self . next_point = position;
794
+ self . next_handle_start = handle_start;
795
+ let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
796
+ let segment = vector_data. all_connected ( point) . collect :: < Vec < _ > > ( ) . first ( ) . map ( |s| s. segment ) ;
797
+
798
+ if self . modifiers . lock_angle {
799
+ self . set_lock_angle ( & vector_data, point, segment) ;
800
+ }
801
+ self . handle_mode = HandleMode :: ColinearEquidistant ;
802
+ }
803
+
762
804
// Stores the segment and point ID of the clicked endpoint
763
805
fn store_clicked_endpoint ( & mut self , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , preferences : & PreferencesMessageHandler ) {
764
806
let point = SnapCandidatePoint :: handle ( document. metadata ( ) . document_to_viewport . inverse ( ) . transform_point2 ( input. mouse . position ) ) ;
0 commit comments