From 4766e3241947ace1c47bf0897092d95c639cd422 Mon Sep 17 00:00:00 2001 From: Koyper Date: Sat, 26 Oct 2024 12:28:59 -0500 Subject: [PATCH] Fix Tree relationship line 1px width draw bug. --- scene/gui/tree.cpp | 42 ++++++++++++++++++++++++------------------ scene/gui/tree.h | 1 + 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 9ea1130e4d9..3dddc38a70e 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2717,8 +2717,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 TreeItem *c = p_item->first_child; int base_ofs = children_pos.y - theme_cache.offset.y + p_draw_ofs.y; - int prev_ofs = base_ofs; - int prev_hl_ofs = base_ofs; + float prev_ofs = base_ofs; + float prev_hl_ofs = base_ofs; while (c) { int child_h = -1; @@ -2731,10 +2731,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 // Draw relationship lines. if (theme_cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root) && c->is_visible_in_tree()) { int parent_ofs = p_pos.x + theme_cache.item_margin; - Point2i parent_pos = Point2i(parent_ofs - theme_cache.arrow->get_width() / 2, p_pos.y + label_h / 2 + theme_cache.arrow->get_height() / 2) - theme_cache.offset + p_draw_ofs; + Point2i parent_pos = Point2i(parent_ofs - theme_cache.arrow->get_width() * 0.5, p_pos.y + label_h * 0.5 + theme_cache.arrow->get_height() * 0.5) - theme_cache.offset + p_draw_ofs; int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? theme_cache.h_separation : theme_cache.item_margin); - Point2i root_pos = Point2i(root_ofs, children_pos.y + child_self_height / 2) - theme_cache.offset + p_draw_ofs; + Point2i root_pos = Point2i(root_ofs, children_pos.y + child_self_height * 0.5) - theme_cache.offset + p_draw_ofs; if (!hide_folding && !p_item->disable_folding && c->get_visible_child_count() > 0) { root_pos -= Point2i(theme_cache.arrow->get_width(), 0); } @@ -2746,6 +2746,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 float parent_line_width = theme_cache.parent_hl_line_width * Math::round(theme_cache.base_scale); float children_line_width = theme_cache.children_hl_line_width * Math::round(theme_cache.base_scale); + float line_pixel_shift = int(Math::round(line_width * content_scale_factor)) % 2 == 0 ? 0.0 : 0.5; + 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; if (root_pos.y + line_width >= 0) { @@ -2753,37 +2757,38 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 root_pos.x = get_size().width - root_pos.x; parent_pos.x = get_size().width - parent_pos.x; } + 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. if (_is_branch_selected(c)) { // 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, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), theme_cache.parent_hl_line_color, parent_line_width); + 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); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), 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); } more_prev_ofs = theme_cache.parent_hl_line_margin; - prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + prev_hl_ofs = parent_bottom_y; } else if (p_item->is_selected(0)) { // If parent item is selected (but this item is not), we draw the line using children highlight style. // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. if (_is_sibling_branch_selected(c)) { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), theme_cache.children_hl_line_color, children_line_width); + 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); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), 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); } - prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + prev_hl_ofs = parent_bottom_y; } else { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(children_line_width / 2), root_pos.y), theme_cache.children_hl_line_color, children_line_width); + 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); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(children_line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(children_line_width / 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); } } } else { @@ -2792,24 +2797,24 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (_is_sibling_branch_selected(c)) { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + theme_cache.parent_hl_line_margin, root_pos.y), theme_cache.relationship_line_color, line_width); + 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); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), 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); } - prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + prev_hl_ofs = parent_bottom_y; } else { if (!is_no_space) { if (htotal >= 0) { - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(line_width / 2), root_pos.y), theme_cache.relationship_line_color, line_width); + 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); } - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(line_width / 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); } } } } - prev_ofs = root_pos.y + more_prev_ofs; + prev_ofs = root_pos.y + more_prev_ofs + line_pixel_shift; } if (child_h < 0) { @@ -4916,6 +4921,7 @@ void Tree::_notification(int p_what) { draw_size.y -= tbh; cache.rtl = is_layout_rtl(); + content_scale_factor = popup_editor->is_embedded() ? 1.0 : popup_editor->get_parent_visible_window()->get_content_scale_factor(); if (root && get_size().x > 0 && get_size().y > 0) { int self_height = 0; // Just to pass a reference, we don't need the root's `self_height`. diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 979b7ac2da3..afcfca964c0 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -488,6 +488,7 @@ private: Vector2 range_drag_capture_pos; bool propagate_mouse_activated = false; + float content_scale_factor = 0.0; Rect2 custom_popup_rect; int edited_col = -1;