Merge pull request #76492 from KoBeWi/shaped_up_nicely
Improve reliability of 2D shape editor redrawing
This commit is contained in:
commit
fc27bc0306
|
@ -42,6 +42,7 @@
|
||||||
#include "scene/resources/segment_shape_2d.h"
|
#include "scene/resources/segment_shape_2d.h"
|
||||||
#include "scene/resources/separation_ray_shape_2d.h"
|
#include "scene/resources/separation_ray_shape_2d.h"
|
||||||
#include "scene/resources/world_boundary_shape_2d.h"
|
#include "scene/resources/world_boundary_shape_2d.h"
|
||||||
|
#include "scene/scene_string_names.h"
|
||||||
|
|
||||||
void CollisionShape2DEditor::_node_removed(Node *p_node) {
|
void CollisionShape2DEditor::_node_removed(Node *p_node) {
|
||||||
if (p_node == node) {
|
if (p_node == node) {
|
||||||
|
@ -129,8 +130,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
|
||||||
} else if (idx == 1) {
|
} else if (idx == 1) {
|
||||||
capsule->set_height(parameter * 2);
|
capsule->set_height(parameter * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -138,9 +137,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
|
||||||
case CIRCLE_SHAPE: {
|
case CIRCLE_SHAPE: {
|
||||||
Ref<CircleShape2D> circle = node->get_shape();
|
Ref<CircleShape2D> circle = node->get_shape();
|
||||||
circle->set_radius(p_point.length());
|
circle->set_radius(p_point.length());
|
||||||
|
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CONCAVE_POLYGON_SHAPE: {
|
case CONCAVE_POLYGON_SHAPE: {
|
||||||
|
@ -158,19 +154,13 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
|
||||||
} else {
|
} else {
|
||||||
world_boundary->set_normal(p_point.normalized());
|
world_boundary->set_normal(p_point.normalized());
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SEPARATION_RAY_SHAPE: {
|
case SEPARATION_RAY_SHAPE: {
|
||||||
Ref<SeparationRayShape2D> ray = node->get_shape();
|
Ref<SeparationRayShape2D> ray = node->get_shape();
|
||||||
|
|
||||||
ray->set_length(Math::abs(p_point.y));
|
ray->set_length(Math::abs(p_point.y));
|
||||||
|
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case RECTANGLE_SHAPE: {
|
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;
|
pos += (size - (Point2)original) * 0.5 * RECT_HANDLES[idx] * 0.5;
|
||||||
node->set_global_position(original_transform.xform(pos));
|
node->set_global_position(original_transform.xform(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -209,13 +197,9 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
|
||||||
} else if (idx == 1) {
|
} else if (idx == 1) {
|
||||||
seg->set_b(p_point);
|
seg->set_b(p_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
node->get_shape()->notify_property_list_changed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
|
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) {
|
} else if (idx == 1) {
|
||||||
undo_redo->add_do_method(capsule.ptr(), "set_height", capsule->get_height());
|
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_radius", values[0]);
|
||||||
undo_redo->add_undo_method(capsule.ptr(), "set_height", values[1]);
|
undo_redo->add_undo_method(capsule.ptr(), "set_height", values[1]);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -244,9 +226,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
|
||||||
Ref<CircleShape2D> circle = node->get_shape();
|
Ref<CircleShape2D> circle = node->get_shape();
|
||||||
|
|
||||||
undo_redo->add_do_method(circle.ptr(), "set_radius", circle->get_radius());
|
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(circle.ptr(), "set_radius", p_org);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -263,14 +243,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
|
||||||
|
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
undo_redo->add_do_method(world_boundary.ptr(), "set_distance", world_boundary->get_distance());
|
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(world_boundary.ptr(), "set_distance", p_org);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
} else {
|
} else {
|
||||||
undo_redo->add_do_method(world_boundary.ptr(), "set_normal", world_boundary->get_normal());
|
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(world_boundary.ptr(), "set_normal", p_org);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -279,9 +255,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
|
||||||
Ref<SeparationRayShape2D> ray = node->get_shape();
|
Ref<SeparationRayShape2D> ray = node->get_shape();
|
||||||
|
|
||||||
undo_redo->add_do_method(ray.ptr(), "set_length", ray->get_length());
|
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(ray.ptr(), "set_length", p_org);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
|
|
||||||
} break;
|
} 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(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(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(rect.ptr(), "set_size", p_org);
|
||||||
undo_redo->add_undo_method(node, "set_global_transform", original_transform);
|
undo_redo->add_undo_method(node, "set_global_transform", original_transform);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -301,14 +273,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
|
||||||
Ref<SegmentShape2D> seg = node->get_shape();
|
Ref<SegmentShape2D> seg = node->get_shape();
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
undo_redo->add_do_method(seg.ptr(), "set_a", seg->get_a());
|
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(seg.ptr(), "set_a", p_org);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
} else if (idx == 1) {
|
} else if (idx == 1) {
|
||||||
undo_redo->add_do_method(seg.ptr(), "set_b", seg->get_b());
|
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(seg.ptr(), "set_b", p_org);
|
||||||
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -322,10 +290,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->get_shape().is_valid()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node->is_visible_in_tree()) {
|
if (!node->is_visible_in_tree()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -410,38 +374,44 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
|
||||||
return false;
|
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) {
|
if (!node) {
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object::cast_to<CapsuleShape2D>(*s)) {
|
if (Object::cast_to<CapsuleShape2D>(*current_shape)) {
|
||||||
shape_type = CAPSULE_SHAPE;
|
shape_type = CAPSULE_SHAPE;
|
||||||
} else if (Object::cast_to<CircleShape2D>(*s)) {
|
} else if (Object::cast_to<CircleShape2D>(*current_shape)) {
|
||||||
shape_type = CIRCLE_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;
|
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;
|
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;
|
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;
|
shape_type = SEPARATION_RAY_SHAPE;
|
||||||
} else if (Object::cast_to<RectangleShape2D>(*s)) {
|
} else if (Object::cast_to<RectangleShape2D>(*current_shape)) {
|
||||||
shape_type = RECTANGLE_SHAPE;
|
shape_type = RECTANGLE_SHAPE;
|
||||||
} else if (Object::cast_to<SegmentShape2D>(*s)) {
|
} else if (Object::cast_to<SegmentShape2D>(*current_shape)) {
|
||||||
shape_type = SEGMENT_SHAPE;
|
shape_type = SEGMENT_SHAPE;
|
||||||
} else {
|
|
||||||
shape_type = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->get_shape().is_valid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node->is_visible_in_tree()) {
|
if (!node->is_visible_in_tree()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_get_current_shape_type();
|
|
||||||
|
|
||||||
if (shape_type == -1) {
|
if (shape_type == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -559,6 +523,12 @@ void CollisionShape2DEditor::_notification(int p_what) {
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
get_tree()->disconnect("node_removed", callable_mp(this, &CollisionShape2DEditor::_node_removed));
|
get_tree()->disconnect("node_removed", callable_mp(this, &CollisionShape2DEditor::_node_removed));
|
||||||
} break;
|
} 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) {
|
if (p_node) {
|
||||||
node = Object::cast_to<CollisionShape2D>(p_node);
|
node = Object::cast_to<CollisionShape2D>(p_node);
|
||||||
|
set_process(true);
|
||||||
_get_current_shape_type();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
set_handle(edit_handle, original_point);
|
set_handle(edit_handle, original_point);
|
||||||
pressed = false;
|
pressed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
edit_handle = -1;
|
edit_handle = -1;
|
||||||
shape_type = -1;
|
|
||||||
|
|
||||||
node = nullptr;
|
node = nullptr;
|
||||||
|
set_process(false);
|
||||||
}
|
}
|
||||||
|
_shape_changed();
|
||||||
canvas_item_editor->update_viewport();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CollisionShape2DEditor::_bind_methods() {
|
|
||||||
ClassDB::bind_method("_get_current_shape_type", &CollisionShape2DEditor::_get_current_shape_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CollisionShape2DEditor::CollisionShape2DEditor() {
|
CollisionShape2DEditor::CollisionShape2DEditor() {
|
||||||
|
|
|
@ -74,16 +74,17 @@ class CollisionShape2DEditor : public Control {
|
||||||
Vector2 original_point;
|
Vector2 original_point;
|
||||||
Point2 last_point;
|
Point2 last_point;
|
||||||
|
|
||||||
|
Ref<Shape2D> current_shape;
|
||||||
|
|
||||||
Variant get_handle_value(int idx) const;
|
Variant get_handle_value(int idx) const;
|
||||||
void set_handle(int idx, Point2 &p_point);
|
void set_handle(int idx, Point2 &p_point);
|
||||||
void commit_handle(int idx, Variant &p_org);
|
void commit_handle(int idx, Variant &p_org);
|
||||||
|
|
||||||
void _get_current_shape_type();
|
void _shape_changed();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
void _node_removed(Node *p_node);
|
void _node_removed(Node *p_node);
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
|
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
|
||||||
|
|
Loading…
Reference in New Issue