diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml index 18dccfa5a982..b05a9376eee5 100644 --- a/doc/classes/BaseButton.xml +++ b/doc/classes/BaseButton.xml @@ -76,6 +76,9 @@ If [code]true[/code], the button will add information about its shortcut in the tooltip. + + Allows the minimum width/height to fit each others, check [enum SizeMode] constants. + If [code]true[/code], the button is in toggle mode. Makes the button flip state between pressed and unpressed each time its area is clicked. @@ -126,5 +129,14 @@ Require a press and a subsequent release before considering the button clicked. + + Ignores the size mode. + + + The height of the button will fit it's width when resized. + + + The width of the button will fit it's height when resized. + diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 5e177772ffad..76ed5806bfa5 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -128,6 +128,12 @@ void BaseButton::_notification(int p_what) { status.press_attempt = false; status.pressing_inside = false; } break; + + case NOTIFICATION_RESIZED: { + if (size_mode != SIZE_MODE_IGNORE) { + callable_mp((Control *)this, &Control::update_minimum_size).call_deferred(); + } + } break; } } @@ -321,6 +327,20 @@ BaseButton::ActionMode BaseButton::get_action_mode() const { return action_mode; } +void BaseButton::set_size_mode(SizeMode p_size_mode) { + if (size_mode == p_size_mode) { + return; + } + size_mode = p_size_mode; + + update_minimum_size(); + queue_redraw(); +} + +BaseButton::SizeMode BaseButton::get_size_mode() const { + return size_mode; +} + void BaseButton::set_button_mask(BitField p_mask) { button_mask = p_mask; } @@ -430,6 +450,16 @@ bool BaseButton::_was_pressed_by_mouse() const { return was_mouse_pressed; } +Size2 BaseButton::_get_final_minimum_size(const Size2 &p_min_size) const { + if (size_mode == SIZE_MODE_IGNORE) { + return p_min_size; + } else if (size_mode == SIZE_MODE_FIT_HEIGHT) { + return Size2(MAX(p_min_size.width, get_size().height), p_min_size.height); + } else { // size_mode == SIZE_MODE_FIT_WIDTH + return Size2(p_min_size.width, MAX(p_min_size.height, get_size().width)); + } +} + PackedStringArray BaseButton::get_configuration_warnings() const { PackedStringArray warnings = Control::get_configuration_warnings(); @@ -451,8 +481,10 @@ void BaseButton::_bind_methods() { ClassDB::bind_method(D_METHOD("is_shortcut_in_tooltip_enabled"), &BaseButton::is_shortcut_in_tooltip_enabled); ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &BaseButton::set_disabled); ClassDB::bind_method(D_METHOD("is_disabled"), &BaseButton::is_disabled); - ClassDB::bind_method(D_METHOD("set_action_mode", "mode"), &BaseButton::set_action_mode); + ClassDB::bind_method(D_METHOD("set_action_mode", "action_mode"), &BaseButton::set_action_mode); ClassDB::bind_method(D_METHOD("get_action_mode"), &BaseButton::get_action_mode); + ClassDB::bind_method(D_METHOD("set_size_mode", "size_mode"), &BaseButton::set_size_mode); + ClassDB::bind_method(D_METHOD("get_size_mode"), &BaseButton::get_size_mode); ClassDB::bind_method(D_METHOD("set_button_mask", "mask"), &BaseButton::set_button_mask); ClassDB::bind_method(D_METHOD("get_button_mask"), &BaseButton::get_button_mask); ClassDB::bind_method(D_METHOD("get_draw_mode"), &BaseButton::get_draw_mode); @@ -479,6 +511,7 @@ void BaseButton::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "button_pressed"), "set_pressed", "is_pressed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "action_mode", PROPERTY_HINT_ENUM, "Button Press,Button Release"), "set_action_mode", "get_action_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "size_mode", PROPERTY_HINT_ENUM, "Ignore, Fit Width, Fit Height"), "set_size_mode", "get_size_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "button_group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group"); @@ -497,6 +530,10 @@ void BaseButton::_bind_methods() { BIND_ENUM_CONSTANT(ACTION_MODE_BUTTON_PRESS); BIND_ENUM_CONSTANT(ACTION_MODE_BUTTON_RELEASE); + BIND_ENUM_CONSTANT(SIZE_MODE_IGNORE); + BIND_ENUM_CONSTANT(SIZE_MODE_FIT_WIDTH); + BIND_ENUM_CONSTANT(SIZE_MODE_FIT_HEIGHT); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "gui/timers/button_shortcut_feedback_highlight_time", PROPERTY_HINT_RANGE, "0.01,10,0.01,suffix:s"), 0.2); } diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index a8d5cee44cad..2ea7570904d1 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -40,6 +40,12 @@ class BaseButton : public Control { GDCLASS(BaseButton, Control); public: + enum SizeMode { + SIZE_MODE_IGNORE, + SIZE_MODE_FIT_WIDTH, + SIZE_MODE_FIT_HEIGHT, + }; + enum ActionMode { ACTION_MODE_BUTTON_PRESS, ACTION_MODE_BUTTON_RELEASE, @@ -56,6 +62,8 @@ class BaseButton : public Control { ObjectID shortcut_context; ActionMode action_mode = ACTION_MODE_BUTTON_RELEASE; + SizeMode size_mode = SIZE_MODE_IGNORE; + struct Status { bool pressed = false; bool hovering = false; @@ -63,7 +71,6 @@ class BaseButton : public Control { bool pressing_inside = false; bool disabled = false; - } status; Ref button_group; @@ -87,6 +94,7 @@ class BaseButton : public Control { void _notification(int p_what); bool _was_pressed_by_mouse() const; + Size2 _get_final_minimum_size(const Size2 &p_min_size) const; GDVIRTUAL0(_pressed) GDVIRTUAL1(_toggled, bool) @@ -122,6 +130,9 @@ class BaseButton : public Control { void set_action_mode(ActionMode p_mode); ActionMode get_action_mode() const; + void set_size_mode(SizeMode p_size_mode); + SizeMode get_size_mode() const; + void set_keep_pressed_outside(bool p_on); bool is_keep_pressed_outside() const; @@ -147,6 +158,7 @@ class BaseButton : public Control { VARIANT_ENUM_CAST(BaseButton::DrawMode) VARIANT_ENUM_CAST(BaseButton::ActionMode) +VARIANT_ENUM_CAST(BaseButton::SizeMode) class ButtonGroup : public Resource { GDCLASS(ButtonGroup, Resource); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index dd344121e1a9..71d123ae5d9b 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -40,7 +40,7 @@ Size2 Button::get_minimum_size() const { _icon = theme_cache.icon; } - return get_minimum_size_for_text_and_icon("", _icon); + return _get_final_minimum_size(get_minimum_size_for_text_and_icon("", _icon)); } void Button::_set_internal_margin(Side p_side, float p_value) { diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 99937aaf41f0..ada51be2d605 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -77,7 +77,7 @@ Size2 CheckBox::get_minimum_size() const { minsize = content_size + padding; } - return minsize; + return _get_final_minimum_size(minsize); } void CheckBox::_notification(int p_what) { diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index 29b9504776fb..1f70b8d17d23 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -81,7 +81,7 @@ Size2 CheckButton::get_minimum_size() const { minsize = content_size + padding; } - return minsize; + return _get_final_minimum_size(minsize); } void CheckButton::_notification(int p_what) { diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 1142ba37f564..3027ec7f9aa1 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -143,7 +143,7 @@ void LinkButton::pressed() { } Size2 LinkButton::get_minimum_size() const { - return text_buf->get_size(); + return _get_final_minimum_size(text_buf->get_size()); } void LinkButton::_notification(int p_what) { diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 5432058f7b31..890c81bb9b95 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -70,7 +70,7 @@ Size2 OptionButton::get_minimum_size() const { minsize = content_size + padding; } - return minsize; + return _get_final_minimum_size(minsize); } void OptionButton::_notification(int p_what) { diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index c267ff93c6f9..6244d7cc9b4d 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -58,7 +58,7 @@ Size2 TextureButton::get_minimum_size() const { } } - return rscale.abs(); + return _get_final_minimum_size(rscale.abs()); } bool TextureButton::has_point(const Point2 &p_point) const {