Skip to content

Commit f463e28

Browse files
committed
Make possible to select remote canvas items inside subviewports
1 parent 2cb2c1f commit f463e28

File tree

1 file changed

+41
-8
lines changed

1 file changed

+41
-8
lines changed

scene/debugger/scene_debugger.cpp

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "core/templates/local_vector.h"
4343
#include "scene/2d/camera_2d.h"
4444
#include "scene/gui/popup_menu.h"
45+
#include "scene/gui/subviewport_container.h"
4546
#include "scene/main/canvas_layer.h"
4647
#include "scene/main/scene_tree.h"
4748
#include "scene/main/window.h"
@@ -2340,11 +2341,29 @@ void RuntimeNodeSelect::_set_selection_visible(bool p_visible) {
23402341

23412342
// Copied and trimmed from the CanvasItemEditor implementation.
23422343
void RuntimeNodeSelect::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<SelectResult> &r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
2343-
if (!p_node || Object::cast_to<Viewport>(p_node)) {
2344+
if (!p_node || Object::cast_to<Window>(p_node)) {
23442345
return;
23452346
}
23462347

2348+
Transform2D xform = p_canvas_xform;
23472349
CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
2350+
CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node);
2351+
2352+
if (SubViewport *sv = Object::cast_to<SubViewport>(p_node)) {
2353+
if (SubViewportContainer *svc = Object::cast_to<SubViewportContainer>(sv->get_parent())) {
2354+
Transform2D sv_xform = p_parent_xform * sv->get_canvas_transform();
2355+
if (svc->is_stretch_enabled()) {
2356+
Transform2D container;
2357+
container.scale(Size2(svc->get_stretch_shrink(), svc->get_stretch_shrink()));
2358+
sv_xform *= container;
2359+
}
2360+
2361+
if (sv->get_visible_rect().has_point((p_parent_xform * xform).affine_inverse().xform(p_pos))) {
2362+
xform = sv_xform;
2363+
}
2364+
}
2365+
}
2366+
23482367
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
23492368
if (ci) {
23502369
if (!ci->is_set_as_top_level()) {
@@ -2353,16 +2372,14 @@ void RuntimeNodeSelect::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_n
23532372
_find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, ci->get_transform(), p_canvas_xform);
23542373
}
23552374
} else {
2356-
CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node);
2357-
_find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, Transform2D(), cl ? cl->get_transform() : p_canvas_xform);
2375+
_find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, Transform2D(), cl ? cl->get_transform() : xform);
23582376
}
23592377
}
23602378

23612379
if (!ci || !ci->is_visible_in_tree()) {
23622380
return;
23632381
}
23642382

2365-
Transform2D xform = p_canvas_xform;
23662383
if (!ci->is_set_as_top_level()) {
23672384
xform *= p_parent_xform;
23682385
}
@@ -2403,11 +2420,29 @@ void RuntimeNodeSelect::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_n
24032420

24042421
// Copied and trimmed from the CanvasItemEditor implementation.
24052422
void RuntimeNodeSelect::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, Vector<SelectResult> &r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
2406-
if (!p_node || Object::cast_to<Viewport>(p_node)) {
2423+
if (!p_node || Object::cast_to<Window>(p_node)) {
24072424
return;
24082425
}
24092426

2427+
Transform2D xform = p_canvas_xform;
24102428
CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
2429+
CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node);
2430+
2431+
if (SubViewport *sv = Object::cast_to<SubViewport>(p_node)) {
2432+
if (SubViewportContainer *svc = Object::cast_to<SubViewportContainer>(sv->get_parent())) {
2433+
Transform2D sv_xform = p_parent_xform * sv->get_canvas_transform();
2434+
if (svc->is_stretch_enabled()) {
2435+
Transform2D container;
2436+
container.scale(Size2(svc->get_stretch_shrink(), svc->get_stretch_shrink()));
2437+
sv_xform *= container;
2438+
}
2439+
2440+
if (sv->get_visible_rect().intersects((p_parent_xform * xform).affine_inverse().xform(p_rect))) {
2441+
xform = sv_xform;
2442+
}
2443+
}
2444+
}
2445+
24112446
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
24122447
if (ci) {
24132448
if (!ci->is_set_as_top_level()) {
@@ -2416,16 +2451,14 @@ void RuntimeNodeSelect::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_
24162451
_find_canvas_items_at_rect(p_rect, p_node->get_child(i), r_items, ci->get_transform(), p_canvas_xform);
24172452
}
24182453
} else {
2419-
CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node);
2420-
_find_canvas_items_at_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), cl ? cl->get_transform() : p_canvas_xform);
2454+
_find_canvas_items_at_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), cl ? cl->get_transform() : xform);
24212455
}
24222456
}
24232457

24242458
if (!ci || !ci->is_visible_in_tree()) {
24252459
return;
24262460
}
24272461

2428-
Transform2D xform = p_canvas_xform;
24292462
if (!ci->is_set_as_top_level()) {
24302463
xform *= p_parent_xform;
24312464
}

0 commit comments

Comments
 (0)