mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 20:23:53 +00:00
Make SubViewportContainer
event propagation aware of focused Control
Propagate `InputEvents` without position either - during the Input-stage, when it has focus or - during the Unhandled-Input-stage, otherwise This makes sure that Gui-Input happens in the correct order. Move "Unhandled key Input" handling before "Unhandled Input" handling, so that Unicode input with Alt / Ctrl modifiers are sent to the nodes in the correct order. Change the default focus mode of `SubViewportContainer` from `FOCUS_NONE` to `FOCUS_CLICK`, to automatically remove focus from other `Control`-nodes, when clicking inside a `SubViewport`.
This commit is contained in:
parent
85c9db592f
commit
e6386bc843
@ -11,6 +11,7 @@
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<members>
|
||||
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="1" />
|
||||
<member name="stretch" type="bool" setter="set_stretch" getter="is_stretch_enabled" default="false">
|
||||
If [code]true[/code], the sub-viewport will be automatically resized to the control's size.
|
||||
[b]Note:[/b] If [code]true[/code], this will prohibit changing [member SubViewport.size] of its children manually.
|
||||
|
@ -160,8 +160,8 @@
|
||||
- [method Node._input]
|
||||
- [method Control._gui_input] for [Control] nodes
|
||||
- [method Node._shortcut_input]
|
||||
- [method Node._unhandled_input]
|
||||
- [method Node._unhandled_key_input]
|
||||
- [method Node._unhandled_input]
|
||||
If an earlier method marks the input as handled via [method set_input_as_handled], any later method in this list will not be called.
|
||||
If none of the methods handle the event and [member physics_object_picking] is [code]true[/code], the event is used for physics object picking.
|
||||
</description>
|
||||
@ -183,8 +183,8 @@
|
||||
While this method serves a similar purpose as [method Input.parse_input_event], it does not remap the specified [param event] based on project settings like [member ProjectSettings.input_devices/pointing/emulate_touch_from_mouse].
|
||||
Calling this method will propagate calls to child nodes for following methods in the given order:
|
||||
- [method Node._shortcut_input]
|
||||
- [method Node._unhandled_input]
|
||||
- [method Node._unhandled_key_input]
|
||||
- [method Node._unhandled_input]
|
||||
If an earlier method marks the input as handled via [method set_input_as_handled], any later method in this list will not be called.
|
||||
If none of the methods handle the event and [member physics_object_picking] is [code]true[/code], the event is used for physics object picking.
|
||||
[b]Note:[/b] This method doesn't propagate input events to embedded [Window]s or [SubViewport]s.
|
||||
|
@ -154,6 +154,18 @@ void SubViewportContainer::_notification(int p_what) {
|
||||
case NOTIFICATION_MOUSE_EXIT: {
|
||||
_notify_viewports(NOTIFICATION_VP_MOUSE_EXIT);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_FOCUS_ENTER: {
|
||||
// If focused, send InputEvent to the SubViewport before the Gui-Input stage.
|
||||
set_process_input(true);
|
||||
set_process_unhandled_input(false);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_FOCUS_EXIT: {
|
||||
// A different Control has focus and should receive Gui-Input before the InputEvent is sent to the SubViewport.
|
||||
set_process_input(false);
|
||||
set_process_unhandled_input(true);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +180,14 @@ void SubViewportContainer::_notify_viewports(int p_notification) {
|
||||
}
|
||||
|
||||
void SubViewportContainer::input(const Ref<InputEvent> &p_event) {
|
||||
_propagate_nonpositional_event(p_event);
|
||||
}
|
||||
|
||||
void SubViewportContainer::unhandled_input(const Ref<InputEvent> &p_event) {
|
||||
_propagate_nonpositional_event(p_event);
|
||||
}
|
||||
|
||||
void SubViewportContainer::_propagate_nonpositional_event(const Ref<InputEvent> &p_event) {
|
||||
ERR_FAIL_COND(p_event.is_null());
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
@ -262,5 +282,6 @@ void SubViewportContainer::_bind_methods() {
|
||||
}
|
||||
|
||||
SubViewportContainer::SubViewportContainer() {
|
||||
set_process_input(true);
|
||||
set_process_unhandled_input(true);
|
||||
set_focus_mode(FOCUS_CLICK);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ class SubViewportContainer : public Container {
|
||||
void _notify_viewports(int p_notification);
|
||||
bool _is_propagated_in_gui_input(const Ref<InputEvent> &p_event);
|
||||
void _send_event_to_viewports(const Ref<InputEvent> &p_event);
|
||||
void _propagate_nonpositional_event(const Ref<InputEvent> &p_event);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
@ -54,6 +55,7 @@ public:
|
||||
bool is_stretch_enabled() const;
|
||||
|
||||
virtual void input(const Ref<InputEvent> &p_event) override;
|
||||
virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
|
||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||
void set_stretch_shrink(int p_shrink);
|
||||
int get_stretch_shrink() const;
|
||||
|
@ -3025,18 +3025,18 @@ void Viewport::_push_unhandled_input_internal(const Ref<InputEvent> &p_event) {
|
||||
get_tree()->_call_input_pause(shortcut_input_group, SceneTree::CALL_INPUT_TYPE_SHORTCUT_INPUT, p_event, this);
|
||||
}
|
||||
|
||||
// Unhandled Input.
|
||||
if (!is_input_handled()) {
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, p_event, this);
|
||||
}
|
||||
|
||||
// Unhandled key Input - Used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, and to handle Unicode input with Alt / Ctrl modifiers after handling shortcuts.
|
||||
if (!is_input_handled() && (Object::cast_to<InputEventKey>(*p_event) != nullptr)) {
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
get_tree()->_call_input_pause(unhandled_key_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, p_event, this);
|
||||
}
|
||||
|
||||
// Unhandled Input.
|
||||
if (!is_input_handled()) {
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, p_event, this);
|
||||
}
|
||||
|
||||
if (physics_object_picking && !is_input_handled()) {
|
||||
if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED &&
|
||||
(Object::cast_to<InputEventMouse>(*p_event) ||
|
||||
|
Loading…
Reference in New Issue
Block a user