summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Sauermann <6299227+Sauermann@users.noreply.github.com>2022-11-13 21:38:29 +0100
committerMarkus Sauermann <6299227+Sauermann@users.noreply.github.com>2023-01-26 15:15:14 +0100
commitc4ed247f5f49eeda614290bf8e0b61df9a6f089e (patch)
tree78673db3f3f5408d5d52fbf6250438fd4b2df9d8
parentb05e1e7d6982c1a0ebbba2e1da60bf05fd2a009a (diff)
Fix position of Tooltips
CanvasItem::get_screen_transform returns a transform from the CanvasItem to the coordinate system, where a Popup - created as a child of the CanvasItem - should be opened. get_screen_transform makes some simplifications, that work well, when used in the editor, but not in general cases. Since Popups like Tooltips are now used more commonly in projects, it becomes necessary to correct these simplifications. This solution introduces Viewport::get_popup_base_transform, which makes the necessary calculations.
-rw-r--r--scene/main/canvas_item.cpp12
-rw-r--r--scene/main/viewport.cpp15
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/main/window.cpp13
-rw-r--r--scene/main/window.h1
5 files changed, 32 insertions, 11 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 7bcd4721fc..eb2615e20a 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 43a2c9473e..94fc2c3ae1 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -4183,6 +4183,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 dc69ec24d8..3e6181075b 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 ebb11ecee8..e46f107f20 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1641,6 +1641,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);
diff --git a/scene/main/window.h b/scene/main/window.h
index 03597b309a..dc48e71a0f 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -314,6 +314,7 @@ public:
int get_theme_default_font_size() const;
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;