@@ -142,14 +142,7 @@ impl PointRadiusHandle {
142142 }
143143 }
144144
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 ) {
153146 match & self . handle_state {
154147 PointRadiusHandleState :: Inactive => {
155148 let Some ( layer) = selected_star_layer else { return } ;
@@ -161,25 +154,12 @@ impl PointRadiusHandle {
161154 for i in 0 ..( 2 * sides) {
162155 let point = star_vertex_position ( viewport, i as i32 , sides, radius1, radius2) ;
163156 let center = viewport. transform_point2 ( DVec2 :: ZERO ) ;
164- let viewport_diagonal = input. viewport_bounds . size ( ) . length ( ) ;
165157
166158 // If the user zooms out such that shape is very small hide the gizmo
167159 if point. distance ( center) < GIZMO_HIDE_THRESHOLD {
168160 return ;
169161 }
170162
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-
183163 overlay_context. manipulator_handle ( point, false , None ) ;
184164 }
185165 }
@@ -191,22 +171,12 @@ impl PointRadiusHandle {
191171 for i in 0 ..sides {
192172 let point = polygon_vertex_position ( viewport, i as i32 , sides, radius) ;
193173 let center = viewport. transform_point2 ( DVec2 :: ZERO ) ;
194- let viewport_diagonal = input. viewport_bounds . size ( ) . length ( ) ;
195174
196175 // If the user zooms out such that shape is very small hide the gizmo
197176 if point. distance ( center) < GIZMO_HIDE_THRESHOLD {
198177 return ;
199178 }
200179
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-
210180 overlay_context. manipulator_handle ( point, false , None ) ;
211181 }
212182 }
@@ -232,12 +202,9 @@ impl PointRadiusHandle {
232202 star_outline ( Some ( layer) , document, overlay_context) ;
233203
234204 // 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) ;
239207 }
240- draw_snapping_ticks ( & self . snap_radii , direction, viewport, angle, overlay_context) ;
241208
242209 return ;
243210 }
@@ -368,25 +335,36 @@ impl PointRadiusHandle {
368335 return snap_radii;
369336 } ;
370337
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 {
374339 return snap_radii;
375340 } ;
341+
342+ let other_radius = if radius_index == 3 { radius_1 } else { radius_2 } ;
343+
376344 let Some ( & TaggedValue :: U32 ( sides) ) = node_inputs[ 1 ] . as_value ( ) else {
377345 return snap_radii;
378346 } ;
379347
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+
380358 // Inner radius for 90°
381359 let b = FRAC_PI_4 * 3. - PI / ( sides as f64 ) ;
382360 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 ;
384362
385363 snap_radii. push ( required_radius) ;
386364
387365 // Also push the case when the when it length increases more than the other
388366
389- let flipped = other_radius * angle * SQRT_2 ;
367+ let flipped = other_radius. abs ( ) * sign * angle * SQRT_2 ;
390368
391369 snap_radii. push ( flipped) ;
392370
@@ -401,11 +379,11 @@ impl PointRadiusHandle {
401379 break ;
402380 }
403381
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) ;
406384 }
407385
408- snap_radii. push ( ( other_radius * 1. ) / factor) ;
386+ snap_radii. push ( ( other_radius. abs ( ) * sign ) / factor) ;
409387 }
410388
411389 snap_radii
@@ -441,21 +419,23 @@ impl PointRadiusHandle {
441419 } ;
442420
443421 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) ;
445422 let center = viewport_transform. transform_point2 ( DVec2 :: ZERO ) ;
446423 let radius_index = self . radius_index ;
447424
448425 let original_radius = self . initial_radius ;
449426
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;
452429 let projection = delta. project_onto ( radius) ;
453430 let sign = radius. dot ( delta) . signum ( ) ;
454431
455- let mut net_delta = projection. length ( ) * sign;
432+ let mut net_delta = projection. length ( ) * sign * original_radius . signum ( ) ;
456433 let new_radius = original_radius + net_delta;
457434
458435 self . update_state ( PointRadiusHandleState :: Dragging ) ;
436+
437+ self . check_if_radius_flipped ( original_radius, new_radius, document, layer, radius_index) ;
438+
459439 if let Some ( ( index, snapped_delta) ) = self . check_snapping ( new_radius, original_radius) {
460440 net_delta = snapped_delta;
461441 self . update_state ( PointRadiusHandleState :: Snapped ( index) ) ;
@@ -467,4 +447,23 @@ impl PointRadiusHandle {
467447 } ) ;
468448 responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
469449 }
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+ }
470469}
0 commit comments