@@ -48,71 +48,101 @@ impl Resize {
4848 /// Compute the drag start and end based on the current mouse position. Ignores the state of the layer.
4949 /// If you want to only draw whilst a layer exists, use [`Resize::calculate_points`].
5050 pub fn calculate_points_ignore_layer ( & mut self , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , center : Key , lock_ratio : Key , in_document : bool ) -> [ DVec2 ; 2 ] {
51+ let ratio = input. keyboard . get ( lock_ratio as usize ) ;
52+ let center = input. keyboard . get ( center as usize ) ;
53+
54+ // Use shared snapping logic with optional center and ratio constraints, considering if coordinates are in document space.
55+ self . compute_snapped_resize_points ( document, input, center, ratio, in_document)
56+ }
57+
58+ pub fn calculate_transform ( & mut self , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , center : Key , lock_ratio : Key , skip_rerender : bool ) -> Option < Message > {
59+ let points_viewport = self . calculate_points ( document, input, center, lock_ratio) ?;
60+ Some (
61+ GraphOperationMessage :: TransformSet {
62+ layer : self . layer ?,
63+ transform : DAffine2 :: from_scale_angle_translation ( points_viewport[ 1 ] - points_viewport[ 0 ] , 0. , points_viewport[ 0 ] ) ,
64+ transform_in : TransformIn :: Viewport ,
65+ skip_rerender,
66+ }
67+ . into ( ) ,
68+ )
69+ }
70+
71+ pub fn calculate_circle_points ( & mut self , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , center : Key ) -> [ DVec2 ; 2 ] {
72+ let center = input. keyboard . get ( center as usize ) ;
73+
74+ // Use shared snapping logic with enforced aspect ratio and optional center snapping.
75+ self . compute_snapped_resize_points ( document, input, center, true , false )
76+ }
77+
78+ /// Calculates two points in viewport space from a drag, applying snapping, optional center mode, and aspect ratio locking.
79+ fn compute_snapped_resize_points ( & mut self , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , center : bool , lock_ratio : bool , in_document : bool ) -> [ DVec2 ; 2 ] {
5180 let start = self . viewport_drag_start ( document) ;
5281 let mouse = input. mouse . position ;
5382 let document_to_viewport = document. navigation_handler . calculate_offset_transform ( input. viewport_bounds . center ( ) , & document. document_ptz ) ;
54- let document_mouse = document_to_viewport . inverse ( ) . transform_point2 ( mouse ) ;
83+ let drag_start = self . drag_start ;
5584 let mut points_viewport = [ start, mouse] ;
85+
5686 let ignore = if let Some ( layer) = self . layer { vec ! [ layer] } else { vec ! [ ] } ;
57- let ratio = input. keyboard . get ( lock_ratio as usize ) ;
58- let center = input. keyboard . get ( center as usize ) ;
59- let snap_data = SnapData :: ignore ( document, input, & ignore) ;
60- let config = SnapTypeConfiguration :: default ( ) ;
61- if ratio {
87+ let snap_data = & SnapData :: ignore ( document, input, & ignore) ;
88+
89+ if lock_ratio {
6290 let viewport_size = points_viewport[ 1 ] - points_viewport[ 0 ] ;
63- let raw_size = if in_document { document_to_viewport. inverse ( ) } else { DAffine2 :: IDENTITY } . transform_vector2 ( viewport_size) ;
91+ let raw_size = if in_document {
92+ document_to_viewport. inverse ( ) . transform_vector2 ( viewport_size)
93+ } else {
94+ viewport_size
95+ } ;
96+
6497 let adjusted_size = raw_size. abs ( ) . max ( raw_size. abs ( ) . yx ( ) ) * raw_size. signum ( ) ;
6598 let size = if in_document { document_to_viewport. transform_vector2 ( adjusted_size) } else { adjusted_size } ;
66- points_viewport[ 1 ] = points_viewport[ 0 ] + size;
6799
100+ points_viewport[ 1 ] = points_viewport[ 0 ] + size;
68101 let end_document = document_to_viewport. inverse ( ) . transform_point2 ( points_viewport[ 1 ] ) ;
69102 let constraint = SnapConstraint :: Line {
70- origin : self . drag_start ,
71- direction : end_document - self . drag_start ,
103+ origin : drag_start,
104+ direction : end_document - drag_start,
72105 } ;
106+
73107 if center {
74- let snapped = self . snap_manager . constrained_snap ( & snap_data, & SnapCandidatePoint :: handle ( end_document) , constraint, config) ;
75- let far = SnapCandidatePoint :: handle ( 2. * self . drag_start - end_document) ;
76- let snapped_far = self . snap_manager . constrained_snap ( & snap_data, & far, constraint, config) ;
108+ let snapped = self
109+ . snap_manager
110+ . constrained_snap ( snap_data, & SnapCandidatePoint :: handle ( end_document) , constraint, SnapTypeConfiguration :: default ( ) ) ;
111+ let far = SnapCandidatePoint :: handle ( 2. * drag_start - end_document) ;
112+ let snapped_far = self . snap_manager . constrained_snap ( snap_data, & far, constraint, SnapTypeConfiguration :: default ( ) ) ;
77113 let best = if snapped_far. other_snap_better ( & snapped) { snapped } else { snapped_far } ;
114+
78115 points_viewport[ 0 ] = document_to_viewport. transform_point2 ( best. snapped_point_document ) ;
79- points_viewport[ 1 ] = document_to_viewport. transform_point2 ( self . drag_start * 2. - best. snapped_point_document ) ;
116+ points_viewport[ 1 ] = document_to_viewport. transform_point2 ( drag_start * 2. - best. snapped_point_document ) ;
80117 self . snap_manager . update_indicator ( best) ;
81118 } else {
82- let snapped = self . snap_manager . constrained_snap ( & snap_data, & SnapCandidatePoint :: handle ( end_document) , constraint, config) ;
119+ let snapped = self
120+ . snap_manager
121+ . constrained_snap ( snap_data, & SnapCandidatePoint :: handle ( end_document) , constraint, SnapTypeConfiguration :: default ( ) ) ;
83122 points_viewport[ 1 ] = document_to_viewport. transform_point2 ( snapped. snapped_point_document ) ;
84123 self . snap_manager . update_indicator ( snapped) ;
85124 }
86- } else if center {
87- let snapped = self . snap_manager . free_snap ( & snap_data, & SnapCandidatePoint :: handle ( document_mouse) , config) ;
88- let opposite = 2. * self . drag_start - document_mouse;
89- let snapped_far = self . snap_manager . free_snap ( & snap_data, & SnapCandidatePoint :: handle ( opposite) , config) ;
90- let best = if snapped_far. other_snap_better ( & snapped) { snapped } else { snapped_far } ;
91- points_viewport[ 0 ] = document_to_viewport. transform_point2 ( best. snapped_point_document ) ;
92- points_viewport[ 1 ] = document_to_viewport. transform_point2 ( self . drag_start * 2. - best. snapped_point_document ) ;
93- self . snap_manager . update_indicator ( best) ;
94125 } else {
95- let snapped = self . snap_manager . free_snap ( & snap_data, & SnapCandidatePoint :: handle ( document_mouse) , config) ;
96- points_viewport[ 1 ] = document_to_viewport. transform_point2 ( snapped. snapped_point_document ) ;
97- self . snap_manager . update_indicator ( snapped) ;
126+ let document_mouse = document_to_viewport. inverse ( ) . transform_point2 ( mouse) ;
127+ if center {
128+ let snapped = self . snap_manager . free_snap ( snap_data, & SnapCandidatePoint :: handle ( document_mouse) , SnapTypeConfiguration :: default ( ) ) ;
129+ let opposite = 2. * drag_start - document_mouse;
130+ let snapped_far = self . snap_manager . free_snap ( snap_data, & SnapCandidatePoint :: handle ( opposite) , SnapTypeConfiguration :: default ( ) ) ;
131+ let best = if snapped_far. other_snap_better ( & snapped) { snapped } else { snapped_far } ;
132+
133+ points_viewport[ 0 ] = document_to_viewport. transform_point2 ( best. snapped_point_document ) ;
134+ points_viewport[ 1 ] = document_to_viewport. transform_point2 ( drag_start * 2. - best. snapped_point_document ) ;
135+ self . snap_manager . update_indicator ( best) ;
136+ } else {
137+ let snapped = self . snap_manager . free_snap ( snap_data, & SnapCandidatePoint :: handle ( document_mouse) , SnapTypeConfiguration :: default ( ) ) ;
138+ points_viewport[ 1 ] = document_to_viewport. transform_point2 ( snapped. snapped_point_document ) ;
139+ self . snap_manager . update_indicator ( snapped) ;
140+ }
98141 }
99142
100143 points_viewport
101144 }
102145
103- pub fn calculate_transform ( & mut self , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , center : Key , lock_ratio : Key , skip_rerender : bool ) -> Option < Message > {
104- let points_viewport = self . calculate_points ( document, input, center, lock_ratio) ?;
105- Some (
106- GraphOperationMessage :: TransformSet {
107- layer : self . layer ?,
108- transform : DAffine2 :: from_scale_angle_translation ( points_viewport[ 1 ] - points_viewport[ 0 ] , 0. , points_viewport[ 0 ] ) ,
109- transform_in : TransformIn :: Viewport ,
110- skip_rerender,
111- }
112- . into ( ) ,
113- )
114- }
115-
116146 pub fn cleanup ( & mut self , responses : & mut VecDeque < Message > ) {
117147 self . snap_manager . cleanup ( responses) ;
118148 self . layer = None ;
0 commit comments