Skip to content

Commit

Permalink
Merge pull request #157 from WhalesState/button-size-mode
Browse files Browse the repository at this point in the history
Add new size mode to `BaseButton`.
  • Loading branch information
jss2a98aj authored Dec 2, 2024
2 parents 73de81a + 13fcc2b commit f5b2fd6
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 8 deletions.
12 changes: 12 additions & 0 deletions doc/classes/BaseButton.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
<member name="shortcut_in_tooltip" type="bool" setter="set_shortcut_in_tooltip" getter="is_shortcut_in_tooltip_enabled" default="true">
If [code]true[/code], the button will add information about its shortcut in the tooltip.
</member>
<member name="size_mode" type="int" setter="set_size_mode" getter="get_size_mode" enum="BaseButton.SizeMode" default="0">
Allows the minimum width/height to fit each others, check [enum SizeMode] constants.
</member>
<member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" default="false">
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.
</member>
Expand Down Expand Up @@ -126,5 +129,14 @@
<constant name="ACTION_MODE_BUTTON_RELEASE" value="1" enum="ActionMode">
Require a press and a subsequent release before considering the button clicked.
</constant>
<constant name="SIZE_MODE_IGNORE" value="0" enum="SizeMode">
Ignores the size mode.
</constant>
<constant name="SIZE_MODE_FIT_WIDTH" value="1" enum="SizeMode">
The height of the button will fit it's width when resized.
</constant>
<constant name="SIZE_MODE_FIT_HEIGHT" value="2" enum="SizeMode">
The width of the button will fit it's height when resized.
</constant>
</constants>
</class>
39 changes: 38 additions & 1 deletion scene/gui/base_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,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;
}
}

Expand Down Expand Up @@ -323,6 +329,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<MouseButtonMask> p_mask) {
button_mask = p_mask;
}
Expand Down Expand Up @@ -432,6 +452,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();

Expand All @@ -453,8 +483,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);
Expand All @@ -481,6 +513,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");
Expand All @@ -499,6 +532,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);
}

Expand Down
14 changes: 13 additions & 1 deletion scene/gui/base_button.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,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,
Expand All @@ -57,14 +63,15 @@ 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;
bool press_attempt = false;
bool pressing_inside = false;

bool disabled = false;

} status;

Ref<ButtonGroup> button_group;
Expand All @@ -88,6 +95,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)
Expand Down Expand Up @@ -123,6 +131,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;

Expand All @@ -148,6 +159,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);
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/check_box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/check_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/link_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/option_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,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) {
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/texture_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit f5b2fd6

Please sign in to comment.