diff options
Diffstat (limited to 'scene/main/canvas_item.cpp')
-rw-r--r-- | scene/main/canvas_item.cpp | 121 |
1 files changed, 52 insertions, 69 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 2022a9a46e..b794bbbc57 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -56,34 +56,19 @@ Transform2D CanvasItem::_edit_get_transform() const { #endif bool CanvasItem::is_visible_in_tree() const { - if (!is_inside_tree()) { - return false; - } - - const CanvasItem *p = this; - - while (p) { - if (!p->visible) { - return false; - } - if (p->window && !p->window->is_visible()) { - return false; - } - p = p->get_parent_item(); - } - - return true; + return visible && visible_in_tree; } -void CanvasItem::_propagate_visibility_changed(bool p_visible) { +void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visible) { if (p_visible && first_draw) { //avoid propagating it twice first_draw = false; } + visible_in_tree = p_visible; notification(NOTIFICATION_VISIBILITY_CHANGED); - if (p_visible) { - update(); //todo optimize - } else { + if (visible && p_visible) { + update(); + } else if (!p_visible && (visible || p_was_visible)) { emit_signal(SceneStringNames::get_singleton()->hidden); } _block(); @@ -99,34 +84,31 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible) { _unblock(); } -void CanvasItem::show() { - if (visible) { +void CanvasItem::set_visible(bool p_visible) { + if (visible == p_visible) { return; } - visible = true; - RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, true); + visible = p_visible; + RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible); if (!is_inside_tree()) { return; } - _propagate_visibility_changed(true); + _propagate_visibility_changed(p_visible, !p_visible); } -void CanvasItem::hide() { - if (!visible) { - return; - } - - visible = false; - RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, false); +void CanvasItem::show() { + set_visible(true); +} - if (!is_inside_tree()) { - return; - } +void CanvasItem::hide() { + set_visible(false); +} - _propagate_visibility_changed(false); +bool CanvasItem::is_visible() const { + return visible; } CanvasItem *CanvasItem::current_item_drawn = nullptr; @@ -142,7 +124,7 @@ void CanvasItem::_update_callback() { RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item()); //todo updating = true - only allow drawing here - if (is_visible_in_tree()) { //todo optimize this!! + if (is_visible_in_tree()) { if (first_draw) { notification(NOTIFICATION_VISIBILITY_CHANGED); first_draw = false; @@ -276,32 +258,44 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!is_inside_tree()); first_draw = true; + Node *parent = get_parent(); if (parent) { CanvasItem *ci = Object::cast_to<CanvasItem>(parent); + if (ci) { + visible_in_tree = ci->is_visible_in_tree(); C = ci->children_items.push_back(this); - } - if (!ci) { - //look for a window - Viewport *viewport = nullptr; - - while (parent) { - viewport = Object::cast_to<Viewport>(parent); - if (viewport) { - break; + } else { + CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent); + + if (cl) { + visible_in_tree = cl->is_visible(); + } else { + // Look for a window. + Viewport *viewport = nullptr; + + while (parent) { + viewport = Object::cast_to<Viewport>(parent); + if (viewport) { + break; + } + parent = parent->get_parent(); } - parent = parent->get_parent(); - } - ERR_FAIL_COND(!viewport); + ERR_FAIL_COND(!viewport); - window = Object::cast_to<Window>(viewport); - if (window) { - window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window = Object::cast_to<Window>(viewport); + if (window) { + window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + visible_in_tree = window->is_visible(); + } else { + visible_in_tree = true; + } } } } + _enter_canvas(); _update_texture_filter_changed(false); @@ -338,6 +332,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; } break; case NOTIFICATION_DRAW: case NOTIFICATION_TRANSFORM_CHANGED: { @@ -348,24 +343,12 @@ void CanvasItem::_notification(int p_what) { } } -void CanvasItem::set_visible(bool p_visible) { - if (p_visible) { - show(); - } else { - hide(); - } -} - void CanvasItem::_window_visibility_changed() { if (visible) { _propagate_visibility_changed(window->is_visible()); } } -bool CanvasItem::is_visible() const { - return visible; -} - void CanvasItem::update() { if (!is_inside_tree()) { return; @@ -1032,8 +1015,8 @@ void CanvasItem::set_notify_transform(bool p_enable) { notify_transform = p_enable; if (notify_transform && is_inside_tree()) { - //this ensures that invalid globals get resolved, so notifications can be received - get_global_transform(); + // This ensures that invalid globals get resolved, so notifications can be received. + _ALLOW_DISCARD_ get_global_transform(); } } |