Skip to content

Commit b2ac089

Browse files
committed
Merge pull request godotengine#113074 from dalexeev/gui-allow-click-buttons-programmatically
GUI: Allow buttons to be pressed programmatically
2 parents 3e85a80 + fa26a01 commit b2ac089

3 files changed

Lines changed: 50 additions & 37 deletions

File tree

doc/classes/BaseButton.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
Returns [code]true[/code] if the mouse has entered the button and has not left it yet.
3535
</description>
3636
</method>
37+
<method name="press">
38+
<return type="void" />
39+
<description>
40+
Presses the button. This causes the corresponding virtual method to be called and the corresponding signal to be emitted, depending on [member toggle_mode]. If [member disabled] is [code]true[/code], nothing happens.
41+
[b]Note:[/b] This method does not change the visual state of the button and does not grab focus to the button.
42+
</description>
43+
</method>
3744
<method name="set_pressed_no_signal">
3845
<return type="void" />
3946
<param index="0" name="pressed" type="bool" />

scene/gui/base_button.cpp

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -118,23 +118,7 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
118118
}
119119

120120
void BaseButton::_accessibility_action_click(const Variant &p_data) {
121-
if (toggle_mode) {
122-
status.pressed = !status.pressed;
123-
124-
if (status.pressed) {
125-
_unpress_group();
126-
if (button_group.is_valid()) {
127-
button_group->emit_signal(SceneStringName(pressed), this);
128-
}
129-
}
130-
131-
_toggled(status.pressed);
132-
_pressed();
133-
} else {
134-
_pressed();
135-
}
136-
queue_accessibility_update();
137-
queue_redraw();
121+
press();
138122
}
139123

140124
void BaseButton::_notification(int p_what) {
@@ -260,14 +244,16 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) {
260244
status.pressing_inside = false;
261245
status.touch_index = -1; // Action completed, release matching touch so later taps aren't dropped if a modal consumes the release.
262246
}
247+
263248
status.pressed = !status.pressed;
249+
264250
_unpress_group();
265251
if (button_group.is_valid()) {
266252
button_group->emit_signal(SceneStringName(pressed), this);
267253
}
254+
268255
_toggled(status.pressed);
269256
_pressed();
270-
queue_accessibility_update();
271257
}
272258
} else {
273259
if ((p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_PRESS) || (p_event->is_released() && action_mode == ACTION_MODE_BUTTON_RELEASE)) {
@@ -285,6 +271,7 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) {
285271
}
286272
}
287273

274+
queue_accessibility_update();
288275
queue_redraw();
289276
}
290277

@@ -320,6 +307,29 @@ bool BaseButton::is_disabled() const {
320307
return status.disabled;
321308
}
322309

