From d8e39912f8b3e52c4003791b5ea2433cf711ae34 Mon Sep 17 00:00:00 2001 From: kobewi Date: Thu, 27 Apr 2023 02:01:51 +0200 Subject: [PATCH] Improve reliability of 2D shape editor redrawing --- .../collision_shape_2d_editor_plugin.cpp | 101 ++++++------------ .../collision_shape_2d_editor_plugin.h | 5 +- 2 files changed, 34 insertions(+), 72 deletions(-) diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 4afbb87197a..64a3346224e 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -42,6 +42,7 @@ #include "scene/resources/segment_shape_2d.h" #include "scene/resources/separation_ray_shape_2d.h" #include "scene/resources/world_boundary_shape_2d.h" +#include "scene/scene_string_names.h" void CollisionShape2DEditor::_node_removed(Node *p_node) { if (p_node == node) { @@ -129,8 +130,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } else if (idx == 1) { capsule->set_height(parameter * 2); } - - canvas_item_editor->update_viewport(); } } break; @@ -138,9 +137,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { case CIRCLE_SHAPE: { Ref circle = node->get_shape(); circle->set_radius(p_point.length()); - - canvas_item_editor->update_viewport(); - } break; case CONCAVE_POLYGON_SHAPE: { @@ -158,19 +154,13 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } else { world_boundary->set_normal(p_point.normalized()); } - - canvas_item_editor->update_viewport(); } - } break; case SEPARATION_RAY_SHAPE: { Ref ray = node->get_shape(); ray->set_length(Math::abs(p_point.y)); - - canvas_item_editor->update_viewport(); - } break; case RECTANGLE_SHAPE: { @@ -194,8 +184,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { pos += (size - (Point2)original) * 0.5 * RECT_HANDLES[idx] * 0.5; node->set_global_position(original_transform.xform(pos)); } - - canvas_item_editor->update_viewport(); } } break; @@ -209,13 +197,9 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } else if (idx == 1) { seg->set_b(p_point); } - - canvas_item_editor->update_viewport(); } - } break; } - node->get_shape()->notify_property_list_changed(); } void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { @@ -233,10 +217,8 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { } else if (idx == 1) { undo_redo->add_do_method(capsule.ptr(), "set_height", capsule->get_height()); } - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(capsule.ptr(), "set_radius", values[0]); undo_redo->add_undo_method(capsule.ptr(), "set_height", values[1]); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; @@ -244,9 +226,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { Ref circle = node->get_shape(); undo_redo->add_do_method(circle.ptr(), "set_radius", circle->get_radius()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(circle.ptr(), "set_radius", p_org); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; @@ -263,14 +243,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { if (idx == 0) { undo_redo->add_do_method(world_boundary.ptr(), "set_distance", world_boundary->get_distance()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(world_boundary.ptr(), "set_distance", p_org); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } else { undo_redo->add_do_method(world_boundary.ptr(), "set_normal", world_boundary->get_normal()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(world_boundary.ptr(), "set_normal", p_org); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } } break; @@ -279,9 +255,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { Ref ray = node->get_shape(); undo_redo->add_do_method(ray.ptr(), "set_length", ray->get_length()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(ray.ptr(), "set_length", p_org); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; @@ -290,10 +264,8 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { undo_redo->add_do_method(rect.ptr(), "set_size", rect->get_size()); undo_redo->add_do_method(node, "set_global_transform", node->get_global_transform()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(rect.ptr(), "set_size", p_org); undo_redo->add_undo_method(node, "set_global_transform", original_transform); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; @@ -301,14 +273,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { Ref seg = node->get_shape(); if (idx == 0) { undo_redo->add_do_method(seg.ptr(), "set_a", seg->get_a()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(seg.ptr(), "set_a", p_org); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } else if (idx == 1) { undo_redo->add_do_method(seg.ptr(), "set_b", seg->get_b()); - undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(seg.ptr(), "set_b", p_org); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } } break; @@ -322,10 +290,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref &p_e return false; } - if (!node->get_shape().is_valid()) { - return false; - } - if (!node->is_visible_in_tree()) { return false; } @@ -410,38 +374,44 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref &p_e return false; } -void CollisionShape2DEditor::_get_current_shape_type() { +void CollisionShape2DEditor::_shape_changed() { + canvas_item_editor->update_viewport(); + + if (current_shape.is_valid()) { + current_shape->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); + current_shape = Ref(); + shape_type = -1; + } + if (!node) { return; } - Ref s = node->get_shape(); + current_shape = node->get_shape(); - if (!s.is_valid()) { + if (current_shape.is_valid()) { + current_shape->connect(SceneStringNames::get_singleton()->changed, callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); + } else { return; } - if (Object::cast_to(*s)) { + if (Object::cast_to(*current_shape)) { shape_type = CAPSULE_SHAPE; - } else if (Object::cast_to(*s)) { + } else if (Object::cast_to(*current_shape)) { shape_type = CIRCLE_SHAPE; - } else if (Object::cast_to(*s)) { + } else if (Object::cast_to(*current_shape)) { shape_type = CONCAVE_POLYGON_SHAPE; - } else if (Object::cast_to(*s)) { + } else if (Object::cast_to(*current_shape)) { shape_type = CONVEX_POLYGON_SHAPE; - } else if (Object::cast_to(*s)) { + } else if (Object::cast_to(*current_shape)) { shape_type = WORLD_BOUNDARY_SHAPE; - } else if (Object::cast_to(*s)) { + } else if (Object::cast_to(*current_shape)) { shape_type = SEPARATION_RAY_SHAPE; - } else if (Object::cast_to(*s)) { + } else if (Object::cast_to(*current_shape)) { shape_type = RECTANGLE_SHAPE; - } else if (Object::cast_to(*s)) { + } else if (Object::cast_to(*current_shape)) { shape_type = SEGMENT_SHAPE; - } else { - shape_type = -1; } - - canvas_item_editor->update_viewport(); } void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { @@ -449,16 +419,10 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla return; } - if (!node->get_shape().is_valid()) { - return; - } - if (!node->is_visible_in_tree()) { return; } - _get_current_shape_type(); - if (shape_type == -1) { return; } @@ -559,6 +523,12 @@ void CollisionShape2DEditor::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { get_tree()->disconnect("node_removed", callable_mp(this, &CollisionShape2DEditor::_node_removed)); } break; + + case NOTIFICATION_PROCESS: { + if (node && node->get_shape() != current_shape) { + _shape_changed(); + } + } break; } } @@ -569,26 +539,17 @@ void CollisionShape2DEditor::edit(Node *p_node) { if (p_node) { node = Object::cast_to(p_node); - - _get_current_shape_type(); - + set_process(true); } else { if (pressed) { set_handle(edit_handle, original_point); pressed = false; } - edit_handle = -1; - shape_type = -1; - node = nullptr; + set_process(false); } - - canvas_item_editor->update_viewport(); -} - -void CollisionShape2DEditor::_bind_methods() { - ClassDB::bind_method("_get_current_shape_type", &CollisionShape2DEditor::_get_current_shape_type); + _shape_changed(); } CollisionShape2DEditor::CollisionShape2DEditor() { diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 9c37b6cf9de..749245ae288 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -74,16 +74,17 @@ class CollisionShape2DEditor : public Control { Vector2 original_point; Point2 last_point; + Ref current_shape; + Variant get_handle_value(int idx) const; void set_handle(int idx, Point2 &p_point); void commit_handle(int idx, Variant &p_org); - void _get_current_shape_type(); + void _shape_changed(); protected: void _notification(int p_what); void _node_removed(Node *p_node); - static void _bind_methods(); public: bool forward_canvas_gui_input(const Ref &p_event);