mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 03:18:37 +08:00
Un-defer the initial theme changed notification
Co-authored-by: Rindbee <idleman@yeah.net>
This commit is contained in:
parent
ddc55ef746
commit
8b128081e8
@ -2789,21 +2789,6 @@ Control *Control::make_custom_tooltip(const String &p_text) const {
|
|||||||
|
|
||||||
// Base object overrides.
|
// Base object overrides.
|
||||||
|
|
||||||
void Control::add_child_notify(Node *p_child) {
|
|
||||||
// We propagate when this node uses a custom theme, so it can pass it on to its children.
|
|
||||||
if (has_theme_owner_node()) {
|
|
||||||
// `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`.
|
|
||||||
data.theme_owner->propagate_theme_changed(p_child, get_theme_owner_node(), false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Control::remove_child_notify(Node *p_child) {
|
|
||||||
// If the removed child isn't inheriting any theme items through this node, then there's no need to propagate.
|
|
||||||
if (has_theme_owner_node()) {
|
|
||||||
data.theme_owner->propagate_theme_changed(p_child, nullptr, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Control::_notification(int p_notification) {
|
void Control::_notification(int p_notification) {
|
||||||
switch (p_notification) {
|
switch (p_notification) {
|
||||||
case NOTIFICATION_POSTINITIALIZE: {
|
case NOTIFICATION_POSTINITIALIZE: {
|
||||||
@ -2811,10 +2796,16 @@ void Control::_notification(int p_notification) {
|
|||||||
_update_theme_item_cache();
|
_update_theme_item_cache();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_PARENTED: {
|
||||||
|
data.theme_owner->assign_theme_on_parented(this);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_UNPARENTED: {
|
||||||
|
data.theme_owner->clear_theme_on_unparented(this);
|
||||||
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
// Need to defer here, because theme owner information might be set in
|
notification(NOTIFICATION_THEME_CHANGED);
|
||||||
// add_child_notify, which doesn't get called until right after this.
|
|
||||||
call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_POST_ENTER_TREE: {
|
case NOTIFICATION_POST_ENTER_TREE: {
|
||||||
|
@ -327,9 +327,6 @@ protected:
|
|||||||
|
|
||||||
// Base object overrides.
|
// Base object overrides.
|
||||||
|
|
||||||
virtual void add_child_notify(Node *p_child) override;
|
|
||||||
virtual void remove_child_notify(Node *p_child) override;
|
|
||||||
|
|
||||||
void _notification(int p_notification);
|
void _notification(int p_notification);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
@ -805,6 +805,14 @@ void Window::_notification(int p_what) {
|
|||||||
_update_theme_item_cache();
|
_update_theme_item_cache();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_PARENTED: {
|
||||||
|
theme_owner->assign_theme_on_parented(this);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_UNPARENTED: {
|
||||||
|
theme_owner->clear_theme_on_unparented(this);
|
||||||
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
bool embedded = false;
|
bool embedded = false;
|
||||||
{
|
{
|
||||||
@ -1290,23 +1298,12 @@ Rect2i Window::get_usable_parent_rect() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Window::add_child_notify(Node *p_child) {
|
void Window::add_child_notify(Node *p_child) {
|
||||||
// We propagate when this node uses a custom theme, so it can pass it on to its children.
|
|
||||||
if (has_theme_owner_node()) {
|
|
||||||
// `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`.
|
|
||||||
theme_owner->propagate_theme_changed(p_child, get_theme_owner_node(), false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_inside_tree() && wrap_controls) {
|
if (is_inside_tree() && wrap_controls) {
|
||||||
child_controls_changed();
|
child_controls_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::remove_child_notify(Node *p_child) {
|
void Window::remove_child_notify(Node *p_child) {
|
||||||
// If the removed child isn't inheriting any theme items through this node, then there's no need to propagate.
|
|
||||||
if (has_theme_owner_node()) {
|
|
||||||
theme_owner->propagate_theme_changed(p_child, nullptr, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_inside_tree() && wrap_controls) {
|
if (is_inside_tree() && wrap_controls) {
|
||||||
child_controls_changed();
|
child_controls_changed();
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,43 @@ bool ThemeOwner::has_owner_node() const {
|
|||||||
|
|
||||||
// Theme propagation.
|
// Theme propagation.
|
||||||
|
|
||||||
|
void ThemeOwner::assign_theme_on_parented(Node *p_for_node) {
|
||||||
|
// We check if there are any themes affecting the parent. If that's the case
|
||||||
|
// its children also need to be affected.
|
||||||
|
// We don't notify here because `NOTIFICATION_THEME_CHANGED` will be handled
|
||||||
|
// a bit later by `NOTIFICATION_ENTER_TREE`.
|
||||||
|
|
||||||
|
Node *parent = p_for_node->get_parent();
|
||||||
|
|
||||||
|
Control *parent_c = Object::cast_to<Control>(parent);
|
||||||
|
if (parent_c && parent_c->has_theme_owner_node()) {
|
||||||
|
propagate_theme_changed(p_for_node, parent_c->get_theme_owner_node(), false, true);
|
||||||
|
} else {
|
||||||
|
Window *parent_w = Object::cast_to<Window>(parent);
|
||||||
|
if (parent_w && parent_w->has_theme_owner_node()) {
|
||||||
|
propagate_theme_changed(p_for_node, parent_w->get_theme_owner_node(), false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeOwner::clear_theme_on_unparented(Node *p_for_node) {
|
||||||
|
// We check if there were any themes affecting the parent. If that's the case
|
||||||
|
// its children need were also affected and need to be updated.
|
||||||
|
// We don't notify because we're exiting the tree, and it's not important.
|
||||||
|
|
||||||
|
Node *parent = p_for_node->get_parent();
|
||||||
|
|
||||||
|
Control *parent_c = Object::cast_to<Control>(parent);
|
||||||
|
if (parent_c && parent_c->has_theme_owner_node()) {
|
||||||
|
propagate_theme_changed(p_for_node, nullptr, false, true);
|
||||||
|
} else {
|
||||||
|
Window *parent_w = Object::cast_to<Window>(parent);
|
||||||
|
if (parent_w && parent_w->has_theme_owner_node()) {
|
||||||
|
propagate_theme_changed(p_for_node, nullptr, false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ThemeOwner::propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign) {
|
void ThemeOwner::propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign) {
|
||||||
Control *c = Object::cast_to<Control>(p_to_node);
|
Control *c = Object::cast_to<Control>(p_to_node);
|
||||||
Window *w = c == nullptr ? Object::cast_to<Window>(p_to_node) : nullptr;
|
Window *w = c == nullptr ? Object::cast_to<Window>(p_to_node) : nullptr;
|
||||||
|
@ -53,6 +53,8 @@ public:
|
|||||||
|
|
||||||
// Theme propagation.
|
// Theme propagation.
|
||||||
|
|
||||||
|
void assign_theme_on_parented(Node *p_for_node);
|
||||||
|
void clear_theme_on_unparented(Node *p_for_node);
|
||||||
void propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign);
|
void propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bool p_notify, bool p_assign);
|
||||||
|
|
||||||
// Theme lookup.
|
// Theme lookup.
|
||||||
|
Loading…
Reference in New Issue
Block a user