Browse Source

Implement Tree's internal minimum width calculation

Gilles Roudière 4 years ago
parent
commit
d7d32ced5b

+ 7 - 7
doc/classes/Tree.xml

@@ -232,7 +232,7 @@
 				Returns the last pressed button's index.
 			</description>
 		</method>
-		<method name="get_root">
+		<method name="get_root" qualifiers="const">
 			<return type="TreeItem">
 			</return>
 			<description>
@@ -272,26 +272,26 @@
 			<description>
 			</description>
 		</method>
-		<method name="set_column_expand">
+		<method name="set_column_custom_minimum_width">
 			<return type="void">
 			</return>
 			<argument index="0" name="column" type="int">
 			</argument>
-			<argument index="1" name="expand" type="bool">
+			<argument index="1" name="min_width" type="int">
 			</argument>
 			<description>
-				If [code]true[/code], the column will have the "Expand" flag of [Control]. Columns that have the "Expand" flag will use their "min_width" in a similar fashion to [member Control.size_flags_stretch_ratio].
+				Overrides the calculated minimum width of a column. It can be set to `0` to restore the default behavior. Columns that have the "Expand" flag will use their "min_width" in a similar fashion to [member Control.size_flags_stretch_ratio].
 			</description>
 		</method>
-		<method name="set_column_min_width">
+		<method name="set_column_expand">
 			<return type="void">
 			</return>
 			<argument index="0" name="column" type="int">
 			</argument>
-			<argument index="1" name="min_width" type="int">
+			<argument index="1" name="expand" type="bool">
 			</argument>
 			<description>
-				Sets the minimum width of a column. Columns that have the "Expand" flag will use their "min_width" in a similar fashion to [member Control.size_flags_stretch_ratio].
+				If [code]true[/code], the column will have the "Expand" flag of [Control]. Columns that have the "Expand" flag will use their "min_width" in a similar fashion to [member Control.size_flags_stretch_ratio].
 			</description>
 		</method>
 		<method name="set_column_title">

+ 4 - 4
doc/classes/TreeItem.xml

@@ -192,7 +192,7 @@
 				Returns [code]true[/code] if [code]expand_right[/code] is set.
 			</description>
 		</method>
-		<method name="get_first_child">
+		<method name="get_first_child" qualifiers="const">
 			<return type="TreeItem">
 			</return>
 			<description>
@@ -260,7 +260,7 @@
 				Returns the metadata value that was set for the given column using [method set_metadata].
 			</description>
 		</method>
-		<method name="get_next">
+		<method name="get_next" qualifiers="const">
 			<return type="TreeItem">
 			</return>
 			<description>
@@ -288,7 +288,7 @@
 				Returns OpenType feature [code]tag[/code] of the item's text.
 			</description>
 		</method>
-		<method name="get_parent">
+		<method name="get_parent" qualifiers="const">
 			<return type="TreeItem">
 			</return>
 			<description>
@@ -391,7 +391,7 @@
 				Returns the given column's tooltip.
 			</description>
 		</method>
-		<method name="get_tree">
+		<method name="get_tree" qualifiers="const">
 			<return type="Tree">
 			</return>
 			<description>

+ 2 - 2
editor/action_map_editor.cpp

