summaryrefslogtreecommitdiff
path: root/editor/plugins/path_2d_editor_plugin.cpp
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2018-12-12 16:02:55 +0100
committerGitHub <noreply@github.com>2018-12-12 16:02:55 +0100
commit4d27b1fe4f5e56d53b9fcd13c08b7e2e497b2d8e (patch)
tree9ec9dc9e20dc99e1d9c6cd615d319e52ad8c9cd8 /editor/plugins/path_2d_editor_plugin.cpp
parent31349eec8e6ebf725c93b22abc3b98c03433b425 (diff)
parentbce3599bd7de6eb1bd65f5d9589b66e261d0f03c (diff)
Merge pull request #24109 from remorse107/godotengine-path2d-editor-fix
Fixed Path2D Plugin Editor so segments can be split.
Diffstat (limited to 'editor/plugins/path_2d_editor_plugin.cpp')
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp94
1 files changed, 88 insertions, 6 deletions
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index c67c96798a..3d4816b17b 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -70,8 +70,9 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node->get_curve().is_valid())
return false;
- Ref<InputEventMouseButton> mb = p_event;
+ real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
@@ -79,8 +80,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Vector2 gpoint = mb->get_position();
Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
- real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
-
if (mb->is_pressed() && action == ACTION_NONE) {
Ref<Curve2D> curve = node->get_curve();
@@ -179,6 +178,41 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return true;
}
+ // Check for segment split.
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && mode == MODE_EDIT && on_edge == true) {
+ Vector2 gpoint = mb->get_position();
+ Ref<Curve2D> curve = node->get_curve();
+
+ int insertion_point = -1;
+ float mbLength = curve->get_closest_offset(xform.affine_inverse().xform(gpoint));
+ int len = curve->get_point_count();
+ for (int i = 0; i < len - 1; i++) {
+ float compareLength = curve->get_closest_offset(curve->get_point_position(i + 1));
+ if (mbLength >= curve->get_closest_offset(curve->get_point_position(i)) && mbLength <= compareLength)
+ insertion_point = i;
+ }
+ if (insertion_point == -1)
+ insertion_point = curve->get_point_count() - 2;
+
+ undo_redo->create_action(TTR("Split Curve"));
+ undo_redo->add_do_method(curve.ptr(), "add_point", xform.affine_inverse().xform(gpoint), Vector2(0, 0), Vector2(0, 0), insertion_point + 1);
+ undo_redo->add_undo_method(curve.ptr(), "remove_point", insertion_point + 1);
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
+ undo_redo->commit_action();
+
+ action = ACTION_MOVING_POINT;
+ action_point = insertion_point + 1;
+ moving_from = curve->get_point_position(action_point);
+ moving_screen_from = gpoint;
+
+ canvas_item_editor->update_viewport();
+
+ on_edge = false;
+
+ return true;
+ }
+
// Check for point movement completion.
if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && action != ACTION_NONE) {
@@ -245,6 +279,49 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (mm.is_valid()) {
+ if (action == ACTION_NONE && mode == MODE_EDIT) {
+ // Handle Edge Follow
+ bool old_edge = on_edge;
+
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Vector2 gpoint = mm->get_position();
+
+ Ref<Curve2D> curve = node->get_curve();
+ if (curve == NULL) return true;
+ if (curve->get_point_count() < 2) return true;
+
+ // Find edge
+ edge_point = xform.xform(curve->get_closest_point(xform.affine_inverse().xform(mm->get_position())));
+ on_edge = false;
+ if (edge_point.distance_to(gpoint) <= grab_threshold) {
+ on_edge = true;
+ }
+ // However, if near a control point or its in-out handles then not on edge
+ int len = curve->get_point_count();
+ for (int i = 0; i < len; i++) {
+ Vector2 pp = curve->get_point_position(i);
+ Vector2 p = xform.xform(pp);
+ if (p.distance_to(gpoint) <= grab_threshold) {
+ on_edge = false;
+ break;
+ }
+ p = xform.xform(pp + curve->get_point_in(i));
+ if (p.distance_to(gpoint) <= grab_threshold) {
+ on_edge = false;
+ break;
+ }
+ p = xform.xform(pp + curve->get_point_out(i));
+ if (p.distance_to(gpoint) <= grab_threshold) {
+ on_edge = false;
+ break;
+ }
+ }
+ if (on_edge || old_edge != on_edge) {
+ canvas_item_editor->update_viewport();
+ return true;
+ }
+ }
+
if (action != ACTION_NONE) {
// Handle point/control movement.
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
@@ -309,7 +386,6 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Control *vpc = canvas_item_editor->get_viewport_control();
for (int i = 0; i < len; i++) {
-
Vector2 point = xform.xform(curve->get_point_position(i));
vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false, Color(1, 1, 1, 1));
@@ -325,6 +401,11 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
vpc->draw_texture_rect(handle, Rect2(pointin - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3));
}
}
+
+ if (on_edge) {
+ Ref<Texture> add_handle = get_icon("EditorHandleAdd", "EditorIcons");
+ p_overlay->draw_texture(add_handle, edge_point - add_handle->get_size() * 0.5);
+ }
}
void Path2DEditor::_node_visibility_changed() {
@@ -442,6 +523,7 @@ Path2DEditor::Path2DEditor(EditorNode *p_editor) {
undo_redo = editor->get_undo_redo();
mirror_handle_angle = true;
mirror_handle_length = true;
+ on_edge = false;
mode = MODE_EDIT;
action = ACTION_NONE;
@@ -455,7 +537,7 @@ Path2DEditor::Path2DEditor(EditorNode *p_editor) {
curve_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit", "EditorIcons"));
curve_edit->set_toggle_mode(true);
curve_edit->set_focus_mode(Control::FOCUS_NONE);
- curve_edit->set_tooltip(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Click: Add Point") + "\n" + TTR("Right Click: Delete Point"));
+ curve_edit->set_tooltip(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Click: Add Point") + "\n" + TTR("Left Click: Split Segment (in curve)") + "\n" + TTR("Right Click: Delete Point"));
curve_edit->connect("pressed", this, "_mode_selected", varray(MODE_EDIT));
base_hb->add_child(curve_edit);
curve_edit_curve = memnew(ToolButton);
@@ -469,7 +551,7 @@ Path2DEditor::Path2DEditor(EditorNode *p_editor) {
curve_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate", "EditorIcons"));
curve_create->set_toggle_mode(true);
curve_create->set_focus_mode(Control::FOCUS_NONE);
- curve_create->set_tooltip(TTR("Add Point (in empty space)") + "\n" + TTR("Split Segment (in curve)"));
+ curve_create->set_tooltip(TTR("Add Point (in empty space)"));
curve_create->connect("pressed", this, "_mode_selected", varray(MODE_CREATE));
base_hb->add_child(curve_create);
curve_del = memnew(ToolButton);