@@ -44,46 +44,67 @@ pub enum ManipulatorAngle {
44
44
#[ derive( Clone , Debug , Default ) ]
45
45
pub struct SelectedLayerState {
46
46
selected_points : HashSet < ManipulatorPointId > ,
47
+ /// Keeps track of the current state; helps avoid unnecessary computation when called by [`ShapeState`].
47
48
ignore_handles : bool ,
48
49
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 > ,
49
53
}
50
54
51
55
impl SelectedLayerState {
52
56
pub fn selected ( & self ) -> impl Iterator < Item = ManipulatorPointId > + ' _ {
53
57
self . selected_points . iter ( ) . copied ( )
54
58
}
59
+
55
60
pub fn is_selected ( & self , point : ManipulatorPointId ) -> bool {
56
61
self . selected_points . contains ( & point)
57
62
}
63
+
58
64
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
- }
62
65
self . selected_points . insert ( point) ;
63
66
}
67
+
64
68
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
- }
68
69
self . selected_points . remove ( & point) ;
69
70
}
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
+ }
80
86
}
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 {
83
90
return ;
84
91
}
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 ) {
85
105
self . selected_points . clear ( ) ;
86
106
}
107
+
87
108
pub fn selected_points_count ( & self ) -> usize {
88
109
self . selected_points . len ( )
89
110
}
@@ -93,8 +114,10 @@ pub type SelectedShapeState = HashMap<LayerNodeIdentifier, SelectedLayerState>;
93
114
94
115
#[ derive( Debug , Default ) ]
95
116
pub 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.
97
118
pub selected_shape_state : SelectedShapeState ,
119
+ ignore_handles : bool ,
120
+ ignore_anchors : bool ,
98
121
}
99
122
100
123
#[ derive( Debug ) ]
@@ -255,6 +278,10 @@ impl ClosestSegment {
255
278
256
279
// TODO Consider keeping a list of selected manipulators to minimize traversals of the layers
257
280
impl 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
+
258
285
pub fn close_selected_path ( & self , document : & DocumentMessageHandler , responses : & mut VecDeque < Message > ) {
259
286
// First collect all selected anchor points across all layers
260
287
let all_selected_points: Vec < ( LayerNodeIdentifier , PointId ) > = self
@@ -507,8 +534,9 @@ impl ShapeState {
507
534
} else {
508
535
// Select all connected points
509
536
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) ;
512
540
selected_stack. extend ( vector_data. connected_points ( point) ) ;
513
541
}
514
542
}
@@ -548,27 +576,17 @@ impl ShapeState {
548
576
}
549
577
}
550
578
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 ) {
564
580
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) ;
566
583
}
567
584
}
568
585
569
- pub fn ignore_selected_handles ( & mut self ) {
586
+ pub fn update_selected_handles_status ( & mut self , status : bool ) {
570
587
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) ;
572
590
}
573
591
}
574
592
@@ -675,6 +693,10 @@ impl ShapeState {
675
693
layer : LayerNodeIdentifier ,
676
694
responses : & mut VecDeque < Message > ,
677
695
) -> Option < ( ) > {
696
+ if self . is_point_ignored ( point) {
697
+ return None ;
698
+ }
699
+
678
700
let vector_data = network_interface. compute_modified_vector ( layer) ?;
679
701
let transform = network_interface. document_metadata ( ) . transform_to_document ( layer) . inverse ( ) ;
680
702
let position = transform. transform_point2 ( new_position) ;
@@ -924,6 +946,10 @@ impl ShapeState {
924
946
let delta = delta_transform. inverse ( ) . transform_vector2 ( delta) ;
925
947
926
948
for & point in state. selected_points . iter ( ) {
949
+ if self . is_point_ignored ( & point) {
950
+ continue ;
951
+ }
952
+
927
953
let handle = match point {
928
954
ManipulatorPointId :: Anchor ( point) => {
929
955
self . move_anchor ( point, & vector_data, delta, layer, Some ( state) , responses) ;
@@ -1596,7 +1622,7 @@ impl ShapeState {
1596
1622
pub fn select_all_in_shape ( & mut self , network_interface : & NodeNetworkInterface , selection_shape : SelectionShape , selection_change : SelectionChange ) {
1597
1623
for ( & layer, state) in & mut self . selected_shape_state {
1598
1624
if selection_change == SelectionChange :: Clear {
1599
- state. clear_points_force ( )
1625
+ state. clear_points ( )
1600
1626
}
1601
1627
1602
1628
let vector_data = network_interface. compute_modified_vector ( layer) ;
0 commit comments