| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  input_map.cpp                                                        */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-13 09:45:09 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "input_map.h"
 | 
					
						
							| 
									
										
										
										
											2017-01-16 08:04:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 11:22:15 +01:00
										 |  |  | #include "core/os/input.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/os/keyboard.h"
 | 
					
						
							|  |  |  | #include "core/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | InputMap *InputMap::singleton = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-03 22:29:07 +00:00
										 |  |  | int InputMap::ALL_DEVICES = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 21:48:16 -04:00
										 |  |  | void InputMap::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions); | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.5f)); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-20 20:58:53 +07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone); | 
					
						
							| 
									
										
										
										
											2021-07-02 00:02:28 -04:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("action_get_deadzone", "action"), &InputMap::action_get_deadzone); | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("action_add_event", "action", "event"), &InputMap::action_add_event); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("action_has_event", "action", "event"), &InputMap::action_has_event); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("action_erase_event", "action", "event"), &InputMap::action_erase_event); | 
					
						
							| 
									
										
										
										
											2018-04-28 19:01:54 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("action_erase_events", "action"), &InputMap::action_erase_events); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_action_list", "action"), &InputMap::_get_action_list); | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("event_is_action", "event", "action", "exact_match"), &InputMap::event_is_action, DEFVAL(false)); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("load_from_globals"), &InputMap::load_from_globals); | 
					
						
							| 
									
										
										
										
											2014-04-23 21:48:16 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-28 01:31:49 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns an nonexistent action error message with a suggestion of the closest | 
					
						
							|  |  |  |  * matching action name (if possible). | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | String InputMap::suggest_actions(const StringName &p_action) const { | 
					
						
							| 
									
										
										
										
											2020-01-28 01:31:49 +01:00
										 |  |  | 	List<StringName> actions = get_actions(); | 
					
						
							|  |  |  | 	StringName closest_action; | 
					
						
							|  |  |  | 	float closest_similarity = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Find the most action with the most similar name.
 | 
					
						
							|  |  |  | 	for (List<StringName>::Element *E = actions.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 		const float similarity = String(E->get()).similarity(p_action); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (similarity > closest_similarity) { | 
					
						
							|  |  |  | 			closest_action = E->get(); | 
					
						
							|  |  |  | 			closest_similarity = similarity; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	String error_message = vformat("The InputMap action \"%s\" doesn't exist.", p_action); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (closest_similarity >= 0.4) { | 
					
						
							|  |  |  | 		// Only include a suggestion in the error message if it's similar enough.
 | 
					
						
							|  |  |  | 		error_message += vformat(" Did you mean \"%s\"?", closest_action); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return error_message; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | void InputMap::add_action(const StringName &p_action, float p_deadzone) { | 
					
						
							| 
									
										
										
										
											2020-01-28 01:31:49 +01:00
										 |  |  | 	ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action \"" + String(p_action) + "\"."); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	input_map[p_action] = Action(); | 
					
						
							|  |  |  | 	static int last_id = 1; | 
					
						
							|  |  |  | 	input_map[p_action].id = last_id; | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 	input_map[p_action].deadzone = p_deadzone; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	last_id++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void InputMap::erase_action(const StringName &p_action) { | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2020-01-28 01:31:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	input_map.erase(p_action); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-04 17:55:09 +02:00
										 |  |  | Array InputMap::_get_actions() { | 
					
						
							|  |  |  | 	Array ret; | 
					
						
							|  |  |  | 	List<StringName> actions = get_actions(); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (actions.empty()) { | 
					
						
							| 
									
										
										
										
											2016-06-04 17:55:09 +02:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-04 17:55:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2016-06-04 17:55:09 +02:00
										 |  |  | 		ret.push_back(E->get()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | List<StringName> InputMap::get_actions() const { | 
					
						
							|  |  |  | 	List<StringName> actions = List<StringName>(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (input_map.empty()) { | 
					
						
							| 
									
										
										
										
											2016-06-04 17:55:09 +02:00
										 |  |  | 		return actions; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (Map<StringName, Action>::Element *E = input_map.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2016-06-04 17:55:09 +02:00
										 |  |  | 		actions.push_back(E->key()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return actions; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	ERR_FAIL_COND_V(!p_event.is_valid(), nullptr); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 14:20:36 +02:00
										 |  |  | 	for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		const Ref<InputEvent> e = E->get(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		//if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here?
 | 
					
						
							|  |  |  | 		//	continue;
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-03 22:29:07 +00:00
										 |  |  | 		int device = e->get_device(); | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 		if (device == ALL_DEVICES || device == p_event->get_device()) { | 
					
						
							| 
									
										
										
										
											2021-10-24 00:10:06 -05:00
										 |  |  | 			if (e->action_match(p_event, p_exact_match, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { | 
					
						
							| 
									
										
										
										
											2018-04-03 22:29:07 +00:00
										 |  |  | 				return E; | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool InputMap::has_action(const StringName &p_action) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return input_map.has(p_action); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 00:02:28 -04:00
										 |  |  | float InputMap::action_get_deadzone(const StringName &p_action) { | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!input_map.has(p_action), 0.0f, suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2021-07-02 00:02:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return input_map[p_action].deadzone; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) { | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	input_map[p_action].deadzone = p_deadzone; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) { | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object."); | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2020-01-28 01:31:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | 	if (_find_event(input_map[p_action], p_event, true)) { | 
					
						
							|  |  |  | 		return; // Already added.
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	input_map[p_action].inputs.push_back(p_event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) { | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2020-01-28 01:31:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | 	return (_find_event(input_map[p_action], p_event, true) != nullptr); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) { | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | 	List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event, true); | 
					
						
							| 
									
										
										
										
											2020-11-03 11:22:15 +01:00
										 |  |  | 	if (E) { | 
					
						
							| 
									
										
										
										
											2016-03-07 18:56:44 +01:00
										 |  |  | 		input_map[p_action].inputs.erase(E); | 
					
						
							| 
									
										
										
										
											2020-11-03 11:22:15 +01:00
										 |  |  | 		if (Input::get_singleton()->is_action_pressed(p_action)) { | 
					
						
							|  |  |  | 			Input::get_singleton()->action_release(p_action); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 19:01:54 +02:00
										 |  |  | void InputMap::action_erase_events(const StringName &p_action) { | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2018-04-28 19:01:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	input_map[p_action].inputs.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Array InputMap::_get_action_list(const StringName &p_action) { | 
					
						
							| 
									
										
										
										
											2015-05-18 10:20:54 -03:00
										 |  |  | 	Array ret; | 
					
						
							| 
									
										
										
										
											2021-05-04 14:20:36 +02:00
										 |  |  | 	const List<Ref<InputEvent>> *al = get_action_list(p_action); | 
					
						
							| 
									
										
										
										
											2015-05-18 10:20:54 -03:00
										 |  |  | 	if (al) { | 
					
						
							| 
									
										
										
										
											2021-05-04 14:20:36 +02:00
										 |  |  | 		for (const List<Ref<InputEvent>>::Element *E = al->front(); E; E = E->next()) { | 
					
						
							| 
									
										
										
										
											2017-01-14 18:03:38 +01:00
										 |  |  | 			ret.push_back(E->get()); | 
					
						
							| 
									
										
										
										
											2015-05-18 10:20:54 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 14:20:36 +02:00
										 |  |  | const List<Ref<InputEvent>> *InputMap::get_action_list(const StringName &p_action) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	const Map<StringName, Action>::Element *E = input_map.find(p_action); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	if (!E) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return &E->get().inputs; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const { | 
					
						
							|  |  |  | 	return event_get_action_status(p_event, p_action, p_exact_match); | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Map<StringName, Action>::Element *E = input_map.find(p_action); | 
					
						
							| 
									
										
										
										
											2021-08-16 19:57:34 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!E, false, suggest_actions(p_action)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 	Ref<InputEventAction> input_event_action = p_event; | 
					
						
							|  |  |  | 	if (input_event_action.is_valid()) { | 
					
						
							| 
									
										
										
										
											2021-08-15 19:23:50 -04:00
										 |  |  | 		bool pressed = input_event_action->is_pressed(); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_pressed != nullptr) { | 
					
						
							| 
									
										
										
										
											2021-08-15 19:23:50 -04:00
										 |  |  | 			*p_pressed = pressed; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (p_strength != nullptr) { | 
					
						
							| 
									
										
										
										
											2021-08-15 19:23:50 -04:00
										 |  |  | 			*p_strength = pressed ? input_event_action->get_strength() : 0.0f; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 		return input_event_action->get_action() == p_action; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 	bool pressed; | 
					
						
							|  |  |  | 	float strength; | 
					
						
							| 
									
										
										
										
											2021-07-22 20:28:08 -04:00
										 |  |  | 	float raw_strength; | 
					
						
							| 
									
										
											  
											
												Allow checking for exact matches with Action events.
Added additional param to action related methods to test for exactness.
If "p_exact_match" is true, then the action will only be "matched" if the provided input event *exactly* matches with the action event.
Before:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* Is Action Pressed = True
Now:
You can still do the above, however you can optionally check that the input is exactly what the action event is:
* Action Event = KEY_S
* Input Event = KEY_CONTROL + KEY_S
* p_exact_match = True
* Is Action Pressed = False
* If the Input Event was only KEY_S, then the result would be true.
Usage:
```gdscript
Input.is_action_pressed(action_name: String, exact_match: bool)
Input.is_action_pressed("my_action", true)
InputMap.event_is_action(p_event, "my_action", true)
func _input(event: InputEvent):
  event.is_action_pressed("my_action", false, true) # false = "allow_echo", true = "exact_match"
  event.is_action("my_action", true)
```
Co-authored-by: Eric M <itsjusteza@gmail.com>
											
										 
											2020-12-14 00:22:42 +10:00
										 |  |  | 	List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, p_exact_match, &pressed, &strength, &raw_strength); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	if (event != nullptr) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_pressed != nullptr) { | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 			*p_pressed = pressed; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (p_strength != nullptr) { | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 			*p_strength = strength; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-07-22 20:28:08 -04:00
										 |  |  | 		if (p_raw_strength != nullptr) { | 
					
						
							|  |  |  | 			*p_raw_strength = raw_strength; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | const Map<StringName, InputMap::Action> &InputMap::get_action_map() const { | 
					
						
							| 
									
										
										
										
											2016-09-01 18:58:52 -03:00
										 |  |  | 	return input_map; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void InputMap::load_from_globals() { | 
					
						
							| 
									
										
										
										
											2017-01-14 18:03:38 +01:00
										 |  |  | 	input_map.clear(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	List<PropertyInfo> pinfo; | 
					
						
							| 
									
										
										
										
											2017-07-19 17:00:46 -03:00
										 |  |  | 	ProjectSettings::get_singleton()->get_property_list(&pinfo); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 		const PropertyInfo &pi = E->get(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!pi.name.begins_with("input/")) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 		Dictionary action = ProjectSettings::get_singleton()->get(pi.name); | 
					
						
							|  |  |  | 		float deadzone = action.has("deadzone") ? (float)action["deadzone"] : 0.5f; | 
					
						
							|  |  |  | 		Array events = action["events"]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 		add_action(name, deadzone); | 
					
						
							|  |  |  | 		for (int i = 0; i < events.size(); i++) { | 
					
						
							|  |  |  | 			Ref<InputEvent> event = events[i]; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (event.is_null()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-21 22:06:34 +01:00
										 |  |  | 			action_add_event(name, event); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void InputMap::load_default() { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	Ref<InputEventKey> key; | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_accept"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							| 
									
										
										
										
											2017-08-06 16:26:07 +03:00
										 |  |  | 	key->set_scancode(KEY_ENTER); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_accept", key); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	key.instance(); | 
					
						
							| 
									
										
										
										
											2017-08-06 16:26:07 +03:00
										 |  |  | 	key->set_scancode(KEY_KP_ENTER); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_accept", key); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_SPACE); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_accept", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_select"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_SPACE); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_select", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_cancel"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_ESCAPE); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_cancel", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_focus_next"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_TAB); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_focus_next", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_focus_prev"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_TAB); | 
					
						
							|  |  |  | 	key->set_shift(true); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_focus_prev", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_left"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_LEFT); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_left", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_right"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_RIGHT); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_right", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_up"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_UP); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_up", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_down"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_DOWN); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_down", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_page_up"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_PAGEUP); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_page_up", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 19:06:57 +02:00
										 |  |  | 	add_action("ui_page_down"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_PAGEDOWN); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	action_add_event("ui_page_down", key); | 
					
						
							| 
									
										
										
										
											2016-06-05 01:19:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-23 12:17:15 +01:00
										 |  |  | 	add_action("ui_home"); | 
					
						
							|  |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_HOME); | 
					
						
							|  |  |  | 	action_add_event("ui_home", key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	add_action("ui_end"); | 
					
						
							|  |  |  | 	key.instance(); | 
					
						
							|  |  |  | 	key->set_scancode(KEY_END); | 
					
						
							|  |  |  | 	action_add_event("ui_end", key); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | InputMap::InputMap() { | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(singleton, "Singleton in InputMap already exist."); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	singleton = this; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |