Merged the functionality of BSInputEventKey to InputEventKey. This new setting can make input event keys act as if they are shortcut matched.

This commit is contained in:
Relintai 2023-06-11 16:06:09 +02:00
parent 452ec50bf7
commit 3afa1142b9
10 changed files with 104 additions and 155 deletions

View File

@ -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<InputEvent> &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;
}
////////////////////////////////////////

View File

@ -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;

View File

@ -43,6 +43,9 @@
<member name="unicode" type="int" setter="set_unicode" getter="get_unicode" default="0">
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.
</member>
<member name="action_match_force_exact" type="bool" setter="set_action_match_force_exact" getter="is_action_match_force_exact" default="false">
If [code]true[/code], the InputEvent will match exact InputActions when used as a keybind in the input singleton, similar to how ShortCuts work.
</member>
</members>
<constants>
</constants>

View File

@ -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<InputEventKey> 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<InputEventJoypadButton> jb = event;

View File

@ -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<InputEventKey> 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<InputEvent> &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventKey> 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);
}

View File

@ -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<InputEventKey> p_event);
virtual bool action_match(const Ref<InputEvent> &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

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BSInputEventKey" inherits="InputEventKey" version="3.11">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="from_input_event_key">
<return type="void" />
<argument index="0" name="event" type="InputEventKey" />
<description>
</description>
</method>
</methods>
<constants>
</constants>
</class>

View File

@ -267,7 +267,7 @@ void InputMapEditor::_press_a_key_confirm() {
if (last_wait_for_key.is_null())
return;
Ref<BSInputEventKey> ie;
Ref<InputEventKey> 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;

View File

@ -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"

View File

@ -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<TouchButton>();
ClassDB::register_class<BSInputEventKey>();
ClassDB::register_class<InputMapEditor>();
}
}