@@ -110,20 +110,25 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
110110 moving_screen_from = gpoint;
111111 return true ;
112112 } else if (mode == MODE_EDIT || mode == MODE_EDIT_CURVE) {
113+ control_points_in_range = 0 ;
113114 // In/out controls can be moved in multiple modes.
114115 if (dist_to_p_out < grab_threshold && i < (curve->get_point_count () - 1 )) {
115116 action = ACTION_MOVING_OUT;
116117 action_point = i;
117118 moving_from = curve->get_point_out (i);
118119 moving_screen_from = gpoint;
119120 orig_in_length = curve->get_point_in (action_point).length ();
120- return true ;
121- } else if (dist_to_p_in < grab_threshold && i > 0 ) {
121+ control_points_in_range += 1 ;
122+ }
123+ if (dist_to_p_in < grab_threshold && i > 0 ) {
122124 action = ACTION_MOVING_IN;
123125 action_point = i;
124126 moving_from = curve->get_point_in (i);
125127 moving_screen_from = gpoint;
126128 orig_out_length = curve->get_point_out (action_point).length ();
129+ control_points_in_range += 1 ;
130+ }
131+ if (control_points_in_range > 0 ) {
127132 return true ;
128133 }
129134 }
@@ -298,6 +303,27 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
298303 Ref<InputEventMouseMotion> mm = p_event;
299304
300305 if (mm.is_valid ()) {
306+ // When both control points were in range of click,
307+ // pick the point that drags the curve outwards.
308+ if (control_points_in_range == 2 ) {
309+ control_points_in_range = 0 ;
310+ Ref<Curve2D> curve = node->get_curve ();
311+ Transform2D xform = canvas_item_editor->get_canvas_transform () * node->get_screen_transform ();
312+ Point2 relative = xform.affine_inverse ().basis_xform (mm->get_relative ());
313+ real_t angle_in = relative.angle_to (curve->get_point_position (action_point - 1 ) - curve->get_point_position (action_point));
314+ real_t angle_out = relative.angle_to (curve->get_point_position (action_point + 1 ) - curve->get_point_position (action_point));
315+
316+ if (Math::abs (angle_in) < Math::abs (angle_out)) {
317+ action = ACTION_MOVING_IN;
318+ moving_from = curve->get_point_in (action_point);
319+ orig_out_length = curve->get_point_out (action_point).length ();
320+ } else {
321+ action = ACTION_MOVING_OUT;
322+ moving_from = curve->get_point_out (action_point);
323+ orig_in_length = curve->get_point_in (action_point).length ();
324+ }
325+ }
326+
301327 if (action == ACTION_NONE && mode == MODE_EDIT) {
302328 // Handle Edge Follow
303329 bool old_edge = on_edge;
0 commit comments