Improve reliability of 2D shape editor redrawing

This commit is contained in:
kobewi 2023-04-27 02:01:51 +02:00
parent 26fb911f79
commit d8e39912f8
2 changed files with 34 additions and 72 deletions

View file

@ -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() {

View file

@ -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);