diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 8a30364ebece..1b2186ef2b32 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -254,6 +254,14 @@
Causes the [Tree] to jump to the specified [TreeItem].
+
+
+
+
+
+ Collapses or uncollapses every [TreeItem] in the [Tree], recursively, starting from the root. If ignore_active_branches is [code]true[/code], the branch containing the currently selected TreeItem will be left in its current state.
+
+
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index 0a680b9627af..54b77da50809 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -336,6 +336,12 @@
Returns the [Tree] that owns this TreeItem.
+
+
+
+ Returns [code]true[/code] if the [TreeItem] has at least one child which is not collapsed and has at least one child of it's own.
+
+
@@ -364,6 +370,12 @@
Returns [code]true[/code] if column [code]column[/code] is editable.
+
+
+
+ Returns [code]true[/code] if the [TreeItem] or at least one of it's descendent have at least one column selected.
+
+
@@ -457,6 +469,17 @@
If [code]true[/code], the column [code]column[/code] is checked. Clears column's indeterminate status.
+
+
+
+
+
+
+ Recursively collapse this [TreeItem] and all its descendants when [code]enable[/code] is [code]true[/code], otherwise expanding them.
+ If [code]ignore_active_branches[/code] is [code]true[/code], branches which contains a selected [TreeItem] will be ignored.
+ If [code]ignore_self[/code] is [code]true[/code], only descendants are affected.
+
+
@@ -671,9 +694,18 @@
Sets the given column's tooltip text.
+
+
+
+ If the [TreeItem] is already collapsed, expands it and all of its children recursively.
+ If the [TreeItem] is expanded and has at least one expanded child, collapses all children recursively without collapsing the current [TreeItem].
+ If the [TreeItem] is expanded and all children are collapsed, collapses the [TreeItem].
+
+
+ Uncollapses the [TreeItem] and all of it's ancestor.
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index 408d6af02261..56c36d06008d 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -1439,29 +1439,11 @@ void ScriptEditorDebugger::_error_selected() {
}
void ScriptEditorDebugger::_expand_errors_list() {
- TreeItem *root = error_tree->get_root();
- if (!root) {
- return;
- }
-
- TreeItem *item = root->get_first_child();
- while (item) {
- item->set_collapsed(false);
- item = item->get_next();
- }
+ error_tree->set_collapsed_all(false, false);
}
void ScriptEditorDebugger::_collapse_errors_list() {
- TreeItem *root = error_tree->get_root();
- if (!root) {
- return;
- }
-
- TreeItem *item = root->get_first_child();
- while (item) {
- item->set_collapsed(true);
- item = item->get_next();
- }
+ error_tree->set_collapsed_all(true, false);
}
void ScriptEditorDebugger::_clear_errors_list() {
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 8c72a886ea72..1b47990d89b1 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -4356,31 +4356,10 @@ void VisualShaderEditor::_tools_menu_option(int p_idx) {
switch (p_idx) {
case EXPAND_ALL:
-
- while (category) {
- category->set_collapsed(false);
- TreeItem *sub_category = category->get_first_child();
- while (sub_category) {
- sub_category->set_collapsed(false);
- sub_category = sub_category->get_next();
- }
- category = category->get_next();
- }
-
+ category->set_collapsed_recursive(false, false, false);
break;
-
case COLLAPSE_ALL:
-
- while (category) {
- category->set_collapsed(true);
- TreeItem *sub_category = category->get_first_child();
- while (sub_category) {
- sub_category->set_collapsed(true);
- sub_category = sub_category->get_next();
- }
- category = category->get_next();
- }
-
+ category->set_collapsed_recursive(true, false, false);
break;
default:
break;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 2e1090e6c0e6..7500f29e8552 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -438,8 +438,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
- bool collapsed = _is_collapsed_recursive(selected_item);
- _set_collapsed_recursive(selected_item, !collapsed);
+ bool collapse = selected_item->has_expanded_child();
+ selected_item->set_collapsed_recursive(collapse, false, false);
tree->ensure_cursor_is_visible();
@@ -1175,17 +1175,6 @@ void SceneTreeDock::add_root_node(Node *p_node) {
editor_data->get_undo_redo().commit_action();
}
-void SceneTreeDock::_node_collapsed(Object *p_obj) {
- TreeItem *ti = Object::cast_to(p_obj);
- if (!ti) {
- return;
- }
-
- if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
- _set_collapsed_recursive(ti, ti->is_collapsed());
- }
-}
-
void SceneTreeDock::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
@@ -1903,48 +1892,6 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
editor_data->get_undo_redo().commit_action();
}
-bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const {
- bool is_branch_collapsed = false;
-
- List needs_check;
- needs_check.push_back(p_item);
-
- while (!needs_check.is_empty()) {
- TreeItem *item = needs_check.back()->get();
- needs_check.pop_back();
-
- TreeItem *child = item->get_first_child();
- is_branch_collapsed = item->is_collapsed() && child;
-
- if (is_branch_collapsed) {
- break;
- }
- while (child) {
- needs_check.push_back(child);
- child = child->get_next();
- }
- }
- return is_branch_collapsed;
-}
-
-void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) {
- List to_collapse;
- to_collapse.push_back(p_item);
-
- while (!to_collapse.is_empty()) {
- TreeItem *item = to_collapse.back()->get();
- to_collapse.pop_back();
-
- item->set_collapsed(p_collapsed);
-
- TreeItem *child = item->get_first_child();
- while (child) {
- to_collapse.push_back(child);
- child = child->get_next();
- }
- }
-}
-
void SceneTreeDock::_script_created(Ref