summaryrefslogtreecommitdiff
path: root/core/input
diff options
context:
space:
mode:
Diffstat (limited to 'core/input')
-rw-r--r--core/input/input.cpp51
-rw-r--r--core/input/input.h11
-rw-r--r--core/input/input_event.cpp70
-rw-r--r--core/input/input_event.h33
-rw-r--r--core/input/input_map.cpp7
5 files changed, 122 insertions, 50 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp
index c205726b0a..72563cc40a 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -163,8 +163,7 @@ void Input::_bind_methods() {
void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
#ifdef TOOLS_ENABLED
-
- const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
+ const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
String pf = p_function;
if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" ||
@@ -180,7 +179,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
- r_options->push_back(quote_style + name + quote_style);
+ r_options->push_back(name.quote(quote_style));
}
}
#endif
@@ -221,7 +220,7 @@ Input::SpeedTrack::SpeedTrack() {
reset();
}
-bool Input::is_key_pressed(int p_keycode) const {
+bool Input::is_key_pressed(Key p_keycode) const {
_THREAD_SAFE_METHOD_
return keys_pressed.has(p_keycode);
}
@@ -460,10 +459,6 @@ Vector3 Input::get_gyroscope() const {
return gyroscope;
}
-void Input::parse_input_event(const Ref<InputEvent> &p_event) {
- _parse_input_event_impl(p_event, false);
-}
-
void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
// Notes on mouse-touch emulation:
// - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects
@@ -472,8 +467,6 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
// - Emulated touch events are handed right to the main loop (i.e., the SceneTree) because they don't
// require additional handling by this class.
- _THREAD_SAFE_METHOD_
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && !k->is_echo() && k->get_keycode() != 0) {
if (k->is_pressed()) {
@@ -838,25 +831,37 @@ void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, co
set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
}
-void Input::accumulate_input_event(const Ref<InputEvent> &p_event) {
+void Input::parse_input_event(const Ref<InputEvent> &p_event) {
+ _THREAD_SAFE_METHOD_
+
ERR_FAIL_COND(p_event.is_null());
- if (!use_accumulated_input) {
- parse_input_event(p_event);
- return;
+ if (use_accumulated_input) {
+ if (buffered_events.is_empty() || !buffered_events.back()->get()->accumulate(p_event)) {
+ buffered_events.push_back(p_event);
+ }
+ } else if (use_input_buffering) {
+ buffered_events.push_back(p_event);
+ } else {
+ _parse_input_event_impl(p_event, false);
}
- if (!accumulated_events.is_empty() && accumulated_events.back()->get()->accumulate(p_event)) {
- return; //event was accumulated, exit
+}
+
+void Input::flush_buffered_events() {
+ _THREAD_SAFE_METHOD_
+
+ while (buffered_events.front()) {
+ _parse_input_event_impl(buffered_events.front()->get(), false);
+ buffered_events.pop_front();
}
+}
- accumulated_events.push_back(p_event);
+bool Input::is_using_input_buffering() {
+ return use_input_buffering;
}
-void Input::flush_accumulated_events() {
- while (accumulated_events.front()) {
- parse_input_event(accumulated_events.front()->get());
- accumulated_events.pop_front();
- }
+void Input::set_use_input_buffering(bool p_enable) {
+ use_input_buffering = p_enable;
}
void Input::set_use_accumulated_input(bool p_enable) {
@@ -864,7 +869,7 @@ void Input::set_use_accumulated_input(bool p_enable) {
}
void Input::release_pressed_events() {
- flush_accumulated_events(); // this is needed to release actions strengths
+ flush_buffered_events(); // this is needed to release actions strengths
keys_pressed.clear();
joy_buttons_pressed.clear();
diff --git a/core/input/input.h b/core/input/input.h
index fbcd5836ea..6819fc8eb0 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -33,6 +33,7 @@
#include "core/input/input_event.h"
#include "core/object/object.h"
+#include "core/os/keyboard.h"
#include "core/os/thread_safe.h"
class Input : public Object {
@@ -110,6 +111,7 @@ private:
bool emulate_touch_from_mouse = false;
bool emulate_mouse_from_touch = false;
+ bool use_input_buffering = false;
bool use_accumulated_input = false;
int mouse_from_touch_index = -1;
@@ -212,7 +214,7 @@ private:
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
- List<Ref<InputEvent>> accumulated_events;
+ List<Ref<InputEvent>> buffered_events;
friend class DisplayServer;
@@ -244,7 +246,7 @@ public:
static Input *get_singleton();
- bool is_key_pressed(int p_keycode) const;
+ bool is_key_pressed(Key p_keycode) const;
bool is_mouse_button_pressed(MouseButton p_button) const;
bool is_joy_button_pressed(int p_device, JoyButton p_button) const;
bool is_action_pressed(const StringName &p_action, bool p_exact = false) const;
@@ -322,8 +324,9 @@ public:
String get_joy_guid(int p_device) const;
void set_fallback_mapping(String p_guid);
- void accumulate_input_event(const Ref<InputEvent> &p_event);
- void flush_accumulated_events();
+ void flush_buffered_events();
+ bool is_using_input_buffering();
+ void set_use_input_buffering(bool p_enable);
void set_use_accumulated_input(bool p_enable);
void release_pressed_events();
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 4a2abffae8..325cdf2127 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -32,6 +32,7 @@
#include "core/input/input_map.h"
#include "core/os/keyboard.h"
+#include "scene/gui/shortcut.h"
const int InputEvent::DEVICE_ID_TOUCH_MOUSE = -1;
const int InputEvent::DEVICE_ID_INTERNAL = -2;
@@ -306,21 +307,21 @@ bool InputEventKey::is_pressed() const {
return pressed;
}
-void InputEventKey::set_keycode(uint32_t p_keycode) {
+void InputEventKey::set_keycode(Key p_keycode) {
keycode = p_keycode;
emit_changed();
}
-uint32_t InputEventKey::get_keycode() const {
+Key InputEventKey::get_keycode() const {
return keycode;
}
-void InputEventKey::set_physical_keycode(uint32_t p_keycode) {
+void InputEventKey::set_physical_keycode(Key p_keycode) {
physical_keycode = p_keycode;
emit_changed();
}
-uint32_t InputEventKey::get_physical_keycode() const {
+Key InputEventKey::get_physical_keycode() const {
return physical_keycode;
}
@@ -386,7 +387,7 @@ String InputEventKey::to_string() {
return vformat("InputEventKey: keycode=%s, mods=%s, physical=%s, pressed=%s, echo=%s", kc, mods, physical, p, e);
}
-Ref<InputEventKey> InputEventKey::create_reference(uint32_t p_keycode) {
+Ref<InputEventKey> InputEventKey::create_reference(Key p_keycode) {
Ref<InputEventKey> ie;
ie.instantiate();
ie->set_keycode(p_keycode & KEY_CODE_MASK);
@@ -430,10 +431,11 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code);
}
if (match) {
+ bool pressed = key->is_pressed();
if (p_pressed != nullptr) {
- *p_pressed = key->is_pressed();
+ *p_pressed = pressed;
}
- float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ float strength = pressed ? 1.0f : 0.0f;
if (p_strength != nullptr) {
*p_strength = strength;
}
@@ -586,10 +588,11 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p
bool match = mb->button_index == button_index;
if (match) {
+ bool pressed = mb->is_pressed();
if (p_pressed != nullptr) {
- *p_pressed = mb->is_pressed();
+ *p_pressed = pressed;
}
- float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ float strength = pressed ? 1.0f : 0.0f;
if (p_strength != nullptr) {
*p_strength = strength;
}
@@ -997,10 +1000,11 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
bool match = button_index == jb->button_index;
if (match) {
+ bool pressed = jb->is_pressed();
if (p_pressed != nullptr) {
- *p_pressed = jb->is_pressed();
+ *p_pressed = pressed;
}
- float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ float strength = pressed ? 1.0f : 0.0f;
if (p_strength != nullptr) {
*p_strength = strength;
}
@@ -1209,6 +1213,22 @@ String InputEventScreenDrag::to_string() {
return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), speed=(%s)", index, String(get_position()), String(get_relative()), String(get_speed()));
}
+bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) {
+ Ref<InputEventScreenDrag> drag = p_event;
+ if (drag.is_null())
+ return false;
+
+ if (get_index() != drag->get_index()) {
+ return false;
+ }
+
+ set_position(drag->get_position());
+ set_speed(drag->get_speed());
+ relative += drag->get_relative();
+
+ return true;
+}
+
void InputEventScreenDrag::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index);
ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index);
@@ -1274,10 +1294,11 @@ bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pres
bool match = action == act->action;
if (match) {
+ bool pressed = act->pressed;
if (p_pressed != nullptr) {
- *p_pressed = act->pressed;
+ *p_pressed = pressed;
}
- float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ float strength = pressed ? 1.0f : 0.0f;
if (p_strength != nullptr) {
*p_strength = strength;
}
@@ -1512,3 +1533,26 @@ void InputEventMIDI::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_number"), "set_controller_number", "get_controller_number");
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_value"), "set_controller_value", "get_controller_value");
}
+
+///////////////////////////////////
+
+void InputEventShortcut::set_shortcut(Ref<Shortcut> p_shortcut) {
+ shortcut = p_shortcut;
+ emit_changed();
+}
+
+Ref<Shortcut> InputEventShortcut::get_shortcut() {
+ return shortcut;
+}
+
+bool InputEventShortcut::is_pressed() const {
+ return true;
+}
+
+String InputEventShortcut::as_text() const {
+ return vformat(RTR("Input Event with Shortcut=%s"), shortcut->get_as_text());
+}
+
+String InputEventShortcut::to_string() {
+ return vformat("InputEventShortcut: shortcut=%s", shortcut->get_as_text());
+}
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 76a45c04a4..517d63eb40 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -34,6 +34,7 @@
#include "core/input/input_enums.h"
#include "core/io/resource.h"
#include "core/math/transform_2d.h"
+#include "core/os/keyboard.h"
#include "core/string/ustring.h"
#include "core/typedefs.h"
@@ -42,6 +43,8 @@
* The events are pretty obvious.
*/
+class Shortcut;
+
/**
* Input Modifier Status
* for keyboard/mouse events.
@@ -161,8 +164,8 @@ class InputEventKey : public InputEventWithModifiers {
bool pressed = false; /// otherwise release
- uint32_t keycode = 0; ///< check keyboard.h , KeyCode enum, without modifier masks
- uint32_t physical_keycode = 0;
+ Key keycode = KEY_NONE; // Key enum, without modifier masks.
+ Key physical_keycode = KEY_NONE;
uint32_t unicode = 0; ///unicode
bool echo = false; /// true if this is an echo key
@@ -174,11 +177,11 @@ public:
void set_pressed(bool p_pressed);
virtual bool is_pressed() const override;
- void set_keycode(uint32_t p_keycode);
- uint32_t get_keycode() const;
+ void set_keycode(Key p_keycode);
+ Key get_keycode() const;
- void set_physical_keycode(uint32_t p_keycode);
- uint32_t get_physical_keycode() const;
+ void set_physical_keycode(Key p_keycode);
+ Key get_physical_keycode() const;
void set_unicode(uint32_t p_unicode);
uint32_t get_unicode() const;
@@ -197,7 +200,7 @@ public:
virtual String as_text() const override;
virtual String to_string() override;
- static Ref<InputEventKey> create_reference(uint32_t p_keycode_with_modifier_masks);
+ static Ref<InputEventKey> create_reference(Key p_keycode_with_modifier_masks);
InputEventKey() {}
};
@@ -407,6 +410,8 @@ public:
virtual String as_text() const override;
virtual String to_string() override;
+ virtual bool accumulate(const Ref<InputEvent> &p_event) override;
+
InputEventScreenDrag() {}
};
@@ -538,4 +543,18 @@ public:
InputEventMIDI() {}
};
+class InputEventShortcut : public InputEvent {
+ GDCLASS(InputEventShortcut, InputEvent);
+
+ Ref<Shortcut> shortcut;
+
+public:
+ void set_shortcut(Ref<Shortcut> p_shortcut);
+ Ref<Shortcut> get_shortcut();
+ virtual bool is_pressed() const override;
+
+ virtual String as_text() const override;
+ virtual String to_string() override;
+};
+
#endif // INPUT_EVENT_H
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 6714705bb5..83ec70757e 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -196,7 +196,7 @@ Array InputMap::_action_get_events(const StringName &p_action) {
const List<Ref<InputEvent>> *al = action_get_events(p_action);
if (al) {
for (const List<Ref<InputEvent>>::Element *E = al->front(); E; E = E->next()) {
- ret.push_back(E);
+ ret.push_back(E->get());
}
}
@@ -222,11 +222,12 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
+ bool pressed = input_event_action->is_pressed();
if (p_pressed != nullptr) {
- *p_pressed = input_event_action->is_pressed();
+ *p_pressed = pressed;
}
if (p_strength != nullptr) {
- *p_strength = (p_pressed != nullptr && *p_pressed) ? input_event_action->get_strength() : 0.0f;
+ *p_strength = pressed ? input_event_action->get_strength() : 0.0f;
}
return input_event_action->get_action() == p_action;
}