Control::accept_event Changed and Move to Node

This commit is contained in:
2750558108 2024-09-14 16:44:13 +08:00
parent 48403b5358
commit d6d2c4ad61
11 changed files with 74 additions and 26 deletions

View File

@ -9,7 +9,7 @@
[b]User Interface nodes and input[/b]
Godot propagates input events via viewports. Each [Viewport] is responsible for propagating [InputEvent]s to their child nodes. As the [member SceneTree.root] is a [Window], this already happens automatically for all UI elements in your game.
Input events are propagated through the [SceneTree] from the root node to all child nodes by calling [method Node._input]. For UI elements specifically, it makes more sense to override the virtual method [method _gui_input], which filters out unrelated input events, such as by checking z-order, [member mouse_filter], focus, or if the event was inside of the control's bounding box.
Call [method accept_event] so no other node receives the event. Once you accept an input, it becomes handled so [method Node._unhandled_input] will not process it.
Call [method Node.accept_event] so no other node receives the event. Once you accept an input, it becomes handled so [method Node._unhandled_input] will not process it.
Only one [Control] node can be in focus. Only the node in focus will receive events. To get the focus, call [method grab_focus]. [Control] nodes lose focus when another node grabs it, or if you hide the node in focus.
Sets [member mouse_filter] to [constant MOUSE_FILTER_IGNORE] to tell a [Control] node to ignore mouse or touch events. You'll need it if you place an icon on top of a button.
[Theme] resources change the Control's appearance. If you change the [Theme] on a [Control] node, it affects all of its children. To override some of the theme's parameters, call one of the [code]add_theme_*_override[/code] methods, like [method add_theme_font_override]. You can override the theme with the Inspector.
@ -120,7 +120,7 @@
<return type="void" />
<param index="0" name="event" type="InputEvent" />
<description>
Virtual method to be implemented by the user. Use this method to process and accept inputs on UI elements. See [method accept_event].
Virtual method to be implemented by the user. Use this method to process and accept inputs on UI elements. See [method Node.accept_event].
[b]Example usage for clicking a control:[/b]
[codeblocks]
[gdscript]
@ -214,13 +214,6 @@
Returns an [Array] of [Vector3i] text ranges and text base directions, in the left-to-right order. Ranges should cover full source [param text] without overlaps. BiDi algorithm will be used on each range separately.
</description>
</method>
<method name="accept_event">
<return type="void" />
<description>
Marks an input event as handled. Once you accept an input event, it stops propagating, even to nodes listening to [method Node._unhandled_input] or [method Node._unhandled_key_input].
[b]Note:[/b] This does not affect the methods in [Input], only the way events are propagated.
</description>
</method>
<method name="add_theme_color_override">
<return type="void" />
<param index="0" name="name" type="StringName" />

View File

@ -5,7 +5,7 @@
</brief_description>
<description>
The [Input] singleton handles key presses, mouse buttons and movement, gamepads, and input actions. Actions and their events can be set in the [b]Input Map[/b] tab in [b]Project &gt; Project Settings[/b], or with the [InputMap] class.
[b]Note:[/b] [Input]'s methods reflect the global input state and are not affected by [method Control.accept_event] or [method Viewport.set_input_as_handled], as those methods only deal with the way input is propagated in the [SceneTree].
[b]Note:[/b] [Input]'s methods reflect the global input state and are not affected by [method Node.accept_event] or [method Viewport.set_input_as_handled], as those methods only deal with the way input is propagated in the [SceneTree].
</description>
<tutorials>
<link title="Inputs documentation index">$DOCS_URL/tutorials/inputs/index.html</link>

View File

