Browse Source

Fix invisible CanvasItem visibility issue

Markus Sauermann 3 years ago
parent
commit
dce6cb7393
3 changed files with 32 additions and 34 deletions
  1. 29 28
      scene/main/canvas_item.cpp
  2. 2 1
      scene/main/canvas_item.h
  3. 1 5
      scene/main/canvas_layer.cpp

+ 29 - 28
scene/main/canvas_item.cpp

@@ -59,35 +59,16 @@ bool CanvasItem::is_visible_in_tree() const {
 	return visible && parent_visible_in_tree;
 }
 
-void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_is_source) {
-	if (p_visible && first_draw) { // Avoid propagating it twice.
-		first_draw = false;
-	}
-	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_is_source)) {
-		emit_signal(SceneStringNames::get_singleton()->hidden);
+void CanvasItem::_propagate_visibility_changed(bool p_parent_visible_in_tree) {
+	parent_visible_in_tree = p_parent_visible_in_tree;
+	if (!visible) {
+		return;
 	}
-	_block();
-
-	for (int i = 0; i < get_child_count(); i++) {
-		CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
-
-		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;
-			}
-		}
+	if (p_parent_visible_in_tree && first_draw) { // Avoid propagating it twice.
+		first_draw = false;
 	}
 
-	_unblock();
+	_handle_visibility_change(p_parent_visible_in_tree);
 }
 
 void CanvasItem::set_visible(bool p_visible) {
@@ -96,14 +77,34 @@ void CanvasItem::set_visible(bool p_visible) {
 	}
 
 	visible = p_visible;
-	RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible);
 
 	if (!parent_visible_in_tree) {
 		notification(NOTIFICATION_VISIBILITY_CHANGED);
 		return;
 	}
 
-	_propagate_visibility_changed(p_visible, true);
+	_handle_visibility_change(p_visible);
+}
+
+void CanvasItem::_handle_visibility_change(bool p_visible) {
+	RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible);
+	notification(NOTIFICATION_VISIBILITY_CHANGED);
+
+	if (p_visible) {
+		update();
+	} else {
+		emit_signal(SceneStringNames::get_singleton()->hidden);
+	}
+
+	_block();
+	for (int i = 0; i < get_child_count(); i++) {
+		CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
+
+		if (c) { // Should the top_levels stop propagation? I think so, but...
+			c->_propagate_visibility_changed(p_visible);
+		}
+	}
+	_unblock();
 }
 
 void CanvasItem::show() {

+ 2 - 1
scene/main/canvas_item.h

@@ -108,7 +108,8 @@ private:
 
 	void _top_level_raise_self();
 
-	void _propagate_visibility_changed(bool p_visible, bool p_is_source = false);
+	void _propagate_visibility_changed(bool p_parent_visible_in_tree);
+	void _handle_visibility_change(bool p_visible);
 
 	void _update_callback();
 

+ 1 - 5
scene/main/canvas_layer.cpp

@@ -58,11 +58,7 @@ void CanvasLayer::set_visible(bool p_visible) {
 		if (c) {
 			RenderingServer::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->parent_visible_in_tree = p_visible;
-			}
+			c->_propagate_visibility_changed(p_visible);
 		}
 	}
 }