From d4ac3b6ded1dcdb5c22ad9c1c5f7b5a0cfa217f0 Mon Sep 17 00:00:00 2001 From: Ninni Pipping Date: Wed, 17 May 2023 14:49:59 +0200 Subject: [PATCH] Make `TextureButton` and `Button` update on texture change --- scene/gui/button.cpp | 23 +++++++++++++-- scene/gui/button.h | 1 + scene/gui/texture_button.cpp | 57 ++++++++++++++++++------------------ scene/gui/texture_button.h | 3 ++ 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index e34384dd6c6..5804d3250d3 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 792e7e24dae..4fefb9fb078 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -96,6 +96,7 @@ private: 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 aa27a695388..b07a3d76696 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 27095469978..9d393d3c65b 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -64,6 +64,9 @@ private: 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;