diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 7d484f416894..57f6a5ac8019 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -366,6 +366,8 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { /* clang-format off */ { "ui_accept", TTRC("Accept") }, { "ui_select", TTRC("Select") }, + { "ui_dialog_positive_option", TTRC("Positive Option") }, + { "ui_dialog_negative_option", TTRC("Negative Option") }, { "ui_cancel", TTRC("Cancel") }, { "ui_close_dialog", TTRC("Close Dialog") }, { "ui_focus_next", TTRC("Focus Next") }, @@ -470,6 +472,14 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::ESCAPE)); default_builtin_cache.insert("ui_cancel", inputs); + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::Y)); + default_builtin_cache.insert("ui_dialog_positive_option", inputs); + + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::N)); + default_builtin_cache.insert("ui_dialog_negative_option", inputs); + inputs = List>(); inputs.push_back(InputEventKey::create_reference(Key::ESCAPE)); default_builtin_cache.insert("ui_close_dialog", inputs); diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 7d7d05d7d618..4b323c8cfb16 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1337,6 +1337,14 @@ Default [InputEventAction] to cut a selection to the clipboard. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. + + Default [InputEventAction] to press the negative action button in a dialog box, like "discard changes." Not to be confused with cancel, which is done with [code]ui_close_dialog[/code]. + [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. + + + Default [InputEventAction] to press the positive action button in a dialog box, like "save changes" or press an "ok" button. + [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. + Default [InputEventAction] to move down in the UI. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 2a0f83be3af2..8fde6a85bd7e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -9202,6 +9202,7 @@ EditorNode::EditorNode() { confirmation = memnew(ConfirmationDialog); confirmation_button = confirmation->add_button(TTRC("Don't Save"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard"); + confirmation->set_negative_action_button(confirmation_button); gui_base->add_child(confirmation); confirmation->set_min_size(Vector2(450.0 * EDSCALE, 0)); confirmation->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_confirm_current)); @@ -9209,7 +9210,8 @@ EditorNode::EditorNode() { confirmation->connect("canceled", callable_mp(this, &EditorNode::_cancel_confirmation)); save_confirmation = memnew(ConfirmationDialog); - save_confirmation->add_button(TTRC("Don't Save"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard"); + Button *dont_save_button = save_confirmation->add_button(TTRC("Don't Save"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard"); + save_confirmation->set_negative_action_button(dont_save_button); gui_base->add_child(save_confirmation); save_confirmation->set_min_size(Vector2(450.0 * EDSCALE, 0)); save_confirmation->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_menu_confirm_current)); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index ce93ac3e8948..dbe290185305 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -340,6 +340,15 @@ void AcceptDialog::_button_visibility_changed(Button *button) { } } +Button *ConfirmationDialog::get_negative_action_button() { + return negative_action_button; +} + +void ConfirmationDialog::set_negative_action_button(Button *p_new_negative_action_button) { + negative_action_button = p_new_negative_action_button; + negative_action_button->set_shortcut(Shortcut::make_from_action("ui_dialog_negative_option")); +} + Button *AcceptDialog::add_button(const String &p_text, bool p_right, const String &p_action) { Button *button = memnew(Button); button->set_text(p_text); @@ -492,6 +501,7 @@ AcceptDialog::AcceptDialog() { buttons_hbox->add_spacer(); ok_button = memnew(Button); set_default_ok_text(ETR("OK")); + ok_button->set_shortcut(Shortcut::make_from_action("ui_dialog_positive_option")); buttons_hbox->add_child(ok_button); // Ensure hiding OK button will hide one of the initial spacers. Control *bound_spacer = buttons_hbox->add_spacer(); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 5a5a1573318b..a7d647312228 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -132,12 +132,15 @@ class AcceptDialog : public Window { class ConfirmationDialog : public AcceptDialog { GDCLASS(ConfirmationDialog, AcceptDialog); Button *cancel = nullptr; + Button *negative_action_button = nullptr; protected: static void _bind_methods(); public: Button *get_cancel_button(); + Button *get_negative_action_button(); + void set_negative_action_button(Button *p_new_negative_action_button); void set_cancel_button_text(String p_cancel_button_text); String get_cancel_button_text() const;