Merge pull request #24109 from remorse107/godotengine-path2d-editor-fix
Fixed Path2D Plugin Editor so segments can be split.
This commit is contained in:
commit
4d27b1fe4f
5 changed files with 96 additions and 12 deletions
|
@ -425,7 +425,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
|
|||
return true;
|
||||
} else {
|
||||
|
||||
const real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
|
||||
const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
|
||||
|
||||
if (!_is_line() && wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_threshold) {
|
||||
//wip closed
|
||||
|
@ -565,7 +565,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
|
|||
offset = _get_offset(j);
|
||||
}
|
||||
|
||||
if (!wip_active && j == edited_point.polygon && EDITOR_DEF("editors/poly_editor/show_previous_outline", true)) {
|
||||
if (!wip_active && j == edited_point.polygon && EDITOR_GET("editors/poly_editor/show_previous_outline")) {
|
||||
|
||||
const Color col = Color(0.5, 0.5, 0.5); // FIXME polygon->get_outline_color();
|
||||
const int n = pre_move_edit.size();
|
||||
|
@ -695,7 +695,7 @@ AbstractPolygon2DEditor::Vertex AbstractPolygon2DEditor::get_active_point() cons
|
|||
|
||||
AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_point(const Vector2 &p_pos) const {
|
||||
|
||||
const real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
|
||||
const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
|
||||
|
||||
const int n_polygons = _get_polygon_count();
|
||||
const Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
|
||||
|
@ -726,7 +726,7 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_point(const
|
|||
|
||||
AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(const Vector2 &p_pos) const {
|
||||
|
||||
const real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
|
||||
const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
|
||||
const real_t eps = grab_threshold * 2;
|
||||
const real_t eps2 = eps * eps;
|
||||
|
||||
|
|
|
@ -456,7 +456,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
|
|||
if (Object::cast_to<Viewport>(p_node))
|
||||
return;
|
||||
|
||||
const real_t grab_distance = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
|
||||
const real_t grab_distance = EDITOR_GET("editors/poly_editor/point_grab_radius");
|
||||
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
|
||||
|
||||
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
|
||||
|
|
|
@ -144,7 +144,7 @@ bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<Inpu
|
|||
Vector<Vector2> poly = node->call("get_polygon");
|
||||
|
||||
//first check if a point is to be added (segment split)
|
||||
real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
|
||||
real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
|
||||
|
||||
switch (mode) {
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -73,6 +73,7 @@ class Path2DEditor : public HBoxContainer {
|
|||
|
||||
bool mirror_handle_angle;
|
||||
bool mirror_handle_length;
|
||||
bool on_edge;
|
||||
|
||||
enum HandleOption {
|
||||
HANDLE_OPTION_ANGLE,
|
||||
|
@ -93,6 +94,7 @@ class Path2DEditor : public HBoxContainer {
|
|||
Point2 moving_screen_from;
|
||||
float orig_in_length;
|
||||
float orig_out_length;
|
||||
Vector2 edge_point;
|
||||
|
||||
void _mode_selected(int p_mode);
|
||||
void _handle_option_pressed(int p_option);
|
||||
|
|
Loading…
Reference in a new issue