Merge pull request #58870 from timothyqiu/canvas-item-visibility-3.x

This commit is contained in:
Rémi Verschelde 2022-03-07 20:49:11 +01:00 committed by GitHub
commit 927dd95b27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 43 deletions

View File

@ -350,21 +350,45 @@ Transform2D CanvasItem::_edit_get_transform() const {
#endif
bool CanvasItem::is_visible_in_tree() const {
return visible && parent_visible_in_tree;
if (!is_inside_tree()) {
return false;
}
const CanvasItem *p = this;
while (p) {
if (!p->visible) {
return false;
}
p = p->get_parent_item();
}
if (canvas_layer) {
return canvas_layer->is_visible();
}
return true;
}
void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_is_source) {
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;
}
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)) {
if (p_visible) {
update(); // Todo optimize.
} else {
emit_signal(SceneStringNames::get_singleton()->hide);
}
_block();
@ -372,12 +396,8 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_is_source)
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 (c && c->visible && !c->toplevel) {
c->_propagate_visibility_changed(p_visible);
}
}
@ -392,14 +412,11 @@ void CanvasItem::set_visible(bool p_visible) {
visible = p_visible;
VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible);
if (!parent_visible_in_tree) {
if (is_inside_tree()) {
notification(NOTIFICATION_VISIBILITY_CHANGED);
}
if (!is_inside_tree()) {
return;
}
_propagate_visibility_changed(p_visible, true);
_propagate_visibility_changed(p_visible);
_change_notify("visible");
}
@ -428,7 +445,7 @@ void CanvasItem::_update_callback() {
VisualServer::get_singleton()->canvas_item_clear(get_canvas_item());
//todo updating = true - only allow drawing here
if (is_visible_in_tree()) {
if (is_visible_in_tree()) { // Todo optimize this!!
if (first_draw) {
notification(NOTIFICATION_VISIBILITY_CHANGED);
first_draw = false;
@ -554,15 +571,7 @@ void CanvasItem::_notification(int p_what) {
if (parent) {
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
if (ci) {
parent_visible_in_tree = ci->is_visible_in_tree();
C = ci->children_items.push_back(this);
} else {
CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent);
if (cl) {
parent_visible_in_tree = cl->is_visible();
} else {
parent_visible_in_tree = true;
}
}
}
_enter_canvas();
@ -594,7 +603,6 @@ void CanvasItem::_notification(int p_what) {
C = nullptr;
}
global_invalid = true;
parent_visible_in_tree = false;
} break;
case NOTIFICATION_DRAW:
case NOTIFICATION_TRANSFORM_CHANGED: {
@ -1059,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);
@ -1260,7 +1269,6 @@ CanvasItem::CanvasItem() :
xform_change(this) {
canvas_item = RID_PRIME(VisualServer::get_singleton()->canvas_item_create());
visible = true;
parent_visible_in_tree = false;
pending_update = false;
modulate = Color(1, 1, 1, 1);
self_modulate = Color(1, 1, 1, 1);

View File

@ -193,7 +193,6 @@ private:
bool first_draw;
bool visible;
bool parent_visible_in_tree;
bool pending_update;
bool toplevel;
bool drawing;
@ -209,8 +208,9 @@ private:
mutable bool global_invalid;
void _toplevel_raise_self();
void _toplevel_visibility_changed(bool p_visible);
void _propagate_visibility_changed(bool p_visible, bool p_is_source = false);
void _propagate_visibility_changed(bool p_visible);
void _update_callback();

View File

@ -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->parent_visible_in_tree = p_visible;
}
}
// 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);
}
}