From 3a77484f7015ad59f6bffed80f56db8cc3214f60 Mon Sep 17 00:00:00 2001 From: kobewi Date: Sat, 19 Feb 2022 13:24:35 +0100 Subject: [PATCH] Fix CanvasItem visibility propagation --- editor/plugins/canvas_item_editor_plugin.cpp | 2 +- scene/main/canvas_item.cpp | 35 ++++++++++++-------- scene/main/canvas_item.h | 4 +-- scene/main/canvas_layer.cpp | 2 +- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 76558eb9463..e0bacc6083a 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3510,7 +3510,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans return; } 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/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 9ad711c5961..26b67b763c1 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -56,19 +56,21 @@ Transform2D CanvasItem::_edit_get_transform() const { #endif bool CanvasItem::is_visible_in_tree() const { - return visible && visible_in_tree; + return visible && parent_visible_in_tree; } -void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visible) { - if (p_visible && first_draw) { //avoid propagating it twice +void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_is_source) { + if (p_visible && first_draw) { // Avoid propagating it twice. first_draw = false; } - visible_in_tree = p_visible; + if (!p_is_source) { + parent_visible_in_tree = p_visible; + } notification(NOTIFICATION_VISIBILITY_CHANGED); if (visible && p_visible) { update(); - } else if (!p_visible && (visible || p_was_visible)) { + } else if (!p_visible && (visible || p_is_source)) { emit_signal(SceneStringNames::get_singleton()->hidden); } _block(); @@ -76,8 +78,12 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visibl for (int i = 0; i < get_child_count(); i++) { CanvasItem *c = Object::cast_to(get_child(i)); - if (c && c->visible) { //should the top_levels stop propagation? i think so but.. - c->_propagate_visibility_changed(p_visible); + if (c) { // Should the top_levels stop propagation? I think so, but... + if (c->visible) { + c->_propagate_visibility_changed(p_visible); + } else { + c->parent_visible_in_tree = p_visible; + } } } @@ -92,11 +98,12 @@ void CanvasItem::set_visible(bool p_visible) { visible = p_visible; RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible); - if (!is_inside_tree()) { + if (!parent_visible_in_tree) { + notification(NOTIFICATION_VISIBILITY_CHANGED); return; } - _propagate_visibility_changed(p_visible, !p_visible); + _propagate_visibility_changed(p_visible, true); } void CanvasItem::show() { @@ -264,13 +271,13 @@ void CanvasItem::_notification(int p_what) { CanvasItem *ci = Object::cast_to(parent); if (ci) { - visible_in_tree = ci->is_visible_in_tree(); + parent_visible_in_tree = ci->is_visible_in_tree(); C = ci->children_items.push_back(this); } else { CanvasLayer *cl = Object::cast_to(parent); if (cl) { - visible_in_tree = cl->is_visible(); + parent_visible_in_tree = cl->is_visible(); } else { // Look for a window. Viewport *viewport = nullptr; @@ -288,9 +295,9 @@ void CanvasItem::_notification(int p_what) { window = Object::cast_to(viewport); if (window) { window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); - visible_in_tree = window->is_visible(); + parent_visible_in_tree = window->is_visible(); } else { - visible_in_tree = true; + parent_visible_in_tree = true; } } } @@ -333,7 +340,7 @@ void CanvasItem::_notification(int p_what) { window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); } global_invalid = true; - visible_in_tree = false; + parent_visible_in_tree = false; } break; case NOTIFICATION_VISIBILITY_CHANGED: { diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 2a9e7bac3da..c0558b6be2d 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -85,7 +85,7 @@ private: Window *window = nullptr; bool first_draw = false; bool visible = true; - bool visible_in_tree = false; + bool parent_visible_in_tree = false; bool clip_children = false; bool pending_update = false; bool top_level = false; @@ -108,7 +108,7 @@ private: void _top_level_raise_self(); - void _propagate_visibility_changed(bool p_visible, bool p_was_visible = false); + void _propagate_visibility_changed(bool p_visible, bool p_is_source = false); void _update_callback(); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 6c627857fa4..be246209045 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -61,7 +61,7 @@ void CanvasLayer::set_visible(bool p_visible) { if (c->is_visible()) { c->_propagate_visibility_changed(p_visible); } else { - c->notification(CanvasItem::NOTIFICATION_VISIBILITY_CHANGED); + c->parent_visible_in_tree = p_visible; } } }