diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/canvas_item.cpp | 12 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 73 | ||||
-rw-r--r-- | scene/main/viewport.h | 2 | ||||
-rw-r--r-- | scene/main/window.cpp | 81 | ||||
-rw-r--r-- | scene/main/window.h | 3 |
5 files changed, 102 insertions, 69 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 7b0554442c..3323c0f848 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -154,17 +154,7 @@ Transform2D CanvasItem::get_global_transform_with_canvas() const { Transform2D CanvasItem::get_screen_transform() const { ERR_FAIL_COND_V(!is_inside_tree(), Transform2D()); - Transform2D xform = get_global_transform_with_canvas(); - - Window *w = Object::cast_to<Window>(get_viewport()); - if (w && !w->is_embedding_subwindows()) { - Transform2D s; - s.set_origin(w->get_position()); - - xform = s * xform; - } - - return xform; + return get_viewport()->get_popup_base_transform() * get_global_transform_with_canvas(); } Transform2D CanvasItem::get_global_transform() const { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 07bcf45899..48cff5aa8e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -704,25 +704,15 @@ void Viewport::_process_picking() { } #ifndef _3D_DISABLED - bool captured = false; - + CollisionObject3D *capture_object = nullptr; if (physics_object_capture.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); - if (co && camera_3d) { - _collision_object_3d_input_event(co, camera_3d, ev, Vector3(), Vector3(), 0); - captured = true; - if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { - physics_object_capture = ObjectID(); - } - - } else { + capture_object = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); + if (!capture_object || !camera_3d || (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed())) { physics_object_capture = ObjectID(); } } - if (captured) { - // None. - } else if (pos == last_pos) { + if (pos == last_pos) { if (last_id.is_valid()) { if (ObjectDB::get_instance(last_id) && last_object) { // Good, exists. @@ -748,13 +738,12 @@ void Viewport::_process_picking() { bool col = space->intersect_ray(ray_params, result); ObjectID new_collider; - if (col) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); - if (co && co->can_process()) { - _collision_object_3d_input_event(co, camera_3d, ev, result.position, result.normal, result.shape); + CollisionObject3D *co = col ? Object::cast_to<CollisionObject3D>(result.collider) : nullptr; + if (co && co->can_process()) { + new_collider = result.collider_id; + if (!capture_object) { last_object = co; last_id = result.collider_id; - new_collider = last_id; if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { physics_object_capture = last_id; } @@ -763,21 +752,24 @@ void Viewport::_process_picking() { if (is_mouse && new_collider != physics_object_over) { if (physics_object_over.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); - if (co) { - co->_mouse_exit(); + CollisionObject3D *previous_co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); + if (previous_co) { + previous_co->_mouse_exit(); } } if (new_collider.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider)); - if (co) { - co->_mouse_enter(); - } + DEV_ASSERT(co); + co->_mouse_enter(); } physics_object_over = new_collider; } + if (capture_object) { + _collision_object_3d_input_event(capture_object, camera_3d, ev, result.position, result.normal, result.shape); + } else if (new_collider.is_valid()) { + _collision_object_3d_input_event(co, camera_3d, ev, result.position, result.normal, result.shape); + } } last_pos = pos; @@ -1050,7 +1042,7 @@ Camera2D *Viewport::get_camera_2d() const { } Transform2D Viewport::get_final_transform() const { - return stretch_transform * global_canvas_transform; + return _get_input_pre_xform().affine_inverse() * stretch_transform * global_canvas_transform; } void Viewport::_update_canvas_items(Node *p_node) { @@ -1133,7 +1125,7 @@ Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) { return ev; // No transformation defined for null event } - Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform(); + Transform2D ai = get_final_transform().affine_inverse(); return ev->xformed_by(ai); } @@ -1795,9 +1787,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (w->is_embedded()) { embedder = w->_get_embedder(); - Transform2D ai = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse(); - - viewport_pos = ai.xform(mpos) + w->get_position(); // To parent coords. + viewport_pos = get_final_transform().xform(mpos) + w->get_position(); // To parent coords. } } } @@ -1847,7 +1837,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (viewport_under) { if (viewport_under != this) { - Transform2D ai = (viewport_under->get_final_transform().affine_inverse() * viewport_under->_get_input_pre_xform()); + Transform2D ai = viewport_under->get_final_transform().affine_inverse(); viewport_pos = ai.xform(viewport_pos); } // Find control under at position. @@ -2853,7 +2843,7 @@ bool Viewport::get_physics_object_picking() { } Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const { - Transform2D xf = get_final_transform(); + Transform2D xf = stretch_transform * global_canvas_transform; return xf.xform(p_viewport_coords); } @@ -3245,7 +3235,7 @@ Viewport::SDFScale Viewport::get_sdf_scale() const { } Transform2D Viewport::get_screen_transform() const { - return _get_input_pre_xform().affine_inverse() * get_final_transform(); + return get_final_transform(); } void Viewport::set_canvas_cull_mask(uint32_t p_canvas_cull_mask) { @@ -4188,6 +4178,21 @@ Transform2D SubViewport::get_screen_transform() const { return container_transform * Viewport::get_screen_transform(); } +Transform2D SubViewport::get_popup_base_transform() const { + if (is_embedding_subwindows()) { + return Transform2D(); + } + SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent()); + if (!c) { + return Viewport::get_screen_transform(); + } + Transform2D container_transform; + if (c->is_stretch_enabled()) { + container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink())); + } + return c->get_screen_transform() * container_transform * Viewport::get_screen_transform(); +} + void SubViewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 603e92b071..d5d5201e9a 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -649,6 +649,7 @@ public: bool get_canvas_cull_mask_bit(uint32_t p_layer) const; virtual Transform2D get_screen_transform() const; + virtual Transform2D get_popup_base_transform() const { return Transform2D(); } #ifndef _3D_DISABLED bool use_xr = false; @@ -775,6 +776,7 @@ public: ClearMode get_clear_mode() const; virtual Transform2D get_screen_transform() const override; + virtual Transform2D get_popup_base_transform() const override; SubViewport(); ~SubViewport(); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 2c6599d849..869d12b4df 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -663,18 +663,18 @@ void Window::set_visible(bool p_visible) { return; } - visible = p_visible; - if (!is_inside_tree()) { + visible = p_visible; return; } - if (updating_child_controls) { - _update_child_controls(); - } - ERR_FAIL_COND_MSG(get_parent() == nullptr, "Can't change visibility of main window."); + visible = p_visible; + + // Stop any queued resizing, as the window will be resized right now. + updating_child_controls = false; + Viewport *embedder_vp = _get_embedder(); if (!embedder_vp) { @@ -833,7 +833,7 @@ bool Window::is_visible() const { } void Window::_update_window_size() { - // Force window to respect size limitations of rendering server + // Force window to respect size limitations of rendering server. RenderingServer *rendering_server = RenderingServer::get_singleton(); if (rendering_server) { Size2i max_window_size = rendering_server->get_maximum_viewport_size(); @@ -1130,6 +1130,7 @@ void Window::_notification(int p_what) { case NOTIFICATION_READY: { if (wrap_controls) { + // Finish any resizing immediately so it doesn't interfere on stuff overriding _ready(). _update_child_controls(); } } break; @@ -1138,9 +1139,7 @@ void Window::_notification(int p_what) { _invalidate_theme_cache(); _update_theme_item_cache(); - if (embedder) { - embedder->_sub_window_update(this); - } else if (window_id != DisplayServer::INVALID_WINDOW_ID) { + if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID) { String tr_title = atr(title); #ifdef DEBUG_ENABLED if (window_id == DisplayServer::MAIN_WINDOW_ID) { @@ -1152,8 +1151,6 @@ void Window::_notification(int p_what) { #endif DisplayServer::get_singleton()->window_set_title(tr_title, window_id); } - - child_controls_changed(); } break; case NOTIFICATION_EXIT_TREE: { @@ -1254,8 +1251,13 @@ Vector<Vector2> Window::get_mouse_passthrough_polygon() const { void Window::set_wrap_controls(bool p_enable) { wrap_controls = p_enable; - if (wrap_controls) { - child_controls_changed(); + + if (!is_inside_tree()) { + return; + } + + if (updating_child_controls) { + _update_child_controls(); } else { _update_window_size(); } @@ -1282,23 +1284,23 @@ Size2 Window::_get_contents_minimum_size() const { return max; } -void Window::_update_child_controls() { - if (!updating_child_controls) { +void Window::child_controls_changed() { + if (!is_inside_tree() || !visible || updating_child_controls) { return; } - _update_window_size(); - - updating_child_controls = false; + updating_child_controls = true; + call_deferred(SNAME("_update_child_controls")); } -void Window::child_controls_changed() { - if (!is_inside_tree() || !visible || updating_child_controls) { +void Window::_update_child_controls() { + if (!updating_child_controls) { return; } - updating_child_controls = true; - call_deferred(SNAME("_update_child_controls")); + _update_window_size(); + + updating_child_controls = false; } bool Window::_can_consume_input_events() const { @@ -1647,7 +1649,24 @@ void Window::_invalidate_theme_cache() { void Window::_update_theme_item_cache() { // Request an update on the next frame to reflect theme changes. // Updating without a delay can cause a lot of lag. - child_controls_changed(); + if (!wrap_controls) { + updating_embedded_window = true; + call_deferred(SNAME("_update_embedded_window")); + } else { + child_controls_changed(); + } +} + +void Window::_update_embedded_window() { + if (!updating_embedded_window) { + return; + } + + if (embedder) { + embedder->_sub_window_update(this); + }; + + updating_embedded_window = false; } void Window::set_theme_type_variation(const StringName &p_theme_type) { @@ -2104,6 +2123,19 @@ Transform2D Window::get_screen_transform() const { return embedder_transform * Viewport::get_screen_transform(); } +Transform2D Window::get_popup_base_transform() const { + if (is_embedding_subwindows()) { + return Transform2D(); + } + Transform2D window_transform; + window_transform.set_origin(get_position()); + window_transform *= Viewport::get_screen_transform(); + if (_get_embedder()) { + return _get_embedder()->get_popup_base_transform() * window_transform; + } + return window_transform; +} + void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title); ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title); @@ -2188,6 +2220,7 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("child_controls_changed"), &Window::child_controls_changed); ClassDB::bind_method(D_METHOD("_update_child_controls"), &Window::_update_child_controls); + ClassDB::bind_method(D_METHOD("_update_embedded_window"), &Window::_update_embedded_window); ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Window::set_theme); ClassDB::bind_method(D_METHOD("get_theme"), &Window::get_theme); diff --git a/scene/main/window.h b/scene/main/window.h index e9c217f973..182caf5f0c 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -116,6 +116,7 @@ private: bool exclusive = false; bool wrap_controls = false; bool updating_child_controls = false; + bool updating_embedded_window = false; bool clamp_to_embedder = false; LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; @@ -123,6 +124,7 @@ private: bool auto_translate = true; void _update_child_controls(); + void _update_embedded_window(); Size2i content_scale_size; ContentScaleMode content_scale_mode = CONTENT_SCALE_MODE_DISABLED; @@ -373,6 +375,7 @@ public: // virtual Transform2D get_screen_transform() const override; + virtual Transform2D get_popup_base_transform() const override; Rect2i get_parent_rect() const; virtual DisplayServer::WindowID get_window_id() const override; |