From 28fa0f5d1366b1e8bc64bf8722f170fa77799090 Mon Sep 17 00:00:00 2001 From: hilfazer Date: Sat, 20 Feb 2021 10:27:03 +0100 Subject: [PATCH] Prevent selecting hidden nodes in Canvas Item Editor --- editor/plugins/canvas_item_editor_plugin.cpp | 11 ++++++----- editor/plugins/spatial_editor_plugin.cpp | 20 +++----------------- scene/main/node.cpp | 17 +++++++++++++++++ scene/main/node.h | 1 + 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 9130080481..f55e3fc2fc 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -619,9 +619,9 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel Node *node = r_items[i].item; // Make sure the selected node is in the current scene, or editable - while (node && node != get_tree()->get_edited_scene_root() && node->get_owner() != scene && !scene->is_editable_instance(node->get_owner())) { - node = node->get_parent(); - }; + if (node && node != get_tree()->get_edited_scene_root()) { + node = scene->get_deepest_editable_node(node); + } // Replace the node by the group if grouped CanvasItem *canvas_item = Object::cast_to(node); @@ -742,7 +742,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n CanvasItem *canvas_item = Object::cast_to(p_node); Node *scene = editor->get_edited_scene(); - bool editable = p_node == scene || p_node->get_owner() == scene || scene->is_editable_instance(p_node->get_owner()); + bool editable = p_node == scene || p_node->get_owner() == scene || p_node == scene->get_deepest_editable_node(p_node); bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_"); bool locked = _is_node_locked(p_node); @@ -3590,6 +3590,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans Node *scene = editor->get_edited_scene(); if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) return; + CanvasItem *canvas_item = Object::cast_to(p_node); if (canvas_item && !canvas_item->is_visible()) return; @@ -3708,7 +3709,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) { CanvasItem *canvas_item = Object::cast_to(p_node); Node *scene = editor->get_edited_scene(); - if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner()))) { + if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && canvas_item != scene->get_deepest_editable_node(canvas_item))) { return false; } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 22021831af..483dff7616 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -75,20 +75,6 @@ #define MIN_FOV 0.01 #define MAX_FOV 179 -static Node *get_deepest_visible_node(Node *start_node, Node const *edited_scene) { - Node const *iterated_item = start_node; - Node *node = start_node; - - while (iterated_item->get_owner() && iterated_item->get_owner() != edited_scene) { - if (!edited_scene->is_editable_instance(iterated_item->get_owner())) - node = iterated_item->get_owner(); - - iterated_item = iterated_item->get_owner(); - } - - return node; -} - void ViewportRotationControl::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { @@ -546,7 +532,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, continue; if (dist < closest_dist) { - item = get_deepest_visible_node(Object::cast_to(spat), edited_scene); + item = edited_scene->get_deepest_editable_node(Object::cast_to(spat)); closest = item->get_instance_id(); closest_dist = dist; @@ -701,7 +687,7 @@ void SpatialEditorViewport::_select_region() { if (!sp || _is_node_locked(sp)) continue; - Node *item = get_deepest_visible_node(Object::cast_to(sp), edited_scene); + Node *item = edited_scene->get_deepest_editable_node(Object::cast_to(sp)); // Replace the node by the group if grouped if (item->is_class("Spatial")) { @@ -1033,7 +1019,7 @@ void SpatialEditorViewport::_list_select(Ref b) { for (int i = 0; i < selection_results.size(); i++) { Spatial *item = selection_results[i].item; - if (item != scene && item->get_owner() != scene && item != get_deepest_visible_node(item, scene)) { + if (item != scene && item->get_owner() != scene && item != scene->get_deepest_editable_node(item)) { //invalid result selection_results.remove(i); i--; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 3c51e4484d..b0efe893b9 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1920,6 +1920,23 @@ bool Node::is_editable_instance(const Node *p_node) const { return p_node->data.editable_instance; } +Node *Node::get_deepest_editable_node(Node *p_start_node) const { + ERR_FAIL_NULL_V(p_start_node, nullptr); + ERR_FAIL_COND_V(!is_a_parent_of(p_start_node), nullptr); + + Node const *iterated_item = p_start_node; + Node *node = p_start_node; + + while (iterated_item->get_owner() && iterated_item->get_owner() != this) { + if (!is_editable_instance(iterated_item->get_owner())) + node = iterated_item->get_owner(); + + iterated_item = iterated_item->get_owner(); + } + + return node; +} + void Node::set_scene_instance_state(const Ref &p_state) { data.instance_state = p_state; diff --git a/scene/main/node.h b/scene/main/node.h index 5959a427b8..d63e72e62a 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -324,6 +324,7 @@ public: void set_editable_instance(Node *p_node, bool p_editable); bool is_editable_instance(const Node *p_node) const; + Node *get_deepest_editable_node(Node *start_node) const; /* NOTIFICATIONS */