mirror of
https://github.com/Redot-Engine/redot-engine.git
synced 2025-12-06 15:21:56 -05:00
Add an additional input stage after physics picking
Allow handling events, that were not used during physics picking. (cherry picked from commit godotengine/godot@fbd5d2ba8b)
This commit is contained in:
committed by
Spartan322
parent
fe04f5ff9b
commit
d14035edcc
@@ -130,6 +130,17 @@
|
|||||||
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).
|
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="_unhandled_picking_input" qualifiers="virtual">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="event" type="InputEvent" />
|
||||||
|
<description>
|
||||||
|
Called when an [InputEventKey] hasn't been consumed by physics picking. The input event propagates up through the node tree in the current [Viewport] until a node consumes it.
|
||||||
|
It is only called if unhandled picking input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_picking_input].
|
||||||
|
To consume the input event and stop it propagating further to other nodes, [method Viewport.set_input_as_handled] can be called.
|
||||||
|
This method can be used to handle mouse and touch events that were not set to handled during physics picking.
|
||||||
|
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="add_child">
|
<method name="add_child">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="node" type="Node" />
|
<param index="0" name="node" type="Node" />
|
||||||
@@ -688,6 +699,12 @@
|
|||||||
Returns [code]true[/code] if the node is processing unhandled key input (see [method set_process_unhandled_key_input]).
|
Returns [code]true[/code] if the node is processing unhandled key input (see [method set_process_unhandled_key_input]).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="is_processing_unhandled_picking_input" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if the node is processing unhandled physics input (see [method set_process_unhandled_picking_input]).
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="move_child">
|
<method name="move_child">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="child_node" type="Node" />
|
<param index="0" name="child_node" type="Node" />
|
||||||
@@ -952,6 +969,13 @@
|
|||||||
[b]Note:[/b] If [method _unhandled_key_input] is overridden, this will be automatically enabled before [method _ready] is called.
|
[b]Note:[/b] If [method _unhandled_key_input] is overridden, this will be automatically enabled before [method _ready] is called.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="set_process_unhandled_picking_input">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="enable" type="bool" />
|
||||||
|
<description>
|
||||||
|
Enables unhandled picking input processing. Enabled automatically if [method _unhandled_picking_input] is overridden. Any calls to this before [method _ready] will be ignored.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="set_scene_instance_load_placeholder">
|
<method name="set_scene_instance_load_placeholder">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="load_placeholder" type="bool" />
|
<param index="0" name="load_placeholder" type="bool" />
|
||||||
|
|||||||
@@ -209,6 +209,10 @@ void Node::_notification(int p_notification) {
|
|||||||
set_process_unhandled_key_input(true);
|
set_process_unhandled_key_input(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_picking_input)) {
|
||||||
|
set_process_unhandled_picking_input(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (GDVIRTUAL_IS_OVERRIDDEN(_process)) {
|
if (GDVIRTUAL_IS_OVERRIDDEN(_process)) {
|
||||||
set_process(true);
|
set_process(true);
|
||||||
}
|
}
|
||||||
@@ -1255,6 +1259,27 @@ bool Node::is_processing_unhandled_key_input() const {
|
|||||||
return data.unhandled_key_input;
|
return data.unhandled_key_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::set_process_unhandled_picking_input(bool p_enable) {
|
||||||
|
ERR_THREAD_GUARD
|
||||||
|
if (p_enable == data.unhandled_picking_input) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data.unhandled_picking_input = p_enable;
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_enable) {
|
||||||
|
add_to_group("_vp_unhandled_picking_input" + itos(get_viewport()->get_instance_id()));
|
||||||
|
} else {
|
||||||
|
remove_from_group("_vp_unhandled_picking_input" + itos(get_viewport()->get_instance_id()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Node::is_processing_unhandled_picking_input() const {
|
||||||
|
return data.unhandled_picking_input;
|
||||||
|
}
|
||||||
|
|
||||||
void Node::set_auto_translate_mode(AutoTranslateMode p_mode) {
|
void Node::set_auto_translate_mode(AutoTranslateMode p_mode) {
|
||||||
ERR_THREAD_GUARD
|
ERR_THREAD_GUARD
|
||||||
if (data.auto_translate_mode == p_mode) {
|
if (data.auto_translate_mode == p_mode) {
|
||||||
@@ -3387,6 +3412,16 @@ void Node::_call_unhandled_key_input(const Ref<InputEvent> &p_event) {
|
|||||||
unhandled_key_input(p_event);
|
unhandled_key_input(p_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::_call_unhandled_picking_input(const Ref<InputEvent> &p_event) {
|
||||||
|
if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
|
||||||
|
GDVIRTUAL_CALL(_unhandled_picking_input, p_event);
|
||||||
|
}
|
||||||
|
if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unhandled_key_input(p_event);
|
||||||
|
}
|
||||||
|
|
||||||
void Node::_validate_property(PropertyInfo &p_property) const {
|
void Node::_validate_property(PropertyInfo &p_property) const {
|
||||||
if ((p_property.name == "process_thread_group_order" || p_property.name == "process_thread_messages") && data.process_thread_group == PROCESS_THREAD_GROUP_INHERIT) {
|
if ((p_property.name == "process_thread_group_order" || p_property.name == "process_thread_messages") && data.process_thread_group == PROCESS_THREAD_GROUP_INHERIT) {
|
||||||
p_property.usage = 0;
|
p_property.usage = 0;
|
||||||
@@ -3405,6 +3440,9 @@ void Node::unhandled_input(const Ref<InputEvent> &p_event) {
|
|||||||
void Node::unhandled_key_input(const Ref<InputEvent> &p_key_event) {
|
void Node::unhandled_key_input(const Ref<InputEvent> &p_key_event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::unhandled_picking_input(const Ref<InputEvent> &p_picking_event) {
|
||||||
|
}
|
||||||
|
|
||||||
Variant Node::_call_deferred_thread_group_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
Variant Node::_call_deferred_thread_group_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
||||||
if (p_argcount < 1) {
|
if (p_argcount < 1) {
|
||||||
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||||
@@ -3558,6 +3596,8 @@ void Node::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("is_processing_unhandled_input"), &Node::is_processing_unhandled_input);
|
ClassDB::bind_method(D_METHOD("is_processing_unhandled_input"), &Node::is_processing_unhandled_input);
|
||||||
ClassDB::bind_method(D_METHOD("set_process_unhandled_key_input", "enable"), &Node::set_process_unhandled_key_input);
|
ClassDB::bind_method(D_METHOD("set_process_unhandled_key_input", "enable"), &Node::set_process_unhandled_key_input);
|
||||||
ClassDB::bind_method(D_METHOD("is_processing_unhandled_key_input"), &Node::is_processing_unhandled_key_input);
|
ClassDB::bind_method(D_METHOD("is_processing_unhandled_key_input"), &Node::is_processing_unhandled_key_input);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_process_unhandled_picking_input", "enable"), &Node::set_process_unhandled_picking_input);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_processing_unhandled_picking_input"), &Node::is_processing_unhandled_picking_input);
|
||||||
ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Node::set_process_mode);
|
ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Node::set_process_mode);
|
||||||
ClassDB::bind_method(D_METHOD("get_process_mode"), &Node::get_process_mode);
|
ClassDB::bind_method(D_METHOD("get_process_mode"), &Node::get_process_mode);
|
||||||
ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process);
|
ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process);
|
||||||
@@ -3795,6 +3835,7 @@ void Node::_bind_methods() {
|
|||||||
GDVIRTUAL_BIND(_shortcut_input, "event");
|
GDVIRTUAL_BIND(_shortcut_input, "event");
|
||||||
GDVIRTUAL_BIND(_unhandled_input, "event");
|
GDVIRTUAL_BIND(_unhandled_input, "event");
|
||||||
GDVIRTUAL_BIND(_unhandled_key_input, "event");
|
GDVIRTUAL_BIND(_unhandled_key_input, "event");
|
||||||
|
GDVIRTUAL_BIND(_unhandled_picking_input, "event");
|
||||||
}
|
}
|
||||||
|
|
||||||
String Node::_get_name_num_separator() {
|
String Node::_get_name_num_separator() {
|
||||||
@@ -3829,6 +3870,7 @@ Node::Node() {
|
|||||||
data.shortcut_input = false;
|
data.shortcut_input = false;
|
||||||
data.unhandled_input = false;
|
data.unhandled_input = false;
|
||||||
data.unhandled_key_input = false;
|
data.unhandled_key_input = false;
|
||||||
|
data.unhandled_picking_input = false;
|
||||||
|
|
||||||
data.physics_interpolated = true;
|
data.physics_interpolated = true;
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ private:
|
|||||||
bool shortcut_input : 1;
|
bool shortcut_input : 1;
|
||||||
bool unhandled_input : 1;
|
bool unhandled_input : 1;
|
||||||
bool unhandled_key_input : 1;
|
bool unhandled_key_input : 1;
|
||||||
|
bool unhandled_picking_input : 1;
|
||||||
|
|
||||||
// Physics interpolation can be turned on and off on a per node basis.
|
// Physics interpolation can be turned on and off on a per node basis.
|
||||||
// This only takes effect when the SceneTree (or project setting) physics interpolation
|
// This only takes effect when the SceneTree (or project setting) physics interpolation
|
||||||
@@ -341,6 +342,7 @@ protected:
|
|||||||
void _call_shortcut_input(const Ref<InputEvent> &p_event);
|
void _call_shortcut_input(const Ref<InputEvent> &p_event);
|
||||||
void _call_unhandled_input(const Ref<InputEvent> &p_event);
|
void _call_unhandled_input(const Ref<InputEvent> &p_event);
|
||||||
void _call_unhandled_key_input(const Ref<InputEvent> &p_event);
|
void _call_unhandled_key_input(const Ref<InputEvent> &p_event);
|
||||||
|
void _call_unhandled_picking_input(const Ref<InputEvent> &p_event);
|
||||||
|
|
||||||
void _validate_property(PropertyInfo &p_property) const;
|
void _validate_property(PropertyInfo &p_property) const;
|
||||||
|
|
||||||
@@ -349,6 +351,7 @@ protected:
|
|||||||
virtual void shortcut_input(const Ref<InputEvent> &p_key_event);
|
virtual void shortcut_input(const Ref<InputEvent> &p_key_event);
|
||||||
virtual void unhandled_input(const Ref<InputEvent> &p_event);
|
virtual void unhandled_input(const Ref<InputEvent> &p_event);
|
||||||
virtual void unhandled_key_input(const Ref<InputEvent> &p_key_event);
|
virtual void unhandled_key_input(const Ref<InputEvent> &p_key_event);
|
||||||
|
virtual void unhandled_picking_input(const Ref<InputEvent> &p_picking_event);
|
||||||
|
|
||||||
GDVIRTUAL1(_process, double)
|
GDVIRTUAL1(_process, double)
|
||||||
GDVIRTUAL1(_physics_process, double)
|
GDVIRTUAL1(_physics_process, double)
|
||||||
@@ -361,6 +364,7 @@ protected:
|
|||||||
GDVIRTUAL1(_shortcut_input, Ref<InputEvent>)
|
GDVIRTUAL1(_shortcut_input, Ref<InputEvent>)
|
||||||
GDVIRTUAL1(_unhandled_input, Ref<InputEvent>)
|
GDVIRTUAL1(_unhandled_input, Ref<InputEvent>)
|
||||||
GDVIRTUAL1(_unhandled_key_input, Ref<InputEvent>)
|
GDVIRTUAL1(_unhandled_key_input, Ref<InputEvent>)
|
||||||
|
GDVIRTUAL1(_unhandled_picking_input, Ref<InputEvent>)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
@@ -578,6 +582,9 @@ public:
|
|||||||
void set_process_unhandled_key_input(bool p_enable);
|
void set_process_unhandled_key_input(bool p_enable);
|
||||||
bool is_processing_unhandled_key_input() const;
|
bool is_processing_unhandled_key_input() const;
|
||||||
|
|
||||||
|
void set_process_unhandled_picking_input(bool p_enable);
|
||||||
|
bool is_processing_unhandled_picking_input() const;
|
||||||
|
|
||||||
_FORCE_INLINE_ bool _is_any_processing() const {
|
_FORCE_INLINE_ bool _is_any_processing() const {
|
||||||
return data.process || data.process_internal || data.physics_process || data.physics_process_internal;
|
return data.process || data.process_internal || data.physics_process || data.physics_process_internal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1232,6 +1232,9 @@ void SceneTree::_call_input_pause(const StringName &p_group, CallInputType p_cal
|
|||||||
case CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT:
|
case CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT:
|
||||||
n->_call_unhandled_key_input(p_input);
|
n->_call_unhandled_key_input(p_input);
|
||||||
break;
|
break;
|
||||||
|
case CALL_INPUT_TYPE_UNHANDLED_PICKING_INPUT:
|
||||||
|
n->_call_unhandled_picking_input(p_input);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ private:
|
|||||||
CALL_INPUT_TYPE_SHORTCUT_INPUT,
|
CALL_INPUT_TYPE_SHORTCUT_INPUT,
|
||||||
CALL_INPUT_TYPE_UNHANDLED_INPUT,
|
CALL_INPUT_TYPE_UNHANDLED_INPUT,
|
||||||
CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT,
|
CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT,
|
||||||
|
CALL_INPUT_TYPE_UNHANDLED_PICKING_INPUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
//used by viewport
|
//used by viewport
|
||||||
|
|||||||
@@ -961,6 +961,11 @@ void Viewport::_process_picking() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // _3D_DISABLED
|
#endif // _3D_DISABLED
|
||||||
|
|
||||||
|
if (!local_input_handled) {
|
||||||
|
ERR_FAIL_COND(!is_inside_tree());
|
||||||
|
get_tree()->_call_input_pause(unhandled_picking_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_PICKING_INPUT, ev, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5015,6 +5020,7 @@ Viewport::Viewport() {
|
|||||||
unhandled_input_group = "_vp_unhandled_input" + id;
|
unhandled_input_group = "_vp_unhandled_input" + id;
|
||||||
shortcut_input_group = "_vp_shortcut_input" + id;
|
shortcut_input_group = "_vp_shortcut_input" + id;
|
||||||
unhandled_key_input_group = "_vp_unhandled_key_input" + id;
|
unhandled_key_input_group = "_vp_unhandled_key_input" + id;
|
||||||
|
unhandled_picking_input_group = "_vp_unhandled_picking_input" + id;
|
||||||
|
|
||||||
// Window tooltip.
|
// Window tooltip.
|
||||||
gui.tooltip_delay = GLOBAL_GET("gui/timers/tooltip_delay_sec");
|
gui.tooltip_delay = GLOBAL_GET("gui/timers/tooltip_delay_sec");
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ private:
|
|||||||
StringName shortcut_input_group;
|
StringName shortcut_input_group;
|
||||||
StringName unhandled_input_group;
|
StringName unhandled_input_group;
|
||||||
StringName unhandled_key_input_group;
|
StringName unhandled_key_input_group;
|
||||||
|
StringName unhandled_picking_input_group;
|
||||||
|
|
||||||
void _update_audio_listener_2d();
|
void _update_audio_listener_2d();
|
||||||
|
|
||||||
|
|||||||
@@ -673,6 +673,18 @@ TEST_CASE("[Node] Processing checks") {
|
|||||||
CHECK_FALSE(node->is_processing_unhandled_key_input());
|
CHECK_FALSE(node->is_processing_unhandled_key_input());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("Unhandled picking input processing") {
|
||||||
|
CHECK_FALSE(node->is_processing_unhandled_picking_input());
|
||||||
|
|
||||||
|
node->set_process_unhandled_picking_input(true);
|
||||||
|
|
||||||
|
CHECK(node->is_processing_unhandled_picking_input());
|
||||||
|
|
||||||
|
node->set_process_unhandled_picking_input(false);
|
||||||
|
|
||||||
|
CHECK_FALSE(node->is_processing_unhandled_picking_input());
|
||||||
|
}
|
||||||
|
|
||||||
SUBCASE("Shortcut input processing") {
|
SUBCASE("Shortcut input processing") {
|
||||||
CHECK_FALSE(node->is_processing_shortcut_input());
|
CHECK_FALSE(node->is_processing_shortcut_input());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user