From bde87db4437b5b9a00299bf9f3c147a842505144 Mon Sep 17 00:00:00 2001 From: Giganzo <158825920+Giganzo@users.noreply.github.com> Date: Tue, 28 Jan 2025 06:40:28 +0100 Subject: [PATCH] Fix get_item_area_rect when tree is scrolled --- editor/plugins/animation_library_editor.cpp | 4 +- scene/gui/tree.cpp | 41 ++++++++++++++++++--- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp index a4224db1c3d..da31447b561 100644 --- a/editor/plugins/animation_library_editor.cpp +++ b/editor/plugins/animation_library_editor.cpp @@ -605,7 +605,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int file_popup->add_separator(); file_popup->add_item(TTR("Open in Inspector"), FILE_MENU_EDIT_LIBRARY); Rect2 pos = tree->get_item_rect(p_item, 1, 0); - Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)) - tree->get_scroll(); + Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)); file_popup->popup(Rect2(popup_pos, Size2())); file_dialog_animation = StringName(); @@ -645,7 +645,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int file_popup->add_separator(); file_popup->add_item(TTR("Open in Inspector"), FILE_MENU_EDIT_ANIMATION); Rect2 pos = tree->get_item_rect(p_item, 1, 0); - Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)) - tree->get_scroll(); + Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)); file_popup->popup(Rect2(popup_pos, Size2())); file_dialog_animation = anim_name; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 5de64bbe3fd..679b13afa03 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -5208,10 +5208,12 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const { } int ofs = get_item_offset(p_item); - int height = compute_item_height(p_item); + int height = compute_item_height(p_item) + theme_cache.v_separation; Rect2 r; - r.position.y = ofs; + r.position.y = ofs - theme_cache.offset.y + theme_cache.panel_style->get_offset().y; r.size.height = height; + bool rtl = is_layout_rtl(); + const Rect2 content_rect = _get_content_rect(); if (p_column == -1) { r.position.x = 0; @@ -5221,18 +5223,45 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const { for (int i = 0; i < p_column; i++) { accum += get_column_width(i); } - r.position.x = accum; + r.position.x = (rtl) ? get_size().x - (accum - theme_cache.offset.x) - get_column_width(p_column) - theme_cache.panel_style->get_margin(SIDE_LEFT) : accum - theme_cache.offset.x + theme_cache.panel_style->get_margin(SIDE_LEFT); r.size.x = get_column_width(p_column); if (p_button != -1) { + // RTL direction support for button rect is different due to buttons not + // having same behavior as they do in LTR when tree is scrolled. const TreeItem::Cell &c = p_item->cells[p_column]; - Vector2 ofst = Vector2(r.position.x + r.size.x, r.position.y); + Vector2 ofst = Vector2(r.position.x + r.size.x + theme_cache.button_margin, r.position.y); + + // Compute total width of buttons block including spacings. + int buttons_width = 0; for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref b = c.buttons[j].texture; Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size(); - ofst.x -= size.x; + buttons_width += size.width + theme_cache.button_margin; + } + for (int j = c.buttons.size() - 1; j >= 0; j--) { + Ref b = c.buttons[j].texture; + Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size(); + ofst.x -= size.x + theme_cache.button_margin; + + if (rtl) { + if (j == p_button) { + return Rect2(r.position, Size2(size.x, r.size.y)); + } + r.position.x += size.x + theme_cache.button_margin; + continue; + } if (j == p_button) { - return Rect2(ofst, size); + float content_rect_end_x = content_rect.position.x + content_rect.size.width; + if (r.position.x + r.size.x < content_rect_end_x) { + return Rect2(ofst, Size2(size.x, r.size.y)); + } + // Button block can be outside of content_rect + if (content_rect_end_x - (r.position.x + theme_cache.h_separation) < buttons_width) { + return Rect2(r.position + Point2(theme_cache.h_separation + (buttons_width - ((r.position.x + r.size.x) - ofst.x)), 0), Size2(size.x, r.size.y)); + } + + return Rect2(ofst - Vector2((r.position.x + r.size.x) - content_rect_end_x, 0), Size2(size.x, r.size.y)); } } }