@@ -302,9 +302,16 @@ impl ClosestSegment {
302302 ( midpoint, segment_ids)
303303 }
304304
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+ }
308315 }
309316
310317 pub fn calculate_perp ( & self , document : & DocumentMessageHandler ) -> DVec2 {
@@ -551,7 +558,7 @@ impl ShapeState {
551558 select_threshold : f64 ,
552559 extend_selection : bool ,
553560 path_overlay_mode : PathOverlayMode ,
554- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
561+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
555562 ) -> Option < Option < SelectedPointsInfo > > {
556563 if self . selected_shape_state . is_empty ( ) {
557564 return None ;
@@ -600,18 +607,18 @@ impl ShapeState {
600607 mouse_position : DVec2 ,
601608 select_threshold : f64 ,
602609 path_overlay_mode : PathOverlayMode ,
603- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
610+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
604611 point_editing_mode : bool ,
605612 ) -> Option < ( bool , Option < SelectedPointsInfo > ) > {
606613 if self . selected_shape_state . is_empty ( ) {
607614 return None ;
608615 }
609616
610- if !point_editing_mode {
611- return None ;
612- }
613-
614617 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+ }
615622 let vector_data = network_interface. compute_modified_vector ( layer) ?;
616623 let point_position = manipulator_point_id. get_position ( & vector_data) ?;
617624
@@ -1483,6 +1490,23 @@ impl ShapeState {
14831490 }
14841491 }
14851492
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+
14861510 pub fn break_path_at_selected_point ( & self , document : & DocumentMessageHandler , responses : & mut VecDeque < Message > ) {
14871511 for ( & layer, state) in & self . selected_shape_state {
14881512 let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else { continue } ;
@@ -1600,7 +1624,7 @@ impl ShapeState {
16001624 mouse_position : DVec2 ,
16011625 select_threshold : f64 ,
16021626 path_overlay_mode : PathOverlayMode ,
1603- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
1627+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
16041628 ) -> Option < ( LayerNodeIdentifier , ManipulatorPointId ) > {
16051629 if self . selected_shape_state . is_empty ( ) {
16061630 return None ;
@@ -1968,20 +1992,91 @@ impl ShapeState {
19681992 selection_shape : SelectionShape ,
19691993 selection_change : SelectionChange ,
19701994 path_overlay_mode : PathOverlayMode ,
1971- frontier_handles_info : Option < HashMap < SegmentId , Vec < PointId > > > ,
1995+ frontier_handles_info : & Option < HashMap < SegmentId , Vec < PointId > > > ,
19721996 select_segments : bool ,
1997+ select_points : bool ,
19731998 // Here, "selection mode" represents touched or enclosed, not to be confused with editing modes
19741999 selection_mode : SelectionMode ,
19752000 ) {
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 > > ) {
19762073 let selected_points = self . selected_points ( ) . cloned ( ) . collect :: < HashSet < _ > > ( ) ;
19772074 let selected_segments = selected_segments ( network_interface, self ) ;
19782075
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 ( ) ;
19842078
2079+ for & layer in self . selected_shape_state . keys ( ) {
19852080 let vector_data = network_interface. compute_modified_vector ( layer) ;
19862081 let Some ( vector_data) = vector_data else { continue } ;
19872082 let transform = network_interface. document_metadata ( ) . transform_to_viewport_if_feeds ( layer, network_interface) ;
@@ -1997,7 +2092,7 @@ impl ShapeState {
19972092
19982093 let polygon_subpath = if let SelectionShape :: Lasso ( polygon) = selection_shape {
19992094 if polygon. len ( ) < 2 {
2000- return ;
2095+ return ( points_inside , segments_inside ) ;
20012096 }
20022097 let polygon: Subpath < PointId > = Subpath :: from_anchors_linear ( polygon. to_vec ( ) , true ) ;
20032098 Some ( polygon)
@@ -2037,10 +2132,7 @@ impl ShapeState {
20372132 } ;
20382133
20392134 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) ;
20442136 }
20452137 }
20462138
@@ -2057,21 +2149,11 @@ impl ShapeState {
20572149 . contains_point ( transformed_position) ,
20582150 } ;
20592151
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) ;
20622154
20632155 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) ;
20752157 }
20762158 }
20772159 }
@@ -2089,13 +2171,12 @@ impl ShapeState {
20892171 . contains_point ( transformed_position) ,
20902172 } ;
20912173
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) ) ;
20972176 }
20982177 }
20992178 }
2179+
2180+ ( points_inside, segments_inside)
21002181 }
21012182}
0 commit comments