Fix: Tree-view items always collapsed by default

Since 660867fa00, having tree-view items uncollapsed by default using
the `set_collapsed()` functions wouldn't work anymore. An attempt to do
this would assert even, so eb71d9f7bc disabled the assert.

I think a function designed to handle exactly this is the best solution,
it makes the intent & behavior more clear than before, and highlights
that this is a special case.

Mitigates #117957, in that it solves the regression, but tree-views still
don't remember their state on screen-layout changes. This is a known
limitation and not supported.

Pull Request: https://projects.blender.org/blender/blender/pulls/119166
This commit is contained in:
Julian Eisel 2024-03-18 19:32:53 +01:00 committed by Julian Eisel
parent 7a395e2e7f
commit 745fd2a2cb
7 changed files with 28 additions and 10 deletions

@ -66,8 +66,7 @@ class AssetCatalogSelectorTree : public ui::AbstractTreeView {
catalog_tree_.foreach_root_item([this](asset_system::AssetCatalogTreeItem &catalog_item) {
Item &item = build_catalog_items_recursive(*this, catalog_item);
/* Uncollapse root items by default (user edits will override this just fine). */
item.set_collapsed(false);
item.uncollapse_by_default();
});
}

@ -213,6 +213,13 @@ class AbstractTreeViewItem : public AbstractViewItem, public TreeViewItemContain
* \returns true when the collapsed state was changed, false otherwise.
*/
virtual bool set_collapsed(bool collapsed);
/**
* Make this item be uncollapsed on first draw (may later be overriden by
* #should_be_collapsed()). Must only be done during tree building.
*
* \note this does not call #on_collapse_change() or #set_collapsed() overrides.
*/
void uncollapse_by_default();
/**
* Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise we

@ -370,12 +370,12 @@ void LayerTreeView::build_tree_node_recursive(TreeViewOrItem &parent, TreeNode &
if (node.is_layer()) {
LayerViewItem &item = parent.add_tree_item<LayerViewItem>(this->grease_pencil_,
node.as_layer());
item.set_collapsed(false);
item.uncollapse_by_default();
}
else if (node.is_group()) {
LayerGroupViewItem &group_item = parent.add_tree_item<LayerGroupViewItem>(this->grease_pencil_,
node.as_group());
group_item.set_collapsed(false);
group_item.uncollapse_by_default();
LISTBASE_FOREACH_BACKWARD (GreasePencilLayerTreeNode *, node_, &node.as_group().children) {
build_tree_node_recursive(group_item, node_->wrap());
}

@ -266,7 +266,7 @@ class NodeTreeInterfaceView : public AbstractTreeView {
item);
NodeSocketViewItem &socket_item = parent_item.add_tree_item<NodeSocketViewItem>(
nodetree_, interface_, *socket);
socket_item.set_collapsed(false);
socket_item.uncollapse_by_default();
break;
}
case NODE_INTERFACE_PANEL: {
@ -274,7 +274,7 @@ class NodeTreeInterfaceView : public AbstractTreeView {
item);
NodePanelViewItem &panel_item = parent_item.add_tree_item<NodePanelViewItem>(
nodetree_, interface_, *panel);
panel_item.set_collapsed(false);
panel_item.uncollapse_by_default();
add_items_for_panel_recursive(*panel, panel_item);
break;
}

@ -527,10 +527,19 @@ bool AbstractTreeViewItem::set_collapsed(const bool collapsed)
return true;
}
void AbstractTreeViewItem::uncollapse_by_default()
{
BLI_assert_msg(this->get_tree_view().is_reconstructed() == false,
"Default state should only be set while building the tree");
BLI_assert(this->supports_collapsing());
/* Set the open state. Note that this may be overridden later by #should_be_collapsed(). */
is_open_ = true;
}
bool AbstractTreeViewItem::is_collapsible() const
{
// BLI_assert_msg(get_tree_view().is_reconstructed(),
// "State can't be queried until reconstruction is completed");
BLI_assert_msg(get_tree_view().is_reconstructed(),
"State can't be queried until reconstruction is completed");
if (children_.is_empty()) {
return false;
}

@ -191,7 +191,7 @@ AssetCatalogTreeView::AssetCatalogTreeView(asset_system::AssetLibrary *library,
void AssetCatalogTreeView::build_tree()
{
AssetCatalogTreeViewAllItem &all_item = add_all_item();
all_item.set_collapsed(false);
all_item.uncollapse_by_default();
if (catalog_tree_) {
/* Pass the "All" item on as parent of the actual catalog items. */

@ -92,6 +92,7 @@ class GeometryDataSetTreeView : public ui::AbstractTreeView {
bke::GeometryComponent::Type::GreasePencil,
IFACE_("Grease Pencil"),
ICON_OUTLINER_DATA_GREASEPENCIL);
grease_pencil.uncollapse_by_default();
GeometryDataSetTreeViewItem &grease_pencil_layers =
grease_pencil.add_tree_item<GeometryDataSetTreeViewItem>(
bke::GeometryComponent::Type::GreasePencil,
@ -127,6 +128,7 @@ class GeometryDataSetTreeView : public ui::AbstractTreeView {
{
GeometryDataSetTreeViewItem &mesh = this->add_tree_item<GeometryDataSetTreeViewItem>(
bke::GeometryComponent::Type::Mesh, IFACE_("Mesh"), ICON_MESH_DATA);
mesh.uncollapse_by_default();
mesh.add_tree_item<GeometryDataSetTreeViewItem>(bke::GeometryComponent::Type::Mesh,
bke::AttrDomain::Point,
IFACE_("Vertex"),
@ -142,6 +144,7 @@ class GeometryDataSetTreeView : public ui::AbstractTreeView {
GeometryDataSetTreeViewItem &curve = this->add_tree_item<GeometryDataSetTreeViewItem>(
bke::GeometryComponent::Type::Curve, IFACE_("Curve"), ICON_CURVE_DATA);
curve.uncollapse_by_default();
curve.add_tree_item<GeometryDataSetTreeViewItem>(bke::GeometryComponent::Type::Curve,
bke::AttrDomain::Point,
IFACE_("Control Point"),
@ -155,6 +158,7 @@ class GeometryDataSetTreeView : public ui::AbstractTreeView {
GeometryDataSetTreeViewItem &pointcloud = this->add_tree_item<GeometryDataSetTreeViewItem>(
bke::GeometryComponent::Type::PointCloud, IFACE_("Point Cloud"), ICON_POINTCLOUD_DATA);
pointcloud.uncollapse_by_default();
pointcloud.add_tree_item<GeometryDataSetTreeViewItem>(bke::GeometryComponent::Type::PointCloud,
bke::AttrDomain::Point,
IFACE_("Point"),
@ -175,7 +179,6 @@ GeometryDataSetTreeViewItem::GeometryDataSetTreeViewItem(
: component_type_(component_type), domain_(std::nullopt), icon_(icon)
{
label_ = label;
this->set_collapsed(false);
}
GeometryDataSetTreeViewItem::GeometryDataSetTreeViewItem(
bke::GeometryComponent::Type component_type, int layer_index, StringRef label, BIFIconID icon)