@ -130,6 +130,13 @@
[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="accept_event">
<return type="void" />
<description>
Stops the input from propagating further down the [SceneTree].
[b]Note:[/b] This does not affect the methods in [Input], only the way events are propagated.
</description>
</method>
<method name="add_child">
<return type="void" />
<param index="0" name="node" type="Node" />

View File

@ -82,6 +82,13 @@ Validate extension JSON: Error: Field 'classes/OS/methods/execute_with_pipe/argu
Optional argument added. Compatibility method registered.
GH-96989
--------
Validate extension JSON: API was removed: classes/Control/methods/accept_event
Method moved to Node. Compatibility method registered.
GH-94684
--------
Validate extension JSON: Error: Field 'classes/SoftBody3D/methods/set_point_pinned/arguments': size changed value in new API, from 3 to 4.

View File

@ -0,0 +1,41 @@
/**************************************************************************/
/* control.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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. */
/**************************************************************************/
#ifndef DISABLE_DEPRECATED
void Control::_accept_event_bind_compat_96989() {
accept_event();
}
void Control::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("accept_event"), &Control::_accept_event_bind_compat_96989);
}
#endif

View File

@ -29,6 +29,7 @@
/**************************************************************************/
#include "control.h"
#include "control.compat.inc"
#include "container.h"
#include "core/config/project_settings.h"
@ -1830,13 +1831,6 @@ void Control::_call_gui_input(const Ref<InputEvent> &p_event) {
void Control::gui_input(const Ref<InputEvent> &p_event) {
}
void Control::accept_event() {
ERR_MAIN_THREAD_GUARD;
if (is_inside_tree()) {
get_viewport()->_gui_accept_event();
}
}
bool Control::has_point(const Point2 &p_point) const {
ERR_READ_THREAD_GUARD_V(false);
bool ret;
@ -3389,7 +3383,6 @@ void Control::_notification(int p_notification) {
}
void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("accept_event"), &Control::accept_event);
ClassDB::bind_method(D_METHOD("get_minimum_size"), &Control::get_minimum_size);
ClassDB::bind_method(D_METHOD("get_combined_minimum_size"), &Control::get_combined_minimum_size);

View File

@ -348,6 +348,11 @@ protected:
void _notification(int p_notification);
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
void _accept_event_bind_compat_96989();
static void _bind_compatibility_methods();
#endif
// Exposed virtual methods.
GDVIRTUAL1RC(bool, _has_point, Vector2)
@ -501,7 +506,6 @@ public:
// Input events.
virtual void gui_input(const Ref<InputEvent> &p_event);
void accept_event();
virtual bool has_point(const Point2 &p_point) const;

View File

@ -3427,6 +3427,13 @@ void Node::unhandled_input(const Ref<InputEvent> &p_event) {
void Node::unhandled_key_input(const Ref<InputEvent> &p_key_event) {
}
void Node::accept_event() {
ERR_MAIN_THREAD_GUARD;
if (is_inside_tree() && get_viewport()->is_inside_tree()) {
get_viewport()->set_input_as_handled();
}
}
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;
@ -3583,6 +3590,7 @@ void Node::_bind_methods() {
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);
ClassDB::bind_method(D_METHOD("accept_event"), &Node::accept_event);
ClassDB::bind_method(D_METHOD("set_process_thread_group", "mode"), &Node::set_process_thread_group);
ClassDB::bind_method(D_METHOD("get_process_thread_group"), &Node::get_process_thread_group);

View File

@ -664,6 +664,8 @@ public:
bool can_process() const;
bool can_process_notification(int p_what) const;
void accept_event();
void set_physics_interpolation_mode(PhysicsInterpolationMode p_mode);
PhysicsInterpolationMode get_physics_interpolation_mode() const { return data.physics_interpolation_mode; }
_FORCE_INLINE_ bool is_physics_interpolated() const { return data.physics_interpolated; }

View File

@ -2460,12 +2460,6 @@ void Viewport::_gui_control_grab_focus(Control *p_control) {
}
}
void Viewport::_gui_accept_event() {
if (is_inside_tree()) {
set_input_as_handled();
}
}
void Viewport::_drop_mouse_focus() {
Control *c = gui.mouse_focus;
BitField<MouseButtonMask> mask = gui.mouse_focus_mask;

View File

@ -439,7 +439,6 @@ private:
void _gui_control_grab_focus(Control *p_control);
void _gui_grab_click_focus(Control *p_control);
void _post_gui_grab_click_focus();
void _gui_accept_event();
bool _gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check);