Browse Source

Allows to map an action to all devices.

This is accomplished by setting a special value (-1) to the device variable
in the InputEvent that's being used to compare with the one received from the OS.

This special value is invalid for a regular input, so it should be safe.
Implements #17942
Nibodhika 7 years ago
parent
commit
1e28f63bcf
4 changed files with 47 additions and 19 deletions
  1. 6 4
      core/input_map.cpp
  2. 5 0
      core/input_map.h
  3. 31 14
      editor/project_settings_editor.cpp
  4. 5 1
      editor/project_settings_editor.h

+ 6 - 4
core/input_map.cpp

@@ -35,6 +35,8 @@
 
 
 InputMap *InputMap::singleton = NULL;
 InputMap *InputMap::singleton = NULL;
 
 
+int InputMap::ALL_DEVICES = -1;
+
 void InputMap::_bind_methods() {
 void InputMap::_bind_methods() {
 
 
 	ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
 	ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
@@ -103,10 +105,10 @@ List<Ref<InputEvent> >::Element *InputMap::_find_event(List<Ref<InputEvent> > &p
 		//if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here?
 		//if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here?
 		//	continue;
 		//	continue;
 
 
-		if (e->get_device() != p_event->get_device())
-			continue;
-		if (e->action_match(p_event))
-			return E;
+		int device = e->get_device();
+		if (device == ALL_DEVICES || device == p_event->get_device())
+			if (e->action_match(p_event))
+				return E;
 	}
 	}
 
 
 	return NULL;
 	return NULL;

+ 5 - 0
core/input_map.h

@@ -39,6 +39,11 @@ class InputMap : public Object {
 	GDCLASS(InputMap, Object);
 	GDCLASS(InputMap, Object);
 
 
 public:
 public:
+	/**
+	* A special value used to signify that a given Action can be triggered by any device
+	*/
+	static int ALL_DEVICES;
+
 	struct Action {
 	struct Action {
 		int id;
 		int id;
 		List<Ref<InputEvent> > inputs;
 		List<Ref<InputEvent> > inputs;

+ 31 - 14
editor/project_settings_editor.cpp

@@ -31,6 +31,7 @@
 #include "project_settings_editor.h"
 #include "project_settings_editor.h"
 
 
 #include "core/global_constants.h"
 #include "core/global_constants.h"
+#include "core/input_map.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 #include "core/translation.h"
 #include "core/translation.h"
@@ -212,7 +213,7 @@ void ProjectSettingsEditor::_device_input_add() {
 			Ref<InputEventMouseButton> mb;
 			Ref<InputEventMouseButton> mb;
 			mb.instance();
 			mb.instance();
 			mb->set_button_index(device_index->get_selected() + 1);
 			mb->set_button_index(device_index->get_selected() + 1);
-			mb->set_device(device_id->get_value());
+			mb->set_device(_get_current_device());
 
 
 			for (int i = 0; i < arr.size(); i++) {
 			for (int i = 0; i < arr.size(); i++) {
 
 
@@ -233,7 +234,7 @@ void ProjectSettingsEditor::_device_input_add() {
 			jm.instance();
 			jm.instance();
 			jm->set_axis(device_index->get_selected() >> 1);
 			jm->set_axis(device_index->get_selected() >> 1);
 			jm->set_axis_value(device_index->get_selected() & 1 ? 1 : -1);
 			jm->set_axis_value(device_index->get_selected() & 1 ? 1 : -1);
-			jm->set_device(device_id->get_value());
+			jm->set_device(_get_current_device());
 
 
 			for (int i = 0; i < arr.size(); i++) {
 			for (int i = 0; i < arr.size(); i++) {
 
 
@@ -254,7 +255,7 @@ void ProjectSettingsEditor::_device_input_add() {
 			jb.instance();
 			jb.instance();
 
 
 			jb->set_button_index(device_index->get_selected());
 			jb->set_button_index(device_index->get_selected());
-			jb->set_device(device_id->get_value());
+			jb->set_device(_get_current_device());
 
 
 			for (int i = 0; i < arr.size(); i++) {
 			for (int i = 0; i < arr.size(); i++) {
 
 
@@ -289,6 +290,20 @@ void ProjectSettingsEditor::_device_input_add() {
 	_show_last_added(ie, name);
 	_show_last_added(ie, name);
 }
 }
 
 
+void ProjectSettingsEditor::_set_current_device(int i_device) {
+	device_id->select(i_device + 1);
+}
+
+int ProjectSettingsEditor::_get_current_device() {
+	return device_id->get_selected() - 1;
+}
+
+String ProjectSettingsEditor::_get_device_string(int i_device) {
+	if (i_device == InputMap::ALL_DEVICES)
+		return TTR("All Devices");
+	return TTR("Device") + " " + itos(i_device);
+}
+
 void ProjectSettingsEditor::_press_a_key_confirm() {
 void ProjectSettingsEditor::_press_a_key_confirm() {
 
 
 	if (last_wait_for_key.is_null())
 	if (last_wait_for_key.is_null())
@@ -422,10 +437,10 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
 			Ref<InputEventMouseButton> mb = p_exiting_event;
 			Ref<InputEventMouseButton> mb = p_exiting_event;
 			if (mb.is_valid()) {
 			if (mb.is_valid()) {
 				device_index->select(mb->get_button_index() - 1);
 				device_index->select(mb->get_button_index() - 1);
-				device_id->set_value(mb->get_device());
+				_set_current_device(mb->get_device());
 				device_input->get_ok()->set_text(TTR("Change"));
 				device_input->get_ok()->set_text(TTR("Change"));
 			} else {
 			} else {
-				device_id->set_value(0);
+				_set_current_device(0);
 				device_input->get_ok()->set_text(TTR("Add"));
 				device_input->get_ok()->set_text(TTR("Add"));
 			}
 			}
 		} break;
 		} break;
@@ -443,10 +458,10 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
 			Ref<InputEventJoypadMotion> jm = p_exiting_event;
 			Ref<InputEventJoypadMotion> jm = p_exiting_event;
 			if (jm.is_valid()) {
 			if (jm.is_valid()) {
 				device_index->select(jm->get_axis() * 2 + (jm->get_axis_value() > 0 ? 1 : 0));
 				device_index->select(jm->get_axis() * 2 + (jm->get_axis_value() > 0 ? 1 : 0));
-				device_id->set_value(jm->get_device());
+				_set_current_device(jm->get_device());
 				device_input->get_ok()->set_text(TTR("Change"));
 				device_input->get_ok()->set_text(TTR("Change"));
 			} else {
 			} else {
-				device_id->set_value(0);
+				_set_current_device(0);
 				device_input->get_ok()->set_text(TTR("Add"));
 				device_input->get_ok()->set_text(TTR("Add"));
 			}
 			}
 		} break;
 		} break;
@@ -464,10 +479,10 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
 			Ref<InputEventJoypadButton> jb = p_exiting_event;
 			Ref<InputEventJoypadButton> jb = p_exiting_event;
 			if (jb.is_valid()) {
 			if (jb.is_valid()) {
 				device_index->select(jb->get_button_index());
 				device_index->select(jb->get_button_index());
-				device_id->set_value(jb->get_device());
+				_set_current_device(jb->get_device());
 				device_input->get_ok()->set_text(TTR("Change"));
 				device_input->get_ok()->set_text(TTR("Change"));
 			} else {
 			} else {
-				device_id->set_value(0);
+				_set_current_device(0);
 				device_input->get_ok()->set_text(TTR("Add"));
 				device_input->get_ok()->set_text(TTR("Add"));
 			}
 			}
 
 
@@ -676,7 +691,7 @@ void ProjectSettingsEditor::_update_actions() {
 
 
 			if (jb.is_valid()) {
 			if (jb.is_valid()) {
 
 
-				String str = TTR("Device") + " " + itos(jb->get_device()) + ", " + TTR("Button") + " " + itos(jb->get_button_index());
+				String str = _get_device_string(jb->get_device()) + ", " + TTR("Button") + " " + itos(jb->get_button_index());
 				if (jb->get_button_index() >= 0 && jb->get_button_index() < JOY_BUTTON_MAX)
 				if (jb->get_button_index() >= 0 && jb->get_button_index() < JOY_BUTTON_MAX)
 					str += String() + " (" + _button_names[jb->get_button_index()] + ").";
 					str += String() + " (" + _button_names[jb->get_button_index()] + ").";
 				else
 				else
@@ -689,7 +704,7 @@ void ProjectSettingsEditor::_update_actions() {
 			Ref<InputEventMouseButton> mb = ie;
 			Ref<InputEventMouseButton> mb = ie;
 
 
 			if (mb.is_valid()) {
 			if (mb.is_valid()) {
-				String str = TTR("Device") + " " + itos(mb->get_device()) + ", ";
+				String str = _get_device_string(mb->get_device()) + ", ";
 				switch (mb->get_button_index()) {
 				switch (mb->get_button_index()) {
 					case BUTTON_LEFT: str += TTR("Left Button."); break;
 					case BUTTON_LEFT: str += TTR("Left Button."); break;
 					case BUTTON_RIGHT: str += TTR("Right Button."); break;
 					case BUTTON_RIGHT: str += TTR("Right Button."); break;
@@ -710,7 +725,7 @@ void ProjectSettingsEditor::_update_actions() {
 				int ax = jm->get_axis();
 				int ax = jm->get_axis();
 				int n = 2 * ax + (jm->get_axis_value() < 0 ? 0 : 1);
 				int n = 2 * ax + (jm->get_axis_value() < 0 ? 0 : 1);
 				String desc = _axis_names[n];
 				String desc = _axis_names[n];
-				String str = TTR("Device") + " " + itos(jm->get_device()) + ", " + TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + desc + ".";
+				String str = _get_device_string(jm->get_device()) + ", " + TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + desc + ".";
 				action->set_text(0, str);
 				action->set_text(0, str);
 				action->set_icon(0, get_icon("JoyAxis", "EditorIcons"));
 				action->set_icon(0, get_icon("JoyAxis", "EditorIcons"));
 			}
 			}
@@ -1781,8 +1796,10 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
 	l->set_text(TTR("Device:"));
 	l->set_text(TTR("Device:"));
 	vbc_left->add_child(l);
 	vbc_left->add_child(l);
 
 
-	device_id = memnew(SpinBox);
-	device_id->set_value(0);
+	device_id = memnew(OptionButton);
+	for (int i = -1; i < 8; i++)
+		device_id->add_item(_get_device_string(i));
+	_set_current_device(0);
 	vbc_left->add_child(device_id);
 	vbc_left->add_child(device_id);
 
 
 	VBoxContainer *vbc_right = memnew(VBoxContainer);
 	VBoxContainer *vbc_right = memnew(VBoxContainer);

+ 5 - 1
editor/project_settings_editor.h

@@ -80,7 +80,7 @@ class ProjectSettingsEditor : public AcceptDialog {
 	ConfirmationDialog *press_a_key;
 	ConfirmationDialog *press_a_key;
 	Label *press_a_key_label;
 	Label *press_a_key_label;
 	ConfirmationDialog *device_input;
 	ConfirmationDialog *device_input;
-	SpinBox *device_id;
+	OptionButton *device_id;
 	OptionButton *device_index;
 	OptionButton *device_index;
 	Label *device_index_label;
 	Label *device_index_label;
 	MenuButton *popup_copy_to_feature;
 	MenuButton *popup_copy_to_feature;
@@ -170,6 +170,10 @@ protected:
 	void _notification(int p_what);
 	void _notification(int p_what);
 	static void _bind_methods();
 	static void _bind_methods();
 
 
+	int _get_current_device();
+	void _set_current_device(int i_device);
+	String _get_device_string(int i_device);
+
 public:
 public:
 	void add_translation(const String &p_translation);
 	void add_translation(const String &p_translation);
 	static ProjectSettingsEditor *get_singleton() { return singleton; }
 	static ProjectSettingsEditor *get_singleton() { return singleton; }