@@ -142,14 +142,7 @@ impl PointRadiusHandle {
142
142
}
143
143
}
144
144
145
- pub fn overlays (
146
- & self ,
147
- selected_star_layer : Option < LayerNodeIdentifier > ,
148
- document : & DocumentMessageHandler ,
149
- input : & InputPreprocessorMessageHandler ,
150
- mouse_position : DVec2 ,
151
- overlay_context : & mut OverlayContext ,
152
- ) {
145
+ pub fn overlays ( & self , selected_star_layer : Option < LayerNodeIdentifier > , document : & DocumentMessageHandler , input : & InputPreprocessorMessageHandler , overlay_context : & mut OverlayContext ) {
153
146
match & self . handle_state {
154
147
PointRadiusHandleState :: Inactive => {
155
148
let Some ( layer) = selected_star_layer else { return } ;
@@ -161,25 +154,12 @@ impl PointRadiusHandle {
161
154
for i in 0 ..( 2 * sides) {
162
155
let point = star_vertex_position ( viewport, i as i32 , sides, radius1, radius2) ;
163
156
let center = viewport. transform_point2 ( DVec2 :: ZERO ) ;
164
- let viewport_diagonal = input. viewport_bounds . size ( ) . length ( ) ;
165
157
166
158
// If the user zooms out such that shape is very small hide the gizmo
167
159
if point. distance ( center) < GIZMO_HIDE_THRESHOLD {
168
160
return ;
169
161
}
170
162
171
- if point. distance ( mouse_position) < 5. {
172
- let Some ( direction) = ( point - center) . try_normalize ( ) else { continue } ;
173
-
174
- overlay_context. manipulator_handle ( point, true , None ) ;
175
- let angle = ( ( i as f64 ) * PI ) / ( sides as f64 ) ;
176
- overlay_context. line ( center, center + direction * viewport_diagonal, None , None ) ;
177
-
178
- draw_snapping_ticks ( & self . snap_radii , direction, viewport, angle, overlay_context) ;
179
-
180
- return ;
181
- }
182
-
183
163
overlay_context. manipulator_handle ( point, false , None ) ;
184
164
}
185
165
}
@@ -191,22 +171,12 @@ impl PointRadiusHandle {
191
171
for i in 0 ..sides {
192
172
let point = polygon_vertex_position ( viewport, i as i32 , sides, radius) ;
193
173
let center = viewport. transform_point2 ( DVec2 :: ZERO ) ;
194
- let viewport_diagonal = input. viewport_bounds . size ( ) . length ( ) ;
195
174
196
175
// If the user zooms out such that shape is very small hide the gizmo
197
176
if point. distance ( center) < GIZMO_HIDE_THRESHOLD {
198
177
return ;
199
178
}
200
179
201
- if point. distance ( mouse_position) < 5. {
202
- let Some ( direction) = ( point - center) . try_normalize ( ) else { continue } ;
203
-
204
- overlay_context. manipulator_handle ( point, true , None ) ;
205
- overlay_context. line ( center, center + direction * viewport_diagonal, None , None ) ;
206
-
207
- return ;
208
- }
209
-
210
180
overlay_context. manipulator_handle ( point, false , None ) ;
211
181
}
212
182
}
@@ -232,12 +202,9 @@ impl PointRadiusHandle {
232
202
star_outline ( Some ( layer) , document, overlay_context) ;
233
203
234
204
// Make the ticks for snapping
235
-
236
- // If dragging to make radius negative don't show the
237
- if ( mouse_position - center) . dot ( direction) < 0. {
238
- return ;
205
+ if ( radius1. signum ( ) * radius2. signum ( ) ) . is_sign_positive ( ) {
206
+ draw_snapping_ticks ( & self . snap_radii , direction, viewport, angle, overlay_context) ;
239
207
}
240
- draw_snapping_ticks ( & self . snap_radii , direction, viewport, angle, overlay_context) ;
241
208
242
209
return ;
243
210
}
@@ -368,25 +335,36 @@ impl PointRadiusHandle {
368
335
return snap_radii;
369
336
} ;
370
337
371
- let other_index = if radius_index == 3 { 2 } else { 3 } ;
372
-
373
- let Some ( & TaggedValue :: F64 ( other_radius) ) = node_inputs[ other_index] . as_value ( ) else {
338
+ let ( Some ( & TaggedValue :: F64 ( radius_1) ) , Some ( & TaggedValue :: F64 ( radius_2) ) ) = ( node_inputs[ 2 ] . as_value ( ) , node_inputs[ 3 ] . as_value ( ) ) else {
374
339
return snap_radii;
375
340
} ;
341
+
342
+ let other_radius = if radius_index == 3 { radius_1 } else { radius_2 } ;
343
+
376
344
let Some ( & TaggedValue :: U32 ( sides) ) = node_inputs[ 1 ] . as_value ( ) else {
377
345
return snap_radii;
378
346
} ;
379
347
348
+ let both_radii_negative = radius_1. is_sign_negative ( ) && radius_2. is_sign_negative ( ) ;
349
+ let both_radii_same_sign = ( radius_1. signum ( ) * radius_2. signum ( ) ) . is_sign_positive ( ) ;
350
+
351
+ // When only one of the radii is negative, no need for snapping
352
+ if !both_radii_same_sign {
353
+ return snap_radii;
354
+ }
355
+
356
+ let sign = if both_radii_negative { -1. } else { 1. } ;
357
+
380
358
// Inner radius for 90°
381
359
let b = FRAC_PI_4 * 3. - PI / ( sides as f64 ) ;
382
360
let angle = b. sin ( ) ;
383
- let required_radius = ( other_radius / angle) * FRAC_1_SQRT_2 ;
361
+ let required_radius = ( other_radius. abs ( ) * sign / angle) * FRAC_1_SQRT_2 ;
384
362
385
363
snap_radii. push ( required_radius) ;
386
364
387
365
// Also push the case when the when it length increases more than the other
388
366
389
- let flipped = other_radius * angle * SQRT_2 ;
367
+ let flipped = other_radius. abs ( ) * sign * angle * SQRT_2 ;
390
368
391
369
snap_radii. push ( flipped) ;
392
370
@@ -401,11 +379,11 @@ impl PointRadiusHandle {
401
379
break ;
402
380
}
403
381
404
- if other_radius * factor > 1e-6 {
405
- snap_radii. push ( other_radius * factor) ;
382
+ if other_radius. abs ( ) * factor > 1e-6 {
383
+ snap_radii. push ( other_radius. abs ( ) * sign * factor) ;
406
384
}
407
385
408
- snap_radii. push ( ( other_radius * 1. ) / factor) ;
386
+ snap_radii. push ( ( other_radius. abs ( ) * sign ) / factor) ;
409
387
}
410
388
411
389
snap_radii
@@ -441,21 +419,23 @@ impl PointRadiusHandle {
441
419
} ;
442
420
443
421
let viewport_transform = document. network_interface . document_metadata ( ) . transform_to_viewport ( layer) ;
444
- let document_transform = document. network_interface . document_metadata ( ) . transform_to_document ( layer) ;
445
422
let center = viewport_transform. transform_point2 ( DVec2 :: ZERO ) ;
446
423
let radius_index = self . radius_index ;
447
424
448
425
let original_radius = self . initial_radius ;
449
426
450
- let delta = viewport_transform. inverse ( ) . transform_point2 ( input. mouse . position ) - document_transform . inverse ( ) . transform_point2 ( drag_start) ;
451
- let radius = document . metadata ( ) . document_to_viewport . transform_point2 ( drag_start) - center;
427
+ let delta = viewport_transform. inverse ( ) . transform_point2 ( input. mouse . position ) - viewport_transform . inverse ( ) . transform_point2 ( drag_start) ;
428
+ let radius = drag_start - center;
452
429
let projection = delta. project_onto ( radius) ;
453
430
let sign = radius. dot ( delta) . signum ( ) ;
454
431
455
- let mut net_delta = projection. length ( ) * sign;
432
+ let mut net_delta = projection. length ( ) * sign * original_radius . signum ( ) ;
456
433
let new_radius = original_radius + net_delta;
457
434
458
435
self . update_state ( PointRadiusHandleState :: Dragging ) ;
436
+
437
+ self . check_if_radius_flipped ( original_radius, new_radius, document, layer, radius_index) ;
438
+
459
439
if let Some ( ( index, snapped_delta) ) = self . check_snapping ( new_radius, original_radius) {
460
440
net_delta = snapped_delta;
461
441
self . update_state ( PointRadiusHandleState :: Snapped ( index) ) ;
@@ -467,4 +447,23 @@ impl PointRadiusHandle {
467
447
} ) ;
468
448
responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
469
449
}
450
+
451
+ fn check_if_radius_flipped ( & mut self , original_radius : f64 , new_radius : f64 , document : & DocumentMessageHandler , layer : LayerNodeIdentifier , radius_index : usize ) {
452
+ let Some ( node_inputs) = NodeGraphLayer :: new ( layer, & document. network_interface ) . find_node_inputs ( "Star" ) else {
453
+ return ;
454
+ } ;
455
+
456
+ let ( Some ( & TaggedValue :: F64 ( radius_1) ) , Some ( & TaggedValue :: F64 ( radius_2) ) ) = ( node_inputs[ 2 ] . as_value ( ) , node_inputs[ 3 ] . as_value ( ) ) else {
457
+ return ;
458
+ } ;
459
+
460
+ let other_radius = if radius_index == 3 { radius_1 } else { radius_2 } ;
461
+
462
+ let flipped = ( other_radius. is_sign_positive ( ) && original_radius. is_sign_negative ( ) && new_radius. is_sign_positive ( ) )
463
+ || ( other_radius. is_sign_negative ( ) && original_radius. is_sign_positive ( ) && new_radius. is_sign_negative ( ) ) ;
464
+
465
+ if flipped {
466
+ self . snap_radii = Self :: calculate_snap_radii ( document, layer, radius_index) ;
467
+ }
468
+ }
470
469
}
0 commit comments