@@ -44,46 +44,67 @@ pub enum ManipulatorAngle {
4444#[ derive( Clone , Debug , Default ) ]
4545pub struct SelectedLayerState {
4646 selected_points : HashSet < ManipulatorPointId > ,
47+ /// Keeps track of the current state; helps avoid unnecessary computation when called by [`ShapeState`].
4748 ignore_handles : bool ,
4849 ignore_anchors : bool ,
50+ /// Points that are selected but ignored (when their overlays are disabled) are stored here.
51+ ignored_handle_points : HashSet < ManipulatorPointId > ,
52+ ignored_anchor_points : HashSet < ManipulatorPointId > ,
4953}
5054
5155impl SelectedLayerState {
5256 pub fn selected ( & self ) -> impl Iterator < Item = ManipulatorPointId > + ' _ {
5357 self . selected_points . iter ( ) . copied ( )
5458 }
59+
5560 pub fn is_selected ( & self , point : ManipulatorPointId ) -> bool {
5661 self . selected_points . contains ( & point)
5762 }
63+
5864 pub fn select_point ( & mut self , point : ManipulatorPointId ) {
59- if ( point. as_handle ( ) . is_some ( ) && self . ignore_handles ) || ( point. as_anchor ( ) . is_some ( ) && self . ignore_anchors ) {
60- return ;
61- }
6265 self . selected_points . insert ( point) ;
6366 }
67+
6468 pub fn deselect_point ( & mut self , point : ManipulatorPointId ) {
65- if ( point. as_handle ( ) . is_some ( ) && self . ignore_handles ) || ( point. as_anchor ( ) . is_some ( ) && self . ignore_anchors ) {
66- return ;
67- }
6869 self . selected_points . remove ( & point) ;
6970 }
70- pub fn set_handles_status ( & mut self , ignore : bool ) {
71- self . ignore_handles = ignore;
72- }
73- pub fn set_anchors_status ( & mut self , ignore : bool ) {
74- self . ignore_anchors = ignore;
75- }
76- pub fn clear_points_force ( & mut self ) {
77- self . selected_points . clear ( ) ;
78- self . ignore_handles = false ;
79- self . ignore_anchors = false ;
71+
72+ pub fn ignore_handles ( & mut self , status : bool ) {
73+ if self . ignore_handles == !status {
74+ return ;
75+ }
76+
77+ self . ignore_handles = !status;
78+
79+ if self . ignore_handles {
80+ self . ignored_handle_points . extend ( self . selected_points . iter ( ) . copied ( ) . filter ( |point| point. as_handle ( ) . is_some ( ) ) ) ;
81+ self . selected_points . retain ( |point| !self . ignored_handle_points . contains ( point) ) ;
82+ } else {
83+ self . selected_points . extend ( self . ignored_handle_points . iter ( ) . copied ( ) ) ;
84+ self . ignored_handle_points . clear ( ) ;
85+ }
8086 }
81- pub fn clear_points ( & mut self ) {
82- if self . ignore_handles || self . ignore_anchors {
87+
88+ pub fn ignore_anchors ( & mut self , status : bool ) {
89+ if self . ignore_anchors == !status {
8390 return ;
8491 }
92+
93+ self . ignore_anchors = !status;
94+
95+ if self . ignore_anchors {
96+ self . ignored_anchor_points . extend ( self . selected_points . iter ( ) . copied ( ) . filter ( |point| point. as_anchor ( ) . is_some ( ) ) ) ;
97+ self . selected_points . retain ( |point| !self . ignored_anchor_points . contains ( point) ) ;
98+ } else {
99+ self . selected_points . extend ( self . ignored_anchor_points . iter ( ) . copied ( ) ) ;
100+ self . ignored_anchor_points . clear ( ) ;
101+ }
102+ }
103+
104+ pub fn clear_points ( & mut self ) {
85105 self . selected_points . clear ( ) ;
86106 }
107+
87108 pub fn selected_points_count ( & self ) -> usize {
88109 self . selected_points . len ( )
89110 }
@@ -93,8 +114,10 @@ pub type SelectedShapeState = HashMap<LayerNodeIdentifier, SelectedLayerState>;
93114
94115#[ derive( Debug , Default ) ]
95116pub struct ShapeState {
96- // The layers we can select and edit manipulators (anchors and handles) from
117+ /// The layers we can select and edit manipulators (anchors and handles) from.
97118 pub selected_shape_state : SelectedShapeState ,
119+ ignore_handles : bool ,
120+ ignore_anchors : bool ,
98121}
99122
100123#[ derive( Debug ) ]
@@ -255,6 +278,10 @@ impl ClosestSegment {
255278
256279// TODO Consider keeping a list of selected manipulators to minimize traversals of the layers
257280impl ShapeState {
281+ pub fn is_point_ignored ( & self , point : & ManipulatorPointId ) -> bool {
282+ ( point. as_handle ( ) . is_some ( ) && self . ignore_handles ) || ( point. as_anchor ( ) . is_some ( ) && self . ignore_anchors )
283+ }
284+
258285 pub fn close_selected_path ( & self , document : & DocumentMessageHandler , responses : & mut VecDeque < Message > ) {
259286 // First collect all selected anchor points across all layers
260287 let all_selected_points: Vec < ( LayerNodeIdentifier , PointId ) > = self
@@ -507,8 +534,9 @@ impl ShapeState {
507534 } else {
508535 // Select all connected points
509536 while let Some ( point) = selected_stack. pop ( ) {
510- if !state. is_selected ( ManipulatorPointId :: Anchor ( point) ) {
511- state. select_point ( ManipulatorPointId :: Anchor ( point) ) ;
537+ let anchor_point = ManipulatorPointId :: Anchor ( point) ;
538+ if !state. is_selected ( anchor_point) {
539+ state. select_point ( anchor_point) ;
512540 selected_stack. extend ( vector_data. connected_points ( point) ) ;
513541 }
514542 }
@@ -548,27 +576,17 @@ impl ShapeState {
548576 }
549577 }
550578
551- pub fn mark_selected_anchors ( & mut self ) {
552- for state in self . selected_shape_state . values_mut ( ) {
553- state. set_anchors_status ( false ) ;
554- }
555- }
556-
557- pub fn mark_selected_handles ( & mut self ) {
558- for state in self . selected_shape_state . values_mut ( ) {
559- state. set_handles_status ( false ) ;
560- }
561- }
562-
563- pub fn ignore_selected_anchors ( & mut self ) {
579+ pub fn update_selected_anchors_status ( & mut self , status : bool ) {
564580 for state in self . selected_shape_state . values_mut ( ) {
565- state. set_anchors_status ( true ) ;
581+ self . ignore_anchors = !status;
582+ state. ignore_anchors ( status) ;
566583 }
567584 }
568585
569- pub fn ignore_selected_handles ( & mut self ) {
586+ pub fn update_selected_handles_status ( & mut self , status : bool ) {
570587 for state in self . selected_shape_state . values_mut ( ) {
571- state. set_handles_status ( true ) ;
588+ self . ignore_handles = !status;
589+ state. ignore_handles ( status) ;
572590 }
573591 }
574592
@@ -675,6 +693,10 @@ impl ShapeState {
675693 layer : LayerNodeIdentifier ,
676694 responses : & mut VecDeque < Message > ,
677695 ) -> Option < ( ) > {
696+ if self . is_point_ignored ( point) {
697+ return None ;
698+ }
699+
678700 let vector_data = network_interface. compute_modified_vector ( layer) ?;
679701 let transform = network_interface. document_metadata ( ) . transform_to_document ( layer) . inverse ( ) ;
680702 let position = transform. transform_point2 ( new_position) ;
@@ -924,6 +946,10 @@ impl ShapeState {
924946 let delta = delta_transform. inverse ( ) . transform_vector2 ( delta) ;
925947
926948 for & point in state. selected_points . iter ( ) {
949+ if self . is_point_ignored ( & point) {
950+ continue ;
951+ }
952+
927953 let handle = match point {
928954 ManipulatorPointId :: Anchor ( point) => {
929955 self . move_anchor ( point, & vector_data, delta, layer, Some ( state) , responses) ;
@@ -1596,7 +1622,7 @@ impl ShapeState {
15961622 pub fn select_all_in_shape ( & mut self , network_interface : & NodeNetworkInterface , selection_shape : SelectionShape , selection_change : SelectionChange ) {
15971623 for ( & layer, state) in & mut self . selected_shape_state {
15981624 if selection_change == SelectionChange :: Clear {
1599- state. clear_points_force ( )
1625+ state. clear_points ( )
16001626 }
16011627
16021628 let vector_data = network_interface. compute_modified_vector ( layer) ;
0 commit comments