Browse Source

Improve reliability of 2D shape editor redrawing

kobewi 2 years ago
parent
commit
d8e39912f8

+ 31 - 70
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<CircleShape2D> 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<SeparationRayShape2D> 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<CircleShape2D> 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<SeparationRayShape2D> 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<SegmentShape2D> 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<InputEvent> &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<InputEvent> &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<Shape2D>();
+		shape_type = -1;
+	}
+
 	if (!node) {
 		return;
 	}
 
-	Ref<Shape2D> 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<CapsuleShape2D>(*s)) {
+	if (Object::cast_to<CapsuleShape2D>(*current_shape)) {
 		shape_type = CAPSULE_SHAPE;
-	} else if (Object::cast_to<CircleShape2D>(*s)) {
+	} else if (Object::cast_to<CircleShape2D>(*current_shape)) {
 		shape_type = CIRCLE_SHAPE;
-	} else if (Object::cast_to<ConcavePolygonShape2D>(*s)) {
+	} else if (Object::cast_to<ConcavePolygonShape2D>(*current_shape)) {
 		shape_type = CONCAVE_POLYGON_SHAPE;
-	} else if (Object::cast_to<ConvexPolygonShape2D>(*s)) {
+	} else if (Object::cast_to<ConvexPolygonShape2D>(*current_shape)) {
 		shape_type = CONVEX_POLYGON_SHAPE;
-	} else if (Object::cast_to<WorldBoundaryShape2D>(*s)) {
+	} else if (Object::cast_to<WorldBoundaryShape2D>(*current_shape)) {
 		shape_type = WORLD_BOUNDARY_SHAPE;
-	} else if (Object::cast_to<SeparationRayShape2D>(*s)) {
+	} else if (Object::cast_to<SeparationRayShape2D>(*current_shape)) {
 		shape_type = SEPARATION_RAY_SHAPE;
-	} else if (Object::cast_to<RectangleShape2D>(*s)) {
+	} else if (Object::cast_to<RectangleShape2D>(*current_shape)) {
 		shape_type = RECTANGLE_SHAPE;
-	} else if (Object::cast_to<SegmentShape2D>(*s)) {
+	} else if (Object::cast_to<SegmentShape2D>(*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<CollisionShape2D>(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() {

+ 3 - 2
editor/plugins/collision_shape_2d_editor_plugin.h

@@ -74,16 +74,17 @@ class CollisionShape2DEditor : public Control {
 	Vector2 original_point;
 	Point2 last_point;
 
+	Ref<Shape2D> 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<InputEvent> &p_event);