Compare commits
11 Commits
tmp-eevee-
...
temp-libra
Author | SHA1 | Date | |
---|---|---|---|
22c056821e | |||
1551744a31 | |||
86b83350ee | |||
34df0c4e35 | |||
080de5d7e7 | |||
072e19cdd9 | |||
1383c53e18 | |||
7040f03f5a | |||
11d7d56d3a | |||
0e38174ed6 | |||
caa40c93eb |
@@ -2591,6 +2591,12 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
|
||||
case TSE_LIBRARY_OVERRIDE:
|
||||
data.icon = ICON_LIBRARY_DATA_OVERRIDE;
|
||||
break;
|
||||
case TSE_LIBRARY_OVERRIDE_RNA_COLLECTION_ITEM: {
|
||||
const auto &override_col_item = tree_element_cast<TreeElementOverrideRNACollectionItem>(
|
||||
te);
|
||||
data.icon = override_col_item->getIcon();
|
||||
break;
|
||||
}
|
||||
case TSE_LINKED_OB:
|
||||
data.icon = ICON_OBJECT_DATA;
|
||||
break;
|
||||
@@ -3305,7 +3311,11 @@ static void outliner_draw_tree_element(bContext *C,
|
||||
offsx += UI_UNIT_X;
|
||||
|
||||
/* Data-type icon. */
|
||||
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
|
||||
if (!(ELEM(tselem->type,
|
||||
TSE_RNA_PROPERTY,
|
||||
TSE_RNA_ARRAY_ELEM,
|
||||
TSE_ID_BASE,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_CONTAINER))) {
|
||||
tselem_draw_icon(block,
|
||||
xmax,
|
||||
(float)startx + offsx,
|
||||
|
@@ -64,6 +64,7 @@
|
||||
#include "tree/common.hh"
|
||||
#include "tree/tree_display.hh"
|
||||
#include "tree/tree_element.hh"
|
||||
#include "tree/tree_element_overrides.hh"
|
||||
|
||||
#ifdef WIN32
|
||||
# include "BLI_math_base.h" /* M_PI */
|
||||
@@ -815,6 +816,17 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
||||
/* idv is the layer itself */
|
||||
id = TREESTORE(parent)->id;
|
||||
}
|
||||
else if (ELEM(type,
|
||||
TSE_LIBRARY_OVERRIDE,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_CONTAINER,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_COLLECTION_ITEM)) {
|
||||
if (auto *override_base_te = tree_element_cast<TreeElementOverridesBase>(parent)) {
|
||||
id = &override_base_te->id;
|
||||
}
|
||||
else if (auto *override_item_te = tree_element_cast<TreeElementOverridesItem>(parent)) {
|
||||
id = override_item_te->getOverrideOwnerID();
|
||||
}
|
||||
}
|
||||
|
||||
/* exceptions */
|
||||
if (type == TSE_ID_BASE) {
|
||||
@@ -875,7 +887,11 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
||||
BLI_assert_msg(0, "Expected this ID type to be ported to new Outliner tree-element design");
|
||||
}
|
||||
}
|
||||
else if (ELEM(type, TSE_LIBRARY_OVERRIDE_BASE, TSE_LIBRARY_OVERRIDE)) {
|
||||
else if (ELEM(type,
|
||||
TSE_LIBRARY_OVERRIDE_BASE,
|
||||
TSE_LIBRARY_OVERRIDE,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_CONTAINER,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_COLLECTION_ITEM)) {
|
||||
if (!te->abstract_element) {
|
||||
BLI_assert_msg(0,
|
||||
"Expected override types to be ported to new Outliner tree-element design");
|
||||
|
@@ -74,6 +74,12 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i
|
||||
case TSE_LIBRARY_OVERRIDE:
|
||||
return std::make_unique<TreeElementOverridesProperty>(
|
||||
legacy_te, *static_cast<TreeElementOverridesData *>(idv));
|
||||
case TSE_LIBRARY_OVERRIDE_RNA_CONTAINER:
|
||||
return std::make_unique<TreeElementOverrideRNAContainer>(
|
||||
legacy_te, *static_cast<PropertyPointerRNA *>(idv));
|
||||
case TSE_LIBRARY_OVERRIDE_RNA_COLLECTION_ITEM:
|
||||
return std::make_unique<TreeElementOverrideRNACollectionItem>(
|
||||
legacy_te, *static_cast<PointerRNA *>(idv));
|
||||
case TSE_RNA_STRUCT:
|
||||
return std::make_unique<TreeElementRNAStruct>(legacy_te,
|
||||
*reinterpret_cast<PointerRNA *>(idv));
|
||||
@@ -98,6 +104,11 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TreeElement &AbstractTreeElement::getLegacyElement() const
|
||||
{
|
||||
return legacy_te_;
|
||||
}
|
||||
|
||||
void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner &space_outliner)
|
||||
{
|
||||
/* Most types can just expand. IDs optionally expand (hence the poll) and do additional, common
|
||||
|
@@ -53,6 +53,8 @@ class AbstractTreeElement {
|
||||
return true;
|
||||
}
|
||||
|
||||
TreeElement &getLegacyElement() const;
|
||||
|
||||
friend void tree_element_expand(const AbstractTreeElement &tree_element,
|
||||
SpaceOutliner &space_outliner);
|
||||
|
||||
|
@@ -38,6 +38,69 @@ TreeElementOverridesBase::TreeElementOverridesBase(TreeElement &legacy_te, ID &i
|
||||
}
|
||||
}
|
||||
|
||||
static void expand_from_rna_path(SpaceOutliner &space_outliner,
|
||||
TreeElement &path_root_te,
|
||||
TreeElementOverridesData &override_data,
|
||||
int *index)
|
||||
{
|
||||
PointerRNA idpoin;
|
||||
RNA_id_pointer_create(&override_data.id, &idpoin);
|
||||
|
||||
TreeElement *parent_to_expand = &path_root_te;
|
||||
|
||||
ListBase path_elems{nullptr};
|
||||
RNA_path_resolve_elements(&idpoin, override_data.override_property.rna_path, &path_elems);
|
||||
|
||||
/* Iterate the properties represented by the path. */
|
||||
LISTBASE_FOREACH (PropertyElemRNA *, prop_ptr_from_path, &path_elems) {
|
||||
/* Create containers for all items that are not leafs (i.e. that are not simple properties, but
|
||||
* may contain child properties). */
|
||||
if (prop_ptr_from_path->next) {
|
||||
PropertyPointerRNA property_and_ptr = {prop_ptr_from_path->ptr, prop_ptr_from_path->prop};
|
||||
TreeElement *container_te = outliner_add_element(&space_outliner,
|
||||
&parent_to_expand->subtree,
|
||||
&property_and_ptr,
|
||||
parent_to_expand,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_CONTAINER,
|
||||
(*index)++);
|
||||
|
||||
parent_to_expand = container_te;
|
||||
/* Iterate over the children the container item expanded, and continue building the path for
|
||||
* the item that matches the current path segment. */
|
||||
LISTBASE_FOREACH (TreeElement *, container_item_te, &container_te->subtree) {
|
||||
if (auto *col_item_te = tree_element_cast<TreeElementOverrideRNACollectionItem>(
|
||||
container_item_te)) {
|
||||
/* Does the collection item RNA pointer match the RNA pointer of the next property in the
|
||||
* path? */
|
||||
if (col_item_te->item_ptr.data == prop_ptr_from_path->next->ptr.data) {
|
||||
parent_to_expand = &col_item_te->getLegacyElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All items within the same owning ID must have a unique index. If the container expands
|
||||
* items, they count up based on the parent's index (or any preceding siblings if any). */
|
||||
*index = BLI_listbase_is_empty(&container_te->subtree) ?
|
||||
container_te->index + 1 :
|
||||
((TreeElement *)container_te->subtree.last)->index + 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The actually overridden property. Must be a "leaf" property (end of the path). */
|
||||
BLI_assert(prop_ptr_from_path->next == nullptr);
|
||||
/* The actual override. */
|
||||
outliner_add_element(&space_outliner,
|
||||
&parent_to_expand->subtree,
|
||||
&override_data,
|
||||
parent_to_expand,
|
||||
TSE_LIBRARY_OVERRIDE,
|
||||
(*index)++);
|
||||
}
|
||||
|
||||
BLI_freelistN(&path_elems);
|
||||
}
|
||||
|
||||
void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const
|
||||
{
|
||||
BLI_assert(id.override_library != nullptr);
|
||||
@@ -50,9 +113,9 @@ void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const
|
||||
|
||||
PointerRNA override_rna_ptr;
|
||||
PropertyRNA *override_rna_prop;
|
||||
short index = 0;
|
||||
int index = 0;
|
||||
|
||||
for (auto *override_prop :
|
||||
for (IDOverrideLibraryProperty *override_prop :
|
||||
ListBaseWrapper<IDOverrideLibraryProperty>(id.override_library->properties)) {
|
||||
const bool is_rna_path_valid = BKE_lib_override_rna_property_find(
|
||||
&idpoin, override_prop, &override_rna_ptr, &override_rna_prop);
|
||||
@@ -60,7 +123,7 @@ void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const
|
||||
ELEM(override_prop->rna_prop_type, PROP_POINTER, PROP_COLLECTION) &&
|
||||
RNA_struct_is_ID(RNA_property_pointer_type(&override_rna_ptr, override_rna_prop))) {
|
||||
bool do_continue = true;
|
||||
for (auto *override_prop_op :
|
||||
for (IDOverrideLibraryPropertyOperation *override_prop_op :
|
||||
ListBaseWrapper<IDOverrideLibraryPropertyOperation>(override_prop->operations)) {
|
||||
if ((override_prop_op->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) {
|
||||
do_continue = false;
|
||||
@@ -73,25 +136,93 @@ void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const
|
||||
}
|
||||
}
|
||||
|
||||
TreeElementOverridesData data = {
|
||||
TreeElementOverridesData override_data = {
|
||||
id, *override_prop, override_rna_ptr, *override_rna_prop, is_rna_path_valid};
|
||||
outliner_add_element(
|
||||
&space_outliner, &legacy_te_.subtree, &data, &legacy_te_, TSE_LIBRARY_OVERRIDE, index++);
|
||||
expand_from_rna_path(space_outliner, legacy_te_, override_data, &index);
|
||||
}
|
||||
}
|
||||
|
||||
TreeElementOverridesProperty::TreeElementOverridesProperty(TreeElement &legacy_te,
|
||||
TreeElementOverridesData &override_data)
|
||||
: AbstractTreeElement(legacy_te),
|
||||
: TreeElementOverridesItem(legacy_te),
|
||||
override_prop_(override_data.override_property),
|
||||
override_rna_ptr(override_data.override_rna_ptr),
|
||||
override_rna_prop(override_data.override_rna_prop)
|
||||
{
|
||||
BLI_assert(legacy_te.store_elem->type == TSE_LIBRARY_OVERRIDE);
|
||||
|
||||
legacy_te.name = override_data.override_property.rna_path;
|
||||
legacy_te.name = RNA_property_identifier(&override_rna_prop);
|
||||
/* Abusing this for now, better way to do it is also pending current refactor of the whole tree
|
||||
* code to use C++. */
|
||||
legacy_te.directdata = POINTER_FROM_UINT(override_data.is_rna_path_valid);
|
||||
}
|
||||
|
||||
TreeElementOverrideRNAContainer::TreeElementOverrideRNAContainer(
|
||||
TreeElement &legacy_te, PropertyPointerRNA &container_prop_and_ptr)
|
||||
: TreeElementOverridesItem(legacy_te),
|
||||
container_ptr(container_prop_and_ptr.ptr),
|
||||
container_prop(*container_prop_and_ptr.prop)
|
||||
{
|
||||
BLI_assert(legacy_te.store_elem->type == TSE_LIBRARY_OVERRIDE_RNA_CONTAINER);
|
||||
legacy_te.name = RNA_property_ui_name(&container_prop);
|
||||
}
|
||||
|
||||
void TreeElementOverrideRNAContainer::expand(SpaceOutliner &space_outliner) const
|
||||
{
|
||||
if (RNA_property_type(&container_prop) != PROP_COLLECTION) {
|
||||
/* Only expand RNA collections. For them the exact item order may matter (e.g. for modifiers),
|
||||
* so display them all to provide full context. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* All items within the same owning ID must have a unique index. Count up based on the parent's
|
||||
* index (or any preceding siblings if any). The parent increases the index counter to be higher
|
||||
* than its last child too. */
|
||||
int index = BLI_listbase_is_empty(&legacy_te_.subtree) ?
|
||||
legacy_te_.parent->index :
|
||||
((TreeElement *)legacy_te_.subtree.last)->index;
|
||||
|
||||
/* Non-const copy. */
|
||||
PointerRNA ptr = container_ptr;
|
||||
RNA_PROP_BEGIN (&ptr, itemptr, &container_prop) {
|
||||
outliner_add_element(&space_outliner,
|
||||
&legacy_te_.subtree,
|
||||
&itemptr,
|
||||
&legacy_te_,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_COLLECTION_ITEM,
|
||||
++index);
|
||||
}
|
||||
RNA_PROP_END;
|
||||
}
|
||||
|
||||
ID *TreeElementOverridesItem::getOverrideOwnerID()
|
||||
{
|
||||
for (AbstractTreeElement *parent = tree_element_cast<AbstractTreeElement>(legacy_te_.parent);
|
||||
parent;
|
||||
parent = tree_element_cast<AbstractTreeElement>(parent->getLegacyElement().parent)) {
|
||||
if (TreeElementOverridesBase *base_te = dynamic_cast<TreeElementOverridesBase *>(parent)) {
|
||||
return &base_te->id;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TreeElementOverrideRNACollectionItem::TreeElementOverrideRNACollectionItem(
|
||||
TreeElement &legacy_te, const PointerRNA &item_ptr)
|
||||
: TreeElementOverridesItem(legacy_te), item_ptr(item_ptr)
|
||||
{
|
||||
BLI_assert(legacy_te.store_elem->type == TSE_LIBRARY_OVERRIDE_RNA_COLLECTION_ITEM);
|
||||
/* Non-const copy. */
|
||||
PointerRNA ptr = item_ptr;
|
||||
PropertyRNA *name_prop = RNA_struct_name_property(item_ptr.type);
|
||||
legacy_te.name = RNA_property_string_get_alloc(&ptr, name_prop, nullptr, 0, nullptr);
|
||||
legacy_te.flag |= TE_FREE_NAME;
|
||||
}
|
||||
|
||||
int TreeElementOverrideRNACollectionItem::getIcon() const
|
||||
{
|
||||
return RNA_struct_ui_icon(item_ptr.type);
|
||||
}
|
||||
|
||||
} // namespace blender::ed::outliner
|
||||
|
@@ -34,7 +34,21 @@ class TreeElementOverridesBase final : public AbstractTreeElement {
|
||||
void expand(SpaceOutliner &) const override;
|
||||
};
|
||||
|
||||
class TreeElementOverridesProperty final : public AbstractTreeElement {
|
||||
/**
|
||||
* Common interface for any item nested under #TreeElementOverridesBase. It gives access to the ID
|
||||
* owning the override.
|
||||
*/
|
||||
class TreeElementOverridesItem : public AbstractTreeElement {
|
||||
public:
|
||||
ID *getOverrideOwnerID();
|
||||
|
||||
protected:
|
||||
using AbstractTreeElement::AbstractTreeElement;
|
||||
};
|
||||
|
||||
class TreeElementOverridesProperty final : public TreeElementOverridesItem {
|
||||
[[maybe_unused]] IDOverrideLibraryProperty &override_prop_;
|
||||
|
||||
public:
|
||||
PointerRNA override_rna_ptr;
|
||||
PropertyRNA &override_rna_prop;
|
||||
@@ -43,4 +57,30 @@ class TreeElementOverridesProperty final : public AbstractTreeElement {
|
||||
TreeElementOverridesProperty(TreeElement &legacy_te, TreeElementOverridesData &override_data);
|
||||
};
|
||||
|
||||
/**
|
||||
* If the override is within some collection or pointer property, the collection/pointer gets its
|
||||
* own parent item with items inside.
|
||||
*/
|
||||
class TreeElementOverrideRNAContainer final : public TreeElementOverridesItem {
|
||||
public:
|
||||
PointerRNA container_ptr;
|
||||
PropertyRNA &container_prop;
|
||||
|
||||
public:
|
||||
TreeElementOverrideRNAContainer(TreeElement &legacy_te,
|
||||
PropertyPointerRNA &container_prop_and_ptr);
|
||||
|
||||
void expand(SpaceOutliner &) const override;
|
||||
};
|
||||
|
||||
class TreeElementOverrideRNACollectionItem final : public TreeElementOverridesItem {
|
||||
public:
|
||||
PointerRNA item_ptr;
|
||||
|
||||
public:
|
||||
TreeElementOverrideRNACollectionItem(TreeElement &legacy_te, const PointerRNA &item_ptr);
|
||||
|
||||
int getIcon() const;
|
||||
};
|
||||
|
||||
} // namespace blender::ed::outliner
|
||||
|
@@ -114,6 +114,10 @@ typedef enum eTreeStoreElemType {
|
||||
TSE_GPENCIL_EFFECT = 43,
|
||||
TSE_LIBRARY_OVERRIDE_BASE = 44,
|
||||
TSE_LIBRARY_OVERRIDE = 45,
|
||||
/** Base item to add when the overridden property is within a nested struct or collection
|
||||
property. */
|
||||
TSE_LIBRARY_OVERRIDE_RNA_CONTAINER = 46,
|
||||
TSE_LIBRARY_OVERRIDE_RNA_COLLECTION_ITEM = 47,
|
||||
} eTreeStoreElemType;
|
||||
|
||||
/** Check whether given #TreeStoreElem should have a real ID in #TreeStoreElem.id member. */
|
||||
|
Reference in New Issue
Block a user