From 3c1f1d6559441a4daadde0ef32fa6213133befc0 Mon Sep 17 00:00:00 2001 From: Adam Chyb Date: Mon, 30 Oct 2023 23:28:43 +1100 Subject: [PATCH] Fixes TreeItem minimum width calculations 1. Adds missing margins to `TreeItem::get_minimum_size`. 2. Sets minimum size dirty flags when an item is (un)collapsed. 3. Fixes depth calculation in `Tree::get_column_minimum_width` that was using the next visible item's depth when calculating the current item's minimum width. Fixes #84015. --- scene/gui/tree.cpp | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 10f4962c4830..ccfcfc4e529f 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -615,6 +615,15 @@ void TreeItem::set_collapsed(bool p_collapsed) { return; } collapsed = p_collapsed; + + for (int i = 0; i < cells.size(); i++) { + cells.write[i].cached_minimum_size_dirty = true; + } + + for (int i = 0; i < tree->columns.size(); i++) { + tree->columns.write[i].cached_minimum_width_dirty = true; + } + TreeItem *ci = tree->selected_item; if (ci) { while (ci && ci != this) { @@ -1483,6 +1492,14 @@ Size2 TreeItem::get_minimum_size(int p_column) { if (cell.cached_minimum_size_dirty) { Size2 size; + size.width += parent_tree->theme_cache.inner_item_margin_left + parent_tree->theme_cache.inner_item_margin_right; + + if (p_column == 0 && !(disable_folding || parent_tree->hide_folding)) { + size.width += parent_tree->theme_cache.item_margin; + } else { + size.width += parent_tree->theme_cache.h_separation; + } + // Text. if (!cell.text.is_empty()) { if (cell.dirty) { @@ -4683,8 +4700,19 @@ int Tree::get_column_minimum_width(int p_column) const { int depth = 0; TreeItem *next; for (TreeItem *item = get_root(); item; item = next) { + // Get the item minimum size. + Size2 item_size = item->get_minimum_size(p_column); + if (p_column == 0) { + item_size.width += theme_cache.item_margin * depth; + } else { + item_size.width += theme_cache.h_separation; + } + + // Check if the item is wider. + min_width = MAX(min_width, item_size.width); + + // Compute the depth of the next item. next = item->get_next_visible(); - // Compute the depth in tree. if (next && p_column == 0) { if (next->get_parent() == item) { depth += 1; @@ -4696,17 +4724,6 @@ int Tree::get_column_minimum_width(int p_column) const { } } } - - // Get the item minimum size. - Size2 item_size = item->get_minimum_size(p_column); - if (p_column == 0) { - item_size.width += theme_cache.item_margin * depth; - } else { - item_size.width += theme_cache.h_separation; - } - - // Check if the item is wider. - min_width = MAX(min_width, item_size.width); } }