@@ -1125,9 +1125,9 @@ ActionMapEditor::ActionMapEditor() {
 	action_tree->set_column_title(0, TTR("Action"));
 	action_tree->set_column_title(1, TTR("Deadzone"));
 	action_tree->set_column_expand(1, false);
-	action_tree->set_column_min_width(1, 80 * EDSCALE);
+	action_tree->set_column_custom_minimum_width(1, 80 * EDSCALE);
 	action_tree->set_column_expand(2, false);
-	action_tree->set_column_min_width(2, 50 * EDSCALE);
+	action_tree->set_column_custom_minimum_width(2, 50 * EDSCALE);
 	action_tree->connect("item_edited", callable_mp(this, &ActionMapEditor::_action_edited));
 	action_tree->connect("item_activated", callable_mp(this, &ActionMapEditor::_tree_item_activated));
 	action_tree->connect("button_pressed", callable_mp(this, &ActionMapEditor::_tree_button_pressed));

+ 5 - 5
editor/debugger/editor_network_profiler.cpp

@@ -178,19 +178,19 @@ EditorNetworkProfiler::EditorNetworkProfiler() {
 	counters_display->set_column_titles_visible(true);
 	counters_display->set_column_title(0, TTR("Node"));
 	counters_display->set_column_expand(0, true);
-	counters_display->set_column_min_width(0, 60 * EDSCALE);
+	counters_display->set_column_custom_minimum_width(0, 60 * EDSCALE);
 	counters_display->set_column_title(1, TTR("Incoming RPC"));
 	counters_display->set_column_expand(1, false);
-	counters_display->set_column_min_width(1, 120 * EDSCALE);
+	counters_display->set_column_custom_minimum_width(1, 120 * EDSCALE);
 	counters_display->set_column_title(2, TTR("Incoming RSET"));
 	counters_display->set_column_expand(2, false);
-	counters_display->set_column_min_width(2, 120 * EDSCALE);
+	counters_display->set_column_custom_minimum_width(2, 120 * EDSCALE);
 	counters_display->set_column_title(3, TTR("Outgoing RPC"));
 	counters_display->set_column_expand(3, false);
-	counters_display->set_column_min_width(3, 120 * EDSCALE);
+	counters_display->set_column_custom_minimum_width(3, 120 * EDSCALE);
 	counters_display->set_column_title(4, TTR("Outgoing RSET"));
 	counters_display->set_column_expand(4, false);
-	counters_display->set_column_min_width(4, 120 * EDSCALE);
+	counters_display->set_column_custom_minimum_width(4, 120 * EDSCALE);
 	add_child(counters_display);
 
 	frame_delay = memnew(Timer);

+ 3 - 3
editor/debugger/editor_profiler.cpp

@@ -631,13 +631,13 @@ EditorProfiler::EditorProfiler() {
 	variables->set_column_titles_visible(true);
 	variables->set_column_title(0, TTR("Name"));
 	variables->set_column_expand(0, true);
-	variables->set_column_min_width(0, 60 * EDSCALE);
+	variables->set_column_custom_minimum_width(0, 60 * EDSCALE);
 	variables->set_column_title(1, TTR("Time"));
 	variables->set_column_expand(1, false);
-	variables->set_column_min_width(1, 100 * EDSCALE);
+	variables->set_column_custom_minimum_width(1, 100 * EDSCALE);
 	variables->set_column_title(2, TTR("Calls"));
 	variables->set_column_expand(2, false);
-	variables->set_column_min_width(2, 60 * EDSCALE);
+	variables->set_column_custom_minimum_width(2, 60 * EDSCALE);
 	variables->connect("item_edited", callable_mp(this, &EditorProfiler::_item_edited));
 
 	graph = memnew(TextureRect);

+ 3 - 3
editor/debugger/editor_visual_profiler.cpp

@@ -773,13 +773,13 @@ EditorVisualProfiler::EditorVisualProfiler() {
 	variables->set_column_titles_visible(true);
 	variables->set_column_title(0, TTR("Name"));
 	variables->set_column_expand(0, true);
-	variables->set_column_min_width(0, 60);
+	variables->set_column_custom_minimum_width(0, 60);
 	variables->set_column_title(1, TTR("CPU"));
 	variables->set_column_expand(1, false);
-	variables->set_column_min_width(1, 60 * EDSCALE);
+	variables->set_column_custom_minimum_width(1, 60 * EDSCALE);
 	variables->set_column_title(2, TTR("GPU"));
 	variables->set_column_expand(2, false);
-	variables->set_column_min_width(2, 60 * EDSCALE);
+	variables->set_column_custom_minimum_width(2, 60 * EDSCALE);
 	variables->connect("cell_selected", callable_mp(this, &EditorVisualProfiler::_item_selected));
 
 	graph = memnew(TextureRect);

+ 4 - 4
editor/debugger/script_editor_debugger.cpp

@@ -1643,7 +1643,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
 		error_tree->set_columns(2);
 
 		error_tree->set_column_expand(0, false);
-		error_tree->set_column_min_width(0, 140);
+		error_tree->set_column_custom_minimum_width(0, 140);
 
 		error_tree->set_column_expand(1, true);
 
@@ -1731,13 +1731,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
 		vmem_tree->set_column_expand(0, true);
 		vmem_tree->set_column_expand(1, false);
 		vmem_tree->set_column_title(1, TTR("Type"));
-		vmem_tree->set_column_min_width(1, 100 * EDSCALE);
+		vmem_tree->set_column_custom_minimum_width(1, 100 * EDSCALE);
 		vmem_tree->set_column_expand(2, false);
 		vmem_tree->set_column_title(2, TTR("Format"));
-		vmem_tree->set_column_min_width(2, 150 * EDSCALE);
+		vmem_tree->set_column_custom_minimum_width(2, 150 * EDSCALE);
 		vmem_tree->set_column_expand(3, false);
 		vmem_tree->set_column_title(3, TTR("Usage"));
-		vmem_tree->set_column_min_width(3, 80 * EDSCALE);
+		vmem_tree->set_column_custom_minimum_width(3, 80 * EDSCALE);
 		vmem_tree->set_hide_root(true);
 
 		tabs->add_child(vmem_vb);

+ 1 - 1
editor/dependency_editor.cpp

@@ -769,7 +769,7 @@ OrphanResourcesDialog::OrphanResourcesDialog() {
 	files = memnew(Tree);
 	files->set_columns(2);
 	files->set_column_titles_visible(true);
-	files->set_column_min_width(1, 100);
+	files->set_column_custom_minimum_width(1, 100);
 	files->set_column_expand(0, true);
 	files->set_column_expand(1, false);
 	files->set_column_title(0, TTR("Resource"));

+ 4 - 4
editor/editor_autoload_settings.cpp

@@ -882,19 +882,19 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
 
 	tree->set_column_title(0, TTR("Name"));
 	tree->set_column_expand(0, true);
-	tree->set_column_min_width(0, 100 * EDSCALE);
+	tree->set_column_custom_minimum_width(0, 100 * EDSCALE);
 
 	tree->set_column_title(1, TTR("Path"));
 	tree->set_column_expand(1, true);
-	tree->set_column_min_width(1, 100 * EDSCALE);
+	tree->set_column_custom_minimum_width(1, 100 * EDSCALE);
 
 	tree->set_column_title(2, TTR("Global Variable"));
 	tree->set_column_expand(2, false);
 	// Reserve enough space for translations of "Global Variable" which may be longer.
-	tree->set_column_min_width(2, 150 * EDSCALE);
+	tree->set_column_custom_minimum_width(2, 150 * EDSCALE);
 
 	tree->set_column_expand(3, false);
-	tree->set_column_min_width(3, 120 * EDSCALE);
+	tree->set_column_custom_minimum_width(3, 120 * EDSCALE);
 
 	tree->connect("cell_selected", callable_mp(this, &EditorAutoloadSettings::_autoload_selected));
 	tree->connect("item_edited", callable_mp(this, &EditorAutoloadSettings::_autoload_edited));

+ 1 - 1
editor/editor_help_search.cpp

@@ -239,7 +239,7 @@ EditorHelpSearch::EditorHelpSearch() {
 	results_tree->set_column_title(0, TTR("Name"));
 	results_tree->set_column_title(1, TTR("Member Type"));
 	results_tree->set_column_expand(1, false);
-	results_tree->set_column_min_width(1, 150 * EDSCALE);
+	results_tree->set_column_custom_minimum_width(1, 150 * EDSCALE);
 	results_tree->set_custom_minimum_size(Size2(0, 100) * EDSCALE);
 	results_tree->set_hide_root(true);
 	results_tree->set_select_mode(Tree::SELECT_ROW);

+ 4 - 4
editor/editor_plugin_settings.cpp

@@ -216,10 +216,10 @@ EditorPluginSettings::EditorPluginSettings() {
 	plugin_list->set_column_expand(2, false);
 	plugin_list->set_column_expand(3, false);
 	plugin_list->set_column_expand(4, false);
-	plugin_list->set_column_min_width(1, 100 * EDSCALE);
-	plugin_list->set_column_min_width(2, 250 * EDSCALE);
-	plugin_list->set_column_min_width(3, 80 * EDSCALE);
-	plugin_list->set_column_min_width(4, 40 * EDSCALE);
+	plugin_list->set_column_custom_minimum_width(1, 100 * EDSCALE);
+	plugin_list->set_column_custom_minimum_width(2, 250 * EDSCALE);
+	plugin_list->set_column_custom_minimum_width(3, 80 * EDSCALE);
+	plugin_list->set_column_custom_minimum_width(4, 40 * EDSCALE);
 	plugin_list->set_hide_root(true);
 	plugin_list->connect("item_edited", callable_mp(this, &EditorPluginSettings::_plugin_activity_changed));
 

+ 1 - 1
editor/find_in_files.cpp

@@ -638,7 +638,7 @@ void FindInFilesPanel::set_with_replace(bool with_replace) {
 		// Results show checkboxes on their left so they can be opted out
 		_results_display->set_columns(2);
 		_results_display->set_column_expand(0, false);
-		_results_display->set_column_min_width(0, 48 * EDSCALE);
+		_results_display->set_column_custom_minimum_width(0, 48 * EDSCALE);
 
 	} else {
 		// Results are single-cell items

+ 3 - 3
editor/import/scene_import_settings.cpp

@@ -1163,13 +1163,13 @@ SceneImportSettings::SceneImportSettings() {
 	external_path_tree->set_columns(3);
 	external_path_tree->set_column_titles_visible(true);
 	external_path_tree->set_column_expand(0, true);
-	external_path_tree->set_column_min_width(0, 100 * EDSCALE);
+	external_path_tree->set_column_custom_minimum_width(0, 100 * EDSCALE);
 	external_path_tree->set_column_title(0, TTR("Resource"));
 	external_path_tree->set_column_expand(1, true);
-	external_path_tree->set_column_min_width(1, 100 * EDSCALE);
+	external_path_tree->set_column_custom_minimum_width(1, 100 * EDSCALE);
 	external_path_tree->set_column_title(1, TTR("Path"));
 	external_path_tree->set_column_expand(2, false);
-	external_path_tree->set_column_min_width(2, 200 * EDSCALE);
+	external_path_tree->set_column_custom_minimum_width(2, 200 * EDSCALE);
 	external_path_tree->set_column_title(2, TTR("Status"));
 	save_path = memnew(EditorFileDialog);
 	save_path->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR);

+ 1 - 1
editor/localization_editor.cpp

@@ -729,7 +729,7 @@ LocalizationEditor::LocalizationEditor() {
 		translation_remap_options->set_column_titles_visible(true);
 		translation_remap_options->set_column_expand(0, true);
 		translation_remap_options->set_column_expand(1, false);
-		translation_remap_options->set_column_min_width(1, 200);
+		translation_remap_options->set_column_custom_minimum_width(1, 200);
 		translation_remap_options->connect("item_edited", callable_mp(this, &LocalizationEditor::_translation_res_option_changed));
 		translation_remap_options->connect("button_pressed", callable_mp(this, &LocalizationEditor::_translation_res_option_delete));
 		tmc->add_child(translation_remap_options);

+ 2 - 2
editor/plugins/animation_player_editor_plugin.cpp

@@ -569,8 +569,8 @@ void AnimationPlayerEditor::_animation_blend() {
 	blend_editor.dialog->popup_centered(Size2(400, 400) * EDSCALE);
 
 	blend_editor.tree->set_hide_root(true);
-	blend_editor.tree->set_column_min_width(0, 10);
-	blend_editor.tree->set_column_min_width(1, 3);
+	blend_editor.tree->set_column_custom_minimum_width(0, 10);
+	blend_editor.tree->set_column_custom_minimum_width(1, 3);
 
 	List<StringName> anims;
 	player->get_animation_list(&anims);

+ 2 - 2
editor/plugins/resource_preloader_editor_plugin.cpp

@@ -367,8 +367,8 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
 	tree = memnew(Tree);
 	tree->connect("button_pressed", callable_mp(this, &ResourcePreloaderEditor::_cell_button_pressed));
 	tree->set_columns(2);
-	tree->set_column_min_width(0, 2);
-	tree->set_column_min_width(1, 3);
+	tree->set_column_custom_minimum_width(0, 2);
+	tree->set_column_custom_minimum_width(1, 3);
 	tree->set_column_expand(0, true);
 	tree->set_column_expand(1, true);
 	tree->set_v_size_flags(SIZE_EXPAND_FILL);

+ 3 - 3
editor/plugins/theme_editor_plugin.cpp

@@ -932,9 +932,9 @@ ThemeItemImportTree::ThemeItemImportTree() {
 	import_items_tree->set_column_expand(0, true);
 	import_items_tree->set_column_expand(IMPORT_ITEM, false);
 	import_items_tree->set_column_expand(IMPORT_ITEM_DATA, false);
-	import_items_tree->set_column_min_width(0, 160 * EDSCALE);
-	import_items_tree->set_column_min_width(IMPORT_ITEM, 80 * EDSCALE);
-	import_items_tree->set_column_min_width(IMPORT_ITEM_DATA, 80 * EDSCALE);
+	import_items_tree->set_column_custom_minimum_width(0, 160 * EDSCALE);
+	import_items_tree->set_column_custom_minimum_width(IMPORT_ITEM, 80 * EDSCALE);
+	import_items_tree->set_column_custom_minimum_width(IMPORT_ITEM_DATA, 80 * EDSCALE);
 
 	ScrollContainer *import_bulk_sc = memnew(ScrollContainer);
 	import_bulk_sc->set_custom_minimum_size(Size2(260.0, 0.0) * EDSCALE);

+ 2 - 2
modules/gdnative/gdnative_library_editor_plugin.cpp

@@ -356,12 +356,12 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
 	tree->set_column_titles_visible(true);
 	tree->set_columns(4);
 	tree->set_column_expand(0, false);
-	tree->set_column_min_width(0, int(200 * EDSCALE));
+	tree->set_column_custom_minimum_width(0, int(200 * EDSCALE));
 	tree->set_column_title(0, TTR("Platform"));
 	tree->set_column_title(1, TTR("Dynamic Library"));
 	tree->set_column_title(2, TTR("Dependencies"));
 	tree->set_column_expand(3, false);
-	tree->set_column_min_width(3, int(110 * EDSCALE));
+	tree->set_column_custom_minimum_width(3, int(110 * EDSCALE));
 	tree->connect("button_pressed", callable_mp(this, &GDNativeLibraryEditor::_on_item_button));
 	tree->connect("item_collapsed", callable_mp(this, &GDNativeLibraryEditor::_on_item_collapsed));
 	tree->connect("item_activated", callable_mp(this, &GDNativeLibraryEditor::_on_item_activated));

+ 119 - 37
scene/gui/tree.cpp

@@ -489,11 +489,11 @@ TreeItem *TreeItem::create_child(int p_idx) {
 	return ti;
 }
 
-Tree *TreeItem::get_tree() {
+Tree *TreeItem::get_tree() const {
 	return tree;
 }
 
-TreeItem *TreeItem::get_next() {
+TreeItem *TreeItem::get_next() const {
 	return next;
 }
 
@@ -516,11 +516,11 @@ TreeItem *TreeItem::get_prev() {
 	return prev;
 }
 
-TreeItem *TreeItem::get_parent() {
+TreeItem *TreeItem::get_parent() const {
 	return parent;
 }
 
-TreeItem *TreeItem::get_first_child() {
+TreeItem *TreeItem::get_first_child() const {
 	return first_child;
 }
 
@@ -953,6 +953,53 @@ bool TreeItem::is_folding_disabled() const {
 	return disable_folding;
 }
 
+Size2 TreeItem::get_minimum_size(int p_column) {
+	ERR_FAIL_INDEX_V(p_column, cells.size(), Size2());
+	Tree *tree = get_tree();
+	ERR_FAIL_COND_V(!tree, Size2());
+
+	Size2 size;
+
+	// Default offset?
+	//size.width += (disable_folding || tree->hide_folding) ? tree->cache.hseparation : tree->cache.item_margin;
+
+	// Text.
+	const TreeItem::Cell &cell = cells[p_column];
+	if (!cell.text.is_empty()) {
+		if (cell.dirty) {
+			tree->update_item_cell(this, p_column);
+		}
+		Size2 text_size = cell.text_buf->get_size();
+		size.width += text_size.width;
+		size.height = MAX(size.height, text_size.height);
+	}
+
+	// Icon.
+	if (cell.icon.is_valid()) {
+		Size2i icon_size = cell.get_icon_size();
+		if (cell.icon_max_w > 0 && icon_size.width > cell.icon_max_w) {
+			icon_size.width = cell.icon_max_w;
+		}
+		size.width += icon_size.width + tree->cache.hseparation;
+		size.height = MAX(size.height, icon_size.height);
+	}
+
+	// Buttons.
+	for (int i = 0; i < cell.buttons.size(); i++) {
+		Ref<Texture2D> texture = cell.buttons[i].texture;
+		if (texture.is_valid()) {
+			Size2 button_size = texture->get_size() + tree->cache.button_pressed->get_minimum_size();
+			size.width += button_size.width;
+			size.height = MAX(size.height, button_size.height);
+		}
+	}
+	if (cell.buttons.size() >= 2) {
+		size.width += (cell.buttons.size() - 1) * tree->cache.button_margin;
+	}
+
+	return size;
+}
+
 Variant TreeItem::_call_recursive_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 	if (p_argcount < 1) {
 		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
@@ -3276,7 +3323,7 @@ Size2 Tree::get_internal_min_size() const {
 		size.height += get_item_height(root);
 	}
 	for (int i = 0; i < columns.size(); i++) {
-		size.width += columns[i].min_width;
+		size.width += get_column_minimum_width(i);
 	}
 
 	return size;
@@ -3457,7 +3504,7 @@ void Tree::_notification(int p_what) {
 		draw_ofs.y += tbh;
 		draw_size.y -= tbh;
 
-		if (root) {
+		if (root && get_size().x > 0 && get_size().y > 0) {
 			draw_item(Point2(), draw_ofs, draw_size, root);
 		}
 
@@ -3563,11 +3610,11 @@ TreeItem *Tree::create_item(TreeItem *p_parent, int p_idx) {
 	return ti;
 }
 
-TreeItem *Tree::get_root() {
+TreeItem *Tree::get_root() const {
 	return root;
 }
 
-TreeItem *Tree::get_last_item() {
+TreeItem *Tree::get_last_item() const {
 	TreeItem *last = root;
 
 	while (last) {
@@ -3697,13 +3744,13 @@ bool Tree::is_root_hidden() const {
 	return hide_root;
 }
 
-void Tree::set_column_min_width(int p_column, int p_min_width) {
+void Tree::set_column_custom_minimum_width(int p_column, int p_min_width) {
 	ERR_FAIL_INDEX(p_column, columns.size());
 
-	if (p_min_width < 1) {
+	if (p_min_width < 0) {
 		return;
 	}
-	columns.write[p_column].min_width = p_min_width;
+	columns.write[p_column].custom_min_width = p_min_width;
 	update();
 }
 
@@ -3770,44 +3817,79 @@ TreeItem *Tree::get_next_selected(TreeItem *p_item) {
 	return nullptr;
 }
 
-int Tree::get_column_width(int p_column) const {
+int Tree::get_column_minimum_width(int p_column) const {
 	ERR_FAIL_INDEX_V(p_column, columns.size(), -1);
 
-	if (!columns[p_column].expand) {
-		return columns[p_column].min_width;
+	if (columns[p_column].custom_min_width != 0) {
+		return columns[p_column].custom_min_width;
+	} else {
+		int depth = 0;
+		int min_width = 0;
+		TreeItem *next;
+		for (TreeItem *item = get_root(); item; item = next) {
+			next = item->get_next_visible();
+			// Compute the depth in tree.
+			if (next && p_column == 0) {
+				if (next->get_parent() == item) {
+					depth += 1;
+				} else {
+					TreeItem *common_parent = item->get_parent();
+					while (common_parent != next->get_parent()) {
+						common_parent = common_parent->get_parent();
+						depth -= 1;
+					}
+				}
+			}
+
+			// Get the item minimum size.
+			Size2 item_size = item->get_minimum_size(p_column);
+			if (p_column == 0) {
+				item_size.width += cache.item_margin * depth;
+			}
+			min_width = MAX(min_width, item_size.width);
+		}
+		return min_width;
 	}
+}
 
-	int expand_area = get_size().width;
+int Tree::get_column_width(int p_column) const {
+	ERR_FAIL_INDEX_V(p_column, columns.size(), -1);
 
-	Ref<StyleBox> bg = cache.bg;
+	if (columns[p_column].expand) {
+		int expand_area = get_size().width;
 
-	if (bg.is_valid()) {
-		expand_area -= bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT);
-	}
+		Ref<StyleBox> bg = cache.bg;
 
-	if (v_scroll->is_visible_in_tree()) {
-		expand_area -= v_scroll->get_combined_minimum_size().width;
-	}
+		if (bg.is_valid()) {
+			expand_area -= bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT);
+		}
+
+		if (v_scroll->is_visible_in_tree()) {
+			expand_area -= v_scroll->get_combined_minimum_size().width;
+		}
 
-	int expanding_columns = 0;
-	int expanding_total = 0;
+		int expanding_columns = 0;
+		int expanding_total = 0;
 
-	for (int i = 0; i < columns.size(); i++) {
-		if (!columns[i].expand) {
-			expand_area -= columns[i].min_width;
-		} else {
-			expanding_total += columns[i].min_width;
-			expanding_columns++;
+		for (int i = 0; i < columns.size(); i++) {
+			if (!columns[i].expand) {
+				expand_area -= get_column_minimum_width(i);
+			} else {
+				expanding_total += get_column_minimum_width(i);
+				expanding_columns++;
+			}
 		}
-	}
 
-	if (expand_area < expanding_total) {
-		return columns[p_column].min_width;
-	}
+		if (expand_area < expanding_total) {
+			return get_column_minimum_width(p_column);
+		}
 
-	ERR_FAIL_COND_V(expanding_columns == 0, -1); // shouldn't happen
+		ERR_FAIL_COND_V(expanding_columns == 0, -1); // shouldn't happen
 
-	return expand_area * columns[p_column].min_width / expanding_total;
+		return expand_area * get_column_minimum_width(p_column) / expanding_total;
+	} else {
+		return get_column_minimum_width(p_column);
+	}
 }
 
 void Tree::propagate_set_columns(TreeItem *p_item) {
@@ -4462,7 +4544,7 @@ void Tree::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("create_item", "parent", "idx"), &Tree::_create_item, DEFVAL(Variant()), DEFVAL(-1));
 
 	ClassDB::bind_method(D_METHOD("get_root"), &Tree::get_root);
-	ClassDB::bind_method(D_METHOD("set_column_min_width", "column", "min_width"), &Tree::set_column_min_width);
+	ClassDB::bind_method(D_METHOD("set_column_custom_minimum_width", "column", "min_width"), &Tree::set_column_custom_minimum_width);
 	ClassDB::bind_method(D_METHOD("set_column_expand", "column", "expand"), &Tree::set_column_expand);
 	ClassDB::bind_method(D_METHOD("get_column_width", "column"), &Tree::get_column_width);
 

+ 11 - 8
scene/gui/tree.h

@@ -315,16 +315,18 @@ public:
 	void set_disable_folding(bool p_disable);
 	bool is_folding_disabled() const;
 
+	Size2 get_minimum_size(int p_column);
+
 	/* Item manipulation */
 
 	TreeItem *create_child(int p_idx = -1);
 
-	Tree *get_tree();
+	Tree *get_tree() const;
 
 	TreeItem *get_prev();
-	TreeItem *get_next();
-	TreeItem *get_parent();
-	TreeItem *get_first_child();
+	TreeItem *get_next() const;
+	TreeItem *get_parent() const;
+	TreeItem *get_first_child() const;
 
 	TreeItem *get_prev_visible(bool p_wrap = false);
 	TreeItem *get_next_visible(bool p_wrap = false);
@@ -408,7 +410,7 @@ private:
 	int drop_mode_flags = 0;
 
 	struct ColumnInfo {
-		int min_width = 1;
+		int custom_min_width = 0;
 		bool expand = true;
 		String title;
 		Ref<TextLine> text_buf;
@@ -625,11 +627,12 @@ public:
 	void clear();
 
 	TreeItem *create_item(TreeItem *p_parent = nullptr, int p_idx = -1);
-	TreeItem *get_root();
-	TreeItem *get_last_item();
+	TreeItem *get_root() const;
+	TreeItem *get_last_item() const;
 
-	void set_column_min_width(int p_column, int p_min_width);
+	void set_column_custom_minimum_width(int p_column, int p_min_width);
 	void set_column_expand(int p_column, bool p_expand);
+	int get_column_minimum_width(int p_column) const;
 	int get_column_width(int p_column) const;
 
 	void set_hide_root(bool p_enabled);