diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 40fbfa54fde5..d262385d2109 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -92,7 +92,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::shortcut_match(const Ref &p_event, bool p_exact_match) const { return false; } @@ -114,7 +114,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("shortcut_match", "event", "exact_match"), &InputEvent::shortcut_match, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type); @@ -174,6 +174,23 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif set_metakey(event->get_metakey()); } +uint32_t InputEventWithModifiers::get_modifiers_mask() const { + uint32_t mask = 0; + if (get_control()) { + mask |= KEY_MASK_CTRL; + } + if (get_shift()) { + mask |= KEY_MASK_SHIFT; + } + if (get_alt()) { + mask |= KEY_MASK_ALT; + } + if (get_metakey()) { + mask |= KEY_MASK_META; + } + return mask; +} + void InputEventWithModifiers::_bind_methods() { ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt); ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt); @@ -243,35 +260,11 @@ bool InputEventKey::is_echo() const { } uint32_t InputEventKey::get_scancode_with_modifiers() const { - uint32_t sc = scancode; - if (get_control()) { - sc |= KEY_MASK_CTRL; - } - if (get_alt()) { - sc |= KEY_MASK_ALT; - } - if (get_shift()) { - sc |= KEY_MASK_SHIFT; - } - if (get_metakey()) { - sc |= KEY_MASK_META; - } - - return sc; + return scancode | get_modifiers_mask(); } uint32_t InputEventKey::get_physical_scancode_with_modifiers() const { - uint32_t sc = physical_scancode; - if (get_control()) - sc |= KEY_MASK_CTRL; - if (get_alt()) - sc |= KEY_MASK_ALT; - if (get_shift()) - sc |= KEY_MASK_SHIFT; - if (get_metakey()) - sc |= KEY_MASK_META; - - return sc; + return physical_scancode | get_modifiers_mask(); } String InputEventKey::as_text() const { @@ -330,16 +323,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::shortcut_match(const Ref &p_event, bool p_exact_match) 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(); - - return code == event_code; + return scancode == key->scancode && + (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); } void InputEventKey::_bind_methods() { @@ -494,6 +485,16 @@ bool InputEventMouseButton::action_match(const Ref &p_event, bool *p return match; } +bool InputEventMouseButton::shortcut_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()); +} + String InputEventMouseButton::as_text() const { String button_index_string = ""; switch (get_button_index()) { @@ -760,6 +761,16 @@ bool InputEventJoypadMotion::action_match(const Ref &p_event, bool * return match; } +bool InputEventJoypadMotion::shortcut_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))); +} + String InputEventJoypadMotion::as_text() const { return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value)); } @@ -827,7 +838,7 @@ bool InputEventJoypadButton::action_match(const Ref &p_event, bool * return match; } -bool InputEventJoypadButton::shortcut_match(const Ref &p_event) const { +bool InputEventJoypadButton::shortcut_match(const Ref &p_event, bool p_exact_match) const { Ref button = p_event; if (button.is_null()) { return false; @@ -1031,7 +1042,7 @@ float InputEventAction::get_strength() const { return strength; } -bool InputEventAction::shortcut_match(const Ref &p_event) const { +bool InputEventAction::shortcut_match(const Ref &p_event, bool p_exact_match) const { if (p_event.is_null()) { return false; } diff --git a/core/os/input_event.h b/core/os/input_event.h index 4db239e98ca6..6f5f2dc80d9e 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -214,7 +214,7 @@ 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 shortcut_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; } @@ -263,6 +263,8 @@ class InputEventWithModifiers : public InputEvent { void set_modifiers_from_event(const InputEventWithModifiers *event); + uint32_t get_modifiers_mask() const; + InputEventWithModifiers(); }; @@ -300,7 +302,7 @@ class InputEventKey : public InputEventWithModifiers { uint32_t get_physical_scancode_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; - virtual bool shortcut_match(const Ref &p_event) const; + virtual bool shortcut_match(const Ref &p_event, bool p_exact_match = true) const; virtual bool is_action_type() const { return true; } @@ -359,6 +361,7 @@ class InputEventMouseButton : public InputEventMouse { 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, bool p_exact_match = true) const; virtual bool is_action_type() const { return true; } virtual String as_text() const; @@ -416,6 +419,7 @@ class InputEventJoypadMotion : public InputEvent { virtual bool is_pressed() 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, bool p_exact_match = true) const; virtual bool is_action_type() const { return true; } virtual String as_text() const; @@ -443,7 +447,7 @@ 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; - virtual bool shortcut_match(const Ref &p_event) const; + virtual bool shortcut_match(const Ref &p_event, bool p_exact_match = true) const; virtual bool is_action_type() const { return true; } virtual String as_text() const; @@ -531,7 +535,7 @@ class InputEventAction : public InputEvent { 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 shortcut_match(const Ref &p_event, bool p_exact_match = true) const; virtual bool is_action_type() const { return true; } virtual String as_text() const; diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml index 794b0f518b0f..4ac2cf1cc47d 100644 --- a/doc/classes/InputEvent.xml +++ b/doc/classes/InputEvent.xml @@ -85,8 +85,10 @@ + - 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 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.