@@ -43,6 +43,7 @@ type TransformData<'a> = (&'a DocumentMessageHandler, &'a InputPreprocessorMessa
43
43
impl MessageHandler < TransformLayerMessage , TransformData < ' _ > > for TransformLayerMessageHandler {
44
44
fn process_message ( & mut self , message : TransformLayerMessage , responses : & mut VecDeque < Message > , ( document, input, tool_data, shape_editor) : TransformData ) {
45
45
let using_path_tool = tool_data. active_tool_type == ToolType :: Path ;
46
+ let using_select_tool = tool_data. active_tool_type == ToolType :: Select ;
46
47
47
48
// TODO: Add support for transforming layer not in the document network
48
49
let selected_layers = document
@@ -75,10 +76,18 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
75
76
let viewspace = document. metadata ( ) . transform_to_viewport ( selected_layers[ 0 ] ) ;
76
77
77
78
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) ) ;
79
80
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
+ }
82
91
}
83
92
} else {
84
93
* selected. pivot = selected. mean_average_of_pivots ( ) ;
@@ -104,12 +113,13 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
104
113
responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
105
114
}
106
115
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 ( ) ;
110
122
111
- // Don't allow grab with no selected layers
112
- if selected_layers. is_empty ( ) {
113
123
return ;
114
124
}
115
125
@@ -120,13 +130,42 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
120
130
selected. original_transforms . clear ( ) ;
121
131
}
122
132
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 ( ) ;
124
141
return ;
125
142
}
126
143
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 ( ) ;
129
146
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
+ }
130
169
}
131
170
132
171
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
136
175
selected. original_transforms . clear ( ) ;
137
176
}
138
177
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 ( ) ;
140
186
return ;
141
187
}
142
188
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 ( ) ;
145
191
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
+ }
146
213
}
147
214
148
215
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
215
282
}
216
283
} ;
217
284
}
285
+
218
286
self . mouse_position = input. mouse . position ;
219
287
}
220
288
TransformLayerMessage :: SelectionChanged => {
0 commit comments