diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index e34384dd6c69..5804d3250d35 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -30,6 +30,7 @@ #include "button.h" +#include "core/core_string_names.h" #include "core/string/translation.h" #include "servers/rendering_server.h" @@ -533,8 +534,26 @@ String Button::get_language() const { } void Button::set_icon(const Ref &p_icon) { - if (icon != p_icon) { - icon = p_icon; + if (icon == p_icon) { + return; + } + + if (icon.is_valid()) { + icon->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Button::_texture_changed)); + } + + icon = p_icon; + + if (icon.is_valid()) { + icon->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Button::_texture_changed)); + } + + queue_redraw(); + update_minimum_size(); +} + +void Button::_texture_changed() { + if (icon.is_valid()) { queue_redraw(); update_minimum_size(); } diff --git a/scene/gui/button.h b/scene/gui/button.h index 792e7e24daee..4fefb9fb078f 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -96,6 +96,7 @@ class Button : public BaseButton { Size2 _fit_icon_size(const Size2 &p_size) const; void _shape(Ref p_paragraph = Ref(), String p_text = ""); + void _texture_changed(); protected: void _set_internal_margin(Side p_side, float p_value); diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index aa27a6953886..b07a3d766961 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -30,6 +30,7 @@ #include "texture_button.h" +#include "core/core_string_names.h" #include "core/typedefs.h" #include @@ -294,42 +295,19 @@ void TextureButton::_bind_methods() { } void TextureButton::set_texture_normal(const Ref &p_normal) { - if (normal == p_normal) { - return; - } - - normal = p_normal; - queue_redraw(); - update_minimum_size(); + _set_texture(&normal, p_normal); } void TextureButton::set_texture_pressed(const Ref &p_pressed) { - if (pressed == p_pressed) { - return; - } - - pressed = p_pressed; - queue_redraw(); - update_minimum_size(); + _set_texture(&pressed, p_pressed); } void TextureButton::set_texture_hover(const Ref &p_hover) { - if (hover == p_hover) { - return; - } - - hover = p_hover; - queue_redraw(); - update_minimum_size(); + _set_texture(&hover, p_hover); } void TextureButton::set_texture_disabled(const Ref &p_disabled) { - if (disabled == p_disabled) { - return; - } - - disabled = p_disabled; - queue_redraw(); + _set_texture(&disabled, p_disabled); } void TextureButton::set_click_mask(const Ref &p_click_mask) { @@ -337,8 +315,7 @@ void TextureButton::set_click_mask(const Ref &p_click_mask) { return; } click_mask = p_click_mask; - queue_redraw(); - update_minimum_size(); + _texture_changed(); } Ref TextureButton::get_texture_normal() const { @@ -369,6 +346,28 @@ void TextureButton::set_texture_focused(const Ref &p_focused) { focused = p_focused; }; +void TextureButton::_set_texture(Ref *p_destination, const Ref &p_texture) { + DEV_ASSERT(p_destination); + Ref &destination = *p_destination; + if (destination == p_texture) { + return; + } + if (destination.is_valid()) { + destination->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureButton::_texture_changed)); + } + destination = p_texture; + if (destination.is_valid()) { + // Pass `CONNECT_REFERENCE_COUNTED` to avoid early disconnect in case the same texture is assigned to different "slots". + destination->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureButton::_texture_changed), CONNECT_REFERENCE_COUNTED); + } + _texture_changed(); +} + +void TextureButton::_texture_changed() { + queue_redraw(); + update_minimum_size(); +} + bool TextureButton::get_ignore_texture_size() const { return ignore_texture_size; } diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index 270954699781..9d393d3c65b6 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -64,6 +64,9 @@ class TextureButton : public BaseButton { bool hflip = false; bool vflip = false; + void _set_texture(Ref *p_destination, const Ref &p_texture); + void _texture_changed(); + protected: virtual Size2 get_minimum_size() const override; virtual bool has_point(const Point2 &p_point) const override;