1+ use super :: line_shape:: NodeGraphLayer ;
12use super :: shape_utility:: { ShapeToolModifierKey , update_radius_sign} ;
23use super :: * ;
34use crate :: messages:: portfolio:: document:: graph_operation:: utility_types:: TransformIn ;
45use crate :: messages:: portfolio:: document:: node_graph:: document_node_definitions:: resolve_document_node_type;
6+ use crate :: messages:: portfolio:: document:: overlays:: utility_types:: OverlayContext ;
57use crate :: messages:: portfolio:: document:: utility_types:: document_metadata:: LayerNodeIdentifier ;
68use crate :: messages:: portfolio:: document:: utility_types:: network_interface:: { InputConnector , NodeTemplate } ;
79use crate :: messages:: tool:: common_functionality:: graph_modification_utils;
810use crate :: messages:: tool:: tool_messages:: tool_prelude:: * ;
911use glam:: DAffine2 ;
1012use graph_craft:: document:: NodeInput ;
1113use graph_craft:: document:: value:: TaggedValue ;
14+ use graphene_std:: vector:: PointId ;
1215use std:: collections:: VecDeque ;
1316
1417#[ derive( Default ) ]
1518pub struct Star ;
1619
20+ #[ derive( Clone , Debug , Default ) ]
21+ pub struct PointRadiusHandle {
22+ pub center : DVec2 ,
23+ pub vertex : Option < PointId > ,
24+ pub index : usize ,
25+ }
26+
27+ #[ derive( Clone , Debug , Default ) ]
28+ pub struct StarShapeData {
29+ pub point_radius_handle : PointRadiusHandle ,
30+ }
31+
1732impl Star {
1833 pub fn create_node ( vertices : u32 ) -> NodeTemplate {
1934 let node_type = resolve_document_node_type ( "Star" ) . expect ( " Star node does not exist" ) ;
@@ -25,6 +40,122 @@ impl Star {
2540 ] )
2641 }
2742
43+ pub fn set_point_radius_handle ( document : & DocumentMessageHandler , mouse_pos : DVec2 , shape_tool_data : & mut ShapeToolData ) -> bool {
44+ if let Some ( ( layer, ( center, _, vertex, index) ) ) = Self :: points_on_inner_circle ( document, mouse_pos) . iter ( ) . next ( ) {
45+ shape_tool_data. data . layer = Some ( * layer) ;
46+ shape_tool_data. star_data . point_radius_handle = PointRadiusHandle {
47+ center : * center,
48+ vertex : Some ( * vertex) ,
49+ index : * index,
50+ } ;
51+ return true ;
52+ }
53+ false
54+ }
55+
56+ pub fn inner_gizmo_overlays ( document : & DocumentMessageHandler , shape_tool_data : & mut ShapeToolData , overlay_context : & mut OverlayContext ) {
57+ let PointRadiusHandle { center, vertex, .. } = shape_tool_data. star_data . point_radius_handle ;
58+ let layer = shape_tool_data. data . layer . unwrap ( ) ;
59+ let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
60+ let viewport = document. metadata ( ) . transform_to_viewport ( layer) ;
61+ let vertex_pos = vector_data. point_domain . position_from_id ( vertex. unwrap ( ) ) . unwrap ( ) ;
62+ Self :: draw_point_radius_overlay ( center, vertex_pos, viewport, overlay_context) ;
63+ }
64+
65+ fn draw_point_radius_overlay ( center : DVec2 , vertex_pos : DVec2 , transform : DAffine2 , overlay_context : & mut OverlayContext ) {
66+ let viewport_center = transform. transform_point2 ( center) ;
67+ let viewport_vertex = transform. transform_point2 ( vertex_pos) ;
68+ let extension_length = ( viewport_vertex - viewport_center) . length ( ) * 0.5 ;
69+ let extension = ( viewport_vertex - viewport_center) . normalize ( ) * extension_length;
70+
71+ overlay_context. line ( viewport_center, viewport_vertex + extension, None , None ) ;
72+ overlay_context. manipulator_handle ( viewport_vertex, true , None ) ;
73+ }
74+ // when hovered
75+ pub fn hover_point_radius_handle ( document : & DocumentMessageHandler , mouse_pos : DVec2 , overlay_context : & mut OverlayContext ) -> bool {
76+ for ( layer, ( center, vertex_pos, _, _) ) in Self :: points_on_inner_circle ( document, mouse_pos) {
77+ let transform = document. metadata ( ) . transform_to_viewport ( layer) ;
78+ Self :: draw_point_radius_overlay ( center, vertex_pos, transform, overlay_context) ;
79+ return true ;
80+ }
81+
82+ for layer in document
83+ . network_interface
84+ . selected_nodes ( )
85+ . selected_visible_and_unlocked_layers ( & document. network_interface )
86+ . filter ( |layer| graph_modification_utils:: get_star_id ( * layer, & document. network_interface ) . is_some ( ) )
87+ {
88+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
89+ return false ;
90+ } ;
91+
92+ for ( _, anchor_positions) in vector_data. point_domain . position_ids ( ) {
93+ let transform = document. metadata ( ) . transform_to_viewport ( layer) ;
94+ overlay_context. manipulator_handle ( transform. transform_point2 ( * anchor_positions) , false , None ) ;
95+ }
96+
97+ return false ;
98+ }
99+ false
100+ }
101+
102+ pub fn points_on_inner_circle ( document : & DocumentMessageHandler , mouse_pos : DVec2 ) -> HashMap < LayerNodeIdentifier , ( DVec2 , DVec2 , PointId , usize ) > {
103+ let mut result = HashMap :: new ( ) ;
104+
105+ for layer in document
106+ . network_interface
107+ . selected_nodes ( )
108+ . selected_visible_and_unlocked_layers ( & document. network_interface )
109+ . filter ( |layer| graph_modification_utils:: get_star_id ( * layer, & document. network_interface ) . is_some ( ) )
110+ {
111+ let Some ( node_inputs) = NodeGraphLayer :: new ( layer, & document. network_interface ) . find_node_inputs ( "Star" ) else {
112+ return result;
113+ } ;
114+
115+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
116+ return result;
117+ } ;
118+
119+ let transform = document. network_interface . document_metadata ( ) . transform_to_viewport ( layer) ;
120+ let center = DVec2 :: ZERO ;
121+
122+ let ( Some ( & TaggedValue :: F64 ( outer) ) , Some ( & TaggedValue :: F64 ( inner) ) ) = ( node_inputs[ 2 ] . as_value ( ) , node_inputs[ 3 ] . as_value ( ) ) else {
123+ return result;
124+ } ;
125+
126+ let mut index = 0 ;
127+
128+ let inner_point = vector_data. point_domain . position_ids ( ) . find ( |( _, pos) | {
129+ let transformed = transform. transform_point2 ( * * pos) ;
130+ if transformed. distance ( mouse_pos) >= 5.0 {
131+ return false ;
132+ }
133+
134+ let dist = pos. distance ( center) ;
135+ if ( dist - inner) . abs ( ) < 1e-6 {
136+ index = 3 ;
137+
138+ true
139+ } else if ( dist - outer) . abs ( ) < 1e-6 {
140+ index = 2 ;
141+ log:: info!( "dist to outer {:?}" , ( dist - outer) . abs( ) ) ;
142+
143+ true
144+ } else {
145+ false
146+ }
147+ } ) ;
148+
149+ // Only insert if we found an inner point
150+ if let Some ( ( point_id, vertex_pos) ) = inner_point {
151+ result. insert ( layer, ( center, * vertex_pos, point_id, index) ) ;
152+ break ;
153+ }
154+ }
155+
156+ result
157+ }
158+
28159 pub fn update_shape (
29160 document : & DocumentMessageHandler ,
30161 ipp : & InputPreprocessorMessageHandler ,
@@ -74,4 +205,54 @@ impl Star {
74205 }
75206 false
76207 }
208+
209+ pub fn update_inner_radius (
210+ document : & DocumentMessageHandler ,
211+ input : & InputPreprocessorMessageHandler ,
212+ layer : LayerNodeIdentifier ,
213+ responses : & mut VecDeque < Message > ,
214+ shape_tool_data : & mut ShapeToolData ,
215+ ) {
216+ let Some ( node_id) = graph_modification_utils:: get_star_id ( layer, & document. network_interface ) else {
217+ return ;
218+ } ;
219+
220+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
221+ return ;
222+ } ;
223+
224+ let Some ( node_inputs) = NodeGraphLayer :: new ( layer, & document. network_interface ) . find_node_inputs ( "Star" ) else {
225+ return ;
226+ } ;
227+
228+ let path = vector_data. stroke_bezier_paths ( ) . next ( ) . unwrap ( ) ;
229+ let center = path. length_centroid ( None , true ) . unwrap ( ) ;
230+ let transform = document. network_interface . document_metadata ( ) . transform_to_viewport ( layer) ;
231+ let index = shape_tool_data. star_data . point_radius_handle . index ;
232+
233+ // inner radiust
234+ let Some ( & TaggedValue :: F64 ( required_radius) ) = node_inputs[ index] . as_value ( ) else {
235+ return ;
236+ } ;
237+
238+ // update_radius_sign(start, end, layer, document, responses);
239+
240+ let delta = input. mouse . position - shape_tool_data. last_mouse_position ;
241+ let radius = document. metadata ( ) . document_to_viewport . transform_point2 ( shape_tool_data. data . drag_start ) - transform. transform_point2 ( center) ;
242+ let projection = delta. project_onto ( radius) ;
243+ let sign = radius. dot ( delta) . signum ( ) ;
244+
245+ let net_delta = projection. length ( ) * sign;
246+ shape_tool_data. last_mouse_position = input. mouse . position ;
247+
248+ // overlay_context.line(transform.transform_point2(center), transform.transform_point2(inner + net_delta), None, None);
249+
250+ // We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
251+
252+ responses. add ( NodeGraphMessage :: SetInput {
253+ input_connector : InputConnector :: node ( node_id, index) ,
254+ input : NodeInput :: value ( TaggedValue :: F64 ( required_radius + net_delta) , false ) ,
255+ } ) ;
256+ responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
257+ }
77258}
0 commit comments