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 {