@@ -5,12 +5,13 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
5
5
use crate :: messages:: portfolio:: document:: { overlays:: utility_types:: OverlayContext , utility_types:: network_interface:: InputConnector } ;
6
6
use crate :: messages:: prelude:: { DocumentMessageHandler , InputPreprocessorMessageHandler , NodeGraphMessage } ;
7
7
use crate :: messages:: prelude:: { FrontendMessage , Responses } ;
8
- use crate :: messages:: tool:: common_functionality:: graph_modification_utils:: { self , get_arc_id} ;
8
+ use crate :: messages:: tool:: common_functionality:: graph_modification_utils:: { self , get_arc_id, get_stroke_width } ;
9
9
use crate :: messages:: tool:: common_functionality:: shapes:: shape_utility:: { extract_arc_parameters, extract_circle_radius} ;
10
- use glam:: DVec2 ;
10
+ use glam:: { DAffine2 , DVec2 } ;
11
11
use graph_craft:: document:: NodeInput ;
12
12
use graph_craft:: document:: value:: TaggedValue ;
13
13
use std:: collections:: VecDeque ;
14
+ use std:: f64:: consts:: FRAC_PI_2 ;
14
15
15
16
#[ derive( Clone , Debug , Default , PartialEq ) ]
16
17
pub enum RadiusHandleState {
@@ -47,25 +48,34 @@ impl RadiusHandle {
47
48
self . handle_state = state;
48
49
}
49
50
51
+ pub fn check_if_inside_dash_lines ( angle : f64 , mouse_position : DVec2 , viewport : DAffine2 , radius : f64 , document : & DocumentMessageHandler , layer : LayerNodeIdentifier ) -> bool {
52
+ let center = viewport. transform_point2 ( DVec2 :: ZERO ) ;
53
+ if let Some ( stroke_width) = get_stroke_width ( layer, & document. network_interface ) {
54
+ let layer_mouse = viewport. inverse ( ) . transform_point2 ( mouse_position) ;
55
+ let spacing = 3. * stroke_width;
56
+ layer_mouse. distance ( DVec2 :: ZERO ) >= ( radius - spacing) && layer_mouse. distance ( DVec2 :: ZERO ) <= ( radius + spacing)
57
+ } else {
58
+ let point_position = viewport. transform_point2 ( calculate_circle_point_position ( angle, radius. abs ( ) ) ) ;
59
+ mouse_position. distance ( center) <= point_position. distance ( center)
60
+ }
61
+ }
62
+
50
63
pub fn handle_actions ( & mut self , layer : LayerNodeIdentifier , document : & DocumentMessageHandler , mouse_position : DVec2 , responses : & mut VecDeque < Message > ) {
51
64
match & self . handle_state {
52
65
RadiusHandleState :: Inactive => {
53
66
let Some ( radius) = extract_circle_radius ( layer, document) . or ( extract_arc_parameters ( Some ( layer) , document) . map ( |( r, _, _, _) | r) ) else {
54
67
return ;
55
68
} ;
56
69
let viewport = document. metadata ( ) . transform_to_viewport ( layer) ;
57
-
58
70
let angle = viewport. inverse ( ) . transform_point2 ( mouse_position) . angle_to ( DVec2 :: X ) ;
59
-
60
- let point_position = viewport. transform_point2 ( get_circle_point_position ( angle, radius. abs ( ) ) ) ;
71
+ let point_position = viewport. transform_point2 ( calculate_circle_point_position ( angle, radius. abs ( ) ) ) ;
61
72
let center = viewport. transform_point2 ( DVec2 :: ZERO ) ;
62
73
63
- log:: info!( "reaching here" ) ;
64
74
if point_position. distance ( center) < GIZMO_HIDE_THRESHOLD {
65
75
return ;
66
76
}
67
77
68
- if mouse_position. distance ( center ) <= point_position . distance ( center ) {
78
+ if Self :: check_if_inside_dash_lines ( angle , mouse_position, viewport , radius . abs ( ) , document , layer ) {
69
79
self . layer = Some ( layer) ;
70
80
self . initial_radius = radius;
71
81
self . previous_mouse_position = mouse_position;
@@ -89,9 +99,35 @@ impl RadiusHandle {
89
99
return ;
90
100
} ;
91
101
let viewport = document. metadata ( ) . transform_to_viewport ( layer) ;
102
+ let center = viewport. transform_point2 ( DVec2 :: ZERO ) ;
103
+
104
+ let start_point = viewport. transform_point2 ( calculate_circle_point_position ( 0. , radius) ) . distance ( center) ;
105
+ let end_point = viewport. transform_point2 ( calculate_circle_point_position ( FRAC_PI_2 , radius) ) . distance ( center) ;
106
+
107
+ if let Some ( stroke_width) = get_stroke_width ( layer, & document. network_interface ) {
108
+ let threshold = 15.0 ;
109
+ let min_radius = start_point. min ( end_point) ;
110
+
111
+ let extra_spacing = if min_radius < threshold {
112
+ 10.0 * ( min_radius / threshold) // smoothly scales from 0 → 10
113
+ } else {
114
+ 10.0
115
+ } ;
116
+
117
+ let spacing = stroke_width + extra_spacing;
118
+ let smaller_radius_x = ( start_point - spacing) . abs ( ) ;
119
+ let smaller_radius_y = ( end_point - spacing) . abs ( ) ;
120
+
121
+ let larger_radius_x = ( start_point + spacing) . abs ( ) ;
122
+ let larger_radius_y = ( end_point + spacing) . abs ( ) ;
123
+
124
+ overlay_context. dashed_ellipse ( center, smaller_radius_x, smaller_radius_y, None , None , None , None , None , None , Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ;
125
+ overlay_context. dashed_ellipse ( center, larger_radius_x, larger_radius_y, None , None , None , None , None , None , Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ;
126
+
127
+ return ;
128
+ }
92
129
93
- overlay_context. dashed_circle ( DVec2 :: ZERO , radius. abs ( ) , None , None , Some ( 20. ) , Some ( 4. ) , Some ( 0.5 ) , Some ( viewport) ) ;
94
- // overlay_context.dashed_line(center, point_position, None, None, Some(4.), Some(4.), Some(0.5));
130
+ overlay_context. dashed_ellipse ( center, start_point, end_point, None , None , None , None , None , None , Some ( 4. ) , Some ( 4. ) , Some ( 0.5 ) ) ;
95
131
}
96
132
}
97
133
}
@@ -124,6 +160,6 @@ impl RadiusHandle {
124
160
}
125
161
}
126
162
127
- fn get_circle_point_position ( theta : f64 , radius : f64 ) -> DVec2 {
163
+ fn calculate_circle_point_position ( theta : f64 , radius : f64 ) -> DVec2 {
128
164
DVec2 :: new ( radius * theta. cos ( ) , -radius * theta. sin ( ) )
129
165
}
0 commit comments