Rework CanvasItem visibility propagation
This commit is contained in:
parent
9d1626b4d7
commit
ab5b5e1577
@ -56,43 +56,19 @@ Transform2D CanvasItem::_edit_get_transform() const {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool CanvasItem::is_visible_in_tree() const {
|
bool CanvasItem::is_visible_in_tree() const {
|
||||||
if (!is_inside_tree()) {
|
return visible && visible_in_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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
if (p_visible && first_draw) { //avoid propagating it twice
|
||||||
first_draw = false;
|
first_draw = false;
|
||||||
}
|
}
|
||||||
|
visible_in_tree = p_visible;
|
||||||
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
||||||
|
|
||||||
if (p_visible) {
|
if (visible && p_visible) {
|
||||||
update(); //todo optimize
|
update();
|
||||||
} else {
|
} else if (!p_visible && (visible || p_was_visible)) {
|
||||||
emit_signal(SceneStringNames::get_singleton()->hidden);
|
emit_signal(SceneStringNames::get_singleton()->hidden);
|
||||||
}
|
}
|
||||||
_block();
|
_block();
|
||||||
@ -120,7 +96,7 @@ void CanvasItem::set_visible(bool p_visible) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_propagate_visibility_changed(p_visible);
|
_propagate_visibility_changed(p_visible, !p_visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasItem::show() {
|
void CanvasItem::show() {
|
||||||
@ -148,7 +124,7 @@ void CanvasItem::_update_callback() {
|
|||||||
|
|
||||||
RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item());
|
RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item());
|
||||||
//todo updating = true - only allow drawing here
|
//todo updating = true - only allow drawing here
|
||||||
if (is_visible_in_tree()) { //todo optimize this!!
|
if (is_visible_in_tree()) {
|
||||||
if (first_draw) {
|
if (first_draw) {
|
||||||
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
||||||
first_draw = false;
|
first_draw = false;
|
||||||
@ -282,32 +258,44 @@ void CanvasItem::_notification(int p_what) {
|
|||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
ERR_FAIL_COND(!is_inside_tree());
|
ERR_FAIL_COND(!is_inside_tree());
|
||||||
first_draw = true;
|
first_draw = true;
|
||||||
|
|
||||||
Node *parent = get_parent();
|
Node *parent = get_parent();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
|
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
|
||||||
|
|
||||||
if (ci) {
|
if (ci) {
|
||||||
|
visible_in_tree = ci->is_visible_in_tree();
|
||||||
C = ci->children_items.push_back(this);
|
C = ci->children_items.push_back(this);
|
||||||
}
|
} else {
|
||||||
if (!ci) {
|
CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent);
|
||||||
//look for a window
|
|
||||||
Viewport *viewport = nullptr;
|
|
||||||
|
|
||||||
while (parent) {
|
if (cl) {
|
||||||
viewport = Object::cast_to<Viewport>(parent);
|
visible_in_tree = cl->is_visible();
|
||||||
if (viewport) {
|
} else {
|
||||||
break;
|
// 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);
|
window = Object::cast_to<Window>(viewport);
|
||||||
if (window) {
|
if (window) {
|
||||||
window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
|
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();
|
_enter_canvas();
|
||||||
|
|
||||||
_update_texture_filter_changed(false);
|
_update_texture_filter_changed(false);
|
||||||
@ -344,6 +332,7 @@ void CanvasItem::_notification(int p_what) {
|
|||||||
window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
|
window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
|
||||||
}
|
}
|
||||||
global_invalid = true;
|
global_invalid = true;
|
||||||
|
visible_in_tree = false;
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_DRAW:
|
case NOTIFICATION_DRAW:
|
||||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
|
@ -87,6 +87,7 @@ private:
|
|||||||
Window *window = nullptr;
|
Window *window = nullptr;
|
||||||
bool first_draw = false;
|
bool first_draw = false;
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
|
bool visible_in_tree = false;
|
||||||
bool clip_children = false;
|
bool clip_children = false;
|
||||||
bool pending_update = false;
|
bool pending_update = false;
|
||||||
bool top_level = false;
|
bool top_level = false;
|
||||||
@ -109,7 +110,7 @@ private:
|
|||||||
|
|
||||||
void _top_level_raise_self();
|
void _top_level_raise_self();
|
||||||
|
|
||||||
void _propagate_visibility_changed(bool p_visible);
|
void _propagate_visibility_changed(bool p_visible, bool p_was_visible = false);
|
||||||
|
|
||||||
void _update_callback();
|
void _update_callback();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user