@@ -16,6 +16,8 @@ use graphene_core::vector::{PointId, VectorModificationType};
16
16
use graphene_core:: Color ;
17
17
use graphene_std:: vector:: { HandleId , ManipulatorPointId , SegmentId , VectorData } ;
18
18
19
+ use std:: fmt;
20
+
19
21
#[ derive( Default ) ]
20
22
pub struct PenTool {
21
23
fsm_state : PenToolFsmState ,
@@ -62,6 +64,7 @@ pub enum PenToolMessage {
62
64
Redo ,
63
65
Undo ,
64
66
UpdateOptions ( PenOptionsUpdate ) ,
67
+ ChangeToolMode ( ToolMode ) ,
65
68
RecalculateLatestPointsPosition ,
66
69
RemovePreviousHandle ,
67
70
GRS { grab : Key , rotate : Key , scale : Key } ,
@@ -94,6 +97,24 @@ pub enum PenOptionsUpdate {
94
97
OverlayModeType ( PenOverlayMode ) ,
95
98
}
96
99
100
+ impl PenTool {
101
+ fn tool_mode_widget ( & self ) -> WidgetHolder {
102
+ let tool_mode_entries = [ ToolMode :: Path , ToolMode :: Spline ]
103
+ . iter ( )
104
+ . map ( |mode| {
105
+ MenuListEntry :: new ( format ! ( "{mode:?}" ) )
106
+ . label ( mode. to_string ( ) )
107
+ . on_commit ( move |_| PenToolMessage :: ChangeToolMode ( * mode) . into ( ) )
108
+ } )
109
+ . collect ( ) ;
110
+
111
+ DropdownInput :: new ( vec ! [ tool_mode_entries] )
112
+ . selected_index ( Some ( ( self . tool_data . tool_mode ) as u32 ) )
113
+ . tooltip ( "Select Spline to draw smooth curves or select Path to draw a path." )
114
+ . widget_holder ( )
115
+ }
116
+ }
117
+
97
118
impl ToolMetadata for PenTool {
98
119
fn icon_name ( & self ) -> String {
99
120
"VectorPenTool" . into ( )
@@ -142,6 +163,10 @@ impl LayoutHolder for PenTool {
142
163
143
164
widgets. push ( Separator :: new ( SeparatorType :: Unrelated ) . widget_holder ( ) ) ;
144
165
166
+ widgets. push ( self . tool_mode_widget ( ) ) ;
167
+
168
+ widgets. push ( Separator :: new ( SeparatorType :: Unrelated ) . widget_holder ( ) ) ;
169
+
145
170
widgets. push (
146
171
RadioInput :: new ( vec ! [
147
172
RadioEntryData :: new( "all" )
@@ -263,8 +288,25 @@ enum HandleMode {
263
288
ColinearEquidistant ,
264
289
}
265
290
291
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Default , serde:: Serialize , serde:: Deserialize , specta:: Type ) ]
292
+ pub enum ToolMode {
293
+ #[ default]
294
+ Path ,
295
+ Spline ,
296
+ }
297
+
298
+ impl fmt:: Display for ToolMode {
299
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
300
+ match self {
301
+ ToolMode :: Path => write ! ( f, "Path" ) ,
302
+ ToolMode :: Spline => write ! ( f, "Spline" ) ,
303
+ }
304
+ }
305
+ }
306
+
266
307
#[ derive( Clone , Debug , Default ) ]
267
308
struct PenToolData {
309
+ tool_mode : ToolMode ,
268
310
snap_manager : SnapManager ,
269
311
latest_points : Vec < LastPoint > ,
270
312
point_index : usize ,
@@ -910,6 +952,10 @@ impl Fsm for PenToolFsmState {
910
952
911
953
let ToolMessage :: Pen ( event) = event else { return self } ;
912
954
match ( self , event) {
955
+ ( state, PenToolMessage :: ChangeToolMode ( mode) ) => {
956
+ tool_data. tool_mode = mode;
957
+ state
958
+ }
913
959
( PenToolFsmState :: PlacingAnchor | PenToolFsmState :: GRSHandle , PenToolMessage :: GRS { grab, rotate, scale } ) => {
914
960
let Some ( layer) = layer else { return PenToolFsmState :: PlacingAnchor } ;
915
961
0 commit comments