diff --git a/source/blender/blenkernel/BKE_grease_pencil.hh b/source/blender/blenkernel/BKE_grease_pencil.hh index 8dafa401a10..27f97f2c156 100644 --- a/source/blender/blenkernel/BKE_grease_pencil.hh +++ b/source/blender/blenkernel/BKE_grease_pencil.hh @@ -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. */ diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index 9e48d4f3261..bfb506516f1 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -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; diff --git a/source/blender/editors/animation/anim_channels_edit.cc b/source/blender/editors/animation/anim_channels_edit.cc index 86bf98119e7..16321c166fd 100644 --- a/source/blender/editors/animation/anim_channels_edit.cc +++ b/source/blender/editors/animation/anim_channels_edit.cc @@ -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(ale->data); + using namespace blender::bke::greasepencil; + LayerGroup &layer_group = static_cast(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); diff --git a/source/blender/editors/animation/anim_filter.cc b/source/blender/editors/animation/anim_filter.cc index b7a12f66470..fe8d94663ed 100644 --- a/source/blender/editors/animation/anim_filter.cc +++ b/source/blender/editors/animation/anim_filter.cc @@ -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); diff --git a/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc b/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc index 647581d05a7..ee2072dc6cc 100644 --- a/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc +++ b/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc @@ -332,6 +332,35 @@ class LayerGroupViewItem : public AbstractTreeViewItem { this->label_ = group_.name(); } + std::optional 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(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()); } diff --git a/source/blender/makesrna/intern/rna_grease_pencil.cc b/source/blender/makesrna/intern/rna_grease_pencil.cc index 836804eab10..e582f390c95 100644 --- a/source/blender/makesrna/intern/rna_grease_pencil.cc +++ b/source/blender/makesrna/intern/rna_grease_pencil.cc @@ -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(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");