Parcourir la source

Merge pull request #48696 from madmiraal/fix-48692

Fix `InputMap.action_erase_event()` failing to erase events correctly.
Rémi Verschelde il y a 4 ans
Parent
commit
4effadc0ba

+ 46 - 39
core/input/input_event.cpp

@@ -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;
 }
 
@@ -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<String> 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<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() {
@@ -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"),
@@ -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"),
@@ -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;
@@ -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;
 	}

+ 12 - 4
core/input/input_event.h

@@ -142,7 +142,8 @@ public:
 	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; }
@@ -212,6 +213,8 @@ public:
 
 	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 @@ public:
 	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; }
 
@@ -313,7 +316,9 @@ public:
 	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;
@@ -373,6 +378,7 @@ public:
 	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;
@@ -401,9 +407,10 @@ public:
 	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;
 
@@ -491,9 +498,10 @@ public:
 	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;
 

+ 1 - 4
core/input/input_map.cpp

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

+ 9 - 6
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]).
 			</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">

+ 1 - 1
editor/editor_settings.cpp

@@ -1585,7 +1585,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;
 				}

+ 1 - 1
editor/settings_config_dialog.cpp

@@ -285,7 +285,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++;

+ 1 - 1
scene/gui/shortcut.cpp

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