summaryrefslogtreecommitdiff
path: root/scene/main/canvas_item.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main/canvas_item.cpp')
-rw-r--r--scene/main/canvas_item.cpp121
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();
}
}