From a8ae40d590b5f789ce7a89aafb24b07c8be16f36 Mon Sep 17 00:00:00 2001 From: BrotherShort <129957860+BrotherShort@users.noreply.github.com> Date: Sun, 8 Feb 2026 10:01:09 +0800 Subject: [PATCH] fix inaccurate tree relationship lines Co-Authored-By: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> --- scene/gui/tree.cpp | 67 +++++++++++++++++++++++++++++++--------------- scene/gui/tree.h | 5 ++-- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 7eab2cc932..d41fc65eb1 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2084,18 +2084,25 @@ int Tree::get_item_height(TreeItem *p_item) const { return height; } -Point2i Tree::convert_rtl_position(const Point2i &pos, int width) const { +Point2i Tree::convert_rtl_position(const Point2i &p_pos, int p_width) const { if (cache.rtl) { - return Point2i(get_size().width - pos.x - width, pos.y); + return Point2i(get_size().width - p_pos.x - p_width, p_pos.y); } - return pos; + return p_pos; } -Rect2i Tree::convert_rtl_rect(const Rect2i &rect) const { +Point2 Tree::convert_rtl_position(const Point2 &p_pos, int p_width) const { if (cache.rtl) { - return Rect2i(Point2i(get_size().width - rect.position.x - rect.size.x, rect.position.y), rect.size); + return Point2(get_size().width - p_pos.x - p_width, p_pos.y); } - return rect; + return p_pos; +} + +Rect2i Tree::convert_rtl_rect(const Rect2i &p_rect) const { + if (cache.rtl) { + return Rect2i(Point2i(get_size().width - p_rect.position.x - p_rect.size.x, p_rect.position.y), p_rect.size); + } + return p_rect; } void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color) const { @@ -2839,11 +2846,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 float parent_line_pixel_shift = int(Math::round(parent_line_width * content_scale_factor)) % 2 == 0 ? 0.0 : 0.5; float children_line_pixel_shift = int(Math::round(children_line_width * content_scale_factor)) % 2 == 0 ? 0.0 : 0.5; - int more_prev_ofs = 0; + int v_hl_margin = 0; if (root_pos.y + line_width >= 0) { - root_pos = convert_rtl_position(root_pos); - parent_pos = convert_rtl_position(parent_pos); float parent_bottom_y = root_pos.y + parent_line_width * 0.5 + parent_line_pixel_shift; // Order of parts on this bend: the horizontal line first, then the vertical line. @@ -2851,12 +2856,16 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 // If this item or one of its children is selected, we draw the line using parent highlight style. if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(root_pos.x, root_pos.y + parent_line_pixel_shift), Point2(parent_pos.x + parent_line_width * 0.5 + parent_line_pixel_shift, root_pos.y + parent_line_pixel_shift), theme_cache.parent_hl_line_color, parent_line_width); + Point2 h_p_1 = convert_rtl_position(Point2(root_pos.x, root_pos.y + parent_line_pixel_shift)); + Point2 h_p_2 = convert_rtl_position(Point2(parent_pos.x + parent_line_width * 0.5 + parent_line_pixel_shift, root_pos.y + parent_line_pixel_shift)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, h_p_1, h_p_2, theme_cache.parent_hl_line_color, parent_line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(parent_pos.x + parent_line_pixel_shift, parent_bottom_y), Point2(parent_pos.x + parent_line_pixel_shift, prev_hl_ofs), theme_cache.parent_hl_line_color, parent_line_width); + Point2 v_p_1 = convert_rtl_position(Point2(parent_pos.x + parent_line_pixel_shift, parent_bottom_y)); + Point2 v_p_2 = convert_rtl_position(Point2(parent_pos.x + parent_line_pixel_shift, prev_hl_ofs)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, v_p_1, v_p_2, theme_cache.parent_hl_line_color, parent_line_width); } - more_prev_ofs = theme_cache.parent_hl_line_margin; + v_hl_margin = theme_cache.parent_hl_line_margin; prev_hl_ofs = parent_bottom_y; has_sibling_selection = _is_sibling_branch_selected(c); } else if (p_item->is_any_column_selected()) { @@ -2865,18 +2874,26 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (has_sibling_selection) { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(root_pos.x, root_pos.y + children_line_pixel_shift), Point2i(parent_pos.x + parent_line_width * 0.5 + children_line_pixel_shift, root_pos.y + children_line_pixel_shift), theme_cache.children_hl_line_color, children_line_width); + Point2 h_p_1 = convert_rtl_position(Point2(root_pos.x, root_pos.y + children_line_pixel_shift)); + Point2 h_p_2 = convert_rtl_position(Point2(parent_pos.x + parent_line_width * 0.5 + children_line_pixel_shift, root_pos.y + children_line_pixel_shift)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, h_p_1, h_p_2, theme_cache.children_hl_line_color, children_line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(parent_pos.x + parent_line_pixel_shift, parent_bottom_y), Point2(parent_pos.x + parent_line_pixel_shift, prev_hl_ofs), theme_cache.parent_hl_line_color, parent_line_width); + Point2 v_p_1 = convert_rtl_position(Point2(parent_pos.x + parent_line_pixel_shift, parent_bottom_y)); + Point2 v_p_2 = convert_rtl_position(Point2(parent_pos.x + parent_line_pixel_shift, prev_hl_ofs)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, v_p_1, v_p_2, theme_cache.parent_hl_line_color, parent_line_width); } prev_hl_ofs = parent_bottom_y; } else { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(root_pos.x, root_pos.y + children_line_pixel_shift), Point2(parent_pos.x + children_line_width * 0.5 + children_line_pixel_shift, root_pos.y + children_line_pixel_shift), theme_cache.children_hl_line_color, children_line_width); + Point2 h_p_1 = convert_rtl_position(Point2(root_pos.x, root_pos.y + children_line_pixel_shift)); + Point2 h_p_2 = convert_rtl_position(Point2(parent_pos.x + children_line_width * 0.5 + children_line_pixel_shift, root_pos.y + children_line_pixel_shift)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, h_p_1, h_p_2, theme_cache.children_hl_line_color, children_line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(parent_pos.x + children_line_pixel_shift, root_pos.y + children_line_width * 0.5 + children_line_pixel_shift), Point2(parent_pos.x + children_line_pixel_shift, prev_ofs + children_line_width * 0.5), theme_cache.children_hl_line_color, children_line_width); + Point2 v_p_1 = convert_rtl_position(Point2(parent_pos.x + children_line_pixel_shift, root_pos.y + children_line_width * 0.5 + children_line_pixel_shift)); + Point2 v_p_2 = convert_rtl_position(Point2(parent_pos.x + children_line_pixel_shift, prev_ofs + children_line_width * 0.5)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, v_p_1, v_p_2, theme_cache.children_hl_line_color, children_line_width); } } } else { @@ -2885,18 +2902,26 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (has_sibling_selection) { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(root_pos.x, root_pos.y + line_pixel_shift), Point2(parent_pos.x + theme_cache.parent_hl_line_margin, root_pos.y + line_pixel_shift), theme_cache.relationship_line_color, line_width); + Point2 h_p_1 = convert_rtl_position(Point2(root_pos.x, root_pos.y + line_pixel_shift)); + Point2 h_p_2 = convert_rtl_position(Point2(parent_pos.x + theme_cache.parent_hl_line_margin, root_pos.y + line_pixel_shift)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, h_p_1, h_p_2, theme_cache.relationship_line_color, line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(parent_pos.x + parent_line_pixel_shift, parent_bottom_y), Point2(parent_pos.x + parent_line_pixel_shift, prev_hl_ofs), theme_cache.parent_hl_line_color, parent_line_width); + Point2 v_p_1 = convert_rtl_position(Point2(parent_pos.x + parent_line_pixel_shift, parent_bottom_y)); + Point2 v_p_2 = convert_rtl_position(Point2(parent_pos.x + parent_line_pixel_shift, prev_hl_ofs)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, v_p_1, v_p_2, theme_cache.parent_hl_line_color, parent_line_width); } prev_hl_ofs = parent_bottom_y; } else { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(root_pos.x, root_pos.y + line_pixel_shift), Point2(parent_pos.x + line_width * 0.5 + line_pixel_shift, root_pos.y + line_pixel_shift), theme_cache.relationship_line_color, line_width); + Point2 h_p_1 = convert_rtl_position(Point2(root_pos.x, root_pos.y + line_pixel_shift)); + Point2 h_p_2 = convert_rtl_position(Point2(parent_pos.x + line_width * 0.5 + line_pixel_shift, root_pos.y + line_pixel_shift)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, h_p_1, h_p_2, theme_cache.relationship_line_color, line_width); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2(parent_pos.x + line_pixel_shift, root_pos.y + line_width * 0.5 + line_pixel_shift), Point2(parent_pos.x + line_pixel_shift, prev_ofs + line_width * 0.5), theme_cache.relationship_line_color, line_width); + Point2 v_p_1 = convert_rtl_position(Point2(parent_pos.x + line_pixel_shift, root_pos.y + line_width * 0.5 + line_pixel_shift)); + Point2 v_p_2 = convert_rtl_position(Point2(parent_pos.x + line_pixel_shift, prev_ofs + line_width * 0.5)); + RenderingServer::get_singleton()->canvas_item_add_line(ci, v_p_1, v_p_2, theme_cache.relationship_line_color, line_width); } } } @@ -2906,7 +2931,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } } - prev_ofs = root_pos.y + more_prev_ofs + line_pixel_shift; + prev_ofs = root_pos.y + v_hl_margin + line_pixel_shift; } if (child_h < 0) { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 81541869bb..2983898778 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -568,8 +568,9 @@ private: int compute_item_height(TreeItem *p_item) const; int get_item_height(TreeItem *p_item) const; - Point2i convert_rtl_position(const Point2i &pos, int width = 0) const; - Rect2i convert_rtl_rect(const Rect2i &Rect2) const; + Point2i convert_rtl_position(const Point2i &p_pos, int p_width = 0) const; + Point2 convert_rtl_position(const Point2 &p_pos, int p_width = 0) const; + Rect2i convert_rtl_rect(const Rect2i &p_rect) const; void _update_all(); void update_column(int p_col); void update_item_cell(TreeItem *p_item, int p_col) const;