feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -36,13 +36,6 @@
|
|||
#include "core/templates/sort_array.h"
|
||||
#include "scene/2d/audio_listener_2d.h"
|
||||
#include "scene/2d/camera_2d.h"
|
||||
#include "scene/2d/physics/collision_object_2d.h"
|
||||
#ifndef _3D_DISABLED
|
||||
#include "scene/3d/audio_listener_3d.h"
|
||||
#include "scene/3d/camera_3d.h"
|
||||
#include "scene/3d/physics/collision_object_3d.h"
|
||||
#include "scene/3d/world_environment.h"
|
||||
#endif // _3D_DISABLED
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/popup.h"
|
||||
|
|
@ -56,6 +49,20 @@
|
|||
#include "servers/audio_server.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
#include "scene/3d/audio_listener_3d.h"
|
||||
#include "scene/3d/camera_3d.h"
|
||||
#include "scene/3d/world_environment.h"
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
#include "scene/2d/physics/collision_object_2d.h"
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
#include "scene/3d/physics/collision_object_3d.h"
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
void ViewportTexture::setup_local_to_scene() {
|
||||
// For the same target viewport, setup is only allowed once to prevent multiple free or multiple creations.
|
||||
if (!vp_changed) {
|
||||
|
|
@ -287,7 +294,7 @@ void Viewport::_sub_window_register(Window *p_window) {
|
|||
ERR_FAIL_COND(gui.sub_windows[i].window == p_window);
|
||||
}
|
||||
|
||||
if (gui.sub_windows.size() == 0) {
|
||||
if (gui.sub_windows.is_empty()) {
|
||||
subwindow_canvas = RS::get_singleton()->canvas_create();
|
||||
RS::get_singleton()->viewport_attach_canvas(viewport, subwindow_canvas);
|
||||
RS::get_singleton()->viewport_set_canvas_stacking(viewport, subwindow_canvas, SUBWINDOW_CANVAS_LAYER, 0);
|
||||
|
|
@ -317,7 +324,13 @@ void Viewport::_sub_window_register(Window *p_window) {
|
|||
|
||||
void Viewport::_sub_window_update(Window *p_window) {
|
||||
int index = _sub_window_find(p_window);
|
||||
ERR_FAIL_COND(index == -1);
|
||||
|
||||
// _sub_window_update is sometimes called deferred, and the window may have been closed since then.
|
||||
// For example, when the user resizes the game window.
|
||||
// In that case, _sub_window_find will not find it, which is expected.
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
SubWindow &sw = gui.sub_windows.write[index];
|
||||
sw.pending_window_update = false;
|
||||
|
|
@ -452,7 +465,7 @@ void Viewport::_sub_window_remove(Window *p_window) {
|
|||
RS::get_singleton()->free(sw.canvas_item);
|
||||
gui.sub_windows.remove_at(index);
|
||||
|
||||
if (gui.sub_windows.size() == 0) {
|
||||
if (gui.sub_windows.is_empty()) {
|
||||
RS::get_singleton()->free(subwindow_canvas);
|
||||
subwindow_canvas = RID();
|
||||
}
|
||||
|
|
@ -502,18 +515,14 @@ int Viewport::_sub_window_find(Window *p_window) const {
|
|||
}
|
||||
|
||||
void Viewport::_update_viewport_path() {
|
||||
if (viewport_textures.is_empty()) {
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Node *scene_root = get_scene_file_path().is_empty() ? get_owner() : this;
|
||||
if (!scene_root && is_inside_tree()) {
|
||||
scene_root = get_tree()->get_edited_scene_root();
|
||||
}
|
||||
if (scene_root && (scene_root == this || scene_root->is_ancestor_of(this))) {
|
||||
NodePath path_in_scene = scene_root->get_path_to(this);
|
||||
for (ViewportTexture *E : viewport_textures) {
|
||||
E->path = path_in_scene;
|
||||
for (ViewportTexture *E : viewport_textures) {
|
||||
Node *loc_scene = E->get_local_scene();
|
||||
if (loc_scene) {
|
||||
E->path = loc_scene->get_path_to(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -543,11 +552,14 @@ void Viewport::_notification(int p_what) {
|
|||
#endif // _3D_DISABLED
|
||||
|
||||
add_to_group("_viewports");
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
if (get_tree()->is_debugging_collisions_hint()) {
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
PhysicsServer2D::get_singleton()->space_set_debug_contacts(find_world_2d()->get_space(), get_tree()->get_collision_debug_contact_count());
|
||||
contact_2d_debug = RenderingServer::get_singleton()->canvas_item_create();
|
||||
RenderingServer::get_singleton()->canvas_item_set_parent(contact_2d_debug, current_canvas);
|
||||
#ifndef _3D_DISABLED
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count());
|
||||
contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create();
|
||||
RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, false);
|
||||
|
|
@ -557,9 +569,10 @@ void Viewport::_notification(int p_what) {
|
|||
RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh);
|
||||
RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario());
|
||||
RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
|
||||
#endif // _3D_DISABLED
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
set_physics_process_internal(true);
|
||||
}
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
|
|
@ -598,17 +611,21 @@ void Viewport::_notification(int p_what) {
|
|||
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, RID());
|
||||
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
if (contact_2d_debug.is_valid()) {
|
||||
RenderingServer::get_singleton()->free(contact_2d_debug);
|
||||
contact_2d_debug = RID();
|
||||
}
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
if (contact_3d_debug_multimesh.is_valid()) {
|
||||
RenderingServer::get_singleton()->free(contact_3d_debug_multimesh);
|
||||
RenderingServer::get_singleton()->free(contact_3d_debug_instance);
|
||||
contact_3d_debug_instance = RID();
|
||||
contact_3d_debug_multimesh = RID();
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
remove_from_group("_viewports");
|
||||
set_physics_process_internal(false);
|
||||
|
|
@ -621,11 +638,13 @@ void Viewport::_notification(int p_what) {
|
|||
_update_viewport_path();
|
||||
} break;
|
||||
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
if (!get_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) {
|
||||
RenderingServer::get_singleton()->canvas_item_clear(contact_2d_debug);
|
||||
RenderingServer::get_singleton()->canvas_item_set_draw_index(contact_2d_debug, 0xFFFFF); //very high index
|
||||
|
|
@ -638,7 +657,8 @@ void Viewport::_notification(int p_what) {
|
|||
RenderingServer::get_singleton()->canvas_item_add_rect(contact_2d_debug, Rect2(points[i] - Vector2(2, 2), Vector2(5, 5)), ccol);
|
||||
}
|
||||
}
|
||||
#ifndef _3D_DISABLED
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
if (get_tree()->is_debugging_collisions_hint() && contact_3d_debug_multimesh.is_valid()) {
|
||||
Vector<Vector3> points = PhysicsServer3D::get_singleton()->space_get_contacts(find_world_3d()->get_space());
|
||||
int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world_3d()->get_space());
|
||||
|
|
@ -651,8 +671,9 @@ void Viewport::_notification(int p_what) {
|
|||
RS::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh, i, point_transform);
|
||||
}
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
} break;
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
|
||||
case NOTIFICATION_VP_MOUSE_ENTER: {
|
||||
gui.mouse_in_viewport = true;
|
||||
|
|
@ -685,6 +706,7 @@ void Viewport::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
void Viewport::_process_picking() {
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
|
|
@ -701,7 +723,7 @@ void Viewport::_process_picking() {
|
|||
physics_picking_events.clear();
|
||||
return;
|
||||
}
|
||||
#ifndef _3D_DISABLED
|
||||
#ifndef XR_DISABLED
|
||||
if (use_xr) {
|
||||
if (XRServer::get_singleton() != nullptr) {
|
||||
Ref<XRInterface> xr_interface = XRServer::get_singleton()->get_primary_interface();
|
||||
|
|
@ -712,21 +734,23 @@ void Viewport::_process_picking() {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // XR_DISABLED
|
||||
|
||||
_drop_physics_mouseover(true);
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
Vector2 last_pos(1e20, 1e20);
|
||||
CollisionObject3D *last_object = nullptr;
|
||||
ObjectID last_id;
|
||||
PhysicsDirectSpaceState3D::RayResult result;
|
||||
#endif // _3D_DISABLED
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
|
||||
SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent());
|
||||
bool parent_ignore_mouse = (parent_svc && parent_svc->get_mouse_filter() == Control::MOUSE_FILTER_IGNORE);
|
||||
bool parent_ignore_mouse = (parent_svc && parent_svc->get_mouse_filter_with_recursive() == Control::MOUSE_FILTER_IGNORE);
|
||||
bool create_passive_hover_event = true;
|
||||
if (gui.mouse_over || parent_ignore_mouse) {
|
||||
// When the mouse is over a Control node, passive hovering would cause input events for Colliders, that are behind Control nodes.
|
||||
|
|
@ -803,6 +827,7 @@ void Viewport::_process_picking() {
|
|||
pos = st->get_position();
|
||||
}
|
||||
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
if (ss2d) {
|
||||
// Send to 2D.
|
||||
|
||||
|
|
@ -895,15 +920,16 @@ void Viewport::_process_picking() {
|
|||
_cleanup_mouseover_colliders(false, false, frame);
|
||||
}
|
||||
}
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
if (physics_object_picking_first_only && is_input_handled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CollisionObject3D *capture_object = nullptr;
|
||||
if (physics_object_capture.is_valid()) {
|
||||
capture_object = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture));
|
||||
capture_object = ObjectDB::get_instance<CollisionObject3D>(physics_object_capture);
|
||||
if (!capture_object || !camera_3d || (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed())) {
|
||||
physics_object_capture = ObjectID();
|
||||
} else {
|
||||
|
|
@ -952,7 +978,7 @@ void Viewport::_process_picking() {
|
|||
|
||||
if (is_mouse && new_collider != physics_object_over) {
|
||||
if (physics_object_over.is_valid()) {
|
||||
CollisionObject3D *previous_co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
|
||||
CollisionObject3D *previous_co = ObjectDB::get_instance<CollisionObject3D>(physics_object_over);
|
||||
if (previous_co) {
|
||||
previous_co->_mouse_exit();
|
||||
}
|
||||
|
|
@ -975,9 +1001,10 @@ void Viewport::_process_picking() {
|
|||
last_pos = pos;
|
||||
}
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
}
|
||||
}
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
|
||||
RID Viewport::get_viewport_rid() const {
|
||||
ERR_READ_THREAD_GUARD_V(RID());
|
||||
|
|
@ -1002,10 +1029,10 @@ void Viewport::update_canvas_items() {
|
|||
_update_canvas_items(this);
|
||||
}
|
||||
|
||||
bool Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override, bool p_allocated) {
|
||||
bool Viewport::_set_size(const Size2i &p_size, const Size2 &p_size_2d_override, bool p_allocated) {
|
||||
Transform2D stretch_transform_new = Transform2D();
|
||||
if (is_size_2d_override_stretch_enabled() && p_size_2d_override.width > 0 && p_size_2d_override.height > 0) {
|
||||
Size2 scale = Size2(p_size) / Size2(p_size_2d_override);
|
||||
Size2 scale = Size2(p_size) / p_size_2d_override;
|
||||
stretch_transform_new.scale(scale);
|
||||
}
|
||||
|
||||
|
|
@ -1058,7 +1085,7 @@ bool Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override,
|
|||
}
|
||||
|
||||
Size2i Viewport::_get_size() const {
|
||||
#ifndef _3D_DISABLED
|
||||
#ifndef XR_DISABLED
|
||||
if (use_xr) {
|
||||
if (XRServer::get_singleton() != nullptr) {
|
||||
Ref<XRInterface> xr_interface = XRServer::get_singleton()->get_primary_interface();
|
||||
|
|
@ -1069,12 +1096,12 @@ Size2i Viewport::_get_size() const {
|
|||
}
|
||||
return Size2i();
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
#endif // XR_DISABLED
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
Size2i Viewport::_get_size_2d_override() const {
|
||||
Size2 Viewport::_get_size_2d_override() const {
|
||||
return size_2d_override;
|
||||
}
|
||||
|
||||
|
|
@ -1092,7 +1119,7 @@ Rect2 Viewport::get_visible_rect() const {
|
|||
r = Rect2(Point2(), size);
|
||||
}
|
||||
|
||||
if (size_2d_override != Size2i()) {
|
||||
if (size_2d_override != Size2()) {
|
||||
r.size = size_2d_override;
|
||||
}
|
||||
|
||||
|
|
@ -1488,7 +1515,28 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont
|
|||
return tooltip;
|
||||
}
|
||||
|
||||
void Viewport::cancel_tooltip() {
|
||||
_gui_cancel_tooltip();
|
||||
}
|
||||
|
||||
void Viewport::show_tooltip(Control *p_control) {
|
||||
if (!p_control) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gui.tooltip_timer.is_valid()) {
|
||||
gui.tooltip_timer->release_connections();
|
||||
gui.tooltip_timer = Ref<SceneTreeTimer>();
|
||||
}
|
||||
gui.tooltip_control = p_control;
|
||||
_gui_show_tooltip_at(p_control->get_size() / 2);
|
||||
}
|
||||
|
||||
void Viewport::_gui_show_tooltip() {
|
||||
_gui_show_tooltip_at(gui.last_mouse_pos);
|
||||
}
|
||||
|
||||
void Viewport::_gui_show_tooltip_at(const Point2i &p_pos) {
|
||||
if (!gui.tooltip_control) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1509,6 +1557,7 @@ void Viewport::_gui_show_tooltip() {
|
|||
// This way, the custom tooltip from `ConnectionsDockTree` can create
|
||||
// its own tooltip without conflicting with the default one, even an empty tooltip.
|
||||
if (base_tooltip && !base_tooltip->is_visible()) {
|
||||
memdelete(base_tooltip);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1546,6 +1595,8 @@ void Viewport::_gui_show_tooltip() {
|
|||
panel->set_flag(Window::FLAG_POPUP, false);
|
||||
panel->set_flag(Window::FLAG_MOUSE_PASSTHROUGH, true);
|
||||
panel->set_wrap_controls(true);
|
||||
panel->set_default_canvas_item_texture_filter(get_default_canvas_item_texture_filter());
|
||||
panel->set_default_canvas_item_texture_repeat(get_default_canvas_item_texture_repeat());
|
||||
panel->add_child(base_tooltip);
|
||||
panel->gui_parent = this;
|
||||
|
||||
|
|
@ -1557,20 +1608,19 @@ void Viewport::_gui_show_tooltip() {
|
|||
if (!window) { // Not embedded.
|
||||
window = gui.tooltip_popup->get_parent_visible_window();
|
||||
}
|
||||
float win_scale = window->content_scale_factor;
|
||||
Size2 scale = get_popup_base_transform().get_scale();
|
||||
real_t popup_scale = MIN(scale.x, scale.y);
|
||||
Point2 tooltip_offset = GLOBAL_GET("display/mouse_cursor/tooltip_position_offset");
|
||||
if (!gui.tooltip_popup->is_embedded()) {
|
||||
tooltip_offset *= win_scale;
|
||||
}
|
||||
tooltip_offset *= popup_scale;
|
||||
Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size());
|
||||
Rect2i vr;
|
||||
if (gui.tooltip_popup->is_embedded()) {
|
||||
vr = gui.tooltip_popup->get_embedder()->get_visible_rect();
|
||||
} else {
|
||||
panel->content_scale_factor = win_scale;
|
||||
r.size *= win_scale;
|
||||
vr = window->get_usable_parent_rect();
|
||||
}
|
||||
panel->content_scale_factor = popup_scale;
|
||||
r.size *= popup_scale;
|
||||
r.size = r.size.ceil();
|
||||
r.size = r.size.min(panel->get_max_size());
|
||||
|
||||
|
|
@ -1822,9 +1872,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (EngineDebugger::get_singleton()) {
|
||||
Array arr;
|
||||
arr.push_back(gui.mouse_focus->get_path());
|
||||
arr.push_back(gui.mouse_focus->get_class());
|
||||
Array arr = { gui.mouse_focus->get_path(), gui.mouse_focus->get_class() };
|
||||
EngineDebugger::get_singleton()->send_message("scene:click_ctrl", arr);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1834,7 +1882,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
while (ci) {
|
||||
Control *control = Object::cast_to<Control>(ci);
|
||||
if (control) {
|
||||
if (control->get_focus_mode() != Control::FOCUS_NONE) {
|
||||
if (control->get_focus_mode_with_recursive() != Control::FOCUS_NONE) {
|
||||
// Grabbing unhovered focus can cause issues when mouse is dragged
|
||||
// with another button held down.
|
||||
if (control != gui.key_focus && gui.mouse_over_hierarchy.has(control)) {
|
||||
|
|
@ -2085,7 +2133,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
}
|
||||
} else {
|
||||
ObjectID control_id = gui.touch_focus[touch_index];
|
||||
Control *over = control_id.is_valid() ? Object::cast_to<Control>(ObjectDB::get_instance(control_id)) : nullptr;
|
||||
Control *over = control_id.is_valid() ? ObjectDB::get_instance<Control>(control_id) : nullptr;
|
||||
if (over && over->can_process()) {
|
||||
touch_event = touch_event->xformed_by(Transform2D()); // Make a copy.
|
||||
pos = over->get_global_transform_with_canvas().affine_inverse().xform(pos);
|
||||
|
|
@ -2120,7 +2168,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
if (drag_event.is_valid()) {
|
||||
const int drag_event_index = drag_event->get_index();
|
||||
ObjectID control_id = gui.touch_focus[drag_event_index];
|
||||
Control *over = control_id.is_valid() ? Object::cast_to<Control>(ObjectDB::get_instance(control_id)) : nullptr;
|
||||
Control *over = control_id.is_valid() ? ObjectDB::get_instance<Control>(control_id) : nullptr;
|
||||
if (!over) {
|
||||
over = gui_find_control(drag_event->get_position());
|
||||
}
|
||||
|
|
@ -2178,6 +2226,17 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
}
|
||||
|
||||
Control *from = gui.key_focus ? gui.key_focus : nullptr;
|
||||
if (!from) {
|
||||
for (int i = 0; i < get_child_count(true); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i, true));
|
||||
if (!c || !c->is_visible_in_tree() || c->is_set_as_top_level()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
from = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (from && p_event->is_pressed()) {
|
||||
Control *next = nullptr;
|
||||
|
|
@ -2194,6 +2253,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
next = from->find_prev_valid_focus();
|
||||
}
|
||||
|
||||
if (p_event->is_action_pressed(SNAME("ui_accessibility_drag_and_drop")) && input->is_action_just_pressed(SNAME("ui_accessibility_drag_and_drop"))) {
|
||||
if (gui_is_dragging()) {
|
||||
from->accessibility_drop();
|
||||
} else {
|
||||
from->accessibility_drag();
|
||||
}
|
||||
}
|
||||
|
||||
if (p_event->is_action_pressed(SNAME("ui_up")) && input->is_action_just_pressed(SNAME("ui_up"))) {
|
||||
next = from->_get_focus_neighbor(SIDE_TOP);
|
||||
}
|
||||
|
|
@ -2218,6 +2285,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
next = from->find_prev_valid_focus();
|
||||
}
|
||||
|
||||
if (p_event->is_action_pressed(SNAME("ui_accessibility_drag_and_drop"), true, true)) {
|
||||
if (gui_is_dragging()) {
|
||||
from->accessibility_drop();
|
||||
} else {
|
||||
from->accessibility_drag();
|
||||
}
|
||||
}
|
||||
|
||||
if (p_event->is_action_pressed(SNAME("ui_up"), true, true)) {
|
||||
next = from->_get_focus_neighbor(SIDE_TOP);
|
||||
}
|
||||
|
|
@ -2243,9 +2318,13 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
|||
}
|
||||
|
||||
void Viewport::_perform_drop(Control *p_control) {
|
||||
gui_perform_drop_at(p_control ? p_control->get_local_mouse_position() : Vector2(), p_control);
|
||||
}
|
||||
|
||||
void Viewport::gui_perform_drop_at(const Point2 &p_pos, Control *p_control) {
|
||||
// Without any arguments, simply cancel Drag and Drop.
|
||||
if (p_control) {
|
||||
gui.drag_successful = _gui_drop(p_control, p_control->get_local_mouse_position(), false);
|
||||
gui.drag_successful = _gui_drop(p_control, p_pos, false);
|
||||
} else {
|
||||
gui.drag_successful = false;
|
||||
}
|
||||
|
|
@ -2259,6 +2338,7 @@ void Viewport::_perform_drop(Control *p_control) {
|
|||
Viewport *section_root = get_section_root_viewport();
|
||||
section_root->gui.drag_data = Variant();
|
||||
gui.dragging = false;
|
||||
gui.drag_description = String();
|
||||
section_root->gui.global_dragging = false;
|
||||
gui.drag_mouse_over = nullptr;
|
||||
Viewport::_propagate_drag_notification(section_root, NOTIFICATION_DRAG_END);
|
||||
|
|
@ -2287,12 +2367,23 @@ void Viewport::gui_set_root_order_dirty() {
|
|||
gui.roots_order_dirty = true;
|
||||
}
|
||||
|
||||
void Viewport::_gui_force_drag_start() {
|
||||
Viewport *section_root = get_section_root_viewport();
|
||||
section_root->gui.global_dragging = true;
|
||||
}
|
||||
|
||||
void Viewport::_gui_force_drag_cancel() {
|
||||
Viewport *section_root = get_section_root_viewport();
|
||||
section_root->gui.global_dragging = false;
|
||||
}
|
||||
|
||||
void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *p_control) {
|
||||
ERR_FAIL_COND_MSG(p_data.get_type() == Variant::NIL, "Drag data must be a value.");
|
||||
|
||||
gui.dragging = true;
|
||||
Viewport *section_root = get_section_root_viewport();
|
||||
section_root->gui.global_dragging = true;
|
||||
ERR_FAIL_COND(!section_root->gui.global_dragging);
|
||||
|
||||
gui.dragging = true;
|
||||
section_root->gui.drag_data = p_data;
|
||||
gui.mouse_focus = nullptr;
|
||||
gui.mouse_focus_mask.clear();
|
||||
|
|
@ -2324,7 +2415,7 @@ Control *Viewport::_gui_get_drag_preview() {
|
|||
if (gui.drag_preview_id.is_null()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
Control *drag_preview = Object::cast_to<Control>(ObjectDB::get_instance(gui.drag_preview_id));
|
||||
Control *drag_preview = ObjectDB::get_instance<Control>(gui.drag_preview_id);
|
||||
if (!drag_preview) {
|
||||
ERR_PRINT("Don't free the control set as drag preview.");
|
||||
gui.drag_preview_id = ObjectID();
|
||||
|
|
@ -2412,7 +2503,7 @@ void Viewport::_gui_update_mouse_over() {
|
|||
int found = gui.mouse_over_hierarchy.find(ancestor_control);
|
||||
if (found >= 0) {
|
||||
// Remove the node if the propagation chain has been broken or it is now MOUSE_FILTER_IGNORE.
|
||||
if (removing || ancestor_control->get_mouse_filter() == Control::MOUSE_FILTER_IGNORE) {
|
||||
if (removing || ancestor_control->get_mouse_filter_with_recursive() == Control::MOUSE_FILTER_IGNORE) {
|
||||
needs_exit.push_back(found);
|
||||
}
|
||||
}
|
||||
|
|
@ -2423,14 +2514,14 @@ void Viewport::_gui_update_mouse_over() {
|
|||
}
|
||||
reached_top = true;
|
||||
}
|
||||
if (!removing && ancestor_control->get_mouse_filter() != Control::MOUSE_FILTER_IGNORE) {
|
||||
if (!removing && ancestor_control->get_mouse_filter_with_recursive() != Control::MOUSE_FILTER_IGNORE) {
|
||||
new_mouse_over_hierarchy.push_back(ancestor_control);
|
||||
// Add the node if it was not found and it is now not MOUSE_FILTER_IGNORE.
|
||||
if (found < 0) {
|
||||
needs_enter.push_back(ancestor_control);
|
||||
}
|
||||
}
|
||||
if (ancestor_control->get_mouse_filter() == Control::MOUSE_FILTER_STOP) {
|
||||
if (ancestor_control->get_mouse_filter_with_recursive() == Control::MOUSE_FILTER_STOP) {
|
||||
// MOUSE_FILTER_STOP breaks the propagation chain.
|
||||
if (reached_top) {
|
||||
break;
|
||||
|
|
@ -2550,11 +2641,13 @@ void Viewport::_drop_mouse_focus() {
|
|||
}
|
||||
|
||||
void Viewport::_drop_physics_mouseover(bool p_paused_only) {
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
_cleanup_mouseover_colliders(true, p_paused_only);
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
if (physics_object_over.is_valid()) {
|
||||
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
|
||||
CollisionObject3D *co = ObjectDB::get_instance<CollisionObject3D>(physics_object_over);
|
||||
if (co) {
|
||||
if (!co->is_inside_tree()) {
|
||||
physics_object_over = ObjectID();
|
||||
|
|
@ -2566,7 +2659,7 @@ void Viewport::_drop_physics_mouseover(bool p_paused_only) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
}
|
||||
|
||||
void Viewport::_gui_grab_click_focus(Control *p_control) {
|
||||
|
|
@ -2660,11 +2753,11 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw
|
|||
|
||||
int limit = p_subwindow->theme_cache.resize_margin;
|
||||
|
||||
if (ABS(dist_x) > limit) {
|
||||
if (Math::abs(dist_x) > limit) {
|
||||
return SUB_WINDOW_RESIZE_DISABLED;
|
||||
}
|
||||
|
||||
if (ABS(dist_y) > limit) {
|
||||
if (Math::abs(dist_y) > limit) {
|
||||
return SUB_WINDOW_RESIZE_DISABLED;
|
||||
}
|
||||
|
||||
|
|
@ -3089,7 +3182,7 @@ void Viewport::_update_mouse_over(Vector2 p_pos) {
|
|||
while (ancestor) {
|
||||
Control *ancestor_control = Object::cast_to<Control>(ancestor);
|
||||
if (ancestor_control) {
|
||||
if (ancestor_control->get_mouse_filter() != Control::MOUSE_FILTER_IGNORE) {
|
||||
if (ancestor_control->get_mouse_filter_with_recursive() != Control::MOUSE_FILTER_IGNORE) {
|
||||
int found = gui.mouse_over_hierarchy.find(ancestor_control);
|
||||
if (found >= 0) {
|
||||
common_ancestor = gui.mouse_over_hierarchy[found];
|
||||
|
|
@ -3097,7 +3190,7 @@ void Viewport::_update_mouse_over(Vector2 p_pos) {
|
|||
}
|
||||
over_ancestors.push_back(ancestor_control);
|
||||
}
|
||||
if (ancestor_control->get_mouse_filter() == Control::MOUSE_FILTER_STOP) {
|
||||
if (ancestor_control->get_mouse_filter_with_recursive() == Control::MOUSE_FILTER_STOP) {
|
||||
// MOUSE_FILTER_STOP breaks the propagation chain.
|
||||
break;
|
||||
}
|
||||
|
|
@ -3339,6 +3432,7 @@ void Viewport::_push_unhandled_input_internal(const Ref<InputEvent> &p_event) {
|
|||
get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, p_event, this);
|
||||
}
|
||||
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
if (physics_object_picking && !is_input_handled()) {
|
||||
if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED &&
|
||||
(Object::cast_to<InputEventMouse>(*p_event) ||
|
||||
|
|
@ -3350,6 +3444,7 @@ void Viewport::_push_unhandled_input_internal(const Ref<InputEvent> &p_event) {
|
|||
set_input_as_handled();
|
||||
}
|
||||
}
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
}
|
||||
|
||||
void Viewport::notify_mouse_entered() {
|
||||
|
|
@ -3368,6 +3463,7 @@ void Viewport::notify_mouse_exited() {
|
|||
_mouse_leave_viewport();
|
||||
}
|
||||
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
void Viewport::set_physics_object_picking(bool p_enable) {
|
||||
ERR_MAIN_THREAD_GUARD;
|
||||
physics_object_picking = p_enable;
|
||||
|
|
@ -3403,6 +3499,7 @@ void Viewport::set_physics_object_picking_first_only(bool p_enable) {
|
|||
bool Viewport::get_physics_object_picking_first_only() {
|
||||
return physics_object_picking_first_only;
|
||||
}
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
|
||||
Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const {
|
||||
ERR_READ_THREAD_GUARD_V(Vector2());
|
||||
|
|
@ -3446,6 +3543,19 @@ void Viewport::set_disable_input_override(bool p_disable) {
|
|||
disable_input_override = p_disable;
|
||||
}
|
||||
|
||||
String Viewport::gui_get_drag_description() const {
|
||||
ERR_READ_THREAD_GUARD_V(String());
|
||||
if (get_section_root_viewport()->gui.drag_description.is_empty()) {
|
||||
return RTR("Drag-and-drop data");
|
||||
} else {
|
||||
return get_section_root_viewport()->gui.drag_description;
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::gui_set_drag_description(const String &p_description) {
|
||||
gui.drag_description = p_description;
|
||||
}
|
||||
|
||||
Variant Viewport::gui_get_drag_data() const {
|
||||
ERR_READ_THREAD_GUARD_V(Variant());
|
||||
return get_section_root_viewport()->gui.drag_data;
|
||||
|
|
@ -4039,6 +4149,7 @@ void Viewport::_camera_2d_set(Camera2D *p_camera_2d) {
|
|||
camera_2d = p_camera_2d;
|
||||
}
|
||||
|
||||
#ifndef PHYSICS_2D_DISABLED
|
||||
void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference) {
|
||||
List<ObjectID> to_erase;
|
||||
List<ObjectID> to_mouse_exit;
|
||||
|
|
@ -4108,6 +4219,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
|
|||
shapes_to_mouse_exit.pop_front();
|
||||
}
|
||||
}
|
||||
#endif // PHYSICS_2D_DISABLED
|
||||
|
||||
AudioListener2D *Viewport::get_audio_listener_2d() const {
|
||||
ERR_READ_THREAD_GUARD_V(nullptr);
|
||||
|
|
@ -4235,6 +4347,7 @@ void Viewport::_audio_listener_3d_make_next_current(AudioListener3D *p_exclude)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
|
||||
Transform3D object_transform = p_object->get_global_transform();
|
||||
Transform3D camera_transform = p_camera->get_global_transform();
|
||||
|
|
@ -4252,6 +4365,7 @@ void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Cam
|
|||
physics_last_camera_transform = camera_transform;
|
||||
physics_last_id = id;
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
Camera3D *Viewport::get_camera_3d() const {
|
||||
ERR_READ_THREAD_GUARD_V(nullptr);
|
||||
|
|
@ -4802,12 +4916,14 @@ void Viewport::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("get_texture"), &Viewport::get_texture);
|
||||
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking);
|
||||
ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
|
||||
ClassDB::bind_method(D_METHOD("set_physics_object_picking_sort", "enable"), &Viewport::set_physics_object_picking_sort);
|
||||
ClassDB::bind_method(D_METHOD("get_physics_object_picking_sort"), &Viewport::get_physics_object_picking_sort);
|
||||
ClassDB::bind_method(D_METHOD("set_physics_object_picking_first_only", "enable"), &Viewport::set_physics_object_picking_first_only);
|
||||
ClassDB::bind_method(D_METHOD("get_physics_object_picking_first_only"), &Viewport::get_physics_object_picking_first_only);
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
|
||||
ClassDB::bind_method(D_METHOD("push_text_input", "text"), &Viewport::push_text_input);
|
||||
|
|
@ -4824,6 +4940,8 @@ void Viewport::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("gui_cancel_drag"), &Viewport::gui_cancel_drag);
|
||||
ClassDB::bind_method(D_METHOD("gui_get_drag_data"), &Viewport::gui_get_drag_data);
|
||||
ClassDB::bind_method(D_METHOD("gui_get_drag_description"), &Viewport::gui_get_drag_description);
|
||||
ClassDB::bind_method(D_METHOD("gui_set_drag_description", "description"), &Viewport::gui_set_drag_description);
|
||||
ClassDB::bind_method(D_METHOD("gui_is_dragging"), &Viewport::gui_is_dragging);
|
||||
ClassDB::bind_method(D_METHOD("gui_is_drag_successful"), &Viewport::gui_is_drag_successful);
|
||||
|
||||
|
|
@ -4885,7 +5003,9 @@ void Viewport::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_mesh_lod_threshold", "pixels"), &Viewport::set_mesh_lod_threshold);
|
||||
ClassDB::bind_method(D_METHOD("get_mesh_lod_threshold"), &Viewport::get_mesh_lod_threshold);
|
||||
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking);
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d);
|
||||
ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d);
|
||||
|
|
@ -4976,10 +5096,12 @@ void Viewport::_bind_methods() {
|
|||
#ifndef _3D_DISABLED
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d");
|
||||
#endif // _3D_DISABLED
|
||||
#if !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
ADD_GROUP("Physics", "physics_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_sort"), "set_physics_object_picking_sort", "get_physics_object_picking_sort");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_first_only"), "set_physics_object_picking_first_only", "get_physics_object_picking_first_only");
|
||||
#endif // !defined(PHYSICS_2D_DISABLED) || !defined(PHYSICS_3D_DISABLED)
|
||||
ADD_GROUP("GUI", "gui_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled");
|
||||
|
|
@ -5223,7 +5345,10 @@ void SubViewport::set_size_2d_override(const Size2i &p_size) {
|
|||
|
||||
Size2i SubViewport::get_size_2d_override() const {
|
||||
ERR_READ_THREAD_GUARD_V(Size2i());
|
||||
return _get_size_2d_override();
|
||||
// Rounding will cause offset issues with the
|
||||
// exact positioning of subwindows, but changing the
|
||||
// type of size_2d_override would break compatibility.
|
||||
return Size2i((_get_size_2d_override() + Size2(0.5, 0.5)).floor());
|
||||
}
|
||||
|
||||
void SubViewport::set_size_2d_override_stretch(bool p_enable) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue