Tree recursive folding

This commit is contained in:
Ninni Pipping
2022-07-01 15:43:39 +02:00
parent 307f560b39
commit df9eaf5f47
7 changed files with 107 additions and 78 deletions

View File

@ -563,6 +563,57 @@ bool TreeItem::is_collapsed() {
return collapsed;
}
void TreeItem::set_collapsed_recursive(bool p_collapsed) {
if (!tree) {
return;
}
set_collapsed(p_collapsed);
TreeItem *child = get_first_child();
while (child) {
child->set_collapsed_recursive(p_collapsed);
child = child->get_next();
}
}
bool TreeItem::_is_any_collapsed(bool p_only_visible) {
TreeItem *child = get_first_child();
// Check on children directly first (avoid recursing if possible).
while (child) {
if (child->get_first_child() && child->is_collapsed() && (!p_only_visible || (child->is_visible() && child->get_visible_child_count()))) {
return true;
}
child = child->get_next();
}
child = get_first_child();
// Otherwise recurse on children.
while (child) {
if (child->get_first_child() && (!p_only_visible || (child->is_visible() && child->get_visible_child_count())) && child->_is_any_collapsed(p_only_visible)) {
return true;
}
child = child->get_next();
}
return false;
}
bool TreeItem::is_any_collapsed(bool p_only_visible) {
if (p_only_visible && !is_visible()) {
return false;
}
// Collapsed if this is collapsed and it has children (only considers visible if only visible is set).
if (is_collapsed() && get_first_child() && (!p_only_visible || get_visible_child_count())) {
return true;
}
return _is_any_collapsed(p_only_visible);
}
void TreeItem::set_visible(bool p_visible) {
if (visible == p_visible) {
return;
@ -1406,6 +1457,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collapsed", "enable"), &TreeItem::set_collapsed);
ClassDB::bind_method(D_METHOD("is_collapsed"), &TreeItem::is_collapsed);
ClassDB::bind_method(D_METHOD("set_collapsed_recursive", "enable"), &TreeItem::set_collapsed_recursive);
ClassDB::bind_method(D_METHOD("is_any_collapsed", "only_visible"), &TreeItem::is_any_collapsed, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_visible", "enable"), &TreeItem::set_visible);
ClassDB::bind_method(D_METHOD("is_visible"), &TreeItem::is_visible);
@ -2572,7 +2626,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
}
if (!p_item->disable_folding && !hide_folding && p_item->first_child && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + theme_cache.item_margin))) {
p_item->set_collapsed(!p_item->is_collapsed());
if (enable_recursive_folding && p_mod->is_shift_pressed()) {
p_item->set_collapsed_recursive(!p_item->is_collapsed());
} else {
p_item->set_collapsed(!p_item->is_collapsed());
}
return -1;
}
@ -2623,7 +2681,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
}
if (!p_item->disable_folding && !hide_folding && !p_item->cells[col].editable && !p_item->cells[col].selectable && p_item->get_first_child()) {
p_item->set_collapsed(!p_item->is_collapsed());
if (enable_recursive_folding && p_mod->is_shift_pressed()) {
p_item->set_collapsed_recursive(!p_item->is_collapsed());
} else {
p_item->set_collapsed(!p_item->is_collapsed());
}
return -1; //collapse/uncollapse because nothing can be done with item
}
@ -5026,6 +5088,14 @@ bool Tree::is_folding_hidden() const {
return hide_folding;
}
void Tree::set_enable_recursive_folding(bool p_enable) {
enable_recursive_folding = p_enable;
}
bool Tree::is_recursive_folding_enabled() const {
return enable_recursive_folding;
}
void Tree::set_drop_mode_flags(int p_flags) {
if (drop_mode_flags == p_flags) {
return;
@ -5129,6 +5199,9 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hide_folding", "hide"), &Tree::set_hide_folding);
ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden);
ClassDB::bind_method(D_METHOD("set_enable_recursive_folding", "enable"), &Tree::set_enable_recursive_folding);
ClassDB::bind_method(D_METHOD("is_recursive_folding_enabled"), &Tree::is_recursive_folding_enabled);
ClassDB::bind_method(D_METHOD("set_drop_mode_flags", "flags"), &Tree::set_drop_mode_flags);
ClassDB::bind_method(D_METHOD("get_drop_mode_flags"), &Tree::get_drop_mode_flags);
@ -5143,6 +5216,7 @@ void Tree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_reselect"), "set_allow_reselect", "get_allow_reselect");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_recursive_folding"), "set_enable_recursive_folding", "is_recursive_folding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden");
ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In Between"), "set_drop_mode_flags", "get_drop_mode_flags");
ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Row,Multi"), "set_select_mode", "get_select_mode");