Merge pull request #107280 from kleonc/accept_dialog_bind_ok_button_visibility_to_spacer

Ensure hiding `AcceptDialog` OK button keeps other buttons centered
This commit is contained in:
Rémi Verschelde
2025-06-09 00:45:51 +02:00
2 changed files with 22 additions and 19 deletions

View File

@ -329,10 +329,10 @@ void AcceptDialog::_custom_action(const String &p_action) {
custom_action(p_action); custom_action(p_action);
} }
void AcceptDialog::_custom_button_visibility_changed(Button *button) { void AcceptDialog::_button_visibility_changed(Button *button) {
Control *right_spacer = Object::cast_to<Control>(button->get_meta("__right_spacer")); Control *bound_spacer = Object::cast_to<Control>(button->get_meta("__bound_spacer"));
if (right_spacer) { if (bound_spacer) {
right_spacer->set_visible(button->is_visible()); bound_spacer->set_visible(button->is_visible());
} }
} }
@ -340,18 +340,18 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
Button *button = memnew(Button); Button *button = memnew(Button);
button->set_text(p_text); button->set_text(p_text);
Control *right_spacer; Control *bound_spacer;
if (p_right) { if (p_right) {
buttons_hbox->add_child(button); buttons_hbox->add_child(button);
right_spacer = buttons_hbox->add_spacer(); bound_spacer = buttons_hbox->add_spacer();
} else { } else {
buttons_hbox->add_child(button); buttons_hbox->add_child(button);
buttons_hbox->move_child(button, 0); buttons_hbox->move_child(button, 0);
right_spacer = buttons_hbox->add_spacer(true); bound_spacer = buttons_hbox->add_spacer(true);
} }
button->set_meta("__right_spacer", right_spacer); button->set_meta("__bound_spacer", bound_spacer);
button->connect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_custom_button_visibility_changed).bind(button)); button->connect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_button_visibility_changed).bind(button));
child_controls_changed(); child_controls_changed();
if (is_visible()) { if (is_visible()) {
@ -383,12 +383,12 @@ void AcceptDialog::remove_button(Button *p_button) {
ERR_FAIL_COND_MSG(p_button->get_parent() != buttons_hbox, vformat("Cannot remove button %s as it does not belong to this dialog.", p_button->get_name())); ERR_FAIL_COND_MSG(p_button->get_parent() != buttons_hbox, vformat("Cannot remove button %s as it does not belong to this dialog.", p_button->get_name()));
ERR_FAIL_COND_MSG(p_button == ok_button, "Cannot remove dialog's OK button."); ERR_FAIL_COND_MSG(p_button == ok_button, "Cannot remove dialog's OK button.");
Control *right_spacer = Object::cast_to<Control>(p_button->get_meta("__right_spacer")); Control *bound_spacer = Object::cast_to<Control>(p_button->get_meta("__bound_spacer"));
if (right_spacer) { if (bound_spacer) {
ERR_FAIL_COND_MSG(right_spacer->get_parent() != buttons_hbox, vformat("Cannot remove button %s as its associated spacer does not belong to this dialog.", p_button->get_name())); ERR_FAIL_COND_MSG(bound_spacer->get_parent() != buttons_hbox, vformat("Cannot remove button %s as its associated spacer does not belong to this dialog.", p_button->get_name()));
} }
p_button->disconnect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_custom_button_visibility_changed)); p_button->disconnect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_button_visibility_changed));
if (p_button->is_connected(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action))) { if (p_button->is_connected(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action))) {
p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action)); p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action));
} }
@ -396,10 +396,10 @@ void AcceptDialog::remove_button(Button *p_button) {
p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed)); p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed));
} }
if (right_spacer) { if (bound_spacer) {
buttons_hbox->remove_child(right_spacer); buttons_hbox->remove_child(bound_spacer);
p_button->remove_meta("__right_spacer"); p_button->remove_meta("__bound_spacer");
right_spacer->queue_free(); bound_spacer->queue_free();
} }
buttons_hbox->remove_child(p_button); buttons_hbox->remove_child(p_button);
@ -486,7 +486,10 @@ AcceptDialog::AcceptDialog() {
ok_button = memnew(Button); ok_button = memnew(Button);
set_default_ok_text(ETR("OK")); set_default_ok_text(ETR("OK"));
buttons_hbox->add_child(ok_button); buttons_hbox->add_child(ok_button);
buttons_hbox->add_spacer(); // Ensure hiding OK button will hide one of the initial spacers.
Control *bound_spacer = buttons_hbox->add_spacer();
ok_button->set_meta("__bound_spacer", bound_spacer);
ok_button->connect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_button_visibility_changed).bind(ok_button));
ok_button->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_ok_pressed)); ok_button->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_ok_pressed));

View File

@ -65,7 +65,7 @@ class AcceptDialog : public Window {
} theme_cache; } theme_cache;
void _custom_action(const String &p_action); void _custom_action(const String &p_action);
void _custom_button_visibility_changed(Button *button); void _button_visibility_changed(Button *button);
void _update_child_rects(); void _update_child_rects();
void _update_ok_text(); void _update_ok_text();