@@ -302,9 +302,16 @@ impl ClosestSegment {
302
302
( midpoint, segment_ids)
303
303
}
304
304
305
- pub fn adjusted_insert_and_select ( & self , shape_editor : & mut ShapeState , responses : & mut VecDeque < Message > , extend_selection : bool ) {
306
- let ( id, _) = self . adjusted_insert ( responses) ;
307
- shape_editor. select_anchor_point_by_id ( self . layer , id, extend_selection)
305
+ pub fn adjusted_insert_and_select ( & self , shape_editor : & mut ShapeState , responses : & mut VecDeque < Message > , extend_selection : bool , point_mode : bool , is_segment_selected : bool ) {
306
+ let ( id, segments) = self . adjusted_insert ( responses) ;
307
+ if point_mode || is_segment_selected {
308
+ shape_editor. select_anchor_point_by_id ( self . layer , id, extend_selection) ;
309
+ }
310
+
311
+ if is_segment_selected {
312
+ let Some ( state) = shape_editor. selected_shape_state . get_mut ( & self . layer ) else { return } ;
313
+ segments. iter ( ) . for_each ( |segment| state. select_segment ( * segment) ) ;
314
+ }
308
315
}
309
316
310
317
pub fn calculate_perp ( & self , document : & DocumentMessageHandler ) -> DVec2 {
@@ -551,7 +558,7 @@ impl ShapeState {
551
558
select_threshold : f64 ,
552
559
extend_selection : bool ,
553
560
path_overlay_mode : PathOverlayMode ,
554
- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
561
+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
555
562
) -> Option < Option < SelectedPointsInfo > > {
556
563
if self . selected_shape_state . is_empty ( ) {
557
564
return None ;
@@ -600,18 +607,18 @@ impl ShapeState {
600
607
mouse_position : DVec2 ,
601
608
select_threshold : f64 ,
602
609
path_overlay_mode : PathOverlayMode ,
603
- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
610
+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
604
611
point_editing_mode : bool ,
605
612
) -> Option < ( bool , Option < SelectedPointsInfo > ) > {
606
613
if self . selected_shape_state . is_empty ( ) {
607
614
return None ;
608
615
}
609
616
610
- if !point_editing_mode {
611
- return None ;
612
- }
613
-
614
617
if let Some ( ( layer, manipulator_point_id) ) = self . find_nearest_point_indices ( network_interface, mouse_position, select_threshold) {
618
+ // If not point editing mode then only handles are allowed to be dragged
619
+ if !point_editing_mode && matches ! ( manipulator_point_id, ManipulatorPointId :: Anchor ( _) ) {
620
+ return None ;
621
+ }
615
622
let vector_data = network_interface. compute_modified_vector ( layer) ?;
616
623
let point_position = manipulator_point_id. get_position ( & vector_data) ?;
617
624
@@ -1483,6 +1490,23 @@ impl ShapeState {
1483
1490
}
1484
1491
}
1485
1492
1493
+ pub fn delete_hanging_selected_anchors ( & mut self , document : & DocumentMessageHandler , responses : & mut VecDeque < Message > ) {
1494
+ for ( & layer, state) in & self . selected_shape_state {
1495
+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
1496
+ continue ;
1497
+ } ;
1498
+
1499
+ for point in & state. selected_points {
1500
+ if let ManipulatorPointId :: Anchor ( anchor) = point {
1501
+ if vector_data. all_connected ( * anchor) . all ( |segment| state. is_segment_selected ( segment. segment ) ) {
1502
+ let modification_type = VectorModificationType :: RemovePoint { id : * anchor } ;
1503
+ responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
1504
+ }
1505
+ }
1506
+ }
1507
+ }
1508
+ }
1509
+
1486
1510
pub fn break_path_at_selected_point ( & self , document : & DocumentMessageHandler , responses : & mut VecDeque < Message > ) {
1487
1511
for ( & layer, state) in & self . selected_shape_state {
1488
1512
let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else { continue } ;
@@ -1600,7 +1624,7 @@ impl ShapeState {
1600
1624
mouse_position : DVec2 ,
1601
1625
select_threshold : f64 ,
1602
1626
path_overlay_mode : PathOverlayMode ,
1603
- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
1627
+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
1604
1628
) -> Option < ( LayerNodeIdentifier , ManipulatorPointId ) > {
1605
1629
if self . selected_shape_state . is_empty ( ) {
1606
1630
return None ;
@@ -1968,20 +1992,91 @@ impl ShapeState {
1968
1992
selection_shape : SelectionShape ,
1969
1993
selection_change : SelectionChange ,
1970
1994
path_overlay_mode : PathOverlayMode ,
1971
- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
1995
+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
1972
1996
select_segments : bool ,
1997
+ select_points : bool ,
1973
1998
// Here, "selection mode" represents touched or enclosed, not to be confused with editing modes
1974
1999
selection_mode : SelectionMode ,
1975
2000
) {
2001
+ let ( points_inside, segments_inside) = self . get_inside_points_and_segments (
2002
+ network_interface,
2003
+ selection_shape,
2004
+ path_overlay_mode,
2005
+ frontier_handles_info,
2006
+ select_segments,
2007
+ select_points,
2008
+ selection_mode,
2009
+ ) ;
2010
+
2011
+ if selection_change == SelectionChange :: Clear {
2012
+ self . deselect_all_points ( ) ;
2013
+ self . deselect_all_segments ( ) ;
2014
+ }
2015
+
2016
+ for ( layer, points) in points_inside {
2017
+ let Some ( state) = self . selected_shape_state . get_mut ( & layer) else { continue } ;
2018
+ let Some ( vector_data) = network_interface. compute_modified_vector ( layer) else { continue } ;
2019
+
2020
+ for point in points {
2021
+ match ( point, selection_change) {
2022
+ ( _, SelectionChange :: Shrink ) => state. deselect_point ( point) ,
2023
+ ( ManipulatorPointId :: EndHandle ( _) | ManipulatorPointId :: PrimaryHandle ( _) , _) => {
2024
+ let handle = point. as_handle ( ) . expect ( "Handle cannot be converted" ) ;
2025
+ if handle. length ( & vector_data) > 0. {
2026
+ state. select_point ( point) ;
2027
+ }
2028
+ }
2029
+ ( _, _) => state. select_point ( point) ,
2030
+ }
2031
+ }
2032
+ }
2033
+
2034
+ for ( layer, segments) in segments_inside {
2035
+ let Some ( state) = self . selected_shape_state . get_mut ( & layer) else { continue } ;
2036
+ match selection_change {
2037
+ SelectionChange :: Shrink => segments. iter ( ) . for_each ( |segment| state. deselect_segment ( * segment) ) ,
2038
+ _ => segments. iter ( ) . for_each ( |segment| state. select_segment ( * segment) ) ,
2039
+ }
2040
+
2041
+ // Also select/deselect the endpoints of respective segments
2042
+ let Some ( vector_data) = network_interface. compute_modified_vector ( layer) else { continue } ;
2043
+ if !select_points && select_segments {
2044
+ vector_data
2045
+ . segment_bezier_iter ( )
2046
+ . filter ( |( segment, _, _, _) | segments. contains ( segment) )
2047
+ . for_each ( |( _, _, start, end) | match selection_change {
2048
+ SelectionChange :: Shrink => {
2049
+ state. deselect_point ( ManipulatorPointId :: Anchor ( start) ) ;
2050
+ state. deselect_point ( ManipulatorPointId :: Anchor ( end) ) ;
2051
+ }
2052
+ _ => {
2053
+ state. select_point ( ManipulatorPointId :: Anchor ( start) ) ;
2054
+ state. select_point ( ManipulatorPointId :: Anchor ( end) ) ;
2055
+ }
2056
+ } ) ;
2057
+ }
2058
+ }
2059
+ }
2060
+
2061
+ #[ allow( clippy:: too_many_arguments) ]
2062
+ pub fn get_inside_points_and_segments (
2063
+ & mut self ,
2064
+ network_interface : & NodeNetworkInterface ,
2065
+ selection_shape : SelectionShape ,
2066
+ path_overlay_mode : PathOverlayMode ,
2067
+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
2068
+ select_segments : bool ,
2069
+ select_points : bool ,
2070
+ // Represents if the box/lasso selection touches or encloses the targets (not to be confused with editing modes).
2071
+ selection_mode : SelectionMode ,
2072
+ ) -> ( HashMap < LayerNodeIdentifier , HashSet < ManipulatorPointId > > , HashMap < LayerNodeIdentifier , HashSet < SegmentId > > ) {
1976
2073
let selected_points = self . selected_points ( ) . cloned ( ) . collect :: < HashSet < _ > > ( ) ;
1977
2074
let selected_segments = selected_segments ( network_interface, self ) ;
1978
2075
1979
- for ( & layer, state) in & mut self . selected_shape_state {
1980
- if selection_change == SelectionChange :: Clear {
1981
- state. clear_points ( ) ;
1982
- state. clear_segments ( ) ;
1983
- }
2076
+ let mut points_inside: HashMap < LayerNodeIdentifier , HashSet < ManipulatorPointId > > = HashMap :: new ( ) ;
2077
+ let mut segments_inside: HashMap < LayerNodeIdentifier , HashSet < SegmentId > > = HashMap :: new ( ) ;
1984
2078
2079
+ for & layer in self . selected_shape_state . keys ( ) {
1985
2080
let vector_data = network_interface. compute_modified_vector ( layer) ;
1986
2081
let Some ( vector_data) = vector_data else { continue } ;
1987
2082
let transform = network_interface. document_metadata ( ) . transform_to_viewport_if_feeds ( layer, network_interface) ;
@@ -1997,7 +2092,7 @@ impl ShapeState {
1997
2092
1998
2093
let polygon_subpath = if let SelectionShape :: Lasso ( polygon) = selection_shape {
1999
2094
if polygon. len ( ) < 2 {
2000
- return ;
2095
+ return ( points_inside , segments_inside ) ;
2001
2096
}
2002
2097
let polygon: Subpath < PointId > = Subpath :: from_anchors_linear ( polygon. to_vec ( ) , true ) ;
2003
2098
Some ( polygon)
@@ -2037,10 +2132,7 @@ impl ShapeState {
2037
2132
} ;
2038
2133
2039
2134
if select {
2040
- match selection_change {
2041
- SelectionChange :: Shrink => state. deselect_segment ( id) ,
2042
- _ => state. select_segment ( id) ,
2043
- }
2135
+ segments_inside. entry ( layer) . or_default ( ) . insert ( id) ;
2044
2136
}
2045
2137
}
2046
2138
@@ -2057,21 +2149,11 @@ impl ShapeState {
2057
2149
. contains_point ( transformed_position) ,
2058
2150
} ;
2059
2151
2060
- if select {
2061
- let is_visible_handle = is_visible_point ( id, & vector_data, path_overlay_mode, frontier_handles_info. clone ( ) , selected_segments. clone ( ) , & selected_points) ;
2152
+ if select && select_points {
2153
+ let is_visible_handle = is_visible_point ( id, & vector_data, path_overlay_mode, frontier_handles_info, selected_segments. clone ( ) , & selected_points) ;
2062
2154
2063
2155
if is_visible_handle {
2064
- match selection_change {
2065
- SelectionChange :: Shrink => state. deselect_point ( id) ,
2066
- _ => {
2067
- // Select only the handles which are of nonzero length
2068
- if let Some ( handle) = id. as_handle ( ) {
2069
- if handle. length ( & vector_data) > 0. {
2070
- state. select_point ( id)
2071
- }
2072
- }
2073
- }
2074
- }
2156
+ points_inside. entry ( layer) . or_default ( ) . insert ( id) ;
2075
2157
}
2076
2158
}
2077
2159
}
@@ -2089,13 +2171,12 @@ impl ShapeState {
2089
2171
. contains_point ( transformed_position) ,
2090
2172
} ;
2091
2173
2092
- if select {
2093
- match selection_change {
2094
- SelectionChange :: Shrink => state. deselect_point ( ManipulatorPointId :: Anchor ( id) ) ,
2095
- _ => state. select_point ( ManipulatorPointId :: Anchor ( id) ) ,
2096
- }
2174
+ if select && select_points {
2175
+ points_inside. entry ( layer) . or_default ( ) . insert ( ManipulatorPointId :: Anchor ( id) ) ;
2097
2176
}
2098
2177
}
2099
2178
}
2179
+
2180
+ ( points_inside, segments_inside)
2100
2181
}
2101
2182
}
0 commit comments