@@ -727,33 +727,31 @@ impl Fsm for SelectToolFsmState {
727
727
// Get the updated selection box bounds
728
728
let quad = Quad :: from_box ( [ tool_data. drag_start , tool_data. drag_current ] ) ;
729
729
730
- let selection_mode = match tool_action_data. preferences . get_selection_mode ( ) {
730
+ let current_selection_mode = match tool_action_data. preferences . get_selection_mode ( ) {
731
731
SelectionMode :: Directional => tool_data. calculate_selection_mode_from_direction ( ) ,
732
- selection_mode => selection_mode,
732
+ SelectionMode :: Touched => SelectionMode :: Touched ,
733
+ SelectionMode :: Enclosed => SelectionMode :: Enclosed ,
733
734
} ;
734
735
735
736
// Draw outline visualizations on the layers to be selected
736
- let mut draw_layer_outline = |layer| overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) ) ;
737
- let intersection: Vec < LayerNodeIdentifier > = match selection_shape {
737
+ let intersected_layers = match selection_shape {
738
738
SelectionShapeType :: Box => document. intersect_quad_no_artboards ( quad, input) . collect ( ) ,
739
739
SelectionShapeType :: Lasso => tool_data. intersect_lasso_no_artboards ( document, input) ,
740
740
} ;
741
- if selection_mode == SelectionMode :: Enclosed {
742
- let is_inside = | layer : & LayerNodeIdentifier | match selection_shape {
741
+ let layers_to_outline = intersected_layers . into_iter ( ) . filter ( |layer| match current_selection_mode {
742
+ SelectionMode :: Enclosed => match selection_shape {
743
743
SelectionShapeType :: Box => document. is_layer_fully_inside ( layer, quad) ,
744
744
SelectionShapeType :: Lasso => tool_data. is_layer_inside_lasso_polygon ( layer, document, input) ,
745
- } ;
746
- for layer in intersection. into_iter ( ) . filter ( is_inside) {
747
- draw_layer_outline ( layer) ;
748
- }
749
- } else if tool_data. nested_selection_behavior == NestedSelectionBehavior :: Deepest {
750
- for layer in intersection. iter ( ) . filter ( |layer| !layer. has_children ( document. metadata ( ) ) ) {
751
- draw_layer_outline ( * layer) ;
752
- }
753
- } else {
754
- for layer in intersection {
755
- draw_layer_outline ( layer) ;
756
- }
745
+ } ,
746
+ SelectionMode :: Touched => match tool_data. nested_selection_behavior {
747
+ NestedSelectionBehavior :: Deepest => !layer. has_children ( document. metadata ( ) ) ,
748
+ NestedSelectionBehavior :: Shallowest => true ,
749
+ } ,
750
+ SelectionMode :: Directional => unreachable ! ( ) ,
751
+ } ) ;
752
+
753
+ for layer in layers_to_outline {
754
+ overlay_context. outline ( document. metadata ( ) . layer_outline ( layer) , document. metadata ( ) . transform_to_viewport ( layer) ) ;
757
755
}
758
756
759
757
// Update the selection box
@@ -766,7 +764,7 @@ impl Fsm for SelectToolFsmState {
766
764
767
765
let polygon = & tool_data. lasso_polygon ;
768
766
769
- match ( selection_shape, selection_mode ) {
767
+ match ( selection_shape, current_selection_mode ) {
770
768
( SelectionShapeType :: Box , SelectionMode :: Enclosed ) => overlay_context. dashed_quad ( quad, fill_color, Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ,
771
769
( SelectionShapeType :: Lasso , SelectionMode :: Enclosed ) => overlay_context. dashed_polygon ( polygon, fill_color, Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ,
772
770
( SelectionShapeType :: Box , _) => overlay_context. quad ( quad, fill_color) ,
@@ -1403,6 +1401,7 @@ impl Fsm for SelectToolFsmState {
1403
1401
let current_selected: HashSet < _ > = document. network_interface . selected_nodes ( ) . selected_layers ( document. metadata ( ) ) . collect ( ) ;
1404
1402
let negative_selection = input. keyboard . key ( remove_from_selection) ;
1405
1403
let selection_modified = new_selected != current_selected;
1404
+
1406
1405
// Negative selection when both Shift and Ctrl are pressed
1407
1406
if negative_selection {
1408
1407
let updated_selection = current_selected
@@ -1411,18 +1410,19 @@ impl Fsm for SelectToolFsmState {
1411
1410
. collect ( ) ;
1412
1411
tool_data. layers_dragging = updated_selection;
1413
1412
} else if selection_modified {
1414
- let filtered_selections = filter_nested_selection ( document. metadata ( ) , & new_selected) ;
1415
- let parent_selected: HashSet < _ > = new_selected
1416
- . into_iter ( )
1417
- . map ( |layer| {
1418
- // Find the parent node
1419
- layer. ancestors ( document. metadata ( ) ) . filter ( not_artboard ( document) ) . last ( ) . unwrap_or ( layer)
1420
- } )
1421
- . collect ( ) ;
1422
- if tool_data. nested_selection_behavior == NestedSelectionBehavior :: Deepest {
1423
- tool_data. layers_dragging . extend ( filtered_selections) ;
1424
- } else {
1425
- tool_data. layers_dragging . extend ( parent_selected. iter ( ) . copied ( ) ) ;
1413
+ match tool_data. nested_selection_behavior {
1414
+ NestedSelectionBehavior :: Deepest => {
1415
+ let filtered_selections = filter_nested_selection ( document. metadata ( ) , & new_selected) ;
1416
+ tool_data. layers_dragging . extend ( filtered_selections) ;
1417
+ }
1418
+ NestedSelectionBehavior :: Shallowest => {
1419
+ // Find each new_selected's parent node
1420
+ let parent_selected: HashSet < _ > = new_selected
1421
+ . into_iter ( )
1422
+ . map ( |layer| layer. ancestors ( document. metadata ( ) ) . filter ( not_artboard ( document) ) . last ( ) . unwrap_or ( layer) )
1423
+ . collect ( ) ;
1424
+ tool_data. layers_dragging . extend ( parent_selected. iter ( ) . copied ( ) ) ;
1425
+ }
1426
1426
}
1427
1427
}
1428
1428
@@ -1713,33 +1713,33 @@ pub fn extend_lasso(lasso_polygon: &mut Vec<DVec2>, point: DVec2) {
1713
1713
}
1714
1714
1715
1715
pub fn filter_nested_selection ( metadata : & DocumentMetadata , new_selected : & HashSet < LayerNodeIdentifier > ) -> HashSet < LayerNodeIdentifier > {
1716
- let mut filtered_selection = HashSet :: new ( ) ;
1717
-
1718
1716
// First collect childless layers
1717
+ let mut filtered_selection: HashSet < _ > = new_selected. iter ( ) . copied ( ) . filter ( |layer| !layer. has_children ( metadata) ) . collect ( ) ;
1718
+
1719
+ // Then process parents with all children selected
1719
1720
for & layer in new_selected {
1721
+ // Skip if the layer is not a parent
1720
1722
if !layer. has_children ( metadata) {
1721
- filtered_selection . insert ( layer ) ;
1723
+ continue ;
1722
1724
}
1723
- }
1724
1725
1725
- // Then process parents with all children selected
1726
- for & layer in new_selected {
1727
- if layer. has_children ( metadata) {
1728
- // if any ancestor is already present in the filtered selection don't put its child
1729
- if layer. ancestors ( metadata) . any ( |ancestor| filtered_selection. contains ( & ancestor) ) {
1730
- continue ;
1731
- }
1732
- let all_children_selected = layer. descendants ( metadata) . all ( |descendant| new_selected. contains ( & descendant) ) ;
1726
+ // If any ancestor is already present in the filtered selection, don't include its child
1727
+ if layer. ancestors ( metadata) . any ( |ancestor| filtered_selection. contains ( & ancestor) ) {
1728
+ continue ;
1729
+ }
1733
1730
1734
- if all_children_selected {
1735
- // Remove all descendants of the parent
1736
- layer. descendants ( metadata) . for_each ( |child| {
1737
- filtered_selection. remove ( & child) ;
1738
- } ) ;
1739
- // Add the parent
1740
- filtered_selection. insert ( layer) ;
1741
- }
1731
+ // Skip if any of the children are not selected
1732
+ if !layer. descendants ( metadata) . all ( |descendant| new_selected. contains ( & descendant) ) {
1733
+ continue ;
1742
1734
}
1735
+
1736
+ // Remove all descendants of the parent
1737
+ for child in layer. descendants ( metadata) {
1738
+ filtered_selection. remove ( & child) ;
1739
+ }
1740
+ // Add the parent
1741
+ filtered_selection. insert ( layer) ;
1743
1742
}
1743
+
1744
1744
filtered_selection
1745
1745
}
0 commit comments