From df9eaf5f47f4547e1e433ebac3b2fcc9b380379f Mon Sep 17 00:00:00 2001 From: Ninni Pipping Date: Fri, 1 Jul 2022 15:43:39 +0200 Subject: [PATCH] Tree recursive folding --- doc/classes/Tree.xml | 3 ++ doc/classes/TreeItem.xml | 15 ++++++++ editor/filesystem_dock.cpp | 17 +-------- editor/scene_tree_dock.cpp | 58 +--------------------------- editor/scene_tree_dock.h | 4 -- scene/gui/tree.cpp | 78 +++++++++++++++++++++++++++++++++++++- scene/gui/tree.h | 10 +++++ 7 files changed, 107 insertions(+), 78 deletions(-) diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index f6a078602c3..539ca381909 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -312,6 +312,9 @@ The drop mode as an OR combination of flags. See [enum DropModeFlags] constants. Once dropping is done, reverts to [constant DROP_MODE_DISABLED]. Setting this during [method Control._can_drop_data] is recommended. This controls the drop sections, i.e. the decision and drawing of possible drop locations based on the mouse position. + + If [code]true[/code], recursive folding is enabled for this [Tree]. Holding down Shift while clicking the fold arrow collapses or uncollapses the [TreeItem] and all its descendants. + If [code]true[/code], the folding arrow is hidden. diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index fdae6d205d6..c109dc57f74 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -321,6 +321,14 @@ Returns the [Tree] that owns this TreeItem. + + + + + Returns [code]true[/code] if this [TreeItem], or any of its descendants, is collapsed. + If [param only_visible] is [code]true[/code] it ignores non-visible [TreeItem]s. + + @@ -442,6 +450,13 @@ If [code]true[/code], the given [param column] is checked. Clears column's indeterminate status. + + + + + Collapses or uncollapses this [TreeItem] and all the descendants of this item. + + diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 19b4932d3dc..424eab2f022 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1751,22 +1751,7 @@ void FileSystemDock::_tree_rmb_option(int p_option) { case FOLDER_COLLAPSE_ALL: { // Expand or collapse the folder if (selected_strings.size() == 1) { - bool is_collapsed = (p_option == FOLDER_COLLAPSE_ALL); - - Vector needs_check; - needs_check.push_back(tree->get_selected()); - - while (needs_check.size()) { - needs_check[0]->set_collapsed(is_collapsed); - - TreeItem *child = needs_check[0]->get_first_child(); - while (child) { - needs_check.push_back(child); - child = child->get_next(); - } - - needs_check.remove_at(0); - } + tree->get_selected()->set_collapsed_recursive(p_option == FOLDER_COLLAPSE_ALL); } } break; default: { diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index aefb2c78c10..d1dc188be92 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -441,8 +441,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 collapsed = selected_item->is_any_collapsed(); + selected_item->set_collapsed_recursive(!collapsed); tree->ensure_cursor_is_visible(); @@ -1223,17 +1223,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: { @@ -1945,48 +1934,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