Skip to content

Commit

Permalink
Prevent selecting hidden nodes in Canvas Item Editor
Browse files Browse the repository at this point in the history
  • Loading branch information
hilfazer committed Feb 20, 2021
1 parent f15f5b4 commit 28fa0f5
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 22 deletions.
11 changes: 6 additions & 5 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CanvasItem>(node);
Expand Down Expand Up @@ -742,7 +742,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(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);

Expand Down Expand Up @@ -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<CanvasItem>(p_node);
if (canvas_item && !canvas_item->is_visible())
return;
Expand Down Expand Up @@ -3708,7 +3709,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) {

CanvasItem *canvas_item = Object::cast_to<CanvasItem>(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;
}

Expand Down
20 changes: 3 additions & 17 deletions editor/plugins/spatial_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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<Node>(spat), edited_scene);
item = edited_scene->get_deepest_editable_node(Object::cast_to<Node>(spat));

closest = item->get_instance_id();
closest_dist = dist;
Expand Down Expand Up @@ -701,7 +687,7 @@ void SpatialEditorViewport::_select_region() {
if (!sp || _is_node_locked(sp))
continue;

Node *item = get_deepest_visible_node(Object::cast_to<Node>(sp), edited_scene);
Node *item = edited_scene->get_deepest_editable_node(Object::cast_to<Node>(sp));

// Replace the node by the group if grouped
if (item->is_class("Spatial")) {
Expand Down Expand Up @@ -1033,7 +1019,7 @@ void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> 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--;
Expand Down
17 changes: 17 additions & 0 deletions scene/main/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<SceneState> &p_state) {

data.instance_state = p_state;
Expand Down
1 change: 1 addition & 0 deletions scene/main/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ class Node : public Object {

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 */

Expand Down

0 comments on commit 28fa0f5

Please sign in to comment.