310+
void BaseButton::press() {
311+
if (is_disabled()) {
312+
return;
313+
}
314+
315+
if (toggle_mode) {
316+
status.pressed = !status.pressed;
317+
318+
_unpress_group();
319+
if (button_group.is_valid()) {
320+
button_group->emit_signal(SceneStringName(pressed), this);
321+
}
322+
323+
_toggled(status.pressed);
324+
_pressed();
325+
} else {
326+
_pressed();
327+
}
328+
329+
queue_accessibility_update();
330+
queue_redraw();
331+
}
332+
323333
void BaseButton::set_pressed(bool p_pressed) {
324334
bool prev_pressed = status.pressed;
325335
set_pressed_no_signal(p_pressed);
@@ -485,21 +495,7 @@ void BaseButton::shortcut_input(const Ref<InputEvent> &p_event) {
485495
ERR_FAIL_COND(p_event.is_null());
486496

487497
if (!is_disabled() && p_event->is_pressed() && is_visible_in_tree() && !p_event->is_echo() && shortcut.is_valid() && shortcut->matches_event(p_event)) {
488-
if (toggle_mode) {
489-
status.pressed = !status.pressed;
490-
491-
_unpress_group();
492-
if (button_group.is_valid()) {
493-
button_group->emit_signal(SceneStringName(pressed), this);
494-
}
495-
496-
_toggled(status.pressed);
497-
_pressed();
498-
queue_accessibility_update();
499-
} else {
500-
_pressed();
501-
}
502-
queue_redraw();
498+
press();
503499
accept_event();
504500

505501
if (shortcut_feedback && is_inside_tree()) {
@@ -590,23 +586,33 @@ PackedStringArray BaseButton::get_configuration_warnings() const {
590586
}
591587

592588
void BaseButton::_bind_methods() {
589+
ClassDB::bind_method(D_METHOD("press"), &BaseButton::press);
593590
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &BaseButton::set_pressed);
594-
ClassDB::bind_method(D_METHOD("is_pressed"), &BaseButton::is_pressed);
595591
ClassDB::bind_method(D_METHOD("set_pressed_no_signal", "pressed"), &BaseButton::set_pressed_no_signal);
592+
593+
ClassDB::bind_method(D_METHOD("is_pressed"), &BaseButton::is_pressed);
596594
ClassDB::bind_method(D_METHOD("is_hovered"), &BaseButton::is_hovered);
595+
597596
ClassDB::bind_method(D_METHOD("set_toggle_mode", "enabled"), &BaseButton::set_toggle_mode);
598597
ClassDB::bind_method(D_METHOD("is_toggle_mode"), &BaseButton::is_toggle_mode);
598+
599599
ClassDB::bind_method(D_METHOD("set_shortcut_in_tooltip", "enabled"), &BaseButton::set_shortcut_in_tooltip);
600600
ClassDB::bind_method(D_METHOD("is_shortcut_in_tooltip_enabled"), &BaseButton::is_shortcut_in_tooltip_enabled);
601+
601602
ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &BaseButton::set_disabled);
602603
ClassDB::bind_method(D_METHOD("is_disabled"), &BaseButton::is_disabled);
604+
603605
ClassDB::bind_method(D_METHOD("set_action_mode", "mode"), &BaseButton::set_action_mode);
604606
ClassDB::bind_method(D_METHOD("get_action_mode"), &BaseButton::get_action_mode);
607+
605608
ClassDB::bind_method(D_METHOD("set_button_mask", "mask"), &BaseButton::set_button_mask);
606609
ClassDB::bind_method(D_METHOD("get_button_mask"), &BaseButton::get_button_mask);
610+
607611
ClassDB::bind_method(D_METHOD("get_draw_mode"), &BaseButton::get_draw_mode);
612+
608613
ClassDB::bind_method(D_METHOD("set_keep_pressed_outside", "enabled"), &BaseButton::set_keep_pressed_outside);
609614
ClassDB::bind_method(D_METHOD("is_keep_pressed_outside"), &BaseButton::is_keep_pressed_outside);
615+
610616
ClassDB::bind_method(D_METHOD("set_shortcut_feedback", "enabled"), &BaseButton::set_shortcut_feedback);
611617
ClassDB::bind_method(D_METHOD("is_shortcut_feedback"), &BaseButton::is_shortcut_feedback);
612618

@@ -628,7 +634,7 @@ void BaseButton::_bind_methods() {
628634
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode");
629635
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "button_pressed"), "set_pressed", "is_pressed");
630636
ADD_PROPERTY(PropertyInfo(Variant::INT, "action_mode", PROPERTY_HINT_ENUM, "Button Press,Button Release"), "set_action_mode", "get_action_mode");
631-
ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask");
637+
ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left,Mouse Right,Mouse Middle"), "set_button_mask", "get_button_mask");
632638
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside");
633639
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "button_group", PROPERTY_HINT_RESOURCE_TYPE, ButtonGroup::get_class_static()), "set_button_group", "get_button_group");
634640

scene/gui/base_button.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,14 @@ class BaseButton : public Control {
109109

110110
virtual bool has_point(const Point2 &p_point) const override;
111111

112-
/* Signals */
113-
114112
bool is_pressed() const; ///< return whether button is pressed (toggled in)
115113
bool is_pressing() const; ///< return whether button is pressed (toggled in)
116114
bool is_hovered() const;
117115

116+
void press();
118117
void set_pressed(bool p_pressed); // Only works in toggle mode.
119118
void set_pressed_no_signal(bool p_pressed);
119+
120120
void set_toggle_mode(bool p_on);
121121
bool is_toggle_mode() const;
122122

0 commit comments

Comments
 (0)