Browse Source

Fix top level CanvasItem visibility

The editor gizmo fix from previously reverted
642591b6a96285d70cd1fefc6b7f997a1395c07f is kept here.
Haoyu Qiu 3 years ago
parent
commit
b76147ec16

+ 1 - 1
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<CanvasItem>(p_node);
-	if (canvas_item && !canvas_item->is_visible()) {
+	if (canvas_item && !canvas_item->is_visible_in_tree()) {
 		return;
 	}
 

+ 14 - 8
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<CanvasLayer>(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<CanvasItem>(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);
 

+ 1 - 0
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);
 

+ 4 - 11
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<CanvasItem>(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);
 	}
 }