diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index dfb3b464f..1a9f93c37 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -267,6 +267,13 @@ bool InputEventKey::is_echo() const { return echo; } +void InputEventKey::set_action_match_force_exact(bool p_enable) { + action_match_force_exact = p_enable; +} +bool InputEventKey::is_action_match_force_exact() const { + return action_match_force_exact; +} + uint32_t InputEventKey::get_scancode_with_modifiers() const { return scancode | get_modifiers_mask(); } @@ -309,6 +316,22 @@ bool InputEventKey::action_match(const Ref &p_event, bool p_exact_ma return false; } + if (action_match_force_exact) { + uint32_t code = get_scancode_with_modifiers(); + uint32_t event_code = key->get_scancode_with_modifiers(); + + bool match = (code == event_code); + if (match) { + if (p_pressed != NULL) { + *p_pressed = key->is_pressed(); + } + if (p_strength != NULL) { + *p_strength = (p_pressed != NULL && *p_pressed) ? 1.0f : 0.0f; + } + } + return match; + } + bool match; if (scancode != 0) { match = scancode == key->scancode; @@ -368,6 +391,9 @@ void InputEventKey::_bind_methods() { ClassDB::bind_method(D_METHOD("set_echo", "echo"), &InputEventKey::set_echo); + ClassDB::bind_method(D_METHOD("set_action_match_force_exact", "unicode"), &InputEventKey::set_action_match_force_exact); + ClassDB::bind_method(D_METHOD("is_action_match_force_exact"), &InputEventKey::is_action_match_force_exact); + ClassDB::bind_method(D_METHOD("get_scancode_with_modifiers"), &InputEventKey::get_scancode_with_modifiers); ClassDB::bind_method(D_METHOD("get_physical_scancode_with_modifiers"), &InputEventKey::get_physical_scancode_with_modifiers); @@ -376,6 +402,7 @@ void InputEventKey::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "physical_scancode"), "set_physical_scancode", "get_physical_scancode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "unicode"), "set_unicode", "get_unicode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "echo"), "set_echo", "is_echo"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "action_match_force_exact"), "set_action_match_force_exact", "is_action_match_force_exact"); } InputEventKey::InputEventKey() { @@ -383,6 +410,7 @@ InputEventKey::InputEventKey() { physical_scancode = 0; unicode = 0; ///unicode echo = false; + action_match_force_exact = false; } //////////////////////////////////////// diff --git a/core/input/input_event.h b/core/input/input_event.h index 8c2290a6e..458fd6a47 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -291,6 +291,8 @@ class InputEventKey : public InputEventWithModifiers { bool echo; /// true if this is an echo key + bool action_match_force_exact; + protected: static void _bind_methods(); @@ -309,6 +311,9 @@ public: void set_echo(bool p_enable); virtual bool is_echo() const; + void set_action_match_force_exact(bool p_enable); + bool is_action_match_force_exact() const; + uint32_t get_scancode_with_modifiers() const; uint32_t get_physical_scancode_with_modifiers() const; diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml index 813353c8a..b11247d9a 100644 --- a/doc/classes/InputEventKey.xml +++ b/doc/classes/InputEventKey.xml @@ -43,6 +43,9 @@ The key Unicode identifier (when relevant). Unicode identifiers for the composite characters and complex scripts may not be available unless IME input mode is active. See [method OS.set_ime_active] for more information. + + If [code]true[/code], the InputEvent will match exact InputActions when used as a keybind in the input singleton, similar to how ShortCuts work. + diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 41bed2ce5..7f107c003 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -30,40 +30,40 @@ #include "project_settings_editor.h" -#include "core/input/input_map.h" -#include "core/os/keyboard.h" #include "core/config/project_settings.h" -#include "core/string/translation.h" -#include "editor/editor_export.h" -#include "editor/editor_node.h" -#include "editor/editor_scale.h" -#include "scene/gui/tab_container.h" -#include "core/variant/array.h" -#include "core/object/class_db.h" -#include "core/math/color.h" -#include "core/variant/dictionary.h" +#include "core/containers/list.h" +#include "core/containers/pool_vector.h" +#include "core/containers/rb_map.h" +#include "core/containers/rb_set.h" #include "core/error/error_list.h" #include "core/error/error_macros.h" +#include "core/input/input_map.h" #include "core/io/resource_loader.h" -#include "core/containers/list.h" -#include "core/containers/rb_map.h" +#include "core/math/color.h" #include "core/math/math_defs.h" #include "core/math/rect2.h" -#include "core/os/memory.h" -#include "core/containers/pool_vector.h" -#include "core/containers/rb_set.h" -#include "core/typedefs.h" +#include "core/object/class_db.h" #include "core/object/undo_redo.h" +#include "core/os/keyboard.h" +#include "core/os/memory.h" +#include "core/string/translation.h" +#include "core/typedefs.h" +#include "core/variant/array.h" +#include "core/variant/dictionary.h" #include "editor/editor_autoload_settings.h" #include "editor/editor_data.h" +#include "editor/editor_export.h" #include "editor/editor_file_dialog.h" #include "editor/editor_inspector.h" +#include "editor/editor_node.h" #include "editor/editor_plugin_settings.h" +#include "editor/editor_scale.h" #include "editor/editor_sectioned_inspector.h" #include "editor/editor_settings.h" #include "editor/import_defaults_editor.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" +#include "scene/gui/check_button.h" #include "scene/gui/control.h" #include "scene/gui/label.h" #include "scene/gui/line_edit.h" @@ -73,10 +73,10 @@ #include "scene/gui/popup.h" #include "scene/gui/popup_menu.h" #include "scene/gui/separator.h" +#include "scene/gui/tab_container.h" #include "scene/gui/texture_rect.h" #include "scene/gui/tool_button.h" #include "scene/gui/tree.h" -#include "scene/gui/check_button.h" #include "scene/main/node.h" #include "scene/main/timer.h" @@ -292,14 +292,50 @@ void ProjectSettingsEditor::_action_edited() { String name = "input/" + ti->get_text(0); Dictionary old_action = ProjectSettings::get_singleton()->get(name); Dictionary new_action = old_action.duplicate(); - new_action["deadzone"] = ti->get_range(1); - undo_redo->create_action(TTR("Change Action deadzone")); - undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, new_action); - undo_redo->add_do_method(this, "_settings_changed"); - undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_action); - undo_redo->add_undo_method(this, "_settings_changed"); - undo_redo->commit_action(); + if (ti->get_cell_mode(1) == TreeItem::CELL_MODE_RANGE) { + new_action["deadzone"] = ti->get_range(1); + + undo_redo->create_action(TTR("Change Action deadzone")); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, new_action); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_action); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); + } else if (ti->get_cell_mode(1) == TreeItem::CELL_MODE_CHECK) { + // Edit action event + String action_prop = "input/" + ti->get_parent()->get_text(0); + + int idx = ti->get_metadata(0); + Dictionary old_val = ProjectSettings::get_singleton()->get(action_prop); + Dictionary action = old_val.duplicate(); + + Array events = action["events"].duplicate(); + ERR_FAIL_INDEX(idx, events.size()); + + Ref event = events[idx]; + + if (event.is_null()) { + return; + } + + event->set_action_match_force_exact(ti->is_checked(1)); + + action["events"] = events; + + setting = true; + undo_redo->create_action(TTR("Set Input Action Event Exact")); + undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action); + undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val); + undo_redo->add_do_method(this, "_update_actions"); + undo_redo->add_undo_method(this, "_update_actions"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); + setting = false; + + _show_last_added(event, name); + } } } @@ -825,6 +861,11 @@ void ProjectSettingsEditor::_update_actions() { } else { action2->set_icon(0, get_theme_icon("KeyboardPhysical", "EditorIcons")); } + + action2->set_cell_mode(1, TreeItem::CELL_MODE_CHECK); + action2->set_text(1, TTR("Exact")); + action2->set_checked(1, k->is_action_match_force_exact()); + action2->set_editable(1, true); } Ref jb = event; diff --git a/modules/ui_extensions/bs_input_event_key.cpp b/modules/ui_extensions/bs_input_event_key.cpp deleted file mode 100644 index 02039d1c5..000000000 --- a/modules/ui_extensions/bs_input_event_key.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright (c) 2019-2023 Péter Magyar - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "bs_input_event_key.h" - -#include "core/input/shortcut.h" - -void BSInputEventKey::from_input_event_key(const Ref event) { - set_device(event->get_device()); - - set_shift(event->get_shift()); - set_alt(event->get_alt()); - set_control(event->get_control()); - set_metakey(event->get_metakey()); - set_command(event->get_command()); - - set_pressed(event->is_pressed()); - - set_scancode(event->get_scancode()); - - set_unicode(event->get_unicode()); - set_echo(event->is_echo()); -} - -bool BSInputEventKey::action_match(const Ref &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { - Ref key = p_event; - if (key.is_null()) - return false; - - uint32_t code = get_scancode_with_modifiers(); - uint32_t event_code = key->get_scancode_with_modifiers(); - - bool match = (code == event_code); - if (match) { - if (p_pressed != NULL) - *p_pressed = key->is_pressed(); - if (p_strength != NULL) - *p_strength = (p_pressed != NULL && *p_pressed) ? 1.0f : 0.0f; - } - return match; -} - -BSInputEventKey::BSInputEventKey() { -} - -void BSInputEventKey::_bind_methods() { - ClassDB::bind_method(D_METHOD("from_input_event_key", "event"), &BSInputEventKey::from_input_event_key); -} diff --git a/modules/ui_extensions/bs_input_event_key.h b/modules/ui_extensions/bs_input_event_key.h deleted file mode 100644 index fe0cf5897..000000000 --- a/modules/ui_extensions/bs_input_event_key.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef BS_INPUT_EVENT_KEY_H -#define BS_INPUT_EVENT_KEY_H -/* -Copyright (c) 2019-2023 Péter Magyar - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "core/input/input_event.h" - -class BSInputEventKey : public InputEventKey { - GDCLASS(BSInputEventKey, InputEventKey); - -public: - void from_input_event_key(const Ref p_event); - virtual bool action_match(const Ref &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const; - - BSInputEventKey(); - -protected: - static void _bind_methods(); -}; - -#endif diff --git a/modules/ui_extensions/doc_classes/BSInputEventKey.xml b/modules/ui_extensions/doc_classes/BSInputEventKey.xml deleted file mode 100644 index abd9a834f..000000000 --- a/modules/ui_extensions/doc_classes/BSInputEventKey.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/modules/ui_extensions/input_map_editor.cpp b/modules/ui_extensions/input_map_editor.cpp index 3de29a6b2..e9556ade5 100644 --- a/modules/ui_extensions/input_map_editor.cpp +++ b/modules/ui_extensions/input_map_editor.cpp @@ -267,7 +267,7 @@ void InputMapEditor::_press_a_key_confirm() { if (last_wait_for_key.is_null()) return; - Ref ie; + Ref ie; ie.instance(); ie->set_scancode(last_wait_for_key->get_scancode()); @@ -275,6 +275,7 @@ void InputMapEditor::_press_a_key_confirm() { ie->set_alt(last_wait_for_key->get_alt()); ie->set_control(last_wait_for_key->get_control()); ie->set_metakey(last_wait_for_key->get_metakey()); + ie->set_action_match_force_exact(true); String name = add_at; int idx = edit_idx; diff --git a/modules/ui_extensions/input_map_editor.h b/modules/ui_extensions/input_map_editor.h index 9d61129f5..dbd94e0ba 100644 --- a/modules/ui_extensions/input_map_editor.h +++ b/modules/ui_extensions/input_map_editor.h @@ -30,7 +30,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "bs_input_event_key.h" #include "scene/gui/dialogs.h" #include "scene/gui/margin_container.h" #include "scene/gui/menu_button.h" diff --git a/modules/ui_extensions/register_types.cpp b/modules/ui_extensions/register_types.cpp index 4fba74785..e2753004c 100644 --- a/modules/ui_extensions/register_types.cpp +++ b/modules/ui_extensions/register_types.cpp @@ -22,7 +22,6 @@ SOFTWARE. #include "register_types.h" -#include "bs_input_event_key.h" #include "core/input/shortcut.h" #include "input_map_editor.h" #include "touch_button.h" @@ -30,7 +29,6 @@ SOFTWARE. void register_ui_extensions_types(ModuleRegistrationLevel p_level) { if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) { ClassDB::register_class(); - ClassDB::register_class(); ClassDB::register_class(); } }