@@ -77,24 +77,6 @@ pub enum PathToolMessage {
77
77
AlternateSelectedHandles ,
78
78
}
79
79
80
- fn handle_hint_data ( ) -> HintData {
81
- return HintData ( vec ! [
82
- HintGroup ( vec![ HintInfo :: mouse( MouseMotion :: Rmb , "" ) , HintInfo :: keys( [ Key :: Escape ] , "Cancel" ) . prepend_slash( ) ] ) ,
83
- HintGroup ( vec![
84
- // TODO: Switch this to the "S" key. Also, make the hint dynamically say "Make Colinear" or "Make Not Colinear" based on its current state. And only
85
- // TODO: show this hint if a handle (not an anchor) is being dragged, and disable that shortcut so it can't be pressed even with the hint not shown.
86
- HintInfo :: keys( [ Key :: Alt ] , "Toggle Colinear Handles" ) ,
87
- // TODO: Switch this to the "Alt" key (since it's equivalent to the "From Center" modifier when drawing a line). And show this only when a handle is being dragged.
88
- HintInfo :: keys( [ Key :: Shift ] , "Equidistant Handles" ) ,
89
- HintInfo :: keys( [ Key :: Tab ] , "Select Opposite Handles" ) , //TODO: only show when handle selected
90
- // TODO: Add "Snap 15°" modifier with the "Shift" key (only when a handle is being dragged).
91
- // TODO: Add "Lock Angle" modifier with the "Ctrl" key (only when a handle is being dragged).
92
- // TODO: Add "Snap 15°" modifier with the "Shift" key (only when a handle is being dragged).
93
- // TODO: Add "Lock Angle" modifier with the "Ctrl" key (only when a handle is being dragged).
94
- HintInfo :: keys( [ Key :: Space ] , "Drag anchor" ) ,
95
- ] ) ,
96
- ] ) ;
97
- }
98
80
impl ToolMetadata for PathTool {
99
81
fn icon_name ( & self ) -> String {
100
82
"VectorPathTool" . into ( )
@@ -191,7 +173,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PathToo
191
173
192
174
match message {
193
175
ToolMessage :: Path ( PathToolMessage :: AlternateSelectedHandles ) => {
194
- if tool_data. shape_editor . handle_selected ( ) {
176
+ if tool_data. shape_editor . handle_with_pair_selected ( & tool_data . document . network_interface ) {
195
177
tool_data. shape_editor . alternate_selected_handles ( & tool_data. document . network_interface ) ;
196
178
responses. add ( PathToolMessage :: SelectedPointUpdated ) ;
197
179
responses. add ( FrontendMessage :: UpdateMouseCursor { cursor : MouseCursorIcon :: None } ) ;
@@ -222,7 +204,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PathToo
222
204
BreakPath ,
223
205
DeleteAndBreakPath ,
224
206
) ,
225
- PathToolFsmState :: Dragging => actions ! ( PathToolMessageDiscriminant ;
207
+ PathToolFsmState :: Dragging ( _ ) => actions ! ( PathToolMessageDiscriminant ;
226
208
Escape ,
227
209
RightClick ,
228
210
FlipSmoothSharp ,
@@ -267,12 +249,25 @@ impl ToolTransition for PathTool {
267
249
}
268
250
}
269
251
}
252
+ #[ derive( Clone , Copy , Debug , Default , PartialEq , Eq ) ]
253
+ pub struct DraggingState {
254
+ point_select_state : PointSelectState ,
255
+ colinear : bool ,
256
+ }
257
+
258
+ #[ derive( Clone , Copy , Default , Debug , PartialEq , Eq ) ]
259
+ pub enum PointSelectState {
260
+ HandleWithPair ,
261
+ #[ default]
262
+ HandleNoPair ,
263
+ Anchor ,
264
+ }
270
265
271
266
#[ derive( Clone , Copy , Debug , Default , PartialEq , Eq ) ]
272
267
enum PathToolFsmState {
273
268
#[ default]
274
269
Ready ,
275
- Dragging ,
270
+ Dragging ( DraggingState ) ,
276
271
DrawingBox ,
277
272
InsertPoint ,
278
273
}
@@ -298,12 +293,13 @@ struct PathToolData {
298
293
auto_panning : AutoPanning ,
299
294
saved_points_before_anchor_select_toggle : Vec < ManipulatorPointId > ,
300
295
select_anchor_toggled : bool ,
296
+ dragging_state : DraggingState ,
301
297
}
302
298
303
299
impl PathToolData {
304
300
fn save_points_before_anchor_toggle ( & mut self , points : Vec < ManipulatorPointId > ) -> PathToolFsmState {
305
301
self . saved_points_before_anchor_select_toggle = points;
306
- PathToolFsmState :: Dragging
302
+ PathToolFsmState :: Dragging ( self . dragging_state )
307
303
}
308
304
309
305
fn remove_saved_points ( & mut self ) {
@@ -380,7 +376,7 @@ impl PathToolData {
380
376
self . start_dragging_point ( selected_points, input, document, shape_editor) ;
381
377
responses. add ( OverlaysMessage :: Draw ) ;
382
378
}
383
- PathToolFsmState :: Dragging
379
+ PathToolFsmState :: Dragging ( self . dragging_state )
384
380
}
385
381
// We didn't find a point nearby, so now we'll try to add a point into the closest path segment
386
382
else if let Some ( closed_segment) = shape_editor. upper_closest_segment ( & document. network_interface , input. mouse . position , SELECTION_TOLERANCE ) {
@@ -404,7 +400,11 @@ impl PathToolData {
404
400
shape_editor. select_connected_anchors ( document, layer, input. mouse . position ) ;
405
401
406
402
responses. add ( DocumentMessage :: StartTransaction ) ;
407
- PathToolFsmState :: Dragging
403
+ PathToolFsmState :: Dragging ( self . dragging_state )
404
+ // PathToolFsmState::Dragging {
405
+ // dragging_state: self.dragging_state,
406
+ // colinear: self.colinear,
407
+ // }
408
408
}
409
409
// Start drawing a box
410
410
else {
@@ -513,7 +513,7 @@ impl Fsm for PathToolFsmState {
513
513
514
514
overlay_context. quad ( Quad :: from_box ( [ tool_data. drag_start_pos , tool_data. previous_mouse_position ] ) , Some ( & ( "#" . to_string ( ) + & fill_color) ) ) ;
515
515
}
516
- Self :: Dragging => {
516
+ Self :: Dragging ( _ ) => {
517
517
tool_data. snap_manager . draw_overlays ( SnapData :: new ( document, input) , & mut overlay_context) ;
518
518
}
519
519
Self :: InsertPoint => {
@@ -579,7 +579,7 @@ impl Fsm for PathToolFsmState {
579
579
580
580
PathToolFsmState :: DrawingBox
581
581
}
582
- ( PathToolFsmState :: Dragging , PathToolMessage :: PointerMove { alt, shift, move_anchor_and_handles } ) => {
582
+ ( PathToolFsmState :: Dragging { .. } , PathToolMessage :: PointerMove { alt, shift, move_anchor_and_handles } ) => {
583
583
let anchor_and_handle_toggled = input. keyboard . get ( move_anchor_and_handles as usize ) ;
584
584
let initial_press = anchor_and_handle_toggled && !tool_data. select_anchor_toggled ;
585
585
let released_from_toggle = tool_data. select_anchor_toggled && !anchor_and_handle_toggled;
@@ -610,7 +610,7 @@ impl Fsm for PathToolFsmState {
610
610
] ;
611
611
tool_data. auto_panning . setup_by_mouse_position ( input, & messages, responses) ;
612
612
613
- PathToolFsmState :: Dragging
613
+ PathToolFsmState :: Dragging ( tool_data . dragging_state )
614
614
}
615
615
( PathToolFsmState :: DrawingBox , PathToolMessage :: PointerOutsideViewport { .. } ) => {
616
616
// Auto-panning
@@ -620,14 +620,14 @@ impl Fsm for PathToolFsmState {
620
620
621
621
PathToolFsmState :: DrawingBox
622
622
}
623
- ( PathToolFsmState :: Dragging , PathToolMessage :: PointerOutsideViewport { shift, .. } ) => {
623
+ ( PathToolFsmState :: Dragging ( dragging_state ) , PathToolMessage :: PointerOutsideViewport { shift, .. } ) => {
624
624
// Auto-panning
625
625
if tool_data. auto_panning . shift_viewport ( input, responses) . is_some ( ) {
626
626
let shift_state = input. keyboard . get ( shift as usize ) ;
627
627
tool_data. drag ( shift_state, shape_editor, document, input, responses) ;
628
628
}
629
629
630
- PathToolFsmState :: Dragging
630
+ PathToolFsmState :: Dragging ( dragging_state )
631
631
}
632
632
( state, PathToolMessage :: PointerOutsideViewport { alt, shift, move_anchor_and_handles } ) => {
633
633
// Auto-panning
@@ -651,7 +651,7 @@ impl Fsm for PathToolFsmState {
651
651
652
652
PathToolFsmState :: Ready
653
653
}
654
- ( PathToolFsmState :: Dragging , PathToolMessage :: Escape | PathToolMessage :: RightClick ) => {
654
+ ( PathToolFsmState :: Dragging { .. } , PathToolMessage :: Escape | PathToolMessage :: RightClick ) => {
655
655
responses. add ( DocumentMessage :: AbortTransaction ) ;
656
656
tool_data. snap_manager . cleanup ( responses) ;
657
657
PathToolFsmState :: Ready
@@ -760,10 +760,15 @@ impl Fsm for PathToolFsmState {
760
760
PathToolFsmState :: Ready
761
761
}
762
762
( _, PathToolMessage :: SelectedPointUpdated ) => {
763
- if shape_editor. handle_selected ( ) {
764
- responses. add ( FrontendMessage :: UpdateInputHints { hint_data : handle_hint_data ( ) } ) ;
765
- }
766
-
763
+ let colinear = match shape_editor. selected_manipulator_angles ( & document. network_interface ) {
764
+ ManipulatorAngle :: Colinear => true ,
765
+ ManipulatorAngle :: Free => false ,
766
+ ManipulatorAngle :: Mixed => true ,
767
+ } ;
768
+ tool_data. dragging_state = DraggingState {
769
+ point_select_state : shape_editor. get_dragging_state ( & document. network_interface ) ,
770
+ colinear,
771
+ } ;
767
772
tool_data. selection_status = get_selection_status ( & document. network_interface , shape_editor) ;
768
773
self
769
774
}
@@ -802,22 +807,40 @@ impl Fsm for PathToolFsmState {
802
807
HintInfo :: keys( [ Key :: Shift ] , "Break Anchor" ) . prepend_plus( ) ,
803
808
] ) ,
804
809
] ) ,
805
- PathToolFsmState :: Dragging => HintData ( vec ! [
806
- HintGroup ( vec![ HintInfo :: mouse( MouseMotion :: Rmb , "" ) , HintInfo :: keys( [ Key :: Escape ] , "Cancel" ) . prepend_slash( ) ] ) ,
807
- HintGroup ( vec![
808
- // TODO: Switch this to the "S" key. Also, make the hint dynamically say "Make Colinear" or "Make Not Colinear" based on its current state. And only
809
- // TODO: show this hint if a handle (not an anchor) is being dragged, and disable that shortcut so it can't be pressed even with the hint not shown.
810
- HintInfo :: keys( [ Key :: Alt ] , "Toggle Colinear Handles" ) ,
811
- // TODO: Switch this to the "Alt" key (since it's equivalent to the "From Center" modifier when drawing a line). And show this only when a handle is being dragged.
812
- HintInfo :: keys( [ Key :: Shift ] , "Equidistant Handles" ) ,
813
- // HintInfo::keys([Key::Tab], "Select Opposite Handles"), //TODO: only show when handle selected
814
- // TODO: Add "Snap 15°" modifier with the "Shift" key (only when a handle is being dragged).
815
- // TODO: Add "Lock Angle" modifier with the "Ctrl" key (only when a handle is being dragged).
816
- // TODO: Add "Snap 15°" modifier with the "Shift" key (only when a handle is being dragged).
817
- // TODO: Add "Lock Angle" modifier with the "Ctrl" key (only when a handle is being dragged).
818
- HintInfo :: keys( [ Key :: Space ] , "Drag anchor" ) ,
819
- ] ) ,
820
- ] ) ,
810
+ PathToolFsmState :: Dragging ( dragging_state) => {
811
+ let colinear = dragging_state. colinear ;
812
+ debug ! ( "STATE: {:?}" , & dragging_state) ;
813
+ let mut dragging_hint_data = HintData ( Vec :: new ( ) ) ;
814
+ dragging_hint_data
815
+ . 0
816
+ . push ( HintGroup ( vec ! [ HintInfo :: mouse( MouseMotion :: Rmb , "" ) , HintInfo :: keys( [ Key :: Escape ] , "Cancel" ) . prepend_slash( ) ] ) ) ;
817
+
818
+ let point_select_state_hint_group: HintGroup = match dragging_state. point_select_state {
819
+ PointSelectState :: HandleNoPair => HintGroup ( vec ! [ HintInfo :: keys( [ Key :: Space ] , "Drag anchor" ) ] ) ,
820
+ PointSelectState :: HandleWithPair => {
821
+ if colinear {
822
+ HintGroup ( vec ! [
823
+ HintInfo :: keys( [ Key :: Space ] , "Drag anchor" ) ,
824
+ HintInfo :: keys( [ Key :: Tab ] , "Select Opposite Handles" ) ,
825
+ HintInfo :: keys( [ Key :: Shift ] , "Equidistant Handles" ) ,
826
+ HintInfo :: keys( [ Key :: KeyV ] , "Disable Colinear Handles" ) ,
827
+ ] )
828
+ } else {
829
+ HintGroup ( vec ! [ HintInfo :: keys( [ Key :: Space ] , "Drag anchor" ) , HintInfo :: keys( [ Key :: KeyV ] , "Toggle Colinear Handles" ) ] )
830
+ }
831
+ }
832
+ PointSelectState :: Anchor => HintGroup ( vec ! [ ] ) ,
833
+ } ;
834
+
835
+ dragging_hint_data. 0 . push ( point_select_state_hint_group) ;
836
+ dragging_hint_data
837
+
838
+ // TODO: Switch this to the "Alt" key (since it's equivalent to the "From Center" modifier when drawing a line). And show this only when a handle is being dragged.
839
+ // TODO: Add "Snap 15°" modifier with the "Shift" key (only when a handle is being dragged).
840
+ // TODO: Add "Lock Angle" modifier with the "Ctrl" key (only when a handle is being dragged).
841
+ // TODO: Add "Snap 15°" modifier with the "Shift" key (only when a handle is being dragged).
842
+ // TODO: Add "Lock Angle" modifier with the "Ctrl" key (only when a handle is being dragged).
843
+ }
821
844
PathToolFsmState :: DrawingBox => HintData ( vec ! [
822
845
HintGroup ( vec![ HintInfo :: mouse( MouseMotion :: Rmb , "" ) , HintInfo :: keys( [ Key :: Escape ] , "Cancel" ) . prepend_slash( ) ] ) ,
823
846
HintGroup ( vec![
0 commit comments