@@ -267,6 +267,7 @@ struct PenToolData {
267267 g1_continuous : bool ,
268268 toggle_colinear_debounce : bool ,
269269
270+ // The segment that the end point is on before it is bent
270271 segment_end_before_bent : Option < SegmentId > ,
271272
272273 angle : f64 ,
@@ -280,6 +281,7 @@ struct PenToolData {
280281 alt_press : bool ,
281282
282283 handle_mode : HandleMode ,
284+ // The point that is being dragged
283285 end_point : Option < PointId > ,
284286 end_point_segment : Option < SegmentId > ,
285287}
@@ -317,7 +319,7 @@ impl PenToolData {
317319 }
318320
319321 /// If the user places the anchor on top of the previous anchor, it becomes sharp and the outgoing handle may be dragged.
320- fn bend_from_previous_point ( & mut self , snap_data : SnapData , transform : DAffine2 , layer : LayerNodeIdentifier ) {
322+ fn bend_from_previous_point ( & mut self , snap_data : SnapData , transform : DAffine2 , layer : LayerNodeIdentifier , preferences : & PreferencesMessageHandler ) {
321323 self . g1_continuous = true ;
322324 let document = snap_data. document ;
323325 self . next_handle_start = self . next_point ;
@@ -333,15 +335,15 @@ impl PenToolData {
333335 self . handle_end = None ;
334336 self . segment_end_before_bent = last_segment. copied ( ) ;
335337 self . end_point_segment = last_segment. copied ( ) ;
338+ self . check_if_different_path ( document, snap_data. input , preferences) ;
339+ self . handle_mode = HandleMode :: Free ;
336340
337341 if let Some ( point) = self . latest_point_mut ( ) {
338342 point. in_segment = None ;
339343 }
340344
341345 if self . modifiers . lock_angle {
342346 self . set_lock_angle ( & vector_data, self . latest_point ( ) . unwrap ( ) . id , last_segment. copied ( ) ) ;
343- } else {
344- self . handle_mode = HandleMode :: Free ;
345347 }
346348 }
347349 }
@@ -391,6 +393,7 @@ impl PenToolData {
391393 let points = [ start, end] ;
392394 let id = SegmentId :: generate ( ) ;
393395 self . segment_end_before_bent = Some ( id) ;
396+ self . end_point_segment = Some ( id) ;
394397 let modification_type = VectorModificationType :: InsertSegment { id, points, handles } ;
395398 responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
396399
@@ -469,12 +472,12 @@ impl PenToolData {
469472 self . update_handle_position ( new_handle_position, anchor_point, responses, layer, is_start) ;
470473 return ;
471474 }
472- let Some ( segment) = self . segment_end_before_bent else { return } ;
473475
474476 if self . end_point_segment == self . segment_end_before_bent {
475477 let handle_offset = if let Some ( handle_end) = self . handle_end {
476478 ( handle_end - anchor_point) . length ( )
477479 } else {
480+ let Some ( segment) = self . segment_end_before_bent else { return } ;
478481 let end_handle = ManipulatorPointId :: EndHandle ( segment) ;
479482 let Some ( end_handle) = end_handle. get_position ( vector_data) else { return } ;
480483 ( end_handle - anchor_point) . length ( )
@@ -487,13 +490,7 @@ impl PenToolData {
487490 let Some ( end_handle) = end_handle. get_position ( vector_data) else { return } ;
488491 let handle_offset = ( end_handle - anchor_point) . length ( ) ;
489492 let new_handle_position = anchor_point + handle_offset * direction;
490- responses. add ( GraphOperationMessage :: Vector {
491- layer,
492- modification_type : VectorModificationType :: SetEndHandle {
493- segment,
494- relative_position : new_handle_position - anchor_point,
495- } ,
496- } ) ;
493+ self . update_handle_position ( new_handle_position, anchor_point, responses, layer, is_start) ;
497494 }
498495 }
499496
@@ -544,26 +541,25 @@ impl PenToolData {
544541 }
545542
546543 fn update_handle_position ( & mut self , new_position : DVec2 , anchor_pos : DVec2 , responses : & mut VecDeque < Message > , layer : LayerNodeIdentifier , is_start : bool ) {
547- if is_start {
544+ let relative_position = new_position - anchor_pos;
545+
546+ let modification_type = if is_start {
548547 let Some ( segment) = self . end_point_segment else { return } ;
549- let relative_position = new_position - anchor_pos;
550- let modification_type = VectorModificationType :: SetPrimaryHandle { segment, relative_position } ;
551- responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
548+ VectorModificationType :: SetPrimaryHandle { segment, relative_position }
552549 } else if self . end_point_segment == self . segment_end_before_bent {
553550 if let Some ( handle) = self . handle_end . as_mut ( ) {
554551 * handle = new_position;
552+ return ;
555553 } else {
556554 let Some ( segment) = self . segment_end_before_bent else { return } ;
557- let relative_position = new_position - anchor_pos;
558- let modification_type = VectorModificationType :: SetEndHandle { segment, relative_position } ;
559- responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
555+ VectorModificationType :: SetEndHandle { segment, relative_position }
560556 }
561557 } else {
562558 let Some ( segment) = self . end_point_segment else { return } ;
563- let relative_position = new_position - anchor_pos ;
564- let modification_type = VectorModificationType :: SetEndHandle { segment , relative_position } ;
565- responses . add ( GraphOperationMessage :: Vector { layer , modification_type } ) ;
566- }
559+ VectorModificationType :: SetEndHandle { segment , relative_position }
560+ } ;
561+
562+ responses . add ( GraphOperationMessage :: Vector { layer , modification_type } ) ;
567563 }
568564
569565 fn place_anchor ( & mut self , snap_data : SnapData , transform : DAffine2 , mouse : DVec2 , preferences : & PreferencesMessageHandler , responses : & mut VecDeque < Message > ) -> Option < PenToolFsmState > {
@@ -671,7 +667,7 @@ impl PenToolData {
671667 tool_options : & PenOptions ,
672668 append : bool ,
673669 preferences : & PreferencesMessageHandler ,
674- ) -> Option < ( PointId , LayerNodeIdentifier ) > {
670+ ) {
675671 let point = SnapCandidatePoint :: handle ( document. metadata ( ) . document_to_viewport . inverse ( ) . transform_point2 ( input. mouse . position ) ) ;
676672 let snapped = self . snap_manager . free_snap ( & SnapData :: new ( document, input) , & point, SnapTypeConfiguration :: default ( ) ) ;
677673 let viewport = document. metadata ( ) . document_to_viewport . transform_point2 ( snapped. snapped_point_document ) ;
@@ -698,11 +694,11 @@ impl PenToolData {
698694 self . set_lock_angle ( & vector_data, point, segment) ;
699695 }
700696
701- return Some ( ( point , layer ) ) ;
697+ return ;
702698 }
703699
704700 if append {
705- if let Some ( ( layer, point, position ) ) = closest_point ( & document, viewport, tolerance, document. metadata ( ) . all_layers ( ) , |_| false , & preferences) {
701+ if let Some ( ( layer, point, _ ) ) = closest_point ( & document, viewport, tolerance, document. metadata ( ) . all_layers ( ) , |_| false , & preferences) {
706702 let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
707703 let segment = vector_data. all_connected ( point) . collect :: < Vec < _ > > ( ) . first ( ) . map ( |s| s. segment ) ;
708704
@@ -715,11 +711,11 @@ impl PenToolData {
715711 if let Some ( layer) = existing_layer {
716712 // Add point to existing layer
717713 responses. add ( PenToolMessage :: AddPointLayerPosition { layer, viewport } ) ;
718- return None ;
714+ return ;
719715 }
720716 }
721717
722- if let Some ( ( layer, point, position ) ) = closest_point ( & document, viewport, tolerance, document. metadata ( ) . all_layers ( ) , |_| false , & preferences) {
718+ if let Some ( ( layer, point, _position ) ) = closest_point ( & document, viewport, tolerance, document. metadata ( ) . all_layers ( ) , |_| false , & preferences) {
723719 let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
724720 let segment = vector_data. all_connected ( point) . collect :: < Vec < _ > > ( ) . first ( ) . map ( |s| s. segment ) ;
725721
@@ -743,7 +739,21 @@ impl PenToolData {
743739 responses. add ( Message :: StartBuffer ) ;
744740 // It is necessary to defer this until the transform of the layer can be accurately computed (quite hacky)
745741 responses. add ( PenToolMessage :: AddPointLayerPosition { layer, viewport } ) ;
746- return None ;
742+ return ;
743+ }
744+
745+ fn check_if_different_path ( & mut self , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , preferences : & PreferencesMessageHandler ) {
746+ let point = SnapCandidatePoint :: handle ( document. metadata ( ) . document_to_viewport . inverse ( ) . transform_point2 ( input. mouse . position ) ) ;
747+ let snapped = self . snap_manager . free_snap ( & SnapData :: new ( document, input) , & point, SnapTypeConfiguration :: default ( ) ) ;
748+ let viewport = document. metadata ( ) . document_to_viewport . transform_point2 ( snapped. snapped_point_document ) ;
749+ let tolerance = crate :: consts:: SNAP_POINT_TOLERANCE ;
750+
751+ if let Some ( ( layer, point, _position) ) = closest_point ( & document, viewport, tolerance, document. metadata ( ) . all_layers ( ) , |_| false , & preferences) {
752+ self . end_point = Some ( point) ;
753+ let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
754+ let segment = vector_data. all_connected ( point) . collect :: < Vec < _ > > ( ) . first ( ) . map ( |s| s. segment ) ;
755+ self . end_point_segment = segment;
756+ }
747757 }
748758
749759 fn set_lock_angle ( & mut self , vector_data : & VectorData , anchor : PointId , segment : Option < SegmentId > ) {
@@ -1043,13 +1053,10 @@ impl Fsm for PenToolFsmState {
10431053 ( PenToolFsmState :: Ready , PenToolMessage :: DragStart { append_to_selected } ) => {
10441054 responses. add ( DocumentMessage :: StartTransaction ) ;
10451055 tool_data. handle_mode = HandleMode :: Free ;
1046- if let Some ( ( point, layer) ) = tool_data. create_initial_point ( document, input, responses, tool_options, input. keyboard . key ( append_to_selected) , preferences) {
1047- tool_data. end_point = Some ( point) ;
1048- let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
1049- let segment = vector_data. all_connected ( point) . collect :: < Vec < _ > > ( ) . first ( ) . map ( |s| s. segment ) ;
1050- tool_data. end_point_segment = segment;
1051- }
10521056
1057+ // Get the closest point and the segment it is on
1058+ tool_data. create_initial_point ( document, input, responses, tool_options, input. keyboard . key ( append_to_selected) , preferences) ;
1059+ tool_data. check_if_different_path ( document, input, preferences) ;
10531060 // Enter the dragging handle state while the mouse is held down, allowing the user to move the mouse and position the handle
10541061 PenToolFsmState :: DraggingHandle ( tool_data. handle_mode )
10551062 }
@@ -1071,7 +1078,7 @@ impl Fsm for PenToolFsmState {
10711078 if tool_data. buffering_merged_vector {
10721079 tool_data. buffering_merged_vector = false ;
10731080 tool_data. handle_mode = HandleMode :: ColinearLocked ;
1074- tool_data. bend_from_previous_point ( SnapData :: new ( document, input) , transform, layer. unwrap ( ) ) ;
1081+ tool_data. bend_from_previous_point ( SnapData :: new ( document, input) , transform, layer. unwrap ( ) , preferences ) ;
10751082 tool_data. place_anchor ( SnapData :: new ( document, input) , transform, input. mouse . position , preferences, responses) ;
10761083 tool_data. buffering_merged_vector = false ;
10771084 PenToolFsmState :: DraggingHandle ( tool_data. handle_mode )
0 commit comments