From 7104229a85acbc30bf5dcc9c8a0ada8571910456 Mon Sep 17 00:00:00 2001 From: Marcel Admiraal Date: Thu, 13 May 2021 18:13:24 +0100 Subject: [PATCH] Fix InputMap.action_erase_event() failing to erase events correctly. --- core/input/input_event.cpp | 85 +++++++++++++++++-------------- core/input/input_event.h | 16 ++++-- core/input/input_map.cpp | 5 +- doc/classes/InputEvent.xml | 15 +++--- editor/editor_settings.cpp | 2 +- editor/settings_config_dialog.cpp | 2 +- scene/gui/shortcut.cpp | 2 +- 7 files changed, 71 insertions(+), 56 deletions(-) diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 6f063c217f25..9b962ff37c57 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -88,7 +88,7 @@ bool InputEvent::action_match(const Ref &p_event, bool *p_pressed, f return false; } -bool InputEvent::shortcut_match(const Ref &p_event) const { +bool InputEvent::is_match(const Ref &p_event, bool p_exact_match) const { return false; } @@ -110,7 +110,7 @@ void InputEvent::_bind_methods() { ClassDB::bind_method(D_METHOD("as_text"), &InputEvent::as_text); - ClassDB::bind_method(D_METHOD("shortcut_match", "event"), &InputEvent::shortcut_match); + ClassDB::bind_method(D_METHOD("is_match", "event", "exact_match"), &InputEvent::is_match, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type); @@ -194,6 +194,23 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif set_meta_pressed(event->is_meta_pressed()); } +uint32_t InputEventWithModifiers::get_modifiers_mask() const { + uint32_t mask = 0; + if (is_ctrl_pressed()) { + mask |= KEY_MASK_CTRL; + } + if (is_shift_pressed()) { + mask |= KEY_MASK_SHIFT; + } + if (is_alt_pressed()) { + mask |= KEY_MASK_ALT; + } + if (is_meta_pressed()) { + mask |= KEY_MASK_META; + } + return mask; +} + String InputEventWithModifiers::as_text() const { Vector mod_names; @@ -313,39 +330,11 @@ bool InputEventKey::is_echo() const { } uint32_t InputEventKey::get_keycode_with_modifiers() const { - uint32_t sc = keycode; - if (is_ctrl_pressed()) { - sc |= KEY_MASK_CTRL; - } - if (is_alt_pressed()) { - sc |= KEY_MASK_ALT; - } - if (is_shift_pressed()) { - sc |= KEY_MASK_SHIFT; - } - if (is_meta_pressed()) { - sc |= KEY_MASK_META; - } - - return sc; + return keycode | get_modifiers_mask(); } uint32_t InputEventKey::get_physical_keycode_with_modifiers() const { - uint32_t sc = physical_keycode; - if (is_ctrl_pressed()) { - sc |= KEY_MASK_CTRL; - } - if (is_alt_pressed()) { - sc |= KEY_MASK_ALT; - } - if (is_shift_pressed()) { - sc |= KEY_MASK_SHIFT; - } - if (is_meta_pressed()) { - sc |= KEY_MASK_META; - } - - return sc; + return physical_keycode | get_modifiers_mask(); } String InputEventKey::as_text() const { @@ -442,16 +431,14 @@ bool InputEventKey::action_match(const Ref &p_event, bool *p_pressed return match; } -bool InputEventKey::shortcut_match(const Ref &p_event) const { +bool InputEventKey::is_match(const Ref &p_event, bool p_exact_match) const { Ref key = p_event; if (key.is_null()) { return false; } - uint32_t code = get_keycode_with_modifiers(); - uint32_t event_code = key->get_keycode_with_modifiers(); - - return code == event_code; + return keycode == key->keycode && + (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); } void InputEventKey::_bind_methods() { @@ -599,6 +586,16 @@ bool InputEventMouseButton::action_match(const Ref &p_event, bool *p return match; } +bool InputEventMouseButton::is_match(const Ref &p_event, bool p_exact_match) const { + Ref mb = p_event; + if (mb.is_null()) { + return false; + } + + return button_index == mb->button_index && + (!p_exact_match || get_modifiers_mask() == mb->get_modifiers_mask()); +} + static const char *_mouse_button_descriptions[9] = { TTRC("Left Mouse Button"), TTRC("Right Mouse Button"), @@ -904,6 +901,16 @@ bool InputEventJoypadMotion::action_match(const Ref &p_event, bool * return match; } +bool InputEventJoypadMotion::is_match(const Ref &p_event, bool p_exact_match) const { + Ref jm = p_event; + if (jm.is_null()) { + return false; + } + + return axis == jm->axis && + (!p_exact_match || ((axis_value < 0) == (jm->axis_value < 0))); +} + static const char *_joy_axis_descriptions[JOY_AXIS_MAX] = { TTRC("Left Stick X-Axis, Joystick 0 X-Axis"), TTRC("Left Stick Y-Axis, Joystick 0 Y-Axis"), @@ -987,7 +994,7 @@ bool InputEventJoypadButton::action_match(const Ref &p_event, bool * return match; } -bool InputEventJoypadButton::shortcut_match(const Ref &p_event) const { +bool InputEventJoypadButton::is_match(const Ref &p_event, bool p_exact_match) const { Ref button = p_event; if (button.is_null()) { return false; @@ -1229,7 +1236,7 @@ float InputEventAction::get_strength() const { return strength; } -bool InputEventAction::shortcut_match(const Ref &p_event) const { +bool InputEventAction::is_match(const Ref &p_event, bool p_exact_match) const { if (p_event.is_null()) { return false; } diff --git a/core/input/input_event.h b/core/input/input_event.h index eed0d79326ae..3ef135221ddd 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -142,7 +142,8 @@ class InputEvent : public Resource { virtual Ref xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const; - virtual bool shortcut_match(const Ref &p_event) const; + virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const; + virtual bool is_action_type() const; virtual bool accumulate(const Ref &p_event) { return false; } @@ -212,6 +213,8 @@ class InputEventWithModifiers : public InputEventFromWindow { void set_modifiers_from_event(const InputEventWithModifiers *event); + uint32_t get_modifiers_mask() const; + virtual String as_text() const override; virtual String to_string() override; @@ -252,7 +255,7 @@ class InputEventKey : public InputEventWithModifiers { uint32_t get_physical_keycode_with_modifiers() const; virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; - virtual bool shortcut_match(const Ref &p_event) const override; + virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } @@ -313,7 +316,9 @@ class InputEventMouseButton : public InputEventMouse { bool is_double_click() const; virtual Ref xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; + virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } virtual String as_text() const override; @@ -373,6 +378,7 @@ class InputEventJoypadMotion : public InputEvent { virtual bool is_pressed() const override; virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } virtual String as_text() const override; @@ -401,9 +407,10 @@ class InputEventJoypadButton : public InputEvent { float get_pressure() const; virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; - virtual bool shortcut_match(const Ref &p_event) const override; + virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } + virtual String as_text() const override; virtual String to_string() override; @@ -491,9 +498,10 @@ class InputEventAction : public InputEvent { virtual bool is_action(const StringName &p_action) const; virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; - virtual bool shortcut_match(const Ref &p_event) const override; virtual bool is_action_type() const override { return true; } + virtual String as_text() const override; virtual String to_string() override; diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 7421909650f3..2cc8f3541805 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -130,12 +130,9 @@ List>::Element *InputMap::_find_event(Action &p_action, const Re for (List>::Element *E = p_action.inputs.front(); E; E = E->next()) { const Ref e = E->get(); - //if (e.type != Ref::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here? - // continue; - int device = e->get_device(); if (device == ALL_DEVICES || device == p_event->get_device()) { - if (p_exact_match && e->shortcut_match(p_event)) { + if (p_exact_match && e->is_match(p_event, true)) { return E; } else if (!p_exact_match && e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { return E; diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml index 28c4773f51ef..9732d1dd42ed 100644 --- a/doc/classes/InputEvent.xml +++ b/doc/classes/InputEvent.xml @@ -90,20 +90,23 @@ Returns [code]true[/code] if this input event is an echo event (only for events of type [InputEventKey]). - + + + + + - Returns [code]true[/code] if this input event is pressed. Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag]. + Returns [code]true[/code] if the specified [code]event[/code] matches this event. Only valid for action events i.e key ([InputEventKey]), button ([InputEventMouseButton] or [InputEventJoypadButton]), axis [InputEventJoypadMotion] or action ([InputEventAction]) events. + If [code]exact_match[/code] is [code]false[/code], it ignores the input modifiers for [InputEventKey] and [InputEventMouseButton] events, and the direction for [InputEventJoypadMotion] events. - + - - - Returns [code]true[/code] if the given input event is checking for the same key ([InputEventKey]), button ([InputEventJoypadButton]) or action ([InputEventAction]). + Returns [code]true[/code] if this input event is pressed. Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag]. diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 0868c31c45c7..17abc9cfe504 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -1709,7 +1709,7 @@ void EditorSettings::set_builtin_action_override(const String &p_name, const Arr // Check equality of each event. for (List>::Element *E = builtin_events.front(); E; E = E->next()) { - if (!E->get()->shortcut_match(p_events[event_idx])) { + if (!E->get()->is_match(p_events[event_idx])) { same_as_builtin = false; break; } diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 4cdf8208778b..9b178c245e74 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -289,7 +289,7 @@ void EditorSettingsDialog::_update_shortcuts() { event_strings.push_back(I->get()->as_text()); // Only check if the events have been the same so far - once one fails, we don't need to check any more. - if (same_as_defaults && !key_default_events[count]->shortcut_match(I->get())) { + if (same_as_defaults && !key_default_events[count]->is_match(I->get())) { same_as_defaults = false; } count++; diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp index cbbcf9e069c6..962c6dcc60ad 100644 --- a/scene/gui/shortcut.cpp +++ b/scene/gui/shortcut.cpp @@ -42,7 +42,7 @@ Ref Shortcut::get_shortcut() const { } bool Shortcut::is_shortcut(const Ref &p_event) const { - return shortcut.is_valid() && shortcut->shortcut_match(p_event); + return shortcut.is_valid() && shortcut->is_match(p_event, true); } String Shortcut::get_as_text() const {