Grease Pencil: Save Layer Group expanded state

Grease Pencil layer groups are drawn in the layer tree using
`AbstractTreeViewItem`. The problem is that the items can't
store their expand/collapse state. This meant that switching
e.g. the tabs in the properties editor would reset the collapsed
state of layer group items.

This PR uses the `GP_LAYER_TREE_NODE_EXPANDED` flag to store
the expand/collapse state. The tree view then reads from the flag to
expand/collapse the items.

This also adds an RNA property to layer groups `is_expanded`.
Allows to check from python if a group is expanded in the UI.

Pull Request: https://projects.blender.org/blender/blender/pulls/131159
This commit is contained in:
Falk David
2024-12-02 11:48:42 +01:00
committed by Falk David
parent 796959c205
commit e5bdfd533b
6 changed files with 72 additions and 7 deletions

View File

@@ -703,6 +703,15 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
const TreeNode *find_node_by_name(StringRefNull name) const;
TreeNode *find_node_by_name(StringRefNull name);
/**
* Returns true if the group is expanded in the UI.
*/
bool is_expanded() const;
/**
* Expand/collapse the group in the UI.
*/
void set_expanded(bool expanded);
/**
* Print the nodes. For debugging purposes.
*/

View File

@@ -1748,6 +1748,16 @@ TreeNode *LayerGroup::find_node_by_name(const StringRefNull name)
return nullptr;
}
bool LayerGroup::is_expanded() const
{
return (this->base.flag & GP_LAYER_TREE_NODE_EXPANDED) != 0;
}
void LayerGroup::set_expanded(const bool expanded)
{
SET_FLAG_FROM_TEST(this->base.flag, expanded, GP_LAYER_TREE_NODE_EXPANDED);
}
void LayerGroup::print_nodes(StringRefNull header) const
{
std::cout << header << std::endl;

View File

@@ -4404,16 +4404,18 @@ static int click_select_channel_grease_pencil_datablock(bAnimListElem *ale)
return (ND_ANIMCHAN | NA_EDITED);
}
static int click_select_channel_grease_pencil_layer_group(bAnimListElem *ale)
static int click_select_channel_grease_pencil_layer_group(bContext *C, bAnimListElem *ale)
{
GreasePencilLayerTreeGroup *layer_group = static_cast<GreasePencilLayerTreeGroup *>(ale->data);
using namespace blender::bke::greasepencil;
LayerGroup &layer_group = static_cast<GreasePencilLayerTreeGroup *>(ale->data)->wrap();
/* Toggle expand:
* - Although the triangle widget already allows this,
* the whole channel can also be used for this purpose.
*/
layer_group->base.flag ^= GP_LAYER_TREE_NODE_EXPANDED;
layer_group.set_expanded(!layer_group.is_expanded());
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_PROPERTIES | NA_EDITED, nullptr);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, nullptr);
return (ND_ANIMCHAN | NA_EDITED);
}
@@ -4593,7 +4595,7 @@ static int mouse_anim_channels(bContext *C,
notifierFlags |= click_select_channel_grease_pencil_datablock(ale);
break;
case ANIMTYPE_GREASE_PENCIL_LAYER_GROUP:
notifierFlags |= click_select_channel_grease_pencil_layer_group(ale);
notifierFlags |= click_select_channel_grease_pencil_layer_group(C, ale);
break;
case ANIMTYPE_GREASE_PENCIL_LAYER:
notifierFlags |= click_select_channel_grease_pencil_layer(C, ac, ale, selectmode, filter);

View File

@@ -2100,7 +2100,7 @@ static size_t animdata_filter_grease_pencil_layer_node_recursive(
size_t tmp_items = 0;
/* Add grease pencil layer channels. */
BEGIN_ANIMFILTER_SUBCHANNELS (layer_group.base.flag &GP_LAYER_TREE_NODE_EXPANDED) {
BEGIN_ANIMFILTER_SUBCHANNELS (layer_group.is_expanded()) {
LISTBASE_FOREACH_BACKWARD (GreasePencilLayerTreeNode *, node_, &layer_group.children) {
tmp_items += animdata_filter_grease_pencil_layer_node_recursive(
ac, &tmp_data, grease_pencil, node_->wrap(), filter_mode);

View File

@@ -332,6 +332,35 @@ class LayerGroupViewItem : public AbstractTreeViewItem {
this->label_ = group_.name();
}
std::optional<bool> should_be_collapsed() const override
{
const bool is_collapsed = !group_.is_expanded();
return is_collapsed;
}
bool set_collapsed(const bool collapsed) override
{
if (!AbstractTreeViewItem::set_collapsed(collapsed)) {
return false;
}
group_.set_expanded(!collapsed);
return true;
}
void on_collapse_change(bContext &C, const bool is_collapsed) override
{
const bool is_expanded = !is_collapsed;
/* Let RNA handle the property change. This makes sure all the notifiers and DEG
* update calls are properly called. */
PointerRNA group_ptr = RNA_pointer_create(
&grease_pencil_.id, &RNA_GreasePencilLayerGroup, &group_);
PropertyRNA *prop = RNA_struct_find_property(&group_ptr, "is_expanded");
RNA_property_boolean_set(&group_ptr, prop, is_expanded);
RNA_property_update(&C, &group_ptr, prop);
}
void build_row(uiLayout &row) override
{
build_layer_group_name(row);
@@ -478,7 +507,6 @@ void LayerTreeView::build_tree_node_recursive(TreeViewOrItem &parent, TreeNode &
else if (node.is_group()) {
LayerGroupViewItem &group_item = parent.add_tree_item<LayerGroupViewItem>(this->grease_pencil_,
node.as_group());
group_item.uncollapse_by_default();
LISTBASE_FOREACH_BACKWARD (GreasePencilLayerTreeNode *, node_, &node.as_group().children) {
build_tree_node_recursive(group_item, node_->wrap());
}

View File

@@ -625,6 +625,12 @@ static void rna_GreasePencilLayerGroup_name_set(PointerRNA *ptr, const char *val
grease_pencil->rename_node(*G_MAIN, group->wrap().as_node(), value);
}
static void rna_GreasePencilLayerGroup_is_expanded_set(PointerRNA *ptr, const bool value)
{
GreasePencilLayerTreeGroup *group = static_cast<GreasePencilLayerTreeGroup *>(ptr->data);
group->wrap().set_expanded(value);
}
static void rna_iterator_grease_pencil_layer_groups_begin(CollectionPropertyIterator *iter,
PointerRNA *ptr)
{
@@ -1173,6 +1179,16 @@ static void rna_def_grease_pencil_layer_group(BlenderRNA *brna)
prop, "Onion Skinning", "Display onion skins before and after the current frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
/* Expanded */
prop = RNA_def_property(srna, "is_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, "GreasePencilLayerTreeNode", "flag", GP_LAYER_TREE_NODE_EXPANDED);
RNA_def_property_ui_text(prop, "Expanded", "The layer groups is expanded in the UI");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_boolean_funcs(prop, nullptr, "rna_GreasePencilLayerGroup_is_expanded_set");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
/* Parent group. */
prop = RNA_def_property(srna, "parent_group", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "GreasePencilLayerGroup");