1
- use super :: utility_types:: OverlayContext ;
1
+ use super :: utility_types:: { DrawHandles , OverlayContext } ;
2
2
use crate :: consts:: HIDE_HANDLE_DISTANCE ;
3
3
use crate :: messages:: tool:: common_functionality:: shape_editor:: { SelectedLayerState , ShapeState } ;
4
4
use crate :: messages:: tool:: tool_messages:: tool_prelude:: { DocumentMessageHandler , PreferencesMessageHandler } ;
5
5
6
6
use graphene_core:: vector:: ManipulatorPointId ;
7
7
8
- use glam:: DVec2 ;
8
+ use bezier_rs:: Bezier ;
9
+ use glam:: { DAffine2 , DVec2 } ;
10
+ use graphene_std:: vector:: { PointId , SegmentId } ;
9
11
use wasm_bindgen:: JsCast ;
10
12
11
13
pub fn overlay_canvas_element ( ) -> Option < web_sys:: HtmlCanvasElement > {
@@ -23,7 +25,70 @@ pub fn overlay_canvas_context() -> web_sys::CanvasRenderingContext2d {
23
25
create_context ( ) . expect ( "Failed to get canvas context" )
24
26
}
25
27
26
- pub fn path_overlays ( document : & DocumentMessageHandler , shape_editor : & mut ShapeState , overlay_context : & mut OverlayContext , draw_handles : bool ) {
28
+ pub fn get_selected_segments ( document : & DocumentMessageHandler , shape_editor : & mut ShapeState ) -> Vec < SegmentId > {
29
+ let selected_points = shape_editor. selected_points ( ) ;
30
+ let selected_anchors: Vec < PointId > = selected_points
31
+ . filter_map ( |point_id| if let ManipulatorPointId :: Anchor ( p) = point_id { Some ( * p) } else { None } )
32
+ . collect ( ) ;
33
+ //Collect the segments whose handles are selected
34
+ let mut selected_segments: Vec < SegmentId > = shape_editor
35
+ . selected_points ( )
36
+ . filter_map ( |point_id| {
37
+ if let ManipulatorPointId :: EndHandle ( segment_id) = point_id {
38
+ Some ( * segment_id)
39
+ } else if let ManipulatorPointId :: PrimaryHandle ( segment_id) = point_id {
40
+ Some ( * segment_id)
41
+ } else {
42
+ None
43
+ }
44
+ } )
45
+ . collect ( ) ;
46
+ //TODO: Currently if there are two duplicate layers, both of their segments get overlays
47
+ // Segments of which the selected anchors are a part of
48
+ for layer in document. network_interface . selected_nodes ( & [ ] ) . unwrap ( ) . selected_layers ( document. metadata ( ) ) {
49
+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
50
+ continue ;
51
+ } ;
52
+ for ( segment_id, _bezier, start, end) in vector_data. segment_bezier_iter ( ) {
53
+ if selected_anchors. contains ( & start) || selected_anchors. contains ( & end) {
54
+ selected_segments. push ( segment_id) ;
55
+ }
56
+ }
57
+ }
58
+ selected_segments
59
+ }
60
+
61
+ fn overlay_bezier_handles (
62
+ segment_id : SegmentId ,
63
+ bezier : Bezier ,
64
+ transform : DAffine2 ,
65
+ overlay_context : & mut OverlayContext ,
66
+ selected : Option < & SelectedLayerState > ,
67
+ is_selected : impl Fn ( Option < & SelectedLayerState > , ManipulatorPointId ) -> bool ,
68
+ ) {
69
+ let bezier = bezier. apply_transformation ( |point| transform. transform_point2 ( point) ) ;
70
+ let not_under_anchor = |position : DVec2 , anchor : DVec2 | position. distance_squared ( anchor) >= HIDE_HANDLE_DISTANCE * HIDE_HANDLE_DISTANCE ;
71
+ match bezier. handles {
72
+ bezier_rs:: BezierHandles :: Quadratic { handle } if not_under_anchor ( handle, bezier. start ) && not_under_anchor ( handle, bezier. end ) => {
73
+ overlay_context. line ( handle, bezier. start , None ) ;
74
+ overlay_context. line ( handle, bezier. end , None ) ;
75
+ overlay_context. manipulator_handle ( handle, is_selected ( selected, ManipulatorPointId :: PrimaryHandle ( segment_id) ) , None ) ;
76
+ }
77
+ bezier_rs:: BezierHandles :: Cubic { handle_start, handle_end } => {
78
+ if not_under_anchor ( handle_start, bezier. start ) {
79
+ overlay_context. line ( handle_start, bezier. start , None ) ;
80
+ overlay_context. manipulator_handle ( handle_start, is_selected ( selected, ManipulatorPointId :: PrimaryHandle ( segment_id) ) , None ) ;
81
+ }
82
+ if not_under_anchor ( handle_end, bezier. end ) {
83
+ overlay_context. line ( handle_end, bezier. end , None ) ;
84
+ overlay_context. manipulator_handle ( handle_end, is_selected ( selected, ManipulatorPointId :: EndHandle ( segment_id) ) , None ) ;
85
+ }
86
+ }
87
+ _ => { }
88
+ }
89
+ }
90
+
91
+ pub fn path_overlays ( document : & DocumentMessageHandler , shape_editor : & mut ShapeState , overlay_context : & mut OverlayContext , draw_handles : DrawHandles ) {
27
92
for layer in document. network_interface . selected_nodes ( & [ ] ) . unwrap ( ) . selected_layers ( document. metadata ( ) ) {
28
93
let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
29
94
continue ;
@@ -35,30 +100,59 @@ pub fn path_overlays(document: &DocumentMessageHandler, shape_editor: &mut Shape
35
100
overlay_context. outline_vector ( & vector_data, transform) ;
36
101
37
102
//TODO: Here define which handles to show and which handles to not, for path tool selection
38
- if draw_handles {
39
- for ( segment_id, bezier, _start, _end) in vector_data. segment_bezier_iter ( ) {
40
- let bezier = bezier. apply_transformation ( |point| transform. transform_point2 ( point) ) ;
41
- let not_under_anchor = |position : DVec2 , anchor : DVec2 | position. distance_squared ( anchor) >= HIDE_HANDLE_DISTANCE * HIDE_HANDLE_DISTANCE ;
42
- match bezier. handles {
43
- bezier_rs:: BezierHandles :: Quadratic { handle } if not_under_anchor ( handle, bezier. start ) && not_under_anchor ( handle, bezier. end ) => {
44
- overlay_context. line ( handle, bezier. start , None ) ;
45
- overlay_context. line ( handle, bezier. end , None ) ;
46
- overlay_context. manipulator_handle ( handle, is_selected ( selected, ManipulatorPointId :: PrimaryHandle ( segment_id) ) , None ) ;
47
- }
48
- bezier_rs:: BezierHandles :: Cubic { handle_start, handle_end } => {
49
- if not_under_anchor ( handle_start, bezier. start ) {
50
- overlay_context. line ( handle_start, bezier. start , None ) ;
51
- overlay_context. manipulator_handle ( handle_start, is_selected ( selected, ManipulatorPointId :: PrimaryHandle ( segment_id) ) , None ) ;
52
- }
53
- if not_under_anchor ( handle_end, bezier. end ) {
54
- overlay_context. line ( handle_end, bezier. end , None ) ;
55
- overlay_context. manipulator_handle ( handle_end, is_selected ( selected, ManipulatorPointId :: EndHandle ( segment_id) ) , None ) ;
103
+ match draw_handles {
104
+ DrawHandles :: All => {
105
+ vector_data. segment_bezier_iter ( ) . for_each ( |( segment_id, bezier, _start, _end) | {
106
+ overlay_bezier_handles ( segment_id, bezier, transform, overlay_context, selected, is_selected) ;
107
+ } ) ;
108
+ }
109
+ DrawHandles :: SelectedAnchors ( ref selected_segments) => {
110
+ vector_data
111
+ . segment_bezier_iter ( )
112
+ . filter ( |( segment_id, ..) | selected_segments. contains ( segment_id) )
113
+ . for_each ( |( segment_id, bezier, _start, _end) | {
114
+ overlay_bezier_handles ( segment_id, bezier, transform, overlay_context, selected, is_selected) ;
115
+ } ) ;
116
+ }
117
+
118
+ DrawHandles :: FrontierHandles ( ref segment_endpoints) => {
119
+ vector_data
120
+ . segment_bezier_iter ( )
121
+ . filter ( |( segment_id, ..) | segment_endpoints. contains_key ( & segment_id) )
122
+ . for_each ( |( segment_id, bezier, start, end) | {
123
+ if segment_endpoints. get ( & segment_id) . unwrap ( ) . len ( ) == 1 {
124
+ let point_to_render = segment_endpoints. get ( & segment_id) . unwrap ( ) [ 0 ] ;
125
+ let bezier = bezier. apply_transformation ( |point| transform. transform_point2 ( point) ) ;
126
+ let not_under_anchor = |position : DVec2 , anchor : DVec2 | position. distance_squared ( anchor) >= HIDE_HANDLE_DISTANCE * HIDE_HANDLE_DISTANCE ;
127
+ match bezier. handles {
128
+ bezier_rs:: BezierHandles :: Quadratic { handle } if not_under_anchor ( handle, bezier. start ) && not_under_anchor ( handle, bezier. end ) => {
129
+ if start == point_to_render {
130
+ overlay_context. line ( handle, bezier. start , None ) ;
131
+ } else {
132
+ overlay_context. line ( handle, bezier. end , None ) ;
133
+ }
134
+ overlay_context. manipulator_handle ( handle, is_selected ( selected, ManipulatorPointId :: PrimaryHandle ( segment_id) ) , None ) ;
135
+ }
136
+ bezier_rs:: BezierHandles :: Cubic { handle_start, handle_end } => {
137
+ if not_under_anchor ( handle_start, bezier. start ) && ( point_to_render == start) {
138
+ overlay_context. line ( handle_start, bezier. start , None ) ;
139
+ overlay_context. manipulator_handle ( handle_start, is_selected ( selected, ManipulatorPointId :: PrimaryHandle ( segment_id) ) , None ) ;
140
+ }
141
+ if not_under_anchor ( handle_end, bezier. end ) && ( point_to_render == end) {
142
+ overlay_context. line ( handle_end, bezier. end , None ) ;
143
+ overlay_context. manipulator_handle ( handle_end, is_selected ( selected, ManipulatorPointId :: EndHandle ( segment_id) ) , None ) ;
144
+ }
145
+ }
146
+ _ => { }
147
+ }
148
+ } else {
149
+ overlay_bezier_handles ( segment_id, bezier, transform, overlay_context, selected, is_selected) ;
56
150
}
57
- }
58
- _ => { }
59
- }
151
+ } ) ;
60
152
}
153
+ DrawHandles :: None => { }
61
154
}
155
+
62
156
for ( & id, & position) in vector_data. point_domain . ids ( ) . iter ( ) . zip ( vector_data. point_domain . positions ( ) ) {
63
157
overlay_context. manipulator_anchor ( transform. transform_point2 ( position) , is_selected ( selected, ManipulatorPointId :: Anchor ( id) ) , None ) ;
64
158
}
0 commit comments