From b76147ec16e254654c83ff4fe7281510241abe4c Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Tue, 8 Mar 2022 01:27:58 +0800 Subject: [PATCH] Fix top level CanvasItem visibility The editor gizmo fix from previously reverted 642591b6a96285d70cd1fefc6b7f997a1395c07f is kept here. --- editor/plugins/canvas_item_editor_plugin.cpp | 2 +- scene/2d/canvas_item.cpp | 22 +++++++++++++------- scene/2d/canvas_item.h | 1 + scene/main/canvas_layer.cpp | 15 ++++--------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 42bad2b50af..b8699b308fb 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3756,7 +3756,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans } CanvasItem *canvas_item = Object::cast_to(p_node); - if (canvas_item && !canvas_item->is_visible()) { + if (canvas_item && !canvas_item->is_visible_in_tree()) { return; } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index e308e0a3da0..936ec558d1b 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -363,18 +363,23 @@ bool CanvasItem::is_visible_in_tree() const { p = p->get_parent_item(); } - const Node *n = get_parent(); - while (n) { - const CanvasLayer *c = Object::cast_to(n); - if (c && !c->is_visible()) { - return false; - } - n = n->get_parent(); + if (canvas_layer) { + return canvas_layer->is_visible(); } return true; } +void CanvasItem::_toplevel_visibility_changed(bool p_visible) { + VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, visible && p_visible); + + if (visible) { + _propagate_visibility_changed(p_visible); + } else { + notification(NOTIFICATION_VISIBILITY_CHANGED); + } +} + void CanvasItem::_propagate_visibility_changed(bool p_visible) { if (p_visible && first_draw) { //avoid propagating it twice first_draw = false; @@ -391,7 +396,7 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible) { for (int i = 0; i < get_child_count(); i++) { CanvasItem *c = Object::cast_to(get_child(i)); - if (c && c->visible) { //should the toplevels stop propagation? i think so but.. + if (c && c->visible && !c->toplevel) { c->_propagate_visibility_changed(p_visible); } } @@ -1062,6 +1067,7 @@ void CanvasItem::force_update_transform() { } void CanvasItem::_bind_methods() { + ClassDB::bind_method(D_METHOD("_toplevel_visibility_changed", "visible"), &CanvasItem::_toplevel_visibility_changed); ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self); ClassDB::bind_method(D_METHOD("_update_callback"), &CanvasItem::_update_callback); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 5639f6d4eb6..072b4aed1b2 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -208,6 +208,7 @@ private: mutable bool global_invalid; void _toplevel_raise_self(); + void _toplevel_visibility_changed(bool p_visible); void _propagate_visibility_changed(bool p_visible); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 3ae191d0bb7..2aa77172d4f 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -51,17 +51,10 @@ void CanvasLayer::set_visible(bool p_visible) { visible = p_visible; emit_signal("visibility_changed"); - for (int i = 0; i < get_child_count(); i++) { - CanvasItem *c = Object::cast_to(get_child(i)); - if (c) { - VisualServer::get_singleton()->canvas_item_set_visible(c->get_canvas_item(), p_visible && c->is_visible()); - - if (c->is_visible()) { - c->_propagate_visibility_changed(p_visible); - } else { - c->notification(CanvasItem::NOTIFICATION_VISIBILITY_CHANGED); - } - } + // For CanvasItems that is explicitly top level or has non-CanvasItem parents. + if (is_inside_tree()) { + const String group = "root_canvas" + itos(canvas.get_id()); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_toplevel_visibility_changed", p_visible); } }