Skip to content

Commit

Permalink
Fix InputMap.action_erase_event() failing to erase events correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
madmiraal committed May 19, 2021
1 parent d0aaf4a commit 7104229
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 56 deletions.
85 changes: 46 additions & 39 deletions core/input/input_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, f
return false;
}

bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event) const {
bool InputEvent::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
return false;
}

Expand All @@ -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);

Expand Down Expand Up @@ -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<String> mod_names;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -442,16 +431,14 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
return match;
}

bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
bool InputEventKey::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
Ref<InputEventKey> 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() {
Expand Down Expand Up @@ -599,6 +586,16 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p
return match;
}

bool InputEventMouseButton::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
Ref<InputEventMouseButton> 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"),
Expand Down Expand Up @@ -904,6 +901,16 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *
return match;
}

bool InputEventJoypadMotion::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
Ref<InputEventJoypadMotion> 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"),
Expand Down Expand Up @@ -987,7 +994,7 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
return match;
}

bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const {
bool InputEventJoypadButton::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
Ref<InputEventJoypadButton> button = p_event;
if (button.is_null()) {
return false;
Expand Down Expand Up @@ -1229,7 +1236,7 @@ float InputEventAction::get_strength() const {
return strength;
}

bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
bool InputEventAction::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
if (p_event.is_null()) {
return false;
}
Expand Down
16 changes: 12 additions & 4 deletions core/input/input_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ class InputEvent : public Resource {
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;

virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;

virtual bool is_action_type() const;

virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; }
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -252,7 +255,7 @@ class InputEventKey : public InputEventWithModifiers {
uint32_t get_physical_keycode_with_modifiers() const;

virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;

virtual bool is_action_type() const override { return true; }

Expand Down Expand Up @@ -313,7 +316,9 @@ class InputEventMouseButton : public InputEventMouse {
bool is_double_click() const;

virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;

virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;

virtual bool is_action_type() const override { return true; }
virtual String as_text() const override;
Expand Down Expand Up @@ -373,6 +378,7 @@ class InputEventJoypadMotion : public InputEvent {
virtual bool is_pressed() const override;

virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;

virtual bool is_action_type() const override { return true; }
virtual String as_text() const override;
Expand Down Expand Up @@ -401,9 +407,10 @@ class InputEventJoypadButton : public InputEvent {
float get_pressure() const;

virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override;
virtual bool is_match(const Ref<InputEvent> &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;

Expand Down Expand Up @@ -491,9 +498,10 @@ class InputEventAction : public InputEvent {
virtual bool is_action(const StringName &p_action) const;

virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;

virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override;
virtual bool is_action_type() const override { return true; }

virtual String as_text() const override;
virtual String to_string() override;

Expand Down
5 changes: 1 addition & 4 deletions core/input/input_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,9 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
const Ref<InputEvent> e = E->get();

//if (e.type != Ref<InputEvent>::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;
Expand Down
15 changes: 9 additions & 6 deletions doc/classes/InputEvent.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,23 @@
Returns [code]true[/code] if this input event is an echo event (only for events of type [InputEventKey]).
</description>
</method>
<method name="is_pressed" qualifiers="const">
<method name="is_match" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="event" type="InputEvent">
</argument>
<argument index="1" name="exact_match" type="bool" default="true">
</argument>
<description>
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.
</description>
</method>
<method name="shortcut_match" qualifiers="const">
<method name="is_pressed" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
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].
</description>
</method>
<method name="xformed_by" qualifiers="const">
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1709,7 +1709,7 @@ void EditorSettings::set_builtin_action_override(const String &p_name, const Arr

// Check equality of each event.
for (List<Ref<InputEvent>>::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;
}
Expand Down
2 changes: 1 addition & 1 deletion editor/settings_config_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/shortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Ref<InputEvent> Shortcut::get_shortcut() const {
}

bool Shortcut::is_shortcut(const Ref<InputEvent> &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 {
Expand Down

0 comments on commit 7104229

Please sign in to comment.