@@ -43,6 +43,7 @@ type TransformData<'a> = (&'a DocumentMessageHandler, &'a InputPreprocessorMessa
4343impl MessageHandler < TransformLayerMessage , TransformData < ' _ > > for TransformLayerMessageHandler {
4444 fn process_message ( & mut self , message : TransformLayerMessage , responses : & mut VecDeque < Message > , ( document, input, tool_data, shape_editor) : TransformData ) {
4545 let using_path_tool = tool_data. active_tool_type == ToolType :: Path ;
46+ let using_select_tool = tool_data. active_tool_type == ToolType :: Select ;
4647
4748 // TODO: Add support for transforming layer not in the document network
4849 let selected_layers = document
@@ -75,10 +76,18 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
7576 let viewspace = document. metadata ( ) . transform_to_viewport ( selected_layers[ 0 ] ) ;
7677
7778 let mut point_count: usize = 0 ;
78- let get_location = |point : & ManipulatorPointId | point. get_position ( & vector_data) . map ( |position| viewspace. transform_point2 ( position) ) ;
79+ let get_location = |point : & & ManipulatorPointId | point. get_position ( & vector_data) . map ( |position| viewspace. transform_point2 ( position) ) ;
7980 let points = shape_editor. selected_points ( ) ;
80-
81- * selected. pivot = points. filter_map ( get_location) . inspect ( |_| point_count += 1 ) . sum :: < DVec2 > ( ) / point_count as f64 ;
81+ let selected_points: Vec < & ManipulatorPointId > = points. collect ( ) ;
82+
83+ if let [ point] = selected_points. as_slice ( ) {
84+ if let ManipulatorPointId :: PrimaryHandle ( _) | ManipulatorPointId :: EndHandle ( _) = point {
85+ let anchor_position = point. get_anchor_position ( & vector_data) . unwrap ( ) ;
86+ * selected. pivot = viewspace. transform_point2 ( anchor_position) ;
87+ } else {
88+ * selected. pivot = selected_points. iter ( ) . filter_map ( get_location) . inspect ( |_| point_count += 1 ) . sum :: < DVec2 > ( ) / point_count as f64 ;
89+ }
90+ }
8291 }
8392 } else {
8493 * selected. pivot = selected. mean_average_of_pivots ( ) ;
@@ -104,12 +113,13 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
104113 responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
105114 }
106115 TransformLayerMessage :: BeginGrab => {
107- if let TransformOperation :: Grabbing ( _) = self . transform_operation {
108- return ;
109- }
116+ if ( !using_path_tool && !using_select_tool)
117+ || ( using_path_tool && shape_editor. selected_points ( ) . next ( ) . is_none ( ) )
118+ || selected_layers. is_empty ( )
119+ || matches ! ( self . transform_operation, TransformOperation :: Grabbing ( _) )
120+ {
121+ selected. original_transforms . clear ( ) ;
110122
111- // Don't allow grab with no selected layers
112- if selected_layers. is_empty ( ) {
113123 return ;
114124 }
115125
@@ -120,13 +130,42 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
120130 selected. original_transforms . clear ( ) ;
121131 }
122132 TransformLayerMessage :: BeginRotate => {
123- if let TransformOperation :: Rotating ( _) = self . transform_operation {
133+ let selected_points: Vec < & ManipulatorPointId > = shape_editor. selected_points ( ) . collect ( ) ;
134+
135+ if ( !using_path_tool && !using_select_tool)
136+ || ( using_path_tool && selected_points. is_empty ( ) )
137+ || selected_layers. is_empty ( )
138+ || matches ! ( self . transform_operation, TransformOperation :: Rotating ( _) )
139+ {
140+ selected. original_transforms . clear ( ) ;
124141 return ;
125142 }
126143
127- // Don't allow rotate with no selected layers
128- if selected_layers . is_empty ( ) {
144+ let Some ( vector_data ) = selected_layers . first ( ) . and_then ( | & layer| document . network_interface . compute_modified_vector ( layer ) ) else {
145+ selected . original_transforms . clear ( ) ;
129146 return ;
147+ } ;
148+
149+ if let [ point] = selected_points. as_slice ( ) {
150+ if matches ! ( point, ManipulatorPointId :: Anchor ( _) ) {
151+ if let Some ( [ handle1, handle2] ) = point. get_handle_pair ( & vector_data) {
152+ let handle1_length = handle1. length ( & vector_data) ;
153+ let handle2_length = handle2. length ( & vector_data) ;
154+
155+ if ( handle1_length == 0. && handle2_length == 0. ) || ( handle1_length == f64:: MAX && handle2_length == f64:: MAX ) {
156+ return ;
157+ }
158+ }
159+ } else {
160+ // TODO: Fix handle snap to anchor issue, see <https://discord.com/channels/731730685944922173/1217752903209713715>
161+
162+ let handle_length = point. as_handle ( ) . map ( |handle| handle. length ( & vector_data) ) ;
163+
164+ if handle_length == Some ( 0. ) {
165+ selected. original_transforms . clear ( ) ;
166+ return ;
167+ }
168+ }
130169 }
131170
132171 begin_operation ( self . transform_operation , & mut self . typing , & mut self . mouse_position , & mut self . start_mouse ) ;
@@ -136,13 +175,41 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
136175 selected. original_transforms . clear ( ) ;
137176 }
138177 TransformLayerMessage :: BeginScale => {
139- if let TransformOperation :: Scaling ( _) = self . transform_operation {
178+ let selected_points: Vec < & ManipulatorPointId > = shape_editor. selected_points ( ) . collect ( ) ;
179+
180+ if ( using_path_tool && selected_points. is_empty ( ) )
181+ || ( !using_path_tool && !using_select_tool)
182+ || selected_layers. is_empty ( )
183+ || matches ! ( self . transform_operation, TransformOperation :: Scaling ( _) )
184+ {
185+ selected. original_transforms . clear ( ) ;
140186 return ;
141187 }
142188
143- // Don't allow scale with no selected layers
144- if selected_layers . is_empty ( ) {
189+ let Some ( vector_data ) = selected_layers . first ( ) . and_then ( | & layer| document . network_interface . compute_modified_vector ( layer ) ) else {
190+ selected . original_transforms . clear ( ) ;
145191 return ;
192+ } ;
193+
194+ if let [ point] = selected_points. as_slice ( ) {
195+ if matches ! ( point, ManipulatorPointId :: Anchor ( _) ) {
196+ if let Some ( [ handle1, handle2] ) = point. get_handle_pair ( & vector_data) {
197+ let handle1_length = handle1. length ( & vector_data) ;
198+ let handle2_length = handle2. length ( & vector_data) ;
199+
200+ if ( handle1_length == 0. && handle2_length == 0. ) || ( handle1_length == f64:: MAX && handle2_length == f64:: MAX ) {
201+ selected. original_transforms . clear ( ) ;
202+ return ;
203+ }
204+ }
205+ } else {
206+ let handle_length = point. as_handle ( ) . map ( |handle| handle. length ( & vector_data) ) ;
207+
208+ if handle_length == Some ( 0. ) {
209+ selected. original_transforms . clear ( ) ;
210+ return ;
211+ }
212+ }
146213 }
147214
148215 begin_operation ( self . transform_operation , & mut self . typing , & mut self . mouse_position , & mut self . start_mouse ) ;
@@ -215,6 +282,7 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
215282 }
216283 } ;
217284 }
285+
218286 self . mouse_position = input. mouse . position ;
219287 }
220288 TransformLayerMessage :: SelectionChanged => {
0 commit comments