1
1
#![ allow( clippy:: too_many_arguments) ]
2
2
3
3
use super :: tool_prelude:: * ;
4
- use crate :: consts:: { COLOR_OVERLAY_BLUE , COLOR_OVERLAY_GREEN , COLOR_OVERLAY_RED , DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD , ROTATE_INCREMENT , SELECTION_DRAG_ANGLE , SELECTION_TOLERANCE } ;
4
+ use crate :: consts:: {
5
+ COLOR_OVERLAY_BLUE , COLOR_OVERLAY_GREEN , COLOR_OVERLAY_RED , COMPASS_ROSE_HOVER_RING_DIAMETER , DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD , ROTATE_INCREMENT , SELECTION_DRAG_ANGLE ,
6
+ SELECTION_TOLERANCE ,
7
+ } ;
5
8
use crate :: messages:: input_mapper:: utility_types:: input_mouse:: ViewportPosition ;
6
9
use crate :: messages:: portfolio:: document:: graph_operation:: utility_types:: TransformIn ;
7
10
use crate :: messages:: portfolio:: document:: overlays:: utility_types:: OverlayContext ;
@@ -577,11 +580,11 @@ impl Fsm for SelectToolFsmState {
577
580
578
581
let show_compass = !( can_get_into_other_states || is_resizing_or_rotating) ;
579
582
let show_compass_with_ring = bounds. map ( |bounds| transform * Quad :: from_box ( bounds) ) . and_then ( |quad| {
580
- show_compass
583
+ ( show_compass && quad . all_sides_at_least_width ( COMPASS_ROSE_HOVER_RING_DIAMETER ) )
581
584
. then_some (
582
585
matches ! ( self , SelectToolFsmState :: Dragging { .. } )
583
586
. then_some ( show_hover_ring)
584
- . or ( quad. contains ( mouse_position) . then_some ( show_hover_ring) ) ,
587
+ . or ( ( quad. contains ( mouse_position) ) . then_some ( show_hover_ring) ) ,
585
588
)
586
589
. flatten ( )
587
590
} ) ;
@@ -590,7 +593,7 @@ impl Fsm for SelectToolFsmState {
590
593
tool_data. pivot . update_pivot ( document, & mut overlay_context, angle) ;
591
594
592
595
// Update compass rose
593
- tool_data. compass_rose . refresh_transform ( document) ;
596
+ tool_data. compass_rose . refresh_position ( document) ;
594
597
let compass_center = tool_data. compass_rose . compass_rose_position ( ) ;
595
598
overlay_context. compass_rose ( compass_center, angle, show_compass_with_ring) ;
596
599
@@ -600,29 +603,31 @@ impl Fsm for SelectToolFsmState {
600
603
compass_rose_state. axis_type ( ) . and_then ( |axis| axis. is_constraint ( ) . then_some ( ( axis, true ) ) )
601
604
} ;
602
605
603
- if let Some ( ( axis, hover) ) = axis_state {
604
- if axis. is_constraint ( ) {
605
- let e0 = tool_data
606
- . bounding_box_manager
607
- . as_ref ( )
608
- . map ( |man| man. transform * Quad :: from_box ( man. bounds ) )
609
- . map_or ( DVec2 :: X , |quad| ( quad. top_left ( ) - quad. top_right ( ) ) . normalize_or ( DVec2 :: X ) ) ;
610
-
611
- let ( direction, color) = match axis {
612
- Axis :: X => ( e0, COLOR_OVERLAY_RED ) ,
613
- Axis :: Y => ( e0. perp ( ) , COLOR_OVERLAY_GREEN ) ,
614
- _ => unreachable ! ( ) ,
615
- } ;
616
-
617
- let viewport_diagonal = input. viewport_bounds . size ( ) . length ( ) ;
618
-
619
- let color = if !hover {
620
- color
621
- } else {
622
- let color_string = & graphene_std:: Color :: from_rgb_str ( color. strip_prefix ( '#' ) . unwrap ( ) ) . unwrap ( ) . with_alpha ( 0.25 ) . rgba_hex ( ) ;
623
- & format ! ( "#{}" , color_string)
624
- } ;
625
- overlay_context. line ( compass_center - direction * viewport_diagonal, compass_center + direction * viewport_diagonal, Some ( color) ) ;
606
+ if show_compass_with_ring. is_some ( ) {
607
+ if let Some ( ( axis, hover) ) = axis_state {
608
+ if axis. is_constraint ( ) {
609
+ let e0 = tool_data
610
+ . bounding_box_manager
611
+ . as_ref ( )
612
+ . map ( |man| man. transform * Quad :: from_box ( man. bounds ) )
613
+ . map_or ( DVec2 :: X , |quad| ( quad. top_left ( ) - quad. top_right ( ) ) . normalize_or ( DVec2 :: X ) ) ;
614
+
615
+ let ( direction, color) = match axis {
616
+ Axis :: X => ( e0, COLOR_OVERLAY_RED ) ,
617
+ Axis :: Y => ( e0. perp ( ) , COLOR_OVERLAY_GREEN ) ,
618
+ _ => unreachable ! ( ) ,
619
+ } ;
620
+
621
+ let viewport_diagonal = input. viewport_bounds . size ( ) . length ( ) ;
622
+
623
+ let color = if !hover {
624
+ color
625
+ } else {
626
+ let color_string = & graphene_std:: Color :: from_rgb_str ( color. strip_prefix ( '#' ) . unwrap ( ) ) . unwrap ( ) . with_alpha ( 0.25 ) . rgba_hex ( ) ;
627
+ & format ! ( "#{}" , color_string)
628
+ } ;
629
+ overlay_context. line ( compass_center - direction * viewport_diagonal, compass_center + direction * viewport_diagonal, Some ( color) ) ;
630
+ }
626
631
}
627
632
}
628
633
@@ -776,16 +781,24 @@ impl Fsm for SelectToolFsmState {
776
781
// If the user clicks on a layer that is in their current selection, go into the dragging mode.
777
782
// If the user clicks on new shape, make that layer their new selection.
778
783
// 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 ) ) ;
779
785
780
- let angle = tool_data
781
- . bounding_box_manager
782
- . as_ref ( )
783
- . map ( |man| man. transform * Quad :: from_box ( man. bounds ) )
784
- . map_or ( 0. , |quad| ( quad. top_left ( ) - quad. top_right ( ) ) . to_angle ( ) ) ;
786
+ let angle = bounds. map_or ( 0. , |quad| ( quad. top_left ( ) - quad. top_right ( ) ) . to_angle ( ) ) ;
785
787
let mouse_position = input. mouse . position ;
786
788
let compass_rose_state = tool_data. compass_rose . compass_rose_state ( mouse_position, angle) ;
787
789
let is_over_pivot = tool_data. pivot . is_over ( mouse_position) ;
788
790
791
+ let show_compass = bounds. is_some_and ( |quad| quad. all_sides_at_least_width ( COMPASS_ROSE_HOVER_RING_DIAMETER ) && quad. contains ( mouse_position) ) ;
792
+ 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 ) ;
801
+
789
802
let state =
790
803
// Dragging the pivot
791
804
if is_over_pivot {
@@ -796,15 +809,30 @@ impl Fsm for SelectToolFsmState {
796
809
797
810
SelectToolFsmState :: DraggingPivot
798
811
}
799
- // Dragging one (or two, forming a corner) of the transform cage bounding box edges
800
- else if dragging_bounds . is_some ( ) {
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 ( ) ) ) ) {
801
814
responses. add ( DocumentMessage :: StartTransaction ) ;
802
815
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
+
803
822
tool_data. layers_dragging = selected;
804
823
805
- if let Some ( bounds) = & mut tool_data. bounding_box_manager {
806
- bounds. original_bound_transform = bounds. transform ;
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 ) ;
807
834
835
+ if let Some ( bounds) = & mut tool_data. bounding_box_manager {
808
836
tool_data. layers_dragging . retain ( |layer| {
809
837
if * layer != LayerNodeIdentifier :: ROOT_PARENT {
810
838
document. network_interface . network ( & [ ] ) . unwrap ( ) . nodes . contains_key ( & layer. to_node ( ) )
@@ -813,32 +841,33 @@ impl Fsm for SelectToolFsmState {
813
841
false
814
842
}
815
843
} ) ;
816
-
817
844
let mut selected = Selected :: new (
818
845
& mut bounds. original_transforms ,
819
846
& mut bounds. center_of_transformation ,
820
- & tool_data . layers_dragging ,
847
+ & selected ,
821
848
responses,
822
849
& document. network_interface ,
823
850
None ,
824
851
& ToolType :: Select ,
825
852
None
826
853
) ;
854
+
827
855
bounds. center_of_transformation = selected. mean_average_of_pivots ( ) ;
828
856
}
829
- tool_data. get_snap_candidates ( document, input) ;
830
857
831
- if input. keyboard . key ( skew) {
832
- SelectToolFsmState :: SkewingBounds
833
- } else {
834
- SelectToolFsmState :: ResizingBounds
835
- }
858
+ tool_data. layers_dragging = selected;
859
+
860
+ SelectToolFsmState :: RotatingBounds
836
861
}
837
- // Dragging near the transform cage bounding box to rotate it
838
- else if rotating_bounds {
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 {
839
864
responses. add ( DocumentMessage :: StartTransaction ) ;
840
865
866
+ tool_data. layers_dragging = selected;
867
+
841
868
if let Some ( bounds) = & mut tool_data. bounding_box_manager {
869
+ bounds. original_bound_transform = bounds. transform ;
870
+
842
871
tool_data. layers_dragging . retain ( |layer| {
843
872
if * layer != LayerNodeIdentifier :: ROOT_PARENT {
844
873
document. network_interface . network ( & [ ] ) . unwrap ( ) . nodes . contains_key ( & layer. to_node ( ) )
@@ -847,41 +876,25 @@ impl Fsm for SelectToolFsmState {
847
876
false
848
877
}
849
878
} ) ;
879
+
850
880
let mut selected = Selected :: new (
851
881
& mut bounds. original_transforms ,
852
882
& mut bounds. center_of_transformation ,
853
- & selected ,
883
+ & tool_data . layers_dragging ,
854
884
responses,
855
885
& document. network_interface ,
856
886
None ,
857
887
& ToolType :: Select ,
858
888
None
859
889
) ;
860
-
861
890
bounds. center_of_transformation = selected. mean_average_of_pivots ( ) ;
862
891
}
892
+ tool_data. get_snap_candidates ( document, input) ;
863
893
864
- tool_data. layers_dragging = selected;
865
-
866
- SelectToolFsmState :: RotatingBounds
867
- }
868
- // Dragging the selected layers around to transform them
869
- else if compass_rose_state. can_grab ( ) || intersection. is_some_and ( |intersection| selected. iter ( ) . any ( |selected_layer| intersection. starts_with ( * selected_layer, document. metadata ( ) ) ) ) {
870
- responses. add ( DocumentMessage :: StartTransaction ) ;
871
-
872
- if input. keyboard . key ( select_deepest) || tool_data. nested_selection_behavior == NestedSelectionBehavior :: Deepest {
873
- tool_data. select_single_layer = intersection;
894
+ if input. keyboard . key ( skew) {
895
+ SelectToolFsmState :: SkewingBounds
874
896
} else {
875
- tool_data. select_single_layer = intersection. and_then ( |intersection| intersection. ancestors ( document. metadata ( ) ) . find ( |ancestor| selected. contains ( ancestor) ) ) ;
876
- }
877
-
878
- tool_data. layers_dragging = selected;
879
-
880
- tool_data. get_snap_candidates ( document, input) ;
881
- let axis = compass_rose_state. axis_type ( ) ;
882
- match axis {
883
- Some ( axis) => SelectToolFsmState :: Dragging { axis, using_compass : true } ,
884
- None => SelectToolFsmState :: Dragging { axis : Axis :: None , using_compass : false }
897
+ SelectToolFsmState :: ResizingBounds
885
898
}
886
899
}
887
900
// Dragging a selection box
0 commit comments