mirror of
https://github.com/Redot-Engine/redot-engine.git
synced 2025-12-06 07:17:42 -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).
|
||||
</description>
|
||||
</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">
|
||||
<return type="void" />
|
||||
<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]).
|
||||
</description>
|
||||
</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">
|
||||
<return type="void" />
|
||||
<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.
|
||||
</description>
|
||||
</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">
|
||||
<return type="void" />
|
||||
<param index="0" name="load_placeholder" type="bool" />
|
||||
|
||||
@@ -209,6 +209,10 @@ void Node::_notification(int p_notification) {
|
||||
set_process_unhandled_key_input(true);
|
||||
}
|
||||
|
||||
if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_picking_input)) {
|
||||
set_process_unhandled_picking_input(true);
|
||||
}
|
||||
|
||||
if (GDVIRTUAL_IS_OVERRIDDEN(_process)) {
|
||||
set_process(true);
|
||||
}
|
||||
@@ -1255,6 +1259,27 @@ bool Node::is_processing_unhandled_key_input() const {
|
||||
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) {
|
||||
ERR_THREAD_GUARD
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
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;
|
||||
@@ -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_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) {
|
||||
if (p_argcount < 1) {
|
||||
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("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("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("get_process_mode"), &Node::get_process_mode);
|
||||
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(_unhandled_input, "event");
|
||||
GDVIRTUAL_BIND(_unhandled_key_input, "event");
|
||||
GDVIRTUAL_BIND(_unhandled_picking_input, "event");
|
||||
}
|
||||
|
||||
String Node::_get_name_num_separator() {
|
||||
@@ -3829,6 +3870,7 @@ Node::Node() {
|
||||
data.shortcut_input = false;
|
||||
data.unhandled_input = false;
|
||||
data.unhandled_key_input = false;
|
||||
data.unhandled_picking_input = false;
|
||||
|
||||
data.physics_interpolated = true;
|
||||
|
||||
|
||||
@@ -221,6 +221,7 @@ private:
|
||||
bool shortcut_input : 1;
|
||||
bool unhandled_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.
|
||||
// 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_unhandled_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;
|
||||
|
||||
@@ -349,6 +351,7 @@ protected:
|
||||
virtual void shortcut_input(const Ref<InputEvent> &p_key_event);
|
||||
virtual void unhandled_input(const Ref<InputEvent> &p_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(_physics_process, double)
|
||||
@@ -361,6 +364,7 @@ protected:
|
||||
GDVIRTUAL1(_shortcut_input, Ref<InputEvent>)
|
||||
GDVIRTUAL1(_unhandled_input, Ref<InputEvent>)
|
||||
GDVIRTUAL1(_unhandled_key_input, Ref<InputEvent>)
|
||||
GDVIRTUAL1(_unhandled_picking_input, Ref<InputEvent>)
|
||||
|
||||
public:
|
||||
enum {
|
||||
@@ -578,6 +582,9 @@ public:
|
||||
void set_process_unhandled_key_input(bool p_enable);
|
||||
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 {
|
||||
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:
|
||||
n->_call_unhandled_key_input(p_input);
|
||||
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_UNHANDLED_INPUT,
|
||||
CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT,
|
||||
CALL_INPUT_TYPE_UNHANDLED_PICKING_INPUT,
|
||||
};
|
||||
|
||||
//used by viewport
|
||||
|
||||
@@ -961,6 +961,11 @@ void Viewport::_process_picking() {
|
||||
}
|
||||
}
|
||||
#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;
|
||||
shortcut_input_group = "_vp_shortcut_input" + id;
|
||||
unhandled_key_input_group = "_vp_unhandled_key_input" + id;
|
||||
unhandled_picking_input_group = "_vp_unhandled_picking_input" + id;
|
||||
|
||||
// Window tooltip.
|
||||
gui.tooltip_delay = GLOBAL_GET("gui/timers/tooltip_delay_sec");
|
||||
|
||||
@@ -278,6 +278,7 @@ private:
|
||||
StringName shortcut_input_group;
|
||||
StringName unhandled_input_group;
|
||||
StringName unhandled_key_input_group;
|
||||
StringName unhandled_picking_input_group;
|
||||
|
||||
void _update_audio_listener_2d();
|
||||
|
||||
|
||||
@@ -673,6 +673,18 @@ TEST_CASE("[Node] Processing checks") {
|
||||
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") {
|
||||
CHECK_FALSE(node->is_processing_shortcut_input());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user