@@ -520,10 +520,12 @@ impl Fsm for SelectToolFsmState {
520
520
. find ( |layer| !document. network_interface . is_artboard ( & layer. to_node ( ) , & [ ] ) )
521
521
. map ( |layer| document. metadata ( ) . transform_to_viewport ( layer) ) ;
522
522
523
- // Check if the matrix is not invertible
524
523
let mut transform = transform. unwrap_or ( DAffine2 :: IDENTITY ) ;
524
+ let mut transform_tampered = false ;
525
+ // Check if the matrix is not invertible
525
526
if transform. matrix2 . determinant ( ) == 0. {
526
527
transform. matrix2 += DMat2 :: IDENTITY * 1e-4 ; // TODO: Is this the cleanest way to handle this?
528
+ transform_tampered = true ;
527
529
}
528
530
529
531
let bounds = document
@@ -543,6 +545,7 @@ impl Fsm for SelectToolFsmState {
543
545
544
546
bounding_box_manager. bounds = bounds;
545
547
bounding_box_manager. transform = transform;
548
+ bounding_box_manager. transform_tampered = transform_tampered;
546
549
547
550
bounding_box_manager. render_overlays ( & mut overlay_context) ;
548
551
} else {
@@ -609,7 +612,7 @@ impl Fsm for SelectToolFsmState {
609
612
let e0 = tool_data
610
613
. bounding_box_manager
611
614
. as_ref ( )
612
- . map ( |man| man . transform * Quad :: from_box ( man . bounds ) )
615
+ . map ( |bounding_box_manager| bounding_box_manager . transform * Quad :: from_box ( bounding_box_manager . bounds ) )
613
616
. map_or ( DVec2 :: X , |quad| ( quad. top_left ( ) - quad. top_right ( ) ) . normalize_or ( DVec2 :: X ) ) ;
614
617
615
618
let ( direction, color) = match axis {
@@ -781,7 +784,10 @@ impl Fsm for SelectToolFsmState {
781
784
// If the user clicks on a layer that is in their current selection, go into the dragging mode.
782
785
// If the user clicks on new shape, make that layer their new selection.
783
786
// Otherwise enter the box select mode
784
- let bounds = tool_data. bounding_box_manager . as_ref ( ) . map ( |man| man. transform * Quad :: from_box ( man. bounds ) ) ;
787
+ let bounds = tool_data
788
+ . bounding_box_manager
789
+ . as_ref ( )
790
+ . map ( |bounding_box_manager| bounding_box_manager. transform * Quad :: from_box ( bounding_box_manager. bounds ) ) ;
785
791
786
792
let angle = bounds. map_or ( 0. , |quad| ( quad. top_left ( ) - quad. top_right ( ) ) . to_angle ( ) ) ;
787
793
let mouse_position = input. mouse . position ;
@@ -790,14 +796,11 @@ impl Fsm for SelectToolFsmState {
790
796
791
797
let show_compass = bounds. is_some_and ( |quad| quad. all_sides_at_least_width ( COMPASS_ROSE_HOVER_RING_DIAMETER ) && quad. contains ( mouse_position) ) ;
792
798
let can_grab_compass_rose = compass_rose_state. can_grab ( ) && show_compass;
793
- let is_flat_layer = document
794
- . network_interface
795
- . selected_nodes ( & [ ] )
796
- . unwrap ( )
797
- . selected_visible_and_unlocked_layers ( & document. network_interface )
798
- . find ( |layer| !document. network_interface . is_artboard ( & layer. to_node ( ) , & [ ] ) )
799
- . map ( |layer| document. metadata ( ) . transform_to_viewport ( layer) )
800
- . is_none_or ( |transform| transform. matrix2 . determinant ( ) . abs ( ) <= f64:: EPSILON ) ;
799
+ let is_flat_layer = tool_data
800
+ . bounding_box_manager
801
+ . as_ref ( )
802
+ . map ( |bounding_box_manager| bounding_box_manager. transform_tampered )
803
+ . unwrap_or ( true ) ;
801
804
802
805
let state =
803
806
// Dragging the pivot
@@ -809,30 +812,15 @@ impl Fsm for SelectToolFsmState {
809
812
810
813
SelectToolFsmState :: DraggingPivot
811
814
}
812
- // Dragging the selected layers around to transform them
813
- else if can_grab_compass_rose || intersection . is_some_and ( |intersection| selected . iter ( ) . any ( |selected_layer| intersection . starts_with ( * selected_layer , document . metadata ( ) ) ) ) {
815
+ // Dragging one (or two, forming a corner) of the transform cage bounding box edges
816
+ else if dragging_bounds . is_some ( ) && !is_flat_layer {
814
817
responses. add ( DocumentMessage :: StartTransaction ) ;
815
818
816
- if input. keyboard . key ( select_deepest) || tool_data. nested_selection_behavior == NestedSelectionBehavior :: Deepest {
817
- tool_data. select_single_layer = intersection;
818
- } else {
819
- tool_data. select_single_layer = intersection. and_then ( |intersection| intersection. ancestors ( document. metadata ( ) ) . find ( |ancestor| selected. contains ( ancestor) ) ) ;
820
- }
821
-
822
819
tool_data. layers_dragging = selected;
823
820
824
- tool_data. get_snap_candidates ( document, input) ;
825
- let ( axis, using_compass) = {
826
- let axis_state = compass_rose_state. axis_type ( ) . filter ( |_| can_grab_compass_rose) ;
827
- ( axis_state. unwrap_or_default ( ) , axis_state. is_some ( ) )
828
- } ;
829
- SelectToolFsmState :: Dragging { axis, using_compass }
830
- }
831
- // Dragging near the transform cage bounding box to rotate it
832
- else if rotating_bounds {
833
- responses. add ( DocumentMessage :: StartTransaction ) ;
834
-
835
821
if let Some ( bounds) = & mut tool_data. bounding_box_manager {
822
+ bounds. original_bound_transform = bounds. transform ;
823
+
836
824
tool_data. layers_dragging . retain ( |layer| {
837
825
if * layer != LayerNodeIdentifier :: ROOT_PARENT {
838
826
document. network_interface . network ( & [ ] ) . unwrap ( ) . nodes . contains_key ( & layer. to_node ( ) )
@@ -841,33 +829,51 @@ impl Fsm for SelectToolFsmState {
841
829
false
842
830
}
843
831
} ) ;
832
+
844
833
let mut selected = Selected :: new (
845
834
& mut bounds. original_transforms ,
846
835
& mut bounds. center_of_transformation ,
847
- & selected ,
836
+ & tool_data . layers_dragging ,
848
837
responses,
849
838
& document. network_interface ,
850
839
None ,
851
840
& ToolType :: Select ,
852
841
None
853
842
) ;
854
-
855
843
bounds. center_of_transformation = selected. mean_average_of_pivots ( ) ;
856
844
}
845
+ tool_data. get_snap_candidates ( document, input) ;
857
846
858
- tool_data. layers_dragging = selected;
859
-
860
- SelectToolFsmState :: RotatingBounds
847
+ if input. keyboard . key ( skew) {
848
+ SelectToolFsmState :: SkewingBounds
849
+ } else {
850
+ SelectToolFsmState :: ResizingBounds
851
+ }
861
852
}
862
- // Dragging one (or two, forming a corner) of the transform cage bounding box edges
863
- else if dragging_bounds . is_some ( ) && !is_flat_layer {
853
+ // Dragging the selected layers around to transform them
854
+ else if can_grab_compass_rose || intersection . is_some_and ( |intersection| selected . iter ( ) . any ( |selected_layer| intersection . starts_with ( * selected_layer , document . metadata ( ) ) ) ) {
864
855
responses. add ( DocumentMessage :: StartTransaction ) ;
865
856
857
+ if input. keyboard . key ( select_deepest) || tool_data. nested_selection_behavior == NestedSelectionBehavior :: Deepest {
858
+ tool_data. select_single_layer = intersection;
859
+ } else {
860
+ tool_data. select_single_layer = intersection. and_then ( |intersection| intersection. ancestors ( document. metadata ( ) ) . find ( |ancestor| selected. contains ( ancestor) ) ) ;
861
+ }
862
+
866
863
tool_data. layers_dragging = selected;
867
864
868
- if let Some ( bounds) = & mut tool_data. bounding_box_manager {
869
- bounds. original_bound_transform = bounds. transform ;
865
+ tool_data. get_snap_candidates ( document, input) ;
866
+ let ( axis, using_compass) = {
867
+ let axis_state = compass_rose_state. axis_type ( ) . filter ( |_| can_grab_compass_rose) ;
868
+ ( axis_state. unwrap_or_default ( ) , axis_state. is_some ( ) )
869
+ } ;
870
+ SelectToolFsmState :: Dragging { axis, using_compass }
871
+ }
872
+ // Dragging near the transform cage bounding box to rotate it
873
+ else if rotating_bounds {
874
+ responses. add ( DocumentMessage :: StartTransaction ) ;
870
875
876
+ if let Some ( bounds) = & mut tool_data. bounding_box_manager {
871
877
tool_data. layers_dragging . retain ( |layer| {
872
878
if * layer != LayerNodeIdentifier :: ROOT_PARENT {
873
879
document. network_interface . network ( & [ ] ) . unwrap ( ) . nodes . contains_key ( & layer. to_node ( ) )
@@ -876,26 +882,23 @@ impl Fsm for SelectToolFsmState {
876
882
false
877
883
}
878
884
} ) ;
879
-
880
885
let mut selected = Selected :: new (
881
886
& mut bounds. original_transforms ,
882
887
& mut bounds. center_of_transformation ,
883
- & tool_data . layers_dragging ,
888
+ & selected ,
884
889
responses,
885
890
& document. network_interface ,
886
891
None ,
887
892
& ToolType :: Select ,
888
893
None
889
894
) ;
895
+
890
896
bounds. center_of_transformation = selected. mean_average_of_pivots ( ) ;
891
897
}
892
- tool_data. get_snap_candidates ( document, input) ;
893
898
894
- if input. keyboard . key ( skew) {
895
- SelectToolFsmState :: SkewingBounds
896
- } else {
897
- SelectToolFsmState :: ResizingBounds
898
- }
899
+ tool_data. layers_dragging = selected;
900
+
901
+ SelectToolFsmState :: RotatingBounds
899
902
}
900
903
// Dragging a selection box
901
904
else {
@@ -953,7 +956,7 @@ impl Fsm for SelectToolFsmState {
953
956
let e0 = tool_data
954
957
. bounding_box_manager
955
958
. as_ref ( )
956
- . map ( |man| man . transform * Quad :: from_box ( man . bounds ) )
959
+ . map ( |bounding_box_manager| bounding_box_manager . transform * Quad :: from_box ( bounding_box_manager . bounds ) )
957
960
. map_or ( DVec2 :: X , |quad| ( quad. top_left ( ) - quad. top_right ( ) ) . normalize_or ( DVec2 :: X ) ) ;
958
961
let mouse_delta = match axis {
959
962
Axis :: X => mouse_delta. project_onto ( e0) ,
0 commit comments