Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/space_outliner
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/space_outliner')
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt56
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c1829
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c1653
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c4573
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c2931
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h317
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c146
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c2215
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c3519
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c3698
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c323
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c598
12 files changed, 11414 insertions, 10444 deletions
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index 83832d62b9e..f08069c418b 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -16,47 +16,47 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenkernel
- ../../blenlib
- ../../blentranslation
- ../../depsgraph
- ../../imbuf
- ../../gpu
- ../../makesdna
- ../../makesrna
- ../../windowmanager
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
+ ../include
+ ../../blenkernel
+ ../../blenlib
+ ../../blentranslation
+ ../../depsgraph
+ ../../imbuf
+ ../../gpu
+ ../../makesdna
+ ../../makesrna
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- outliner_collections.c
- outliner_dragdrop.c
- outliner_draw.c
- outliner_edit.c
- outliner_ops.c
- outliner_select.c
- outliner_tools.c
- outliner_tree.c
- outliner_utils.c
- space_outliner.c
+ outliner_collections.c
+ outliner_dragdrop.c
+ outliner_draw.c
+ outliner_edit.c
+ outliner_ops.c
+ outliner_select.c
+ outliner_tools.c
+ outliner_tree.c
+ outliner_utils.c
+ space_outliner.c
- outliner_intern.h
+ outliner_intern.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
- bf_editor_undo
+ bf_blenkernel
+ bf_blenlib
+ bf_editor_undo
)
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 30eaefe6149..835c154786b 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -56,78 +56,81 @@
bool outliner_is_collection_tree_element(const TreeElement *te)
{
- TreeStoreElem *tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
- if (!tselem) {
- return false;
- }
+ if (!tselem) {
+ return false;
+ }
- if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
- return true;
- }
- else if (tselem->type == 0 && te->idcode == ID_GR) {
- return true;
- }
+ if (ELEM(tselem->type,
+ TSE_LAYER_COLLECTION,
+ TSE_SCENE_COLLECTION_BASE,
+ TSE_VIEW_COLLECTION_BASE)) {
+ return true;
+ }
+ else if (tselem->type == 0 && te->idcode == ID_GR) {
+ return true;
+ }
- return false;
+ return false;
}
Collection *outliner_collection_from_tree_element(const TreeElement *te)
{
- TreeStoreElem *tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
- if (!tselem) {
- return NULL;
- }
+ if (!tselem) {
+ return NULL;
+ }
- if (tselem->type == TSE_LAYER_COLLECTION) {
- LayerCollection *lc = te->directdata;
- return lc->collection;
- }
- else if (ELEM(tselem->type, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
- Scene *scene = (Scene *)tselem->id;
- return BKE_collection_master(scene);
- }
- else if (tselem->type == 0 && te->idcode == ID_GR) {
- return (Collection *)tselem->id;
- }
+ if (tselem->type == TSE_LAYER_COLLECTION) {
+ LayerCollection *lc = te->directdata;
+ return lc->collection;
+ }
+ else if (ELEM(tselem->type, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
+ Scene *scene = (Scene *)tselem->id;
+ return BKE_collection_master(scene);
+ }
+ else if (tselem->type == 0 && te->idcode == ID_GR) {
+ return (Collection *)tselem->id;
+ }
- return NULL;
+ return NULL;
}
TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *customdata)
{
- struct IDsSelectedData *data = customdata;
- TreeStoreElem *tselem = TREESTORE(te);
+ struct IDsSelectedData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
- if (outliner_is_collection_tree_element(te)) {
- BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
- return TRAVERSE_CONTINUE;
- }
+ if (outliner_is_collection_tree_element(te)) {
+ BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
+ return TRAVERSE_CONTINUE;
+ }
- if (tselem->type || (tselem->id && GS(tselem->id->name) != ID_GR)) {
- return TRAVERSE_SKIP_CHILDS;
- }
+ if (tselem->type || (tselem->id && GS(tselem->id->name) != ID_GR)) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
- return TRAVERSE_CONTINUE;
+ return TRAVERSE_CONTINUE;
}
TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata)
{
- struct IDsSelectedData *data = customdata;
- TreeStoreElem *tselem = TREESTORE(te);
+ struct IDsSelectedData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
- if (outliner_is_collection_tree_element(te)) {
- return TRAVERSE_CONTINUE;
- }
+ if (outliner_is_collection_tree_element(te)) {
+ return TRAVERSE_CONTINUE;
+ }
- if (tselem->type || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) {
- return TRAVERSE_SKIP_CHILDS;
- }
+ if (tselem->type || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
- BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
+ BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
- return TRAVERSE_CONTINUE;
+ return TRAVERSE_CONTINUE;
}
/* -------------------------------------------------------------------- */
@@ -135,1247 +138,1302 @@ TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *custom
bool ED_outliner_collections_editor_poll(bContext *C)
{
- SpaceOutliner *so = CTX_wm_space_outliner(C);
- return (so != NULL) && ELEM(so->outlinevis, SO_VIEW_LAYER, SO_SCENES, SO_LIBRARIES);
+ SpaceOutliner *so = CTX_wm_space_outliner(C);
+ return (so != NULL) && ELEM(so->outlinevis, SO_VIEW_LAYER, SO_SCENES, SO_LIBRARIES);
}
static bool outliner_view_layer_collections_editor_poll(bContext *C)
{
- SpaceOutliner *so = CTX_wm_space_outliner(C);
- return (so != NULL) && (so->outlinevis == SO_VIEW_LAYER);
+ SpaceOutliner *so = CTX_wm_space_outliner(C);
+ return (so != NULL) && (so->outlinevis == SO_VIEW_LAYER);
}
/********************************* New Collection ****************************/
-struct CollectionNewData
-{
- bool error;
- Collection *collection;
+struct CollectionNewData {
+ bool error;
+ Collection *collection;
};
static TreeTraversalAction collection_find_selected_to_add(TreeElement *te, void *customdata)
{
- struct CollectionNewData *data = customdata;
- Collection *collection = outliner_collection_from_tree_element(te);
+ struct CollectionNewData *data = customdata;
+ Collection *collection = outliner_collection_from_tree_element(te);
- if (!collection) {
- return TRAVERSE_SKIP_CHILDS;
- }
+ if (!collection) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
- if (data->collection != NULL) {
- data->error = true;
- return TRAVERSE_BREAK;
- }
+ if (data->collection != NULL) {
+ data->error = true;
+ return TRAVERSE_BREAK;
+ }
- data->collection = collection;
- return TRAVERSE_CONTINUE;
+ data->collection = collection;
+ return TRAVERSE_CONTINUE;
}
static int collection_new_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- struct CollectionNewData data = {
- .error = false,
- .collection = NULL,
- };
+ struct CollectionNewData data = {
+ .error = false,
+ .collection = NULL,
+ };
- if (RNA_boolean_get(op->ptr, "nested")) {
- outliner_build_tree(bmain, scene, view_layer, soops, ar);
+ if (RNA_boolean_get(op->ptr, "nested")) {
+ outliner_build_tree(bmain, scene, view_layer, soops, ar);
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_selected_to_add, &data);
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, collection_find_selected_to_add, &data);
- if (data.error) {
- BKE_report(op->reports, RPT_ERROR, "More than one collection is selected");
- return OPERATOR_CANCELLED;
- }
- }
+ if (data.error) {
+ BKE_report(op->reports, RPT_ERROR, "More than one collection is selected");
+ return OPERATOR_CANCELLED;
+ }
+ }
- if (data.collection == NULL || ID_IS_LINKED(data.collection)) {
- data.collection = BKE_collection_master(scene);
- }
+ if (data.collection == NULL || ID_IS_LINKED(data.collection)) {
+ data.collection = BKE_collection_master(scene);
+ }
- if (ID_IS_LINKED(scene)) {
- BKE_report(op->reports, RPT_ERROR, "Can't add a new collection to linked scene/collection");
- return OPERATOR_CANCELLED;
- }
+ if (ID_IS_LINKED(scene)) {
+ BKE_report(op->reports, RPT_ERROR, "Can't add a new collection to linked scene/collection");
+ return OPERATOR_CANCELLED;
+ }
- BKE_collection_add(
- bmain,
- data.collection,
- NULL);
+ BKE_collection_add(bmain, data.collection, NULL);
- DEG_id_tag_update(&data.collection->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
+ DEG_id_tag_update(&data.collection->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
- outliner_cleanup_tree(soops);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
- return OPERATOR_FINISHED;
+ outliner_cleanup_tree(soops);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_new(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "New Collection";
- ot->idname = "OUTLINER_OT_collection_new";
- ot->description = "Add a new collection inside selected collection";
+ /* identifiers */
+ ot->name = "New Collection";
+ ot->idname = "OUTLINER_OT_collection_new";
+ ot->description = "Add a new collection inside selected collection";
- /* api callbacks */
- ot->exec = collection_new_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_new_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- PropertyRNA *prop = RNA_def_boolean(ot->srna, "nested", true, "Nested", "Add as child of selected collection");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "nested", true, "Nested", "Add as child of selected collection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/**************************** Delete Collection ******************************/
struct CollectionEditData {
- Scene *scene;
- SpaceOutliner *soops;
- GSet *collections_to_edit;
+ Scene *scene;
+ SpaceOutliner *soops;
+ GSet *collections_to_edit;
};
static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *customdata)
{
- struct CollectionEditData *data = customdata;
- Collection *collection = outliner_collection_from_tree_element(te);
+ struct CollectionEditData *data = customdata;
+ Collection *collection = outliner_collection_from_tree_element(te);
- if (!collection) {
- return TRAVERSE_SKIP_CHILDS;
- }
+ if (!collection) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
- if (collection->flag & COLLECTION_IS_MASTER) {
- /* skip - showing warning/error message might be misleading
- * when deleting multiple collections, so just do nothing */
- }
- else {
- /* Delete, duplicate and link don't edit children, those will come along
- * with the parents. */
- BLI_gset_add(data->collections_to_edit, collection);
- return TRAVERSE_SKIP_CHILDS;
- }
+ if (collection->flag & COLLECTION_IS_MASTER) {
+ /* skip - showing warning/error message might be misleading
+ * when deleting multiple collections, so just do nothing */
+ }
+ else {
+ /* Delete, duplicate and link don't edit children, those will come along
+ * with the parents. */
+ BLI_gset_add(data->collections_to_edit, collection);
+ return TRAVERSE_SKIP_CHILDS;
+ }
- return TRAVERSE_CONTINUE;
+ return TRAVERSE_CONTINUE;
}
static int collection_delete_exec(bContext *C, wmOperator *op)
{
- struct wmMsgBus *mbus = CTX_wm_message_bus(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- const Base *basact_prev = BASACT(view_layer);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
- bool hierarchy = RNA_boolean_get(op->ptr, "hierarchy");
-
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
-
- /* We first walk over and find the Collections we actually want to delete (ignoring duplicates). */
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
-
- /* Effectively delete the collections. */
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
-
- /* Test in case collection got deleted as part of another one. */
- if (BLI_findindex(&bmain->collections, collection) != -1) {
- /* We cannot allow to delete collections that are indirectly linked, or that are used by (linked to...)
- * other linked scene/collection. */
- bool skip = false;
- if (ID_IS_LINKED(collection)) {
- if (collection->id.tag & LIB_TAG_INDIRECT) {
- skip = true;
- }
- else {
- for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) {
- Collection *parent = cparent->collection;
- if (ID_IS_LINKED(parent)) {
- skip = true;
- break;
- }
- else if (parent->flag & COLLECTION_IS_MASTER) {
- Scene *parent_scene = BKE_collection_master_scene_search(bmain, parent);
- if (ID_IS_LINKED(parent_scene)) {
- skip = true;
- break;
- }
- }
- }
- }
- }
-
- if (!skip) {
- BKE_collection_delete(bmain, collection, hierarchy);
- }
- else {
- BKE_reportf(op->reports, RPT_WARNING,
- "Cannot delete linked collection '%s', it is used by other linked scenes/collections",
- collection->id.name + 2);
- }
- }
- }
-
- BLI_gset_free(data.collections_to_edit, NULL);
-
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
-
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
-
- if (basact_prev != BASACT(view_layer)) {
- WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
- }
-
- return OPERATOR_FINISHED;
+ struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const Base *basact_prev = BASACT(view_layer);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
+ bool hierarchy = RNA_boolean_get(op->ptr, "hierarchy");
+
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
+
+ /* We first walk over and find the Collections we actually want to delete (ignoring duplicates). */
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
+
+ /* Effectively delete the collections. */
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+
+ /* Test in case collection got deleted as part of another one. */
+ if (BLI_findindex(&bmain->collections, collection) != -1) {
+ /* We cannot allow to delete collections that are indirectly linked, or that are used by (linked to...)
+ * other linked scene/collection. */
+ bool skip = false;
+ if (ID_IS_LINKED(collection)) {
+ if (collection->id.tag & LIB_TAG_INDIRECT) {
+ skip = true;
+ }
+ else {
+ for (CollectionParent *cparent = collection->parents.first; cparent;
+ cparent = cparent->next) {
+ Collection *parent = cparent->collection;
+ if (ID_IS_LINKED(parent)) {
+ skip = true;
+ break;
+ }
+ else if (parent->flag & COLLECTION_IS_MASTER) {
+ Scene *parent_scene = BKE_collection_master_scene_search(bmain, parent);
+ if (ID_IS_LINKED(parent_scene)) {
+ skip = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (!skip) {
+ BKE_collection_delete(bmain, collection, hierarchy);
+ }
+ else {
+ BKE_reportf(
+ op->reports,
+ RPT_WARNING,
+ "Cannot delete linked collection '%s', it is used by other linked scenes/collections",
+ collection->id.name + 2);
+ }
+ }
+ }
+
+ BLI_gset_free(data.collections_to_edit, NULL);
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+
+ if (basact_prev != BASACT(view_layer)) {
+ WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
+ }
+
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_delete(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Collection";
- ot->idname = "OUTLINER_OT_collection_delete";
- ot->description = "Delete selected collections";
+ /* identifiers */
+ ot->name = "Delete Collection";
+ ot->idname = "OUTLINER_OT_collection_delete";
+ ot->description = "Delete selected collections";
- /* api callbacks */
- ot->exec = collection_delete_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_delete_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- PropertyRNA *prop = RNA_def_boolean(ot->srna, "hierarchy", false, "Hierarchy", "Delete child objects and collections");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "hierarchy", false, "Hierarchy", "Delete child objects and collections");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/****************************** Select Objects *******************************/
struct CollectionObjectsSelectData {
- bool error;
- LayerCollection *layer_collection;
+ bool error;
+ LayerCollection *layer_collection;
};
-static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata)
+static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te,
+ void *customdata)
{
- struct CollectionObjectsSelectData *data = customdata;
- TreeStoreElem *tselem = TREESTORE(te);
+ struct CollectionObjectsSelectData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
- switch (tselem->type) {
- case TSE_LAYER_COLLECTION:
- data->layer_collection = te->directdata;
- return TRAVERSE_BREAK;
- case TSE_R_LAYER:
- case TSE_SCENE_COLLECTION_BASE:
- case TSE_VIEW_COLLECTION_BASE:
- return TRAVERSE_CONTINUE;
- default:
- return TRAVERSE_SKIP_CHILDS;
- }
+ switch (tselem->type) {
+ case TSE_LAYER_COLLECTION:
+ data->layer_collection = te->directdata;
+ return TRAVERSE_BREAK;
+ case TSE_R_LAYER:
+ case TSE_SCENE_COLLECTION_BASE:
+ case TSE_VIEW_COLLECTION_BASE:
+ return TRAVERSE_CONTINUE;
+ default:
+ return TRAVERSE_SKIP_CHILDS;
+ }
}
static LayerCollection *outliner_active_layer_collection(bContext *C)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct CollectionObjectsSelectData data = {
- .layer_collection = NULL,
- };
+ struct CollectionObjectsSelectData data = {
+ .layer_collection = NULL,
+ };
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_layer_collection, &data);
- return data.layer_collection;
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_layer_collection, &data);
+ return data.layer_collection;
}
static int collection_objects_select_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- LayerCollection *layer_collection = outliner_active_layer_collection(C);
- bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ LayerCollection *layer_collection = outliner_active_layer_collection(C);
+ bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
- if (layer_collection == NULL) {
- return OPERATOR_CANCELLED;
- }
+ if (layer_collection == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- BKE_layer_collection_objects_select(view_layer, layer_collection, deselect);
+ BKE_layer_collection_objects_select(view_layer, layer_collection, deselect);
- Scene *scene = CTX_data_scene(C);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
+ Scene *scene = CTX_data_scene(C);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_objects_select(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Objects";
- ot->idname = "OUTLINER_OT_collection_objects_select";
- ot->description = "Select objects in collection";
+ /* identifiers */
+ ot->name = "Select Objects";
+ ot->idname = "OUTLINER_OT_collection_objects_select";
+ ot->description = "Select objects in collection";
- /* api callbacks */
- ot->exec = collection_objects_select_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_objects_select_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_objects_deselect(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Deselect Objects";
- ot->idname = "OUTLINER_OT_collection_objects_deselect";
- ot->description = "Deselect objects in collection";
+ /* identifiers */
+ ot->name = "Deselect Objects";
+ ot->idname = "OUTLINER_OT_collection_objects_deselect";
+ ot->description = "Deselect objects in collection";
- /* api callbacks */
- ot->exec = collection_objects_select_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_objects_select_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************************** Duplicate Collection *****************************/
struct CollectionDuplicateData {
- TreeElement *te;
+ TreeElement *te;
};
-static TreeTraversalAction outliner_find_first_selected_collection(TreeElement *te, void *customdata)
+static TreeTraversalAction outliner_find_first_selected_collection(TreeElement *te,
+ void *customdata)
{
- struct CollectionDuplicateData *data = customdata;
- TreeStoreElem *tselem = TREESTORE(te);
+ struct CollectionDuplicateData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
- switch (tselem->type) {
- case TSE_LAYER_COLLECTION:
- data->te = te;
- return TRAVERSE_BREAK;
- case TSE_R_LAYER:
- case TSE_SCENE_COLLECTION_BASE:
- case TSE_VIEW_COLLECTION_BASE:
- default:
- return TRAVERSE_CONTINUE;
- }
+ switch (tselem->type) {
+ case TSE_LAYER_COLLECTION:
+ data->te = te;
+ return TRAVERSE_BREAK;
+ case TSE_R_LAYER:
+ case TSE_SCENE_COLLECTION_BASE:
+ case TSE_VIEW_COLLECTION_BASE:
+ default:
+ return TRAVERSE_CONTINUE;
+ }
}
static TreeElement *outliner_active_collection(bContext *C)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct CollectionDuplicateData data = {
- .te = NULL,
- };
+ struct CollectionDuplicateData data = {
+ .te = NULL,
+ };
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_collection, &data);
- return data.te;
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_collection, &data);
+ return data.te;
}
static int collection_duplicate_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- TreeElement *te = outliner_active_collection(C);
- const bool linked = strstr(op->idname, "linked") != NULL;
-
- /* Can happen when calling from a key binding. */
- if (te == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active collection");
- return OPERATOR_CANCELLED;
- }
-
- Collection *collection = outliner_collection_from_tree_element(te);
- Collection *parent = (te->parent) ? outliner_collection_from_tree_element(te->parent) : NULL;
-
- /* We are allowed to duplicated linked collections (they will become local IDs then),
- * but we should not allow its parent to be a linked ID, ever.
- * This can happen when a whole scene is linked e.g. */
- if (parent != NULL && ID_IS_LINKED(parent)) {
- Scene *scene = CTX_data_scene(C);
- parent = ID_IS_LINKED(scene) ? NULL : BKE_collection_master(scene);
- }
- else if (parent != NULL && (parent->flag & COLLECTION_IS_MASTER) != 0) {
- Scene *scene = BKE_collection_master_scene_search(bmain, parent);
- BLI_assert(scene != NULL);
- if (ID_IS_LINKED(scene)) {
- scene = CTX_data_scene(C);
- parent = ID_IS_LINKED(scene) ? NULL : BKE_collection_master(scene);
- }
- }
-
- if (collection->flag & COLLECTION_IS_MASTER) {
- BKE_report(op->reports, RPT_ERROR, "Can't duplicate the master collection");
- return OPERATOR_CANCELLED;
- }
-
- if (parent == NULL) {
- BKE_report(op->reports, RPT_WARNING,
- "Could not find a valid parent collection for the new duplicate, "
- "it won't be linked to any view layer");
- }
-
- BKE_collection_duplicate(bmain, parent, collection, true, true, !linked);
-
- DEG_relations_tag_update(bmain);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, CTX_data_scene(C));
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ TreeElement *te = outliner_active_collection(C);
+ const bool linked = strstr(op->idname, "linked") != NULL;
+
+ /* Can happen when calling from a key binding. */
+ if (te == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active collection");
+ return OPERATOR_CANCELLED;
+ }
+
+ Collection *collection = outliner_collection_from_tree_element(te);
+ Collection *parent = (te->parent) ? outliner_collection_from_tree_element(te->parent) : NULL;
+
+ /* We are allowed to duplicated linked collections (they will become local IDs then),
+ * but we should not allow its parent to be a linked ID, ever.
+ * This can happen when a whole scene is linked e.g. */
+ if (parent != NULL && ID_IS_LINKED(parent)) {
+ Scene *scene = CTX_data_scene(C);
+ parent = ID_IS_LINKED(scene) ? NULL : BKE_collection_master(scene);
+ }
+ else if (parent != NULL && (parent->flag & COLLECTION_IS_MASTER) != 0) {
+ Scene *scene = BKE_collection_master_scene_search(bmain, parent);
+ BLI_assert(scene != NULL);
+ if (ID_IS_LINKED(scene)) {
+ scene = CTX_data_scene(C);
+ parent = ID_IS_LINKED(scene) ? NULL : BKE_collection_master(scene);
+ }
+ }
+
+ if (collection->flag & COLLECTION_IS_MASTER) {
+ BKE_report(op->reports, RPT_ERROR, "Can't duplicate the master collection");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (parent == NULL) {
+ BKE_report(op->reports,
+ RPT_WARNING,
+ "Could not find a valid parent collection for the new duplicate, "
+ "it won't be linked to any view layer");
+ }
+
+ BKE_collection_duplicate(bmain, parent, collection, true, true, !linked);
+
+ DEG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, CTX_data_scene(C));
+
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_duplicate_linked(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Duplicate Linked Collection";
- ot->idname = "OUTLINER_OT_collection_duplicate_linked";
- ot->description = "Recursively duplicate the collection, all its children and objects, with linked object data";
+ /* identifiers */
+ ot->name = "Duplicate Linked Collection";
+ ot->idname = "OUTLINER_OT_collection_duplicate_linked";
+ ot->description =
+ "Recursively duplicate the collection, all its children and objects, with linked object "
+ "data";
- /* api callbacks */
- ot->exec = collection_duplicate_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_duplicate_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_duplicate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Duplicate Collection";
- ot->idname = "OUTLINER_OT_collection_duplicate";
- ot->description = "Recursively duplicate the collection, all its children, objects and object data";
+ /* identifiers */
+ ot->name = "Duplicate Collection";
+ ot->idname = "OUTLINER_OT_collection_duplicate";
+ ot->description =
+ "Recursively duplicate the collection, all its children, objects and object data";
- /* api callbacks */
- ot->exec = collection_duplicate_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_duplicate_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/**************************** Link Collection ******************************/
static int collection_link_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- Collection *active_collection = CTX_data_layer_collection(C)->collection;
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Collection *active_collection = CTX_data_layer_collection(C)->collection;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
- if (ID_IS_LINKED(active_collection) ||
- ((active_collection->flag & COLLECTION_IS_MASTER) && ID_IS_LINKED(scene)))
- {
- BKE_report(op->reports, RPT_ERROR, "Cannot add a colection to a linked collection/scene");
- return OPERATOR_CANCELLED;
- }
+ if (ID_IS_LINKED(active_collection) ||
+ ((active_collection->flag & COLLECTION_IS_MASTER) && ID_IS_LINKED(scene))) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot add a colection to a linked collection/scene");
+ return OPERATOR_CANCELLED;
+ }
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
- /* We first walk over and find the Collections we actually want to link (ignoring duplicates). */
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
+ /* We first walk over and find the Collections we actually want to link (ignoring duplicates). */
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
- /* Effectively link the collections. */
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- BKE_collection_child_add(bmain, active_collection, collection);
- id_fake_user_clear(&collection->id);
- }
+ /* Effectively link the collections. */
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ BKE_collection_child_add(bmain, active_collection, collection);
+ id_fake_user_clear(&collection->id);
+ }
- BLI_gset_free(data.collections_to_edit, NULL);
+ BLI_gset_free(data.collections_to_edit, NULL);
- DEG_id_tag_update(&active_collection->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
+ DEG_id_tag_update(&active_collection->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_link(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Link Collection";
- ot->idname = "OUTLINER_OT_collection_link";
- ot->description = "Link selected collections to active scene";
+ /* identifiers */
+ ot->name = "Link Collection";
+ ot->idname = "OUTLINER_OT_collection_link";
+ ot->description = "Link selected collections to active scene";
- /* api callbacks */
- ot->exec = collection_link_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_link_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************************** Instance Collection ******************************/
static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
- /* We first walk over and find the Collections we actually want to instance (ignoring duplicates). */
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
+ /* We first walk over and find the Collections we actually want to instance (ignoring duplicates). */
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
- /* Find an active collection to add to, that doesn't give dependency cycles. */
- LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
+ /* Find an active collection to add to, that doesn't give dependency cycles. */
+ LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- while (BKE_collection_find_cycle(active_lc->collection, collection)) {
- active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
- }
- }
+ while (BKE_collection_find_cycle(active_lc->collection, collection)) {
+ active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
+ }
+ }
- /* Effectively instance the collections. */
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- Object *ob = ED_object_add_type(C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, NULL, false, 0);
- ob->instance_collection = collection;
- ob->transflag |= OB_DUPLICOLLECTION;
- id_lib_extern(&collection->id);
- }
+ /* Effectively instance the collections. */
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ Object *ob = ED_object_add_type(
+ C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, NULL, false, 0);
+ ob->instance_collection = collection;
+ ob->transflag |= OB_DUPLICOLLECTION;
+ id_lib_extern(&collection->id);
+ }
- BLI_gset_free(data.collections_to_edit, NULL);
+ BLI_gset_free(data.collections_to_edit, NULL);
- DEG_relations_tag_update(bmain);
+ DEG_relations_tag_update(bmain);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_instance(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Instance Collection";
- ot->idname = "OUTLINER_OT_collection_instance";
- ot->description = "Instance selected collections to active scene";
+ /* identifiers */
+ ot->name = "Instance Collection";
+ ot->idname = "OUTLINER_OT_collection_instance";
+ ot->description = "Instance selected collections to active scene";
- /* api callbacks */
- ot->exec = collection_instance_exec;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_instance_exec;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************************** Exclude Collection ******************************/
static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, void *customdata)
{
- struct CollectionEditData *data = customdata;
- TreeStoreElem *tselem = TREESTORE(te);
+ struct CollectionEditData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
- if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) {
- return TRAVERSE_CONTINUE;
- }
+ if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) {
+ return TRAVERSE_CONTINUE;
+ }
- LayerCollection *lc = te->directdata;
+ LayerCollection *lc = te->directdata;
- if (lc->collection->flag & COLLECTION_IS_MASTER) {
- /* skip - showing warning/error message might be misleading
- * when deleting multiple collections, so just do nothing */
- }
- else {
- /* Delete, duplicate and link don't edit children, those will come along
- * with the parents. */
- BLI_gset_add(data->collections_to_edit, lc);
- }
+ if (lc->collection->flag & COLLECTION_IS_MASTER) {
+ /* skip - showing warning/error message might be misleading
+ * when deleting multiple collections, so just do nothing */
+ }
+ else {
+ /* Delete, duplicate and link don't edit children, those will come along
+ * with the parents. */
+ BLI_gset_add(data->collections_to_edit, lc);
+ }
- return TRAVERSE_CONTINUE;
+ return TRAVERSE_CONTINUE;
}
static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
{
- /* Poll function so the right click menu show current state of selected collections. */
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- if (!(soops && soops->outlinevis == SO_VIEW_LAYER)) {
- return false;
- }
+ /* Poll function so the right click menu show current state of selected collections. */
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ if (!(soops && soops->outlinevis == SO_VIEW_LAYER)) {
+ return false;
+ }
- Scene *scene = CTX_data_scene(C);
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
- bool result = false;
+ Scene *scene = CTX_data_scene(C);
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
+ bool result = false;
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- if (clear && (lc->flag & flag)) {
- result = true;
- }
- else if (!clear && !(lc->flag & flag)) {
- result = true;
- }
- }
+ if (clear && (lc->flag & flag)) {
+ result = true;
+ }
+ else if (!clear && !(lc->flag & flag)) {
+ result = true;
+ }
+ }
- BLI_gset_free(data.collections_to_edit, NULL);
- return result;
+ BLI_gset_free(data.collections_to_edit, NULL);
+ return result;
}
static bool collections_exclude_set_poll(bContext *C)
{
- return collections_view_layer_poll(C, false, LAYER_COLLECTION_EXCLUDE);
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_EXCLUDE);
}
static bool collections_exclude_clear_poll(bContext *C)
{
- return collections_view_layer_poll(C, true, LAYER_COLLECTION_EXCLUDE);
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_EXCLUDE);
}
static bool collections_holdout_set_poll(bContext *C)
{
- return collections_view_layer_poll(C, false, LAYER_COLLECTION_HOLDOUT);
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_HOLDOUT);
}
static bool collections_holdout_clear_poll(bContext *C)
{
- return collections_view_layer_poll(C, true, LAYER_COLLECTION_HOLDOUT);
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_HOLDOUT);
}
static bool collections_indirect_only_set_poll(bContext *C)
{
- return collections_view_layer_poll(C, false, LAYER_COLLECTION_INDIRECT_ONLY);
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_INDIRECT_ONLY);
}
static bool collections_indirect_only_clear_poll(bContext *C)
{
- return collections_view_layer_poll(C, true, LAYER_COLLECTION_INDIRECT_ONLY);
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_INDIRECT_ONLY);
}
static void layer_collection_flag_recursive_set(LayerCollection *lc, int flag)
{
- for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
- if (lc->flag & flag) {
- nlc->flag |= flag;
- }
- else {
- nlc->flag &= ~flag;
- }
+ for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
+ if (lc->flag & flag) {
+ nlc->flag |= flag;
+ }
+ else {
+ nlc->flag &= ~flag;
+ }
- layer_collection_flag_recursive_set(nlc, flag);
- }
+ layer_collection_flag_recursive_set(nlc, flag);
+ }
}
static int collection_view_layer_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
- bool clear = strstr(op->idname, "clear") != NULL;
- int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
- strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
- LAYER_COLLECTION_EXCLUDE;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
+ bool clear = strstr(op->idname, "clear") != NULL;
+ int flag = strstr(op->idname, "holdout") ?
+ LAYER_COLLECTION_HOLDOUT :
+ strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
+ LAYER_COLLECTION_EXCLUDE;
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- if (clear) {
- lc->flag &= ~flag;
- }
- else {
- lc->flag |= flag;
- }
+ if (clear) {
+ lc->flag &= ~flag;
+ }
+ else {
+ lc->flag |= flag;
+ }
- layer_collection_flag_recursive_set(lc, flag);
- }
+ layer_collection_flag_recursive_set(lc, flag);
+ }
- BLI_gset_free(data.collections_to_edit, NULL);
+ BLI_gset_free(data.collections_to_edit, NULL);
- BKE_layer_collection_sync(scene, view_layer);
- DEG_relations_tag_update(bmain);
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_relations_tag_update(bmain);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Exclude";
- ot->idname = "OUTLINER_OT_collection_exclude_set";
- ot->description = "Exclude collection from the active view layer";
+ /* identifiers */
+ ot->name = "Set Exclude";
+ ot->idname = "OUTLINER_OT_collection_exclude_set";
+ ot->description = "Exclude collection from the active view layer";
- /* api callbacks */
- ot->exec = collection_view_layer_exec;
- ot->poll = collections_exclude_set_poll;
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_exclude_set_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Exclude";
- ot->idname = "OUTLINER_OT_collection_exclude_clear";
- ot->description = "Include collection in the active view layer";
+ /* identifiers */
+ ot->name = "Clear Exclude";
+ ot->idname = "OUTLINER_OT_collection_exclude_clear";
+ ot->description = "Include collection in the active view layer";
- /* api callbacks */
- ot->exec = collection_view_layer_exec;
- ot->poll = collections_exclude_clear_poll;
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_exclude_clear_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_holdout_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Holdout";
- ot->idname = "OUTLINER_OT_collection_holdout_set";
- ot->description = "Mask collection in the active view layer";
+ /* identifiers */
+ ot->name = "Set Holdout";
+ ot->idname = "OUTLINER_OT_collection_holdout_set";
+ ot->description = "Mask collection in the active view layer";
- /* api callbacks */
- ot->exec = collection_view_layer_exec;
- ot->poll = collections_holdout_set_poll;
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_holdout_set_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Holdout";
- ot->idname = "OUTLINER_OT_collection_holdout_clear";
- ot->description = "Clear masking of collection in the active view layer";
+ /* identifiers */
+ ot->name = "Clear Holdout";
+ ot->idname = "OUTLINER_OT_collection_holdout_clear";
+ ot->description = "Clear masking of collection in the active view layer";
- /* api callbacks */
- ot->exec = collection_view_layer_exec;
- ot->poll = collections_holdout_clear_poll;
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_holdout_clear_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_indirect_only_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Indirect Only";
- ot->idname = "OUTLINER_OT_collection_indirect_only_set";
- ot->description = "Set collection to only contribute indirectly (through shadows and reflections) in the view layer";
+ /* identifiers */
+ ot->name = "Set Indirect Only";
+ ot->idname = "OUTLINER_OT_collection_indirect_only_set";
+ ot->description =
+ "Set collection to only contribute indirectly (through shadows and reflections) in the view "
+ "layer";
- /* api callbacks */
- ot->exec = collection_view_layer_exec;
- ot->poll = collections_indirect_only_set_poll;
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_indirect_only_set_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Indirect Only";
- ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
- ot->description = "Clear collection contributing only indirectly in the view layer";
+ /* identifiers */
+ ot->name = "Clear Indirect Only";
+ ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
+ ot->description = "Clear collection contributing only indirectly in the view layer";
- /* api callbacks */
- ot->exec = collection_view_layer_exec;
- ot->poll = collections_indirect_only_clear_poll;
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_indirect_only_clear_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************************** Visibility Operators ******************************/
static int collection_isolate_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- const bool extend = RNA_boolean_get(op->ptr, "extend");
- bool depsgraph_changed = false;
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
-
- /* Hide all collections before the isolate function - needed in order to support multiple selected collections. */
- if (!extend) {
- LayerCollection *lc_master = view_layer->layer_collections.first;
- for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter; lc_iter = lc_iter->next) {
- lc_iter->flag |= LAYER_COLLECTION_RESTRICT_VIEW;
- layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
- }
- }
-
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
-
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- depsgraph_changed |= BKE_layer_collection_isolate(scene, view_layer, layer_collection, true);
- }
- BLI_gset_free(data.collections_to_edit, NULL);
-
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
-
- if (depsgraph_changed) {
- DEG_relations_tag_update(CTX_data_main(C));
- }
-
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool depsgraph_changed = false;
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
+
+ /* Hide all collections before the isolate function - needed in order to support multiple selected collections. */
+ if (!extend) {
+ LayerCollection *lc_master = view_layer->layer_collections.first;
+ for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ lc_iter->flag |= LAYER_COLLECTION_RESTRICT_VIEW;
+ layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
+ }
+ }
+
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
+
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ depsgraph_changed |= BKE_layer_collection_isolate(scene, view_layer, layer_collection, true);
+ }
+ BLI_gset_free(data.collections_to_edit, NULL);
+
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+
+ if (depsgraph_changed) {
+ DEG_relations_tag_update(CTX_data_main(C));
+ }
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+ return OPERATOR_FINISHED;
}
static int collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
- if (!RNA_property_is_set(op->ptr, prop) && (event->shift)) {
- RNA_property_boolean_set(op->ptr, prop, true);
- }
- return collection_isolate_exec(C, op);
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
+ if (!RNA_property_is_set(op->ptr, prop) && (event->shift)) {
+ RNA_property_boolean_set(op->ptr, prop, true);
+ }
+ return collection_isolate_exec(C, op);
}
void OUTLINER_OT_collection_isolate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Isolate Collection";
- ot->idname = "OUTLINER_OT_collection_isolate";
- ot->description = "Hide all but this collection and its parents";
+ /* identifiers */
+ ot->name = "Isolate Collection";
+ ot->idname = "OUTLINER_OT_collection_isolate";
+ ot->description = "Hide all but this collection and its parents";
- /* api callbacks */
- ot->exec = collection_isolate_exec;
- ot->invoke = collection_isolate_invoke;
- ot->poll = ED_outliner_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = collection_isolate_exec;
+ ot->invoke = collection_isolate_invoke;
+ ot->poll = ED_outliner_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- PropertyRNA *prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend current visible collections");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "extend", false, "Extend", "Extend current visible collections");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static bool collection_show_poll(bContext *C)
{
- return collections_view_layer_poll(C, true, LAYER_COLLECTION_RESTRICT_VIEW);
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_RESTRICT_VIEW);
}
static bool collection_hide_poll(bContext *C)
{
- return collections_view_layer_poll(C, false, LAYER_COLLECTION_RESTRICT_VIEW);
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_RESTRICT_VIEW);
}
static bool collection_inside_poll(bContext *C)
{
- if (!ED_outliner_collections_editor_poll(C)) {
- return false;
- }
- return outliner_active_layer_collection(C) != NULL;
+ if (!ED_outliner_collections_editor_poll(C)) {
+ return false;
+ }
+ return outliner_active_layer_collection(C) != NULL;
}
static int collection_visibility_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- const bool is_inside = strstr(op->idname, "inside") != NULL;
- const bool show = strstr(op->idname, "show") != NULL;
- bool depsgraph_changed = false;
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ const bool is_inside = strstr(op->idname, "inside") != NULL;
+ const bool show = strstr(op->idname, "show") != NULL;
+ bool depsgraph_changed = false;
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- depsgraph_changed |= BKE_layer_collection_set_visible(view_layer, layer_collection, show, is_inside);
- }
- BLI_gset_free(data.collections_to_edit, NULL);
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ depsgraph_changed |= BKE_layer_collection_set_visible(
+ view_layer, layer_collection, show, is_inside);
+ }
+ BLI_gset_free(data.collections_to_edit, NULL);
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
- if (depsgraph_changed) {
- DEG_relations_tag_update(CTX_data_main(C));
- }
+ if (depsgraph_changed) {
+ DEG_relations_tag_update(CTX_data_main(C));
+ }
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
- return OPERATOR_FINISHED;
+ WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_show(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Show Collection";
- ot->idname = "OUTLINER_OT_collection_show";
- ot->description = "Show the collection in this view layer";
+ /* identifiers */
+ ot->name = "Show Collection";
+ ot->idname = "OUTLINER_OT_collection_show";
+ ot->description = "Show the collection in this view layer";
- /* api callbacks */
- ot->exec = collection_visibility_exec;
- ot->poll = collection_show_poll;
+ /* api callbacks */
+ ot->exec = collection_visibility_exec;
+ ot->poll = collection_show_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_hide(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Hide Collection";
- ot->idname = "OUTLINER_OT_collection_hide";
- ot->description = "Hide the collection in this view layer";
+ /* identifiers */
+ ot->name = "Hide Collection";
+ ot->idname = "OUTLINER_OT_collection_hide";
+ ot->description = "Hide the collection in this view layer";
- /* api callbacks */
- ot->exec = collection_visibility_exec;
- ot->poll = collection_hide_poll;
+ /* api callbacks */
+ ot->exec = collection_visibility_exec;
+ ot->poll = collection_hide_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_show_inside(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Show Inside Collection";
- ot->idname = "OUTLINER_OT_collection_show_inside";
- ot->description = "Show all the objects and collections inside the collection";
+ /* identifiers */
+ ot->name = "Show Inside Collection";
+ ot->idname = "OUTLINER_OT_collection_show_inside";
+ ot->description = "Show all the objects and collections inside the collection";
- /* api callbacks */
- ot->exec = collection_visibility_exec;
- ot->poll = collection_inside_poll;
+ /* api callbacks */
+ ot->exec = collection_visibility_exec;
+ ot->poll = collection_inside_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_hide_inside(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Hide Inside Collection";
- ot->idname = "OUTLINER_OT_collection_hide_inside";
- ot->description = "Hide all the objects and collections inside the collection";
+ /* identifiers */
+ ot->name = "Hide Inside Collection";
+ ot->idname = "OUTLINER_OT_collection_hide_inside";
+ ot->description = "Hide all the objects and collections inside the collection";
- /* api callbacks */
- ot->exec = collection_visibility_exec;
- ot->poll = collection_inside_poll;
+ /* api callbacks */
+ ot->exec = collection_visibility_exec;
+ ot->poll = collection_inside_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static bool collection_flag_poll(bContext *C, bool clear, int flag)
{
- if (!ED_outliner_collections_editor_poll(C)) {
- return false;
- }
+ if (!ED_outliner_collections_editor_poll(C)) {
+ return false;
+ }
- TreeElement *te = outliner_active_collection(C);
- if (te == NULL) {
- return false;
- }
+ TreeElement *te = outliner_active_collection(C);
+ if (te == NULL) {
+ return false;
+ }
- Collection *collection = outliner_collection_from_tree_element(te);
- if (collection == NULL) {
- return false;
- }
+ Collection *collection = outliner_collection_from_tree_element(te);
+ if (collection == NULL) {
+ return false;
+ }
- if (clear && (collection->flag & flag)) {
- return true;
- }
- else if (!clear && !(collection->flag & flag)) {
- return true;
- }
+ if (clear && (collection->flag & flag)) {
+ return true;
+ }
+ else if (!clear && !(collection->flag & flag)) {
+ return true;
+ }
- return false;
+ return false;
}
static bool collection_enable_poll(bContext *C)
{
- return collection_flag_poll(C, true, COLLECTION_RESTRICT_VIEW);
+ return collection_flag_poll(C, true, COLLECTION_RESTRICT_VIEW);
}
static bool collection_disable_poll(bContext *C)
{
- return collection_flag_poll(C, false, COLLECTION_RESTRICT_VIEW);
+ return collection_flag_poll(C, false, COLLECTION_RESTRICT_VIEW);
}
static bool collection_enable_render_poll(bContext *C)
{
- return collection_flag_poll(C, true, COLLECTION_RESTRICT_RENDER);
+ return collection_flag_poll(C, true, COLLECTION_RESTRICT_RENDER);
}
static bool collection_disable_render_poll(bContext *C)
{
- return collection_flag_poll(C, false, COLLECTION_RESTRICT_RENDER);
+ return collection_flag_poll(C, false, COLLECTION_RESTRICT_RENDER);
}
static int collection_flag_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- const bool is_render = strstr(op->idname, "render");
- const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
- int flag = is_render ? COLLECTION_RESTRICT_RENDER : COLLECTION_RESTRICT_VIEW;
- struct CollectionEditData data = {.scene = scene, .soops = soops,};
- data.collections_to_edit = BLI_gset_ptr_new(__func__);
- const bool has_layer_collection = soops->outlinevis == SO_VIEW_LAYER;
-
- if (has_layer_collection) {
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- Collection *collection = layer_collection->collection;
- if (ID_IS_LINKED(collection)) {
- continue;
- }
- if (clear) {
- collection->flag &= ~flag;
- }
- else {
- collection->flag |= flag;
- }
-
- /* Make sure (at least for this view layer) the collection is visible. */
- if (clear && !is_render) {
- layer_collection->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
- }
- }
- BLI_gset_free(data.collections_to_edit, NULL);
- }
- else {
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
-
- if (clear) {
- collection->flag &= ~flag;
- }
- else {
- collection->flag |= flag;
- }
- }
- BLI_gset_free(data.collections_to_edit, NULL);
- }
-
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
-
- if (!is_render) {
- DEG_relations_tag_update(CTX_data_main(C));
- }
-
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ const bool is_render = strstr(op->idname, "render");
+ const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
+ int flag = is_render ? COLLECTION_RESTRICT_RENDER : COLLECTION_RESTRICT_VIEW;
+ struct CollectionEditData data = {
+ .scene = scene,
+ .soops = soops,
+ };
+ data.collections_to_edit = BLI_gset_ptr_new(__func__);
+ const bool has_layer_collection = soops->outlinevis == SO_VIEW_LAYER;
+
+ if (has_layer_collection) {
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, layer_collection_find_data_to_edit, &data);
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ Collection *collection = layer_collection->collection;
+ if (ID_IS_LINKED(collection)) {
+ continue;
+ }
+ if (clear) {
+ collection->flag &= ~flag;
+ }
+ else {
+ collection->flag |= flag;
+ }
+
+ /* Make sure (at least for this view layer) the collection is visible. */
+ if (clear && !is_render) {
+ layer_collection->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+ }
+ }
+ BLI_gset_free(data.collections_to_edit, NULL);
+ }
+ else {
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+
+ if (clear) {
+ collection->flag &= ~flag;
+ }
+ else {
+ collection->flag |= flag;
+ }
+ }
+ BLI_gset_free(data.collections_to_edit, NULL);
+ }
+
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+
+ if (!is_render) {
+ DEG_relations_tag_update(CTX_data_main(C));
+ }
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_enable(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Enable Collection";
- ot->idname = "OUTLINER_OT_collection_enable";
- ot->description = "Enable viewport drawing in the view layers";
+ /* identifiers */
+ ot->name = "Enable Collection";
+ ot->idname = "OUTLINER_OT_collection_enable";
+ ot->description = "Enable viewport drawing in the view layers";
- /* api callbacks */
- ot->exec = collection_flag_exec;
- ot->poll = collection_enable_poll;
+ /* api callbacks */
+ ot->exec = collection_flag_exec;
+ ot->poll = collection_enable_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_disable(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Disable Collection";
- ot->idname = "OUTLINER_OT_collection_disable";
- ot->description = "Disable viewport drawing in the view layers";
+ /* identifiers */
+ ot->name = "Disable Collection";
+ ot->idname = "OUTLINER_OT_collection_disable";
+ ot->description = "Disable viewport drawing in the view layers";
- /* api callbacks */
- ot->exec = collection_flag_exec;
- ot->poll = collection_disable_poll;
+ /* api callbacks */
+ ot->exec = collection_flag_exec;
+ ot->poll = collection_disable_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_enable_render(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Enable Collection in Render";
- ot->idname = "OUTLINER_OT_collection_enable_render";
- ot->description = "Render the collection";
+ /* identifiers */
+ ot->name = "Enable Collection in Render";
+ ot->idname = "OUTLINER_OT_collection_enable_render";
+ ot->description = "Render the collection";
- /* api callbacks */
- ot->exec = collection_flag_exec;
- ot->poll = collection_enable_render_poll;
+ /* api callbacks */
+ ot->exec = collection_flag_exec;
+ ot->poll = collection_enable_render_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OUTLINER_OT_collection_disable_render(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Disable Collection in Render";
- ot->idname = "OUTLINER_OT_collection_disable_render";
- ot->description = "Do not render this collection";
+ /* identifiers */
+ ot->name = "Disable Collection in Render";
+ ot->idname = "OUTLINER_OT_collection_disable_render";
+ ot->description = "Do not render this collection";
- /* api callbacks */
- ot->exec = collection_flag_exec;
- ot->poll = collection_disable_render_poll;
+ /* api callbacks */
+ ot->exec = collection_flag_exec;
+ ot->poll = collection_disable_render_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
struct OutlinerHideEditData {
- Scene *scene;
- ViewLayer *view_layer;
- SpaceOutliner *soops;
- GSet *collections_to_edit;
- GSet *bases_to_edit;
+ Scene *scene;
+ ViewLayer *view_layer;
+ SpaceOutliner *soops;
+ GSet *collections_to_edit;
+ GSet *bases_to_edit;
};
static TreeTraversalAction outliner_hide_find_data_to_edit(TreeElement *te, void *customdata)
{
- struct OutlinerHideEditData *data = customdata;
- TreeStoreElem *tselem = TREESTORE(te);
+ struct OutlinerHideEditData *data = customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
- if (tselem == NULL) {
- return TRAVERSE_CONTINUE;
- }
+ if (tselem == NULL) {
+ return TRAVERSE_CONTINUE;
+ }
- if (tselem->type == TSE_LAYER_COLLECTION) {
- LayerCollection *lc = te->directdata;
+ if (tselem->type == TSE_LAYER_COLLECTION) {
+ LayerCollection *lc = te->directdata;
- if (lc->collection->flag & COLLECTION_IS_MASTER) {
- /* Skip - showing warning/error message might be misleading
- * when deleting multiple collections, so just do nothing. */
- }
- else {
- /* Delete, duplicate and link don't edit children,
- * those will come along with the parents. */
- BLI_gset_add(data->collections_to_edit, lc);
- }
- }
- else if (tselem->type == 0 && te->idcode == ID_OB) {
- Object *ob = (Object *)tselem->id;
- Base *base = BKE_view_layer_base_find(data->view_layer, ob);
- BLI_gset_add(data->bases_to_edit, base);
- }
+ if (lc->collection->flag & COLLECTION_IS_MASTER) {
+ /* Skip - showing warning/error message might be misleading
+ * when deleting multiple collections, so just do nothing. */
+ }
+ else {
+ /* Delete, duplicate and link don't edit children,
+ * those will come along with the parents. */
+ BLI_gset_add(data->collections_to_edit, lc);
+ }
+ }
+ else if (tselem->type == 0 && te->idcode == ID_OB) {
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_view_layer_base_find(data->view_layer, ob);
+ BLI_gset_add(data->bases_to_edit, base);
+ }
- return TRAVERSE_CONTINUE;
+ return TRAVERSE_CONTINUE;
}
static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct OutlinerHideEditData data = {.scene = scene, .view_layer = view_layer, .soops = soops,};
- data.collections_to_edit = BLI_gset_ptr_new("outliner_hide_exec__collections_to_edit");
- data.bases_to_edit = BLI_gset_ptr_new("outliner_hide_exec__bases_to_edit");
-
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_hide_find_data_to_edit, &data);
-
- GSetIterator collections_to_edit_iter;
- GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- BKE_layer_collection_set_visible(view_layer, layer_collection, false, false);
- }
- BLI_gset_free(data.collections_to_edit, NULL);
-
- GSetIterator bases_to_edit_iter;
- GSET_ITER(bases_to_edit_iter, data.bases_to_edit) {
- Base *base = BLI_gsetIterator_getKey(&bases_to_edit_iter);
- base->flag |= BASE_HIDDEN;
- }
- BLI_gset_free(data.bases_to_edit, NULL);
-
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
-
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ struct OutlinerHideEditData data = {
+ .scene = scene,
+ .view_layer = view_layer,
+ .soops = soops,
+ };
+ data.collections_to_edit = BLI_gset_ptr_new("outliner_hide_exec__collections_to_edit");
+ data.bases_to_edit = BLI_gset_ptr_new("outliner_hide_exec__bases_to_edit");
+
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_hide_find_data_to_edit, &data);
+
+ GSetIterator collections_to_edit_iter;
+ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
+ LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
+ BKE_layer_collection_set_visible(view_layer, layer_collection, false, false);
+ }
+ BLI_gset_free(data.collections_to_edit, NULL);
+
+ GSetIterator bases_to_edit_iter;
+ GSET_ITER (bases_to_edit_iter, data.bases_to_edit) {
+ Base *base = BLI_gsetIterator_getKey(&bases_to_edit_iter);
+ base->flag |= BASE_HIDDEN;
+ }
+ BLI_gset_free(data.bases_to_edit, NULL);
+
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+
+ WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_hide(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Hide";
- ot->idname = "OUTLINER_OT_hide";
- ot->description = "Hide selected objects and collections";
+ /* identifiers */
+ ot->name = "Hide";
+ ot->idname = "OUTLINER_OT_hide";
+ ot->description = "Hide selected objects and collections";
- /* api callbacks */
- ot->exec = outliner_hide_exec;
- ot->poll = outliner_view_layer_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = outliner_hide_exec;
+ ot->poll = outliner_view_layer_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int outliner_unhide_all_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- /* Unhide all the collections. */
- LayerCollection *lc_master = view_layer->layer_collections.first;
- for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter; lc_iter = lc_iter->next) {
- lc_iter->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
- layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
- }
+ /* Unhide all the collections. */
+ LayerCollection *lc_master = view_layer->layer_collections.first;
+ for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ lc_iter->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+ layer_collection_flag_recursive_set(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
+ }
- /* Unhide all objects. */
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- base->flag &= ~BASE_HIDDEN;
- }
+ /* Unhide all objects. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ base->flag &= ~BASE_HIDDEN;
+ }
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
- return OPERATOR_FINISHED;
+ WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_unhide_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Unhide All";
- ot->idname = "OUTLINER_OT_unhide_all";
- ot->description = "Unhide all objects and collections";
+ /* identifiers */
+ ot->name = "Unhide All";
+ ot->idname = "OUTLINER_OT_unhide_all";
+ ot->description = "Unhide all objects and collections";
- /* api callbacks */
- ot->exec = outliner_unhide_all_exec;
- ot->poll = outliner_view_layer_collections_editor_poll;
+ /* api callbacks */
+ ot->exec = outliner_unhide_all_exec;
+ ot->poll = outliner_view_layer_collections_editor_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/**
@@ -1385,13 +1443,14 @@ void OUTLINER_OT_unhide_all(wmOperatorType *ot)
*/
void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct IDsSelectedData data = {{NULL}};
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
- LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
- TreeElement *ten_selected = (TreeElement *)link->data;
- Object *ob = (Object *)TREESTORE(ten_selected)->id;
- BLI_addtail(objects, BLI_genericNodeN(ob));
- }
- BLI_freelistN(&data.selected_array);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ struct IDsSelectedData data = {{NULL}};
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
+ LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
+ TreeElement *ten_selected = (TreeElement *)link->data;
+ Object *ob = (Object *)TREESTORE(ten_selected)->id;
+ BLI_addtail(objects, BLI_genericNodeN(ob));
+ }
+ BLI_freelistN(&data.selected_array);
}
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 647fdeccb40..cff262698fa 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -69,948 +69,981 @@
/* ******************** Drop Target Find *********************** */
-static TreeElement *outliner_dropzone_element(TreeElement *te, const float fmval[2], const bool children)
+static TreeElement *outliner_dropzone_element(TreeElement *te,
+ const float fmval[2],
+ const bool children)
{
- if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
- /* name and first icon */
- if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) {
- return te;
- }
- }
- /* Not it. Let's look at its children. */
- if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0 && (te->subtree.first)) {
- for (te = te->subtree.first; te; te = te->next) {
- TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
- if (te_valid) {
- return te_valid;
- }
- }
- }
- return NULL;
+ if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
+ /* name and first icon */
+ if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) {
+ return te;
+ }
+ }
+ /* Not it. Let's look at its children. */
+ if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0 && (te->subtree.first)) {
+ for (te = te->subtree.first; te; te = te->next) {
+ TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
+ if (te_valid) {
+ return te_valid;
+ }
+ }
+ }
+ return NULL;
}
/* Find tree element to drop into. */
-static TreeElement *outliner_dropzone_find(const SpaceOutliner *soops, const float fmval[2], const bool children)
+static TreeElement *outliner_dropzone_find(const SpaceOutliner *soops,
+ const float fmval[2],
+ const bool children)
{
- TreeElement *te;
-
- for (te = soops->tree.first; te; te = te->next) {
- TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
- if (te_valid) {
- return te_valid;
- }
- }
- return NULL;
+ TreeElement *te;
+
+ for (te = soops->tree.first; te; te = te->next) {
+ TreeElement *te_valid = outliner_dropzone_element(te, fmval, children);
+ if (te_valid) {
+ return te_valid;
+ }
+ }
+ return NULL;
}
static TreeElement *outliner_drop_find(bContext *C, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- float fmval[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ float fmval[2];
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- return outliner_dropzone_find(soops, fmval, true);
+ return outliner_dropzone_find(soops, fmval, true);
}
static ID *outliner_ID_drop_find(bContext *C, const wmEvent *event, short idcode)
{
- TreeElement *te = outliner_drop_find(C, event);
- TreeStoreElem *tselem = (te) ? TREESTORE(te) : NULL;
-
- if (te && te->idcode == idcode && tselem->type == 0) {
- return tselem->id;
- }
- else {
- return NULL;
- }
+ TreeElement *te = outliner_drop_find(C, event);
+ TreeStoreElem *tselem = (te) ? TREESTORE(te) : NULL;
+
+ if (te && te->idcode == idcode && tselem->type == 0) {
+ return tselem->id;
+ }
+ else {
+ return NULL;
+ }
}
/* Find tree element to drop into, with additional before and after reorder support. */
-static TreeElement *outliner_drop_insert_find(
- bContext *C, const wmEvent *event,
- TreeElementInsertType *r_insert_type)
+static TreeElement *outliner_drop_insert_find(bContext *C,
+ const wmEvent *event,
+ TreeElementInsertType *r_insert_type)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- TreeElement *te_hovered;
- float view_mval[2];
-
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
- te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
-
- if (te_hovered) {
- /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */
- const float margin = UI_UNIT_Y * (1.0f / 4);
-
- if (view_mval[1] < (te_hovered->ys + margin)) {
- if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) {
- /* inserting after a open item means we insert into it, but as first child */
- if (BLI_listbase_is_empty(&te_hovered->subtree)) {
- *r_insert_type = TE_INSERT_INTO;
- return te_hovered;
- }
- else {
- *r_insert_type = TE_INSERT_BEFORE;
- return te_hovered->subtree.first;
- }
- }
- else {
- *r_insert_type = TE_INSERT_AFTER;
- return te_hovered;
- }
- }
- else if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
- *r_insert_type = TE_INSERT_BEFORE;
- return te_hovered;
- }
- else {
- *r_insert_type = TE_INSERT_INTO;
- return te_hovered;
- }
- }
- else {
- /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */
- TreeElement *first = soops->tree.first;
- TreeElement *last = soops->tree.last;
-
- if (view_mval[1] < last->ys) {
- *r_insert_type = TE_INSERT_AFTER;
- return last;
- }
- else if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
- *r_insert_type = TE_INSERT_BEFORE;
- return first;
- }
- else {
- BLI_assert(0);
- return NULL;
- }
- }
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ TreeElement *te_hovered;
+ float view_mval[2];
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+ te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
+
+ if (te_hovered) {
+ /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */
+ const float margin = UI_UNIT_Y * (1.0f / 4);
+
+ if (view_mval[1] < (te_hovered->ys + margin)) {
+ if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) {
+ /* inserting after a open item means we insert into it, but as first child */
+ if (BLI_listbase_is_empty(&te_hovered->subtree)) {
+ *r_insert_type = TE_INSERT_INTO;
+ return te_hovered;
+ }
+ else {
+ *r_insert_type = TE_INSERT_BEFORE;
+ return te_hovered->subtree.first;
+ }
+ }
+ else {
+ *r_insert_type = TE_INSERT_AFTER;
+ return te_hovered;
+ }
+ }
+ else if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
+ *r_insert_type = TE_INSERT_BEFORE;
+ return te_hovered;
+ }
+ else {
+ *r_insert_type = TE_INSERT_INTO;
+ return te_hovered;
+ }
+ }
+ else {
+ /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */
+ TreeElement *first = soops->tree.first;
+ TreeElement *last = soops->tree.last;
+
+ if (view_mval[1] < last->ys) {
+ *r_insert_type = TE_INSERT_AFTER;
+ return last;
+ }
+ else if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
+ *r_insert_type = TE_INSERT_BEFORE;
+ return first;
+ }
+ else {
+ BLI_assert(0);
+ return NULL;
+ }
+ }
}
-static Collection *outliner_collection_from_tree_element_and_parents(TreeElement *te, TreeElement **r_te)
+static Collection *outliner_collection_from_tree_element_and_parents(TreeElement *te,
+ TreeElement **r_te)
{
- while (te != NULL) {
- Collection *collection = outliner_collection_from_tree_element(te);
- if (collection) {
- *r_te = te;
- return collection;
- }
- te = te->parent;
- }
- return NULL;
+ while (te != NULL) {
+ Collection *collection = outliner_collection_from_tree_element(te);
+ if (collection) {
+ *r_te = te;
+ return collection;
+ }
+ te = te->parent;
+ }
+ return NULL;
}
-static TreeElement *outliner_drop_insert_collection_find(
- bContext *C, const wmEvent *event,
- TreeElementInsertType *r_insert_type)
+static TreeElement *outliner_drop_insert_collection_find(bContext *C,
+ const wmEvent *event,
+ TreeElementInsertType *r_insert_type)
{
- TreeElement *te = outliner_drop_insert_find(C, event, r_insert_type);
- if (!te) {
- return NULL;
- }
-
- TreeElement *collection_te;
- Collection *collection = outliner_collection_from_tree_element_and_parents(te, &collection_te);
- if (!collection) {
- return NULL;
- }
-
- if (collection_te != te) {
- *r_insert_type = TE_INSERT_INTO;
- }
-
- /* We can't insert before/after master collection. */
- if (collection->flag & COLLECTION_IS_MASTER) {
- *r_insert_type = TE_INSERT_INTO;
- }
-
- return collection_te;
+ TreeElement *te = outliner_drop_insert_find(C, event, r_insert_type);
+ if (!te) {
+ return NULL;
+ }
+
+ TreeElement *collection_te;
+ Collection *collection = outliner_collection_from_tree_element_and_parents(te, &collection_te);
+ if (!collection) {
+ return NULL;
+ }
+
+ if (collection_te != te) {
+ *r_insert_type = TE_INSERT_INTO;
+ }
+
+ /* We can't insert before/after master collection. */
+ if (collection->flag & COLLECTION_IS_MASTER) {
+ *r_insert_type = TE_INSERT_INTO;
+ }
+
+ return collection_te;
}
/* ******************** Parent Drop Operator *********************** */
static bool parent_drop_allowed(SpaceOutliner *soops, TreeElement *te, Object *potential_child)
{
- TreeStoreElem *tselem = TREESTORE(te);
- if (te->idcode != ID_OB || tselem->type != 0) {
- return false;
- }
-
- Object *potential_parent = (Object *)tselem->id;
-
- if (potential_parent == potential_child) {
- return false;
- }
- if (BKE_object_is_child_recursive(potential_child, potential_parent)) {
- return false;
- }
- if (potential_parent == potential_child->parent) {
- return false;
- }
-
- /* check that parent/child are both in the same scene */
- Scene *scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
-
- /* currently outliner organized in a way that if there's no parent scene
- * element for object it means that all displayed objects belong to
- * active scene and parenting them is allowed (sergey) */
- if (scene) {
- for (ViewLayer *view_layer = scene->view_layers.first;
- view_layer;
- view_layer = view_layer->next)
- {
- if (BKE_view_layer_base_find(view_layer, potential_child)) {
- return true;
- }
- }
- return false;
- }
- else {
- return true;
- }
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (te->idcode != ID_OB || tselem->type != 0) {
+ return false;
+ }
+
+ Object *potential_parent = (Object *)tselem->id;
+
+ if (potential_parent == potential_child) {
+ return false;
+ }
+ if (BKE_object_is_child_recursive(potential_child, potential_parent)) {
+ return false;
+ }
+ if (potential_parent == potential_child->parent) {
+ return false;
+ }
+
+ /* check that parent/child are both in the same scene */
+ Scene *scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
+
+ /* currently outliner organized in a way that if there's no parent scene
+ * element for object it means that all displayed objects belong to
+ * active scene and parenting them is allowed (sergey) */
+ if (scene) {
+ for (ViewLayer *view_layer = scene->view_layers.first; view_layer;
+ view_layer = view_layer->next) {
+ if (BKE_view_layer_base_find(view_layer, potential_child)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ else {
+ return true;
+ }
}
static bool allow_parenting_without_modifier_key(SpaceOutliner *soops)
{
- switch (soops->outlinevis) {
- case SO_VIEW_LAYER:
- return soops->filter & SO_FILTER_NO_COLLECTION;
- case SO_SCENES:
- return true;
- default:
- return false;
- }
+ switch (soops->outlinevis) {
+ case SO_VIEW_LAYER:
+ return soops->filter & SO_FILTER_NO_COLLECTION;
+ case SO_SCENES:
+ return true;
+ default:
+ return false;
+ }
}
-static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+static bool parent_drop_poll(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ const char **UNUSED(tooltip))
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
-
- bool changed = outliner_flag_set(&soops->tree, TSE_DRAG_ANY, false);
- if (changed) {
- ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
- }
-
- Object *potential_child = (Object *)WM_drag_ID(drag, ID_OB);
- if (!potential_child) {
- return false;
- }
-
- if (!allow_parenting_without_modifier_key(soops)) {
- if (!event->shift) {
- return false;
- }
- }
-
- TreeElement *te = outliner_drop_find(C, event);
- if (!te) {
- return false;
- }
-
- if (parent_drop_allowed(soops, te, potential_child)) {
- TREESTORE(te)->flag |= TSE_DRAG_INTO;
- ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
- return true;
- }
-
- return false;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+ bool changed = outliner_flag_set(&soops->tree, TSE_DRAG_ANY, false);
+ if (changed) {
+ ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
+ }
+
+ Object *potential_child = (Object *)WM_drag_ID(drag, ID_OB);
+ if (!potential_child) {
+ return false;
+ }
+
+ if (!allow_parenting_without_modifier_key(soops)) {
+ if (!event->shift) {
+ return false;
+ }
+ }
+
+ TreeElement *te = outliner_drop_find(C, event);
+ if (!te) {
+ return false;
+ }
+
+ if (parent_drop_allowed(soops, te, potential_child)) {
+ TREESTORE(te)->flag |= TSE_DRAG_INTO;
+ ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
+ return true;
+ }
+
+ return false;
}
static int parent_drop_exec(bContext *C, wmOperator *op)
{
- Object *par = NULL, *ob = NULL;
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- int partype = -1;
- char parname[MAX_NAME], childname[MAX_NAME];
-
- partype = RNA_enum_get(op->ptr, "type");
- RNA_string_get(op->ptr, "parent", parname);
- par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname);
- RNA_string_get(op->ptr, "child", childname);
- ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
-
- if (ID_IS_LINKED(ob)) {
- BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
- return OPERATOR_CANCELLED;
- }
-
- ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL);
-
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
-
- return OPERATOR_FINISHED;
+ Object *par = NULL, *ob = NULL;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ int partype = -1;
+ char parname[MAX_NAME], childname[MAX_NAME];
+
+ partype = RNA_enum_get(op->ptr, "type");
+ RNA_string_get(op->ptr, "parent", parname);
+ par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname);
+ RNA_string_get(op->ptr, "child", childname);
+ ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
+
+ if (ID_IS_LINKED(ob)) {
+ BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
+ return OPERATOR_CANCELLED;
+ }
+
+ ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL);
+
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
+
+ return OPERATOR_FINISHED;
}
static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- Main *bmain = CTX_data_main(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te = outliner_drop_find(C, event);
- TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
-
- if (!(te && te->idcode == ID_OB && tselem->type == 0)) {
- return OPERATOR_CANCELLED;
- }
-
- Object *par = (Object *)tselem->id;
- Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
-
- if (ELEM(NULL, ob, par)) {
- return OPERATOR_CANCELLED;
- }
- if (ob == par) {
- return OPERATOR_CANCELLED;
- }
- if (ID_IS_LINKED(ob)) {
- BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
- return OPERATOR_CANCELLED;
- }
-
- char childname[MAX_NAME];
- char parname[MAX_NAME];
- STRNCPY(childname, ob->id.name + 2);
- STRNCPY(parname, par->id.name + 2);
- RNA_string_set(op->ptr, "child", childname);
- RNA_string_set(op->ptr, "parent", parname);
-
- Scene *scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
-
- if (scene == NULL) {
- /* currently outlier organized in a way, that if there's no parent scene
- * element for object it means that all displayed objects belong to
- * active scene and parenting them is allowed (sergey)
- */
-
- scene = CTX_data_scene(C);
- }
-
- if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) {
- int partype = 0;
- if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) {
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
- }
- }
- else {
- /* Menu creation */
- wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false);
- uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE);
- uiLayout *layout = UI_popup_menu_layout(pup);
- PointerRNA ptr;
-
- /* Cannot use uiItemEnumO()... have multiple properties to set. */
- uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_OBJECT);
-
- /* par becomes parent, make the associated menus */
- if (par->type == OB_ARMATURE) {
- uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE);
-
- uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME);
-
- uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE);
-
- uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO);
-
- uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_BONE);
- }
- else if (par->type == OB_CURVE) {
- uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_CURVE);
-
- uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_FOLLOW);
-
- uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_PATH_CONST);
- }
- else if (par->type == OB_LATTICE) {
- uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
- RNA_string_set(&ptr, "parent", parname);
- RNA_string_set(&ptr, "child", childname);
- RNA_enum_set(&ptr, "type", PAR_LATTICE);
- }
-
- UI_popup_menu_end(C, pup);
-
- return OPERATOR_INTERFACE;
- }
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te = outliner_drop_find(C, event);
+ TreeStoreElem *tselem = te ? TREESTORE(te) : NULL;
+
+ if (!(te && te->idcode == ID_OB && tselem->type == 0)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Object *par = (Object *)tselem->id;
+ Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
+
+ if (ELEM(NULL, ob, par)) {
+ return OPERATOR_CANCELLED;
+ }
+ if (ob == par) {
+ return OPERATOR_CANCELLED;
+ }
+ if (ID_IS_LINKED(ob)) {
+ BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
+ return OPERATOR_CANCELLED;
+ }
+
+ char childname[MAX_NAME];
+ char parname[MAX_NAME];
+ STRNCPY(childname, ob->id.name + 2);
+ STRNCPY(parname, par->id.name + 2);
+ RNA_string_set(op->ptr, "child", childname);
+ RNA_string_set(op->ptr, "parent", parname);
+
+ Scene *scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
+
+ if (scene == NULL) {
+ /* currently outlier organized in a way, that if there's no parent scene
+ * element for object it means that all displayed objects belong to
+ * active scene and parenting them is allowed (sergey)
+ */
+
+ scene = CTX_data_scene(C);
+ }
+
+ if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) {
+ int partype = 0;
+ if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) {
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
+ }
+ }
+ else {
+ /* Menu creation */
+ wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+ PointerRNA ptr;
+
+ /* Cannot use uiItemEnumO()... have multiple properties to set. */
+ uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_OBJECT);
+
+ /* par becomes parent, make the associated menus */
+ if (par->type == OB_ARMATURE) {
+ uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE);
+
+ uiItemFullO_ptr(
+ layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME);
+
+ uiItemFullO_ptr(
+ layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE);
+
+ uiItemFullO_ptr(
+ layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO);
+
+ uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_BONE);
+ }
+ else if (par->type == OB_CURVE) {
+ uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_CURVE);
+
+ uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_FOLLOW);
+
+ uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_PATH_CONST);
+ }
+ else if (par->type == OB_LATTICE) {
+ uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
+ RNA_string_set(&ptr, "parent", parname);
+ RNA_string_set(&ptr, "child", childname);
+ RNA_enum_set(&ptr, "type", PAR_LATTICE);
+ }
+
+ UI_popup_menu_end(C, pup);
+
+ return OPERATOR_INTERFACE;
+ }
+
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_parent_drop(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Drop to Set Parent";
- ot->description = "Drag to parent in Outliner";
- ot->idname = "OUTLINER_OT_parent_drop";
+ /* identifiers */
+ ot->name = "Drop to Set Parent";
+ ot->description = "Drag to parent in Outliner";
+ ot->idname = "OUTLINER_OT_parent_drop";
- /* api callbacks */
- ot->invoke = parent_drop_invoke;
- ot->exec = parent_drop_exec;
+ /* api callbacks */
+ ot->invoke = parent_drop_invoke;
+ ot->exec = parent_drop_exec;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- RNA_def_string(ot->srna, "child", "Object", MAX_NAME, "Child", "Child Object");
- RNA_def_string(ot->srna, "parent", "Object", MAX_NAME, "Parent", "Parent Object");
- RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
+ /* properties */
+ RNA_def_string(ot->srna, "child", "Object", MAX_NAME, "Child", "Child Object");
+ RNA_def_string(ot->srna, "parent", "Object", MAX_NAME, "Parent", "Parent Object");
+ RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
}
/* ******************** Parent Clear Operator *********************** */
-static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+static bool parent_clear_poll(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ const char **UNUSED(tooltip))
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
-
- if (!allow_parenting_without_modifier_key(soops)) {
- if (!event->shift) {
- return false;
- }
- }
-
- Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
- if (!ob) {
- return false;
- }
- if (!ob->parent) {
- return false;
- }
-
- TreeElement *te = outliner_drop_find(C, event);
- if (te) {
- TreeStoreElem *tselem = TREESTORE(te);
- ID *id = tselem->id;
- if (!id) {
- return true;
- }
-
- switch (GS(id->name)) {
- case ID_OB:
- return ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE);
- case ID_GR:
- return event->shift;
- default:
- return true;
- }
- }
- else {
- return true;
- }
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+ if (!allow_parenting_without_modifier_key(soops)) {
+ if (!event->shift) {
+ return false;
+ }
+ }
+
+ Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
+ if (!ob) {
+ return false;
+ }
+ if (!ob->parent) {
+ return false;
+ }
+
+ TreeElement *te = outliner_drop_find(C, event);
+ if (te) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ ID *id = tselem->id;
+ if (!id) {
+ return true;
+ }
+
+ switch (GS(id->name)) {
+ case ID_OB:
+ return ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE);
+ case ID_GR:
+ return event->shift;
+ default:
+ return true;
+ }
+ }
+ else {
+ return true;
+ }
}
static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- Main *bmain = CTX_data_main(C);
- Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
+ Main *bmain = CTX_data_main(C);
+ Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
- if (ob == NULL) {
- return OPERATOR_CANCELLED;
- }
+ if (ob == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- ED_object_parent_clear(ob, 0);
+ ED_object_parent_clear(ob, 0);
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
- return OPERATOR_FINISHED;
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_parent_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Drop to Clear Parent";
- ot->description = "Drag to clear parent in Outliner";
- ot->idname = "OUTLINER_OT_parent_clear";
+ /* identifiers */
+ ot->name = "Drop to Clear Parent";
+ ot->description = "Drag to clear parent in Outliner";
+ ot->idname = "OUTLINER_OT_parent_clear";
- /* api callbacks */
- ot->invoke = parent_clear_invoke;
+ /* api callbacks */
+ ot->invoke = parent_clear_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* ******************** Scene Drop Operator *********************** */
-static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+static bool scene_drop_poll(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ const char **UNUSED(tooltip))
{
- /* Ensure item under cursor is valid drop target */
- Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
- return (ob && (outliner_ID_drop_find(C, event, ID_SCE) != NULL));
+ /* Ensure item under cursor is valid drop target */
+ Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
+ return (ob && (outliner_ID_drop_find(C, event, ID_SCE) != NULL));
}
static int scene_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = (Scene *)outliner_ID_drop_find(C, event, ID_SCE);
- Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
-
- if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) {
- return OPERATOR_CANCELLED;
- }
-
- if (BKE_scene_has_object(scene, ob)) {
- return OPERATOR_CANCELLED;
- }
-
- Collection *collection;
- if (scene != CTX_data_scene(C)) {
- /* when linking to an inactive scene link to the master collection */
- collection = BKE_collection_master(scene);
- }
- else {
- collection = CTX_data_collection(C);
- }
-
- BKE_collection_object_add(bmain, collection, ob);
-
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
- Base *base = BKE_view_layer_base_find(view_layer, ob);
- if (base) {
- ED_object_base_select(base, BA_SELECT);
- }
- }
-
- DEG_relations_tag_update(bmain);
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = (Scene *)outliner_ID_drop_find(C, event, ID_SCE);
+ Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB);
+
+ if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (BKE_scene_has_object(scene, ob)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Collection *collection;
+ if (scene != CTX_data_scene(C)) {
+ /* when linking to an inactive scene link to the master collection */
+ collection = BKE_collection_master(scene);
+ }
+ else {
+ collection = CTX_data_collection(C);
+ }
+
+ BKE_collection_object_add(bmain, collection, ob);
+
+ for (ViewLayer *view_layer = scene->view_layers.first; view_layer;
+ view_layer = view_layer->next) {
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ if (base) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
+
+ DEG_relations_tag_update(bmain);
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
+
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_scene_drop(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Drop Object to Scene";
- ot->description = "Drag object to scene in Outliner";
- ot->idname = "OUTLINER_OT_scene_drop";
+ /* identifiers */
+ ot->name = "Drop Object to Scene";
+ ot->description = "Drag object to scene in Outliner";
+ ot->idname = "OUTLINER_OT_scene_drop";
- /* api callbacks */
- ot->invoke = scene_drop_invoke;
+ /* api callbacks */
+ ot->invoke = scene_drop_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* ******************** Material Drop Operator *********************** */
-static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip))
+static bool material_drop_poll(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ const char **UNUSED(tooltip))
{
- /* Ensure item under cursor is valid drop target */
- Material *ma = (Material *)WM_drag_ID(drag, ID_MA);
- return (ma && (outliner_ID_drop_find(C, event, ID_OB) != NULL));
+ /* Ensure item under cursor is valid drop target */
+ Material *ma = (Material *)WM_drag_ID(drag, ID_MA);
+ return (ma && (outliner_ID_drop_find(C, event, ID_OB) != NULL));
}
static int material_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- Main *bmain = CTX_data_main(C);
- Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB);
- Material *ma = (Material *)WM_drag_ID_from_event(event, ID_MA);
+ Main *bmain = CTX_data_main(C);
+ Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB);
+ Material *ma = (Material *)WM_drag_ID_from_event(event, ID_MA);
- if (ELEM(NULL, ob, ma)) {
- return OPERATOR_CANCELLED;
- }
+ if (ELEM(NULL, ob, ma)) {
+ return OPERATOR_CANCELLED;
+ }
- /* only drop grease pencil material on grease pencil objects */
- if ((ma->gp_style != NULL) && (ob->type != OB_GPENCIL)) {
- return OPERATOR_CANCELLED;
- }
+ /* only drop grease pencil material on grease pencil objects */
+ if ((ma->gp_style != NULL) && (ob->type != OB_GPENCIL)) {
+ return OPERATOR_CANCELLED;
+ }
- assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
+ assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_material_drop(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Drop Material on Object";
- ot->description = "Drag material to object in Outliner";
- ot->idname = "OUTLINER_OT_material_drop";
+ /* identifiers */
+ ot->name = "Drop Material on Object";
+ ot->description = "Drag material to object in Outliner";
+ ot->idname = "OUTLINER_OT_material_drop";
- /* api callbacks */
- ot->invoke = material_drop_invoke;
+ /* api callbacks */
+ ot->invoke = material_drop_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* ******************** Collection Drop Operator *********************** */
typedef struct CollectionDrop {
- Collection *from;
- Collection *to;
+ Collection *from;
+ Collection *to;
- TreeElement *te;
- TreeElementInsertType insert_type;
+ TreeElement *te;
+ TreeElementInsertType insert_type;
} CollectionDrop;
static Collection *collection_parent_from_ID(ID *id)
{
- /* Can't change linked parent collections. */
- if (!id || ID_IS_LINKED(id)) {
- return NULL;
- }
-
- /* Also support dropping into/from scene collection. */
- if (GS(id->name) == ID_SCE) {
- return ((Scene *)id)->master_collection;
- }
- else if (GS(id->name) == ID_GR) {
- return (Collection *)id;
- }
-
- return NULL;
+ /* Can't change linked parent collections. */
+ if (!id || ID_IS_LINKED(id)) {
+ return NULL;
+ }
+
+ /* Also support dropping into/from scene collection. */
+ if (GS(id->name) == ID_SCE) {
+ return ((Scene *)id)->master_collection;
+ }
+ else if (GS(id->name) == ID_GR) {
+ return (Collection *)id;
+ }
+
+ return NULL;
}
-static bool collection_drop_init(bContext *C, wmDrag *drag, const wmEvent *event, CollectionDrop *data)
+static bool collection_drop_init(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ CollectionDrop *data)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
-
- /* Get collection to drop into. */
- TreeElementInsertType insert_type;
- TreeElement *te = outliner_drop_insert_collection_find(C, event, &insert_type);
- if (!te) {
- return false;
- }
-
- Collection *to_collection = outliner_collection_from_tree_element(te);
- if (ID_IS_LINKED(to_collection)) {
- return false;
- }
-
- /* Get drag datablocks. */
- if (drag->type != WM_DRAG_ID) {
- return false;
- }
-
- wmDragID *drag_id = drag->ids.first;
- if (drag_id == NULL) {
- return false;
- }
-
- ID *id = drag_id->id;
- if (!(id && ELEM(GS(id->name), ID_GR, ID_OB))) {
- return false;
- }
-
- /* Get collection to drag out of. */
- ID *parent = drag_id->from_parent;
- Collection *from_collection = collection_parent_from_ID(parent);
- if (event->ctrl || soops->outlinevis == SO_SCENES) {
- from_collection = NULL;
- }
-
- /* Get collections. */
- if (GS(id->name) == ID_GR) {
- if (id == &to_collection->id) {
- return false;
- }
- }
- else {
- insert_type = TE_INSERT_INTO;
- }
-
- data->from = from_collection;
- data->to = to_collection;
- data->te = te;
- data->insert_type = insert_type;
-
- return true;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+ /* Get collection to drop into. */
+ TreeElementInsertType insert_type;
+ TreeElement *te = outliner_drop_insert_collection_find(C, event, &insert_type);
+ if (!te) {
+ return false;
+ }
+
+ Collection *to_collection = outliner_collection_from_tree_element(te);
+ if (ID_IS_LINKED(to_collection)) {
+ return false;
+ }
+
+ /* Get drag datablocks. */
+ if (drag->type != WM_DRAG_ID) {
+ return false;
+ }
+
+ wmDragID *drag_id = drag->ids.first;
+ if (drag_id == NULL) {
+ return false;
+ }
+
+ ID *id = drag_id->id;
+ if (!(id && ELEM(GS(id->name), ID_GR, ID_OB))) {
+ return false;
+ }
+
+ /* Get collection to drag out of. */
+ ID *parent = drag_id->from_parent;
+ Collection *from_collection = collection_parent_from_ID(parent);
+ if (event->ctrl || soops->outlinevis == SO_SCENES) {
+ from_collection = NULL;
+ }
+
+ /* Get collections. */
+ if (GS(id->name) == ID_GR) {
+ if (id == &to_collection->id) {
+ return false;
+ }
+ }
+ else {
+ insert_type = TE_INSERT_INTO;
+ }
+
+ data->from = from_collection;
+ data->to = to_collection;
+ data->te = te;
+ data->insert_type = insert_type;
+
+ return true;
}
-static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip)
+static bool collection_drop_poll(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ const char **tooltip)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- bool changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
-
- CollectionDrop data;
- if (!event->shift && collection_drop_init(C, drag, event, &data)) {
- TreeElement *te = data.te;
- TreeStoreElem *tselem = TREESTORE(te);
- if (!data.from || event->ctrl) {
- tselem->flag |= TSE_DRAG_INTO;
- changed = true;
- *tooltip = IFACE_("Link inside Collection");
- }
- else {
- switch (data.insert_type) {
- case TE_INSERT_BEFORE:
- tselem->flag |= TSE_DRAG_BEFORE;
- changed = true;
- if (te->prev && outliner_is_collection_tree_element(te->prev)) {
- *tooltip = TIP_("Move between collections");
- }
- else {
- *tooltip = TIP_("Move before collection");
- }
- break;
- case TE_INSERT_AFTER:
- tselem->flag |= TSE_DRAG_AFTER;
- changed = true;
- if (te->next && outliner_is_collection_tree_element(te->next)) {
- *tooltip = TIP_("Move between collections");
- }
- else {
- *tooltip = TIP_("Move after collection");
- }
- break;
- case TE_INSERT_INTO:
- tselem->flag |= TSE_DRAG_INTO;
- changed = true;
- *tooltip = TIP_("Move inside collection (Ctrl to link, Shift to parent)");
- break;
- }
- }
- if (changed) {
- ED_region_tag_redraw_no_rebuild(ar);
- }
- return true;
- }
- else {
- if (changed) {
- ED_region_tag_redraw_no_rebuild(ar);
- }
- return false;
- }
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ bool changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
+
+ CollectionDrop data;
+ if (!event->shift && collection_drop_init(C, drag, event, &data)) {
+ TreeElement *te = data.te;
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (!data.from || event->ctrl) {
+ tselem->flag |= TSE_DRAG_INTO;
+ changed = true;
+ *tooltip = IFACE_("Link inside Collection");
+ }
+ else {
+ switch (data.insert_type) {
+ case TE_INSERT_BEFORE:
+ tselem->flag |= TSE_DRAG_BEFORE;
+ changed = true;
+ if (te->prev && outliner_is_collection_tree_element(te->prev)) {
+ *tooltip = TIP_("Move between collections");
+ }
+ else {
+ *tooltip = TIP_("Move before collection");
+ }
+ break;
+ case TE_INSERT_AFTER:
+ tselem->flag |= TSE_DRAG_AFTER;
+ changed = true;
+ if (te->next && outliner_is_collection_tree_element(te->next)) {
+ *tooltip = TIP_("Move between collections");
+ }
+ else {
+ *tooltip = TIP_("Move after collection");
+ }
+ break;
+ case TE_INSERT_INTO:
+ tselem->flag |= TSE_DRAG_INTO;
+ changed = true;
+ *tooltip = TIP_("Move inside collection (Ctrl to link, Shift to parent)");
+ break;
+ }
+ }
+ if (changed) {
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+ return true;
+ }
+ else {
+ if (changed) {
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+ return false;
+ }
}
static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
-
- if (event->custom != EVT_DATA_DRAGDROP) {
- return OPERATOR_CANCELLED;
- }
-
- ListBase *lb = event->customdata;
- wmDrag *drag = lb->first;
-
- CollectionDrop data;
- if (!collection_drop_init(C, drag, event, &data)) {
- return OPERATOR_CANCELLED;
- }
-
- /* Before/after insert handling. */
- Collection *relative = NULL;
- bool relative_after = false;
-
- if (ELEM(data.insert_type, TE_INSERT_BEFORE, TE_INSERT_AFTER)) {
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
-
- relative = data.to;
- relative_after = (data.insert_type == TE_INSERT_AFTER);
-
- TreeElement *parent_te = outliner_find_parent_element(&soops->tree, NULL, data.te);
- data.to = (parent_te) ? outliner_collection_from_tree_element(parent_te) : NULL;
- }
-
- if (!data.to) {
- return OPERATOR_CANCELLED;
- }
-
- if (BKE_collection_is_empty(data.to)) {
- TREESTORE(data.te)->flag &= ~TSE_CLOSED;
- }
-
- for (wmDragID *drag_id = drag->ids.first; drag_id; drag_id = drag_id->next) {
- /* Ctrl enables linking, so we don't need a from collection then. */
- Collection *from = (event->ctrl) ? NULL : collection_parent_from_ID(drag_id->from_parent);
-
- if (GS(drag_id->id->name) == ID_OB) {
- /* Move/link object into collection. */
- Object *object = (Object *)drag_id->id;
-
- if (from) {
- BKE_collection_object_move(bmain, scene, data.to, from, object);
- }
- else {
- BKE_collection_object_add(bmain, data.to, object);
- }
- }
- else if (GS(drag_id->id->name) == ID_GR) {
- /* Move/link collection into collection. */
- Collection *collection = (Collection *)drag_id->id;
-
- if (collection != from) {
- BKE_collection_move(bmain, data.to, from, relative, relative_after, collection);
- }
- }
-
- if (from) {
- DEG_id_tag_update(&from->id, ID_RECALC_COPY_ON_WRITE);
- }
- }
-
- /* Update dependency graph. */
- DEG_id_tag_update(&data.to->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
-
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (event->custom != EVT_DATA_DRAGDROP) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ListBase *lb = event->customdata;
+ wmDrag *drag = lb->first;
+
+ CollectionDrop data;
+ if (!collection_drop_init(C, drag, event, &data)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Before/after insert handling. */
+ Collection *relative = NULL;
+ bool relative_after = false;
+
+ if (ELEM(data.insert_type, TE_INSERT_BEFORE, TE_INSERT_AFTER)) {
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+ relative = data.to;
+ relative_after = (data.insert_type == TE_INSERT_AFTER);
+
+ TreeElement *parent_te = outliner_find_parent_element(&soops->tree, NULL, data.te);
+ data.to = (parent_te) ? outliner_collection_from_tree_element(parent_te) : NULL;
+ }
+
+ if (!data.to) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (BKE_collection_is_empty(data.to)) {
+ TREESTORE(data.te)->flag &= ~TSE_CLOSED;
+ }
+
+ for (wmDragID *drag_id = drag->ids.first; drag_id; drag_id = drag_id->next) {
+ /* Ctrl enables linking, so we don't need a from collection then. */
+ Collection *from = (event->ctrl) ? NULL : collection_parent_from_ID(drag_id->from_parent);
+
+ if (GS(drag_id->id->name) == ID_OB) {
+ /* Move/link object into collection. */
+ Object *object = (Object *)drag_id->id;
+
+ if (from) {
+ BKE_collection_object_move(bmain, scene, data.to, from, object);
+ }
+ else {
+ BKE_collection_object_add(bmain, data.to, object);
+ }
+ }
+ else if (GS(drag_id->id->name) == ID_GR) {
+ /* Move/link collection into collection. */
+ Collection *collection = (Collection *)drag_id->id;
+
+ if (collection != from) {
+ BKE_collection_move(bmain, data.to, from, relative, relative_after, collection);
+ }
+ }
+
+ if (from) {
+ DEG_id_tag_update(&from->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ }
+
+ /* Update dependency graph. */
+ DEG_id_tag_update(&data.to->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_collection_drop(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Move to Collection";
- ot->description = "Drag to move to collection in Outliner";
- ot->idname = "OUTLINER_OT_collection_drop";
+ /* identifiers */
+ ot->name = "Move to Collection";
+ ot->description = "Drag to move to collection in Outliner";
+ ot->idname = "OUTLINER_OT_collection_drop";
- /* api callbacks */
- ot->invoke = collection_drop_invoke;
- ot->poll = ED_operator_outliner_active;
+ /* api callbacks */
+ ot->invoke = collection_drop_invoke;
+ ot->poll = ED_operator_outliner_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* ********************* Outliner Drag Operator ******************** */
-static TreeElement *outliner_item_drag_element_find(SpaceOutliner *soops, ARegion *ar, const wmEvent *event)
+static TreeElement *outliner_item_drag_element_find(SpaceOutliner *soops,
+ ARegion *ar,
+ const wmEvent *event)
{
- /* note: using EVT_TWEAK_ events to trigger dragging is fine,
- * it sends coordinates from where dragging was started */
- const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
- return outliner_find_item_at_y(soops, &soops->tree, my);
+ /* note: using EVT_TWEAK_ events to trigger dragging is fine,
+ * it sends coordinates from where dragging was started */
+ const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
+ return outliner_find_item_at_y(soops, &soops->tree, my);
}
-static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int outliner_item_drag_drop_invoke(bContext *C,
+ wmOperator *UNUSED(op),
+ const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te = outliner_item_drag_element_find(soops, ar, event);
-
- if (!te) {
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- TreeElementIcon data = tree_element_get_icon(TREESTORE(te), te);
- if (!data.drag_id) {
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
-
- if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
- /* For collections and objects we cheat and drag all selected. */
-
- /* Only drag element under mouse if it was not selected before. */
- if ((TREESTORE(te)->flag & TSE_SELECTED) == 0) {
- outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
- TREESTORE(te)->flag |= TSE_SELECTED;
- }
-
- /* Gather all selected elements. */
- struct IDsSelectedData selected = {
- .selected_array = {NULL, NULL},
- };
-
- if (GS(data.drag_id->name) == ID_OB) {
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &selected);
- }
- else {
- outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_collections, &selected);
- }
-
- LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
- TreeElement *te_selected = (TreeElement *)link->data;
- ID *id;
-
- if (GS(data.drag_id->name) == ID_OB) {
- id = TREESTORE(te_selected)->id;
- }
- else {
- /* Keep collection hierarchies intact when dragging. */
- bool parent_selected = false;
- for (TreeElement *te_parent = te_selected->parent; te_parent; te_parent = te_parent->parent) {
- if (outliner_is_collection_tree_element(te_parent)) {
- if (TREESTORE(te_parent)->flag & TSE_SELECTED) {
- parent_selected = true;
- break;
- }
- }
- }
-
- if (parent_selected) {
- continue;
- }
-
- id = &outliner_collection_from_tree_element(te_selected)->id;
- }
-
- /* Find parent collection. */
- Collection *parent = NULL;
-
- if (te_selected->parent) {
- for (TreeElement *te_parent = te_selected->parent; te_parent; te_parent = te_parent->parent) {
- if (outliner_is_collection_tree_element(te_parent)) {
- parent = outliner_collection_from_tree_element(te_parent);
- break;
- }
- }
- }
- else {
- Scene *scene = CTX_data_scene(C);
- parent = BKE_collection_master(scene);
- }
-
- WM_drag_add_ID(drag, id, &parent->id);
- }
-
- BLI_freelistN(&selected.selected_array);
- }
- else {
- /* Add single ID. */
- WM_drag_add_ID(drag, data.drag_id, data.drag_parent);
- }
-
- return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te = outliner_item_drag_element_find(soops, ar, event);
+
+ if (!te) {
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ TreeElementIcon data = tree_element_get_icon(TREESTORE(te), te);
+ if (!data.drag_id) {
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
+
+ if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
+ /* For collections and objects we cheat and drag all selected. */
+
+ /* Only drag element under mouse if it was not selected before. */
+ if ((TREESTORE(te)->flag & TSE_SELECTED) == 0) {
+ outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
+ TREESTORE(te)->flag |= TSE_SELECTED;
+ }
+
+ /* Gather all selected elements. */
+ struct IDsSelectedData selected = {
+ .selected_array = {NULL, NULL},
+ };
+
+ if (GS(data.drag_id->name) == ID_OB) {
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &selected);
+ }
+ else {
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_collections, &selected);
+ }
+
+ LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
+ TreeElement *te_selected = (TreeElement *)link->data;
+ ID *id;
+
+ if (GS(data.drag_id->name) == ID_OB) {
+ id = TREESTORE(te_selected)->id;
+ }
+ else {
+ /* Keep collection hierarchies intact when dragging. */
+ bool parent_selected = false;
+ for (TreeElement *te_parent = te_selected->parent; te_parent;
+ te_parent = te_parent->parent) {
+ if (outliner_is_collection_tree_element(te_parent)) {
+ if (TREESTORE(te_parent)->flag & TSE_SELECTED) {
+ parent_selected = true;
+ break;
+ }
+ }
+ }
+
+ if (parent_selected) {
+ continue;
+ }
+
+ id = &outliner_collection_from_tree_element(te_selected)->id;
+ }
+
+ /* Find parent collection. */
+ Collection *parent = NULL;
+
+ if (te_selected->parent) {
+ for (TreeElement *te_parent = te_selected->parent; te_parent;
+ te_parent = te_parent->parent) {
+ if (outliner_is_collection_tree_element(te_parent)) {
+ parent = outliner_collection_from_tree_element(te_parent);
+ break;
+ }
+ }
+ }
+ else {
+ Scene *scene = CTX_data_scene(C);
+ parent = BKE_collection_master(scene);
+ }
+
+ WM_drag_add_ID(drag, id, &parent->id);
+ }
+
+ BLI_freelistN(&selected.selected_array);
+ }
+ else {
+ /* Add single ID. */
+ WM_drag_add_ID(drag, data.drag_id, data.drag_parent);
+ }
+
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
}
/* Outliner drag and drop. This operator mostly exists to support dragging
@@ -1019,12 +1052,12 @@ static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *UNUSED(op), c
void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
{
- ot->name = "Drag and Drop";
- ot->idname = "OUTLINER_OT_item_drag_drop";
- ot->description = "Drag and drop element to another place";
+ ot->name = "Drag and Drop";
+ ot->idname = "OUTLINER_OT_item_drag_drop";
+ ot->description = "Drag and drop element to another place";
- ot->invoke = outliner_item_drag_drop_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->invoke = outliner_item_drag_drop_invoke;
+ ot->poll = ED_operator_outliner_active;
}
/* *************************** Drop Boxes ************************** */
@@ -1032,11 +1065,11 @@ void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
/* region dropbox definition */
void outliner_dropboxes(void)
{
- ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
+ ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
- WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL);
- WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL);
- WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL);
- WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL);
- WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL);
+ WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL);
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index ff0b9d8a55f..2d33c5db49d 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -84,56 +84,56 @@
static void outliner_height(SpaceOutliner *soops, ListBase *lb, int *h)
{
- TreeElement *te = lb->first;
- while (te) {
- TreeStoreElem *tselem = TREESTORE(te);
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_height(soops, &te->subtree, h);
- }
- (*h) += UI_UNIT_Y;
- te = te->next;
- }
+ TreeElement *te = lb->first;
+ while (te) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_height(soops, &te->subtree, h);
+ }
+ (*h) += UI_UNIT_Y;
+ te = te->next;
+ }
}
#if 0 // XXX this is currently disabled until te->xend is set correctly
static void outliner_width(SpaceOutliner *soops, ListBase *lb, int *w)
{
- TreeElement *te = lb->first;
- while (te) {
-// TreeStoreElem *tselem = TREESTORE(te);
-
- // XXX fixme... te->xend is not set yet
- if (!TSELEM_OPEN(tselem, soops)) {
- if (te->xend > *w)
- *w = te->xend;
- }
- outliner_width(soops, &te->subtree, w);
- te = te->next;
- }
+ TreeElement *te = lb->first;
+ while (te) {
+// TreeStoreElem *tselem = TREESTORE(te);
+
+ // XXX fixme... te->xend is not set yet
+ if (!TSELEM_OPEN(tselem, soops)) {
+ if (te->xend > *w)
+ *w = te->xend;
+ }
+ outliner_width(soops, &te->subtree, w);
+ te = te->next;
+ }
}
#endif
static void outliner_rna_width(SpaceOutliner *soops, ListBase *lb, int *w, int startx)
{
- TreeElement *te = lb->first;
- while (te) {
- TreeStoreElem *tselem = TREESTORE(te);
- // XXX fixme... (currently, we're using a fixed length of 100)!
+ TreeElement *te = lb->first;
+ while (te) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ // XXX fixme... (currently, we're using a fixed length of 100)!
#if 0
- if (te->xend) {
- if (te->xend > *w)
- *w = te->xend;
- }
+ if (te->xend) {
+ if (te->xend > *w)
+ *w = te->xend;
+ }
#endif
- if (startx + 100 > *w) {
- *w = startx + 100;
- }
-
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_rna_width(soops, &te->subtree, w, startx + UI_UNIT_X);
- }
- te = te->next;
- }
+ if (startx + 100 > *w) {
+ *w = startx + 100;
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_rna_width(soops, &te->subtree, w, startx + UI_UNIT_X);
+ }
+ te = te->next;
+ }
}
/**
@@ -141,830 +141,1092 @@ static void outliner_rna_width(SpaceOutliner *soops, ListBase *lb, int *w, int s
*/
static bool is_object_data_in_editmode(const ID *id, const Object *obact)
{
- const short id_type = GS(id->name);
- return (
- (obact && (obact->mode & OB_MODE_EDIT)) &&
- (id && OB_DATA_SUPPORT_EDITMODE(id_type)) &&
- (GS(((ID *)obact->data)->name) == id_type) &&
- BKE_object_data_is_in_editmode(id)
- );
+ const short id_type = GS(id->name);
+ return ((obact && (obact->mode & OB_MODE_EDIT)) && (id && OB_DATA_SUPPORT_EDITMODE(id_type)) &&
+ (GS(((ID *)obact->data)->name) == id_type) && BKE_object_data_is_in_editmode(id));
}
/* ****************************************************** */
-static void restrictbutton_recursive_ebone(bContext *C, EditBone *ebone_parent, int flag, bool set_flag)
+static void restrictbutton_recursive_ebone(bContext *C,
+ EditBone *ebone_parent,
+ int flag,
+ bool set_flag)
{
- Object *obedit = CTX_data_edit_object(C);
- bArmature *arm = obedit->data;
- EditBone *ebone;
-
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
- if (set_flag) {
- ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
- ebone->flag |= flag;
- }
- else {
- ebone->flag &= ~flag;
- }
- }
- }
+ Object *obedit = CTX_data_edit_object(C);
+ bArmature *arm = obedit->data;
+ EditBone *ebone;
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
+ if (set_flag) {
+ ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ ebone->flag |= flag;
+ }
+ else {
+ ebone->flag &= ~flag;
+ }
+ }
+ }
}
static void restrictbutton_recursive_bone(Bone *bone_parent, int flag, bool set_flag)
{
- Bone *bone;
- for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
- if (set_flag) {
- bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
- bone->flag |= flag;
- }
- else {
- bone->flag &= ~flag;
- }
- restrictbutton_recursive_bone(bone, flag, set_flag);
- }
-
+ Bone *bone;
+ for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
+ if (set_flag) {
+ bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ bone->flag |= flag;
+ }
+ else {
+ bone->flag &= ~flag;
+ }
+ restrictbutton_recursive_bone(bone, flag, set_flag);
+ }
}
static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *UNUSED(poin2))
{
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, poin);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, poin);
}
static void restrictbutton_bone_visibility_cb(bContext *C, void *UNUSED(poin), void *poin2)
{
- Bone *bone = (Bone *)poin2;
- if (bone->flag & BONE_HIDDEN_P) {
- bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
+ Bone *bone = (Bone *)poin2;
+ if (bone->flag & BONE_HIDDEN_P) {
+ bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
- if (CTX_wm_window(C)->eventstate->ctrl) {
- restrictbutton_recursive_bone(bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0);
- }
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_bone(bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0);
+ }
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
static void restrictbutton_bone_select_cb(bContext *C, void *UNUSED(poin), void *poin2)
{
- Bone *bone = (Bone *)poin2;
- if (bone->flag & BONE_UNSELECTABLE) {
- bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
+ Bone *bone = (Bone *)poin2;
+ if (bone->flag & BONE_UNSELECTABLE) {
+ bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
- if (CTX_wm_window(C)->eventstate->ctrl) {
- restrictbutton_recursive_bone(bone, BONE_UNSELECTABLE, (bone->flag & BONE_UNSELECTABLE) != 0);
- }
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_bone(bone, BONE_UNSELECTABLE, (bone->flag & BONE_UNSELECTABLE) != 0);
+ }
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
static void restrictbutton_ebone_select_cb(bContext *C, void *UNUSED(poin), void *poin2)
{
- EditBone *ebone = (EditBone *)poin2;
+ EditBone *ebone = (EditBone *)poin2;
- if (ebone->flag & BONE_UNSELECTABLE) {
- ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
+ if (ebone->flag & BONE_UNSELECTABLE) {
+ ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
- if (CTX_wm_window(C)->eventstate->ctrl) {
- restrictbutton_recursive_ebone(C, ebone, BONE_UNSELECTABLE, (ebone->flag & BONE_UNSELECTABLE) != 0);
- }
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_ebone(
+ C, ebone, BONE_UNSELECTABLE, (ebone->flag & BONE_UNSELECTABLE) != 0);
+ }
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
static void restrictbutton_ebone_visibility_cb(bContext *C, void *UNUSED(poin), void *poin2)
{
- EditBone *ebone = (EditBone *)poin2;
- if (ebone->flag & BONE_HIDDEN_A) {
- ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
+ EditBone *ebone = (EditBone *)poin2;
+ if (ebone->flag & BONE_HIDDEN_A) {
+ ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
- if (CTX_wm_window(C)->eventstate->ctrl) {
- restrictbutton_recursive_ebone(C, ebone, BONE_HIDDEN_A, (ebone->flag & BONE_HIDDEN_A) != 0);
- }
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_ebone(C, ebone, BONE_HIDDEN_A, (ebone->flag & BONE_HIDDEN_A) != 0);
+ }
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
static void restrictbutton_gp_layer_flag_cb(bContext *C, void *poin, void *UNUSED(poin2))
{
- ID *id = (ID *)poin;
+ ID *id = (ID *)poin;
- DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
{
- ID *id = (ID *)poin;
+ ID *id = (ID *)poin;
- BLI_assert(id != NULL);
+ BLI_assert(id != NULL);
- if (id->flag & LIB_FAKEUSER) {
- id_us_plus(id);
- }
- else {
- id_us_min(id);
- }
+ if (id->flag & LIB_FAKEUSER) {
+ id_us_plus(id);
+ }
+ else {
+ id_us_min(id);
+ }
}
static int base_pushed_state_cb(bContext *UNUSED(C), void *poin)
{
- Base *base = poin;
- Object *ob = base->object;
+ Base *base = poin;
+ Object *ob = base->object;
- const bool is_visible = ((base->flag & BASE_HIDDEN) == 0) &&
- ((ob->restrictflag & OB_RESTRICT_VIEW) == 0);
- return !is_visible;
+ const bool is_visible = ((base->flag & BASE_HIDDEN) == 0) &&
+ ((ob->restrictflag & OB_RESTRICT_VIEW) == 0);
+ return !is_visible;
}
static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
{
- wmWindow *win = CTX_wm_window(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = poin;
- Base *base = poin2;
- Object *ob = base->object;
- bool do_disable = (CTX_wm_window(C)->eventstate->alt != 0);
- bool do_isolate = (win->eventstate->ctrl != 0) && !do_disable;
- bool extend = (win->eventstate->shift != 0);
- bool depsgraph_changed = false;
- const bool is_linked = ID_IS_LINKED(ob);
-
- if (do_disable) {
- if (!is_linked) {
- ob->restrictflag |= OB_RESTRICT_VIEW;
- depsgraph_changed = true;
- }
- }
- else if (do_isolate) {
- depsgraph_changed = (!is_linked) && ((ob->restrictflag & OB_RESTRICT_VIEW) != 0);
-
- if (!extend) {
- /* Make only one base visible. */
- for (Base *other = view_layer->object_bases.first; other; other = other->next) {
- other->flag |= BASE_HIDDEN;
- }
-
- base->flag &= ~BASE_HIDDEN;
- }
- else {
- /* Toggle visibility of one base. */
- base->flag ^= BASE_HIDDEN;
- }
-
- if (!is_linked) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
- }
- }
- else if (ob->restrictflag & OB_RESTRICT_VIEW) {
- if (!is_linked) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
- base->flag &= ~BASE_HIDDEN;
- }
- depsgraph_changed = true;
- }
- else {
- base->flag ^= BASE_HIDDEN;
- }
-
- if (depsgraph_changed) {
- BKE_main_collection_sync_remap(bmain);
- DEG_id_tag_update(&ob->id, LIB_TAG_COPIED_ON_WRITE);
- DEG_relations_tag_update(bmain);
- WM_main_add_notifier(NC_OBJECT | ND_DRAW, &ob->id);
- }
-
- if (!do_disable) {
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
+ wmWindow *win = CTX_wm_window(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = poin;
+ Base *base = poin2;
+ Object *ob = base->object;
+ bool do_disable = (CTX_wm_window(C)->eventstate->alt != 0);
+ bool do_isolate = (win->eventstate->ctrl != 0) && !do_disable;
+ bool extend = (win->eventstate->shift != 0);
+ bool depsgraph_changed = false;
+ const bool is_linked = ID_IS_LINKED(ob);
+
+ if (do_disable) {
+ if (!is_linked) {
+ ob->restrictflag |= OB_RESTRICT_VIEW;
+ depsgraph_changed = true;
+ }
+ }
+ else if (do_isolate) {
+ depsgraph_changed = (!is_linked) && ((ob->restrictflag & OB_RESTRICT_VIEW) != 0);
+
+ if (!extend) {
+ /* Make only one base visible. */
+ for (Base *other = view_layer->object_bases.first; other; other = other->next) {
+ other->flag |= BASE_HIDDEN;
+ }
+
+ base->flag &= ~BASE_HIDDEN;
+ }
+ else {
+ /* Toggle visibility of one base. */
+ base->flag ^= BASE_HIDDEN;
+ }
+
+ if (!is_linked) {
+ ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ }
+ }
+ else if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ if (!is_linked) {
+ ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ base->flag &= ~BASE_HIDDEN;
+ }
+ depsgraph_changed = true;
+ }
+ else {
+ base->flag ^= BASE_HIDDEN;
+ }
+
+ if (depsgraph_changed) {
+ BKE_main_collection_sync_remap(bmain);
+ DEG_id_tag_update(&ob->id, LIB_TAG_COPIED_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, &ob->id);
+ }
+
+ if (!do_disable) {
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
}
static int layer_collection_pushed_state_cb(bContext *UNUSED(C), void *poin)
{
- LayerCollection *lc = poin;
- Collection *collection = lc->collection;
+ LayerCollection *lc = poin;
+ Collection *collection = lc->collection;
- const bool is_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) == 0) &&
- ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0);
- return !is_visible;
+ const bool is_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) == 0) &&
+ ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0);
+ return !is_visible;
}
static void hidebutton_layer_collection_flag_cb(bContext *C, void *poin, void *poin2)
{
- Main *bmain = CTX_data_main(C);
- wmWindow *win = CTX_wm_window(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = poin;
- LayerCollection *lc = poin2;
- Collection *collection = lc->collection;
- bool do_disable = (win->eventstate->alt != 0);
- bool do_isolate = (win->eventstate->ctrl != 0) && !do_disable;
- bool extend = (win->eventstate->shift != 0);
- bool depsgraph_changed = false;
-
- if (do_disable) {
- if (!ID_IS_LINKED(collection)) {
- collection->flag |= COLLECTION_RESTRICT_VIEW;
- depsgraph_changed = true;
- }
- }
- else if (do_isolate) {
- depsgraph_changed |= BKE_layer_collection_isolate(scene, view_layer, lc, extend);
- }
- else {
- bool make_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0) ||
- ((collection->flag & COLLECTION_RESTRICT_VIEW) != 0);
- depsgraph_changed |= BKE_layer_collection_set_visible(view_layer, lc, make_visible, extend);
- }
-
- BKE_layer_collection_sync(scene, view_layer);
- DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
-
- if (depsgraph_changed) {
- BKE_main_collection_sync_remap(bmain);
- DEG_relations_tag_update(bmain);
- }
- WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
+ Main *bmain = CTX_data_main(C);
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = poin;
+ LayerCollection *lc = poin2;
+ Collection *collection = lc->collection;
+ bool do_disable = (win->eventstate->alt != 0);
+ bool do_isolate = (win->eventstate->ctrl != 0) && !do_disable;
+ bool extend = (win->eventstate->shift != 0);
+ bool depsgraph_changed = false;
+
+ if (do_disable) {
+ if (!ID_IS_LINKED(collection)) {
+ collection->flag |= COLLECTION_RESTRICT_VIEW;
+ depsgraph_changed = true;
+ }
+ }
+ else if (do_isolate) {
+ depsgraph_changed |= BKE_layer_collection_isolate(scene, view_layer, lc, extend);
+ }
+ else {
+ bool make_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0) ||
+ ((collection->flag & COLLECTION_RESTRICT_VIEW) != 0);
+ depsgraph_changed |= BKE_layer_collection_set_visible(view_layer, lc, make_visible, extend);
+ }
+
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+
+ if (depsgraph_changed) {
+ BKE_main_collection_sync_remap(bmain);
+ DEG_relations_tag_update(bmain);
+ }
+ WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL);
}
static void namebutton_cb(bContext *C, void *tsep, char *oldname)
{
- Main *bmain = CTX_data_main(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- Object *obedit = CTX_data_edit_object(C);
- BLI_mempool *ts = soops->treestore;
- TreeStoreElem *tselem = tsep;
-
- if (ts && tselem) {
- TreeElement *te = outliner_find_tree_element(&soops->tree, tselem);
-
- if (tselem->type == 0) {
- BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
-
- switch (GS(tselem->id->name)) {
- case ID_MA:
- WM_event_add_notifier(C, NC_MATERIAL, NULL); break;
- case ID_TE:
- WM_event_add_notifier(C, NC_TEXTURE, NULL); break;
- case ID_IM:
- WM_event_add_notifier(C, NC_IMAGE, NULL); break;
- case ID_SCE:
- WM_event_add_notifier(C, NC_SCENE, NULL); break;
- case ID_OB:
- {
- Object *ob = (Object *)tselem->id;
- if (ob->type == OB_MBALL) {
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- }
- DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL); break;
- }
- default:
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL); break;
- }
- /* Check the library target exists */
- if (te->idcode == ID_LI) {
- Library *lib = (Library *)tselem->id;
- char expanded[FILE_MAX];
-
- BKE_library_filepath_set(bmain, lib, lib->name);
-
- BLI_strncpy(expanded, lib->name, sizeof(expanded));
- BLI_path_abs(expanded, BKE_main_blendfile_path(bmain));
- if (!BLI_exists(expanded)) {
- BKE_reportf(CTX_wm_reports(C), RPT_ERROR,
- "Library path '%s' does not exist, correct this before saving", expanded);
- }
- else if (lib->id.tag & LIB_TAG_MISSING) {
- BKE_reportf(CTX_wm_reports(C), RPT_INFO,
- "Library path '%s' is now valid, please reload the library", expanded);
- lib->id.tag &= ~LIB_TAG_MISSING;
- }
- }
- }
- else {
- switch (tselem->type) {
- case TSE_DEFGROUP:
- defgroup_unique_name(te->directdata, (Object *)tselem->id); // id = object
- break;
- case TSE_NLA_ACTION:
- BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
- break;
- case TSE_EBONE:
- {
- bArmature *arm = (bArmature *)tselem->id;
- if (arm->edbo) {
- EditBone *ebone = te->directdata;
- char newname[sizeof(ebone->name)];
-
- /* restore bone name */
- BLI_strncpy(newname, ebone->name, sizeof(ebone->name));
- BLI_strncpy(ebone->name, oldname, sizeof(ebone->name));
- ED_armature_bone_rename(bmain, obedit->data, oldname, newname);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- }
- break;
- }
-
- case TSE_BONE:
- {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Scene *scene = CTX_data_scene(C);
- bArmature *arm = (bArmature *)tselem->id;
- Bone *bone = te->directdata;
- char newname[sizeof(bone->name)];
-
- /* always make current object active */
- tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true);
-
- /* restore bone name */
- BLI_strncpy(newname, bone->name, sizeof(bone->name));
- BLI_strncpy(bone->name, oldname, sizeof(bone->name));
- ED_armature_bone_rename(bmain, arm, oldname, newname);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- break;
- }
- case TSE_POSE_CHANNEL:
- {
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = (Object *)tselem->id;
- bPoseChannel *pchan = te->directdata;
- char newname[sizeof(pchan->name)];
-
- /* always make current pose-bone active */
- tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true);
-
- BLI_assert(ob->type == OB_ARMATURE);
-
- /* restore bone name */
- BLI_strncpy(newname, pchan->name, sizeof(pchan->name));
- BLI_strncpy(pchan->name, oldname, sizeof(pchan->name));
- ED_armature_bone_rename(bmain, ob->data, oldname, newname);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- break;
- }
- case TSE_POSEGRP:
- {
- Object *ob = (Object *)tselem->id; // id = object
- bActionGroup *grp = te->directdata;
-
- BLI_uniquename(&ob->pose->agroups, grp, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "Group"), '.',
- offsetof(bActionGroup, name), sizeof(grp->name));
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
- break;
- }
- case TSE_GP_LAYER:
- {
- bGPdata *gpd = (bGPdata *)tselem->id; /* id = GP Datablock */
- bGPDlayer *gpl = te->directdata;
-
- /* always make layer active */
- BKE_gpencil_layer_setactive(gpd, gpl);
-
- // XXX: name needs translation stuff
- BLI_uniquename(&gpd->layers, gpl, "GP Layer", '.',
- offsetof(bGPDlayer, info), sizeof(gpl->info));
-
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, gpd);
- break;
- }
- case TSE_R_LAYER:
- {
- Scene *scene = (Scene *)tselem->id;
- ViewLayer *view_layer = te->directdata;
-
- /* Restore old name. */
- char newname[sizeof(view_layer->name)];
- BLI_strncpy(newname, view_layer->name, sizeof(view_layer->name));
- BLI_strncpy(view_layer->name, oldname, sizeof(view_layer->name));
-
- /* Rename, preserving animation and compositing data. */
- BKE_view_layer_rename(bmain, scene, view_layer, newname);
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
- break;
- }
- case TSE_LAYER_COLLECTION:
- {
- BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
- WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
- break;
- }
- }
- }
- tselem->flag &= ~TSE_TEXTBUT;
- }
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BLI_mempool *ts = soops->treestore;
+ TreeStoreElem *tselem = tsep;
+
+ if (ts && tselem) {
+ TreeElement *te = outliner_find_tree_element(&soops->tree, tselem);
+
+ if (tselem->type == 0) {
+ BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
+
+ switch (GS(tselem->id->name)) {
+ case ID_MA:
+ WM_event_add_notifier(C, NC_MATERIAL, NULL);
+ break;
+ case ID_TE:
+ WM_event_add_notifier(C, NC_TEXTURE, NULL);
+ break;
+ case ID_IM:
+ WM_event_add_notifier(C, NC_IMAGE, NULL);
+ break;
+ case ID_SCE:
+ WM_event_add_notifier(C, NC_SCENE, NULL);
+ break;
+ case ID_OB: {
+ Object *ob = (Object *)tselem->id;
+ if (ob->type == OB_MBALL) {
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+ DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
+ break;
+ }
+ default:
+ WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
+ break;
+ }
+ /* Check the library target exists */
+ if (te->idcode == ID_LI) {
+ Library *lib = (Library *)tselem->id;
+ char expanded[FILE_MAX];
+
+ BKE_library_filepath_set(bmain, lib, lib->name);
+
+ BLI_strncpy(expanded, lib->name, sizeof(expanded));
+ BLI_path_abs(expanded, BKE_main_blendfile_path(bmain));
+ if (!BLI_exists(expanded)) {
+ BKE_reportf(CTX_wm_reports(C),
+ RPT_ERROR,
+ "Library path '%s' does not exist, correct this before saving",
+ expanded);
+ }
+ else if (lib->id.tag & LIB_TAG_MISSING) {
+ BKE_reportf(CTX_wm_reports(C),
+ RPT_INFO,
+ "Library path '%s' is now valid, please reload the library",
+ expanded);
+ lib->id.tag &= ~LIB_TAG_MISSING;
+ }
+ }
+ }
+ else {
+ switch (tselem->type) {
+ case TSE_DEFGROUP:
+ defgroup_unique_name(te->directdata, (Object *)tselem->id); // id = object
+ break;
+ case TSE_NLA_ACTION:
+ BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
+ break;
+ case TSE_EBONE: {
+ bArmature *arm = (bArmature *)tselem->id;
+ if (arm->edbo) {
+ EditBone *ebone = te->directdata;
+ char newname[sizeof(ebone->name)];
+
+ /* restore bone name */
+ BLI_strncpy(newname, ebone->name, sizeof(ebone->name));
+ BLI_strncpy(ebone->name, oldname, sizeof(ebone->name));
+ ED_armature_bone_rename(bmain, obedit->data, oldname, newname);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ }
+ break;
+ }
+
+ case TSE_BONE: {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Scene *scene = CTX_data_scene(C);
+ bArmature *arm = (bArmature *)tselem->id;
+ Bone *bone = te->directdata;
+ char newname[sizeof(bone->name)];
+
+ /* always make current object active */
+ tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true);
+
+ /* restore bone name */
+ BLI_strncpy(newname, bone->name, sizeof(bone->name));
+ BLI_strncpy(bone->name, oldname, sizeof(bone->name));
+ ED_armature_bone_rename(bmain, arm, oldname, newname);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ break;
+ }
+ case TSE_POSE_CHANNEL: {
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = (Object *)tselem->id;
+ bPoseChannel *pchan = te->directdata;
+ char newname[sizeof(pchan->name)];
+
+ /* always make current pose-bone active */
+ tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true);
+
+ BLI_assert(ob->type == OB_ARMATURE);
+
+ /* restore bone name */
+ BLI_strncpy(newname, pchan->name, sizeof(pchan->name));
+ BLI_strncpy(pchan->name, oldname, sizeof(pchan->name));
+ ED_armature_bone_rename(bmain, ob->data, oldname, newname);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ break;
+ }
+ case TSE_POSEGRP: {
+ Object *ob = (Object *)tselem->id; // id = object
+ bActionGroup *grp = te->directdata;
+
+ BLI_uniquename(&ob->pose->agroups,
+ grp,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "Group"),
+ '.',
+ offsetof(bActionGroup, name),
+ sizeof(grp->name));
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
+ break;
+ }
+ case TSE_GP_LAYER: {
+ bGPdata *gpd = (bGPdata *)tselem->id; /* id = GP Datablock */
+ bGPDlayer *gpl = te->directdata;
+
+ /* always make layer active */
+ BKE_gpencil_layer_setactive(gpd, gpl);
+
+ // XXX: name needs translation stuff
+ BLI_uniquename(
+ &gpd->layers, gpl, "GP Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, gpd);
+ break;
+ }
+ case TSE_R_LAYER: {
+ Scene *scene = (Scene *)tselem->id;
+ ViewLayer *view_layer = te->directdata;
+
+ /* Restore old name. */
+ char newname[sizeof(view_layer->name)];
+ BLI_strncpy(newname, view_layer->name, sizeof(view_layer->name));
+ BLI_strncpy(view_layer->name, oldname, sizeof(view_layer->name));
+
+ /* Rename, preserving animation and compositing data. */
+ BKE_view_layer_rename(bmain, scene, view_layer, newname);
+ WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
+ break;
+ }
+ case TSE_LAYER_COLLECTION: {
+ BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
+ WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
+ break;
+ }
+ }
+ }
+ tselem->flag &= ~TSE_TEXTBUT;
+ }
}
-static void outliner_draw_restrictbuts(
- uiBlock *block, Scene *scene, ViewLayer *view_layer, ARegion *ar, SpaceOutliner *soops, ListBase *lb)
+static void outliner_draw_restrictbuts(uiBlock *block,
+ Scene *scene,
+ ViewLayer *view_layer,
+ ARegion *ar,
+ SpaceOutliner *soops,
+ ListBase *lb)
{
- /* Get RNA properties (once for speed). */
- static struct RestrictProperties {
- bool initialized;
-
- PropertyRNA *object_hide_viewport, *object_hide_select, *object_hide_render;
- PropertyRNA *collection_hide_viewport, *collection_hide_select, *collection_hide_render;
- PropertyRNA *modifier_show_viewport, *modifier_show_render;
- } props = {false};
-
- if (!props.initialized) {
- props.object_hide_viewport = RNA_struct_type_find_property(&RNA_Object, "hide_viewport");
- props.object_hide_select = RNA_struct_type_find_property(&RNA_Object, "hide_select");
- props.object_hide_render = RNA_struct_type_find_property(&RNA_Object, "hide_render");
- props.collection_hide_select = RNA_struct_type_find_property(&RNA_Collection, "hide_select");
- props.collection_hide_viewport = RNA_struct_type_find_property(&RNA_Collection, "hide_viewport");
- props.collection_hide_render = RNA_struct_type_find_property(&RNA_Collection, "hide_render");
- props.modifier_show_viewport = RNA_struct_type_find_property(&RNA_Modifier, "show_viewport");
- props.modifier_show_render = RNA_struct_type_find_property(&RNA_Modifier, "show_render");
-
- props.initialized = true;
- }
-
- /* Create buttons. */
- uiBut *bt;
-
- for (TreeElement *te = lb->first; te; te = te->next) {
- TreeStoreElem *tselem = TREESTORE(te);
- if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
- if (tselem->type == TSE_R_LAYER && (soops->outlinevis == SO_SCENES)) {
- /* View layer render toggle. */
- ViewLayer *layer = te->directdata;
-
- bt = uiDefIconButBitS(
- block, UI_BTYPE_ICON_TOGGLE_N, VIEW_LAYER_RENDER, 0, ICON_RESTRICT_RENDER_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &layer->flag, 0, 0, 0, 0, TIP_("Use view layer for rendering"));
- UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
- }
- else if (tselem->type == 0 && te->idcode == ID_OB) {
- PointerRNA ptr;
- Object *ob = (Object *)tselem->id;
- RNA_pointer_create(&ob->id, &RNA_Object, ob, &ptr);
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
- if (base) {
- int icon = ICON_RESTRICT_VIEW_ON;
- if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0) {
- icon = (base->flag & BASE_HIDDEN) != 0 ?
- ICON_HIDE_ON :
- ICON_HIDE_OFF;
- }
- bt = uiDefIconBut(
- block, UI_BTYPE_ICON_TOGGLE, 0, icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0,
- TIP_("Hide object in viewport\n"
- "* Alt to disable for all viewports\n"
- "* Ctrl to isolate visibility"));
- UI_but_func_set(bt, hidebutton_base_flag_cb, view_layer, base);
- UI_but_func_pushed_state_set(bt, base_pushed_state_cb, base);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
- else {
- bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, props.object_hide_viewport, -1, 0, 0, -1, -1, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
-
- bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, props.object_hide_select, -1, 0, 0, -1, -1, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
- bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, props.object_hide_render, -1, 0, 0, -1, -1, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
- }
- else if (tselem->type == TSE_MODIFIER) {
- ModifierData *md = (ModifierData *)te->directdata;
-
- PointerRNA ptr;
- RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
-
- bt = uiDefIconButR_prop(
- block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, props.modifier_show_viewport, -1, 0, 0, -1, -1, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
- bt = uiDefIconButR_prop(
- block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, props.modifier_show_render, -1, 0, 0, -1, -1, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
- else if (tselem->type == TSE_POSE_CHANNEL) {
- bPoseChannel *pchan = (bPoseChannel *)te->directdata;
- Bone *bone = pchan->bone;
- Object *ob = (Object *)tselem->id;
-
- bt = uiDefIconButBitI(
- block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_P, 0, ICON_HIDE_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitI(
- block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
- TIP_("Restrict/Allow selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
- }
- else if (tselem->type == TSE_EBONE) {
- EditBone *ebone = (EditBone *)te->directdata;
-
- bt = uiDefIconButBitI(
- block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitI(
- block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
- TIP_("Restrict/Allow selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
- }
- else if (tselem->type == TSE_GP_LAYER) {
- ID *id = tselem->id;
- bGPDlayer *gpl = (bGPDlayer *)te->directdata;
-
- bt = uiDefIconButBitS(
- block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_HIDE, 0, ICON_HIDE_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &gpl->flag, 0, 0, 0, 0,
- TIP_("Restrict/Allow visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
-
- bt = uiDefIconButBitS(
- block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_LOCKED, 0, ICON_UNLOCKED,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &gpl->flag, 0, 0, 0, 0,
- TIP_("Restrict/Allow editing of strokes and keyframes in this layer"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
- else if (outliner_is_collection_tree_element(te)) {
- LayerCollection *lc = (tselem->type == TSE_LAYER_COLLECTION) ? te->directdata : NULL;
- Collection *collection = outliner_collection_from_tree_element(te);
-
- if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) &&
- !(collection->flag & COLLECTION_IS_MASTER))
- {
- PointerRNA collection_ptr;
- RNA_id_pointer_create(&collection->id, &collection_ptr);
-
- if (lc != NULL) {
- int icon = ICON_RESTRICT_VIEW_ON;
- if ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0) {
- icon = (lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0 ?
- ICON_HIDE_ON :
- ICON_HIDE_OFF;
- }
- bt = uiDefIconBut(
- block, UI_BTYPE_TOGGLE, 0, icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0,
- TIP_("Hide collection in viewport\n"
- "* Alt to disable for all viewports\n"
- "* Ctrl to isolate visibility\n"
- "* Shift to hide inside objects and collections"));
- UI_but_func_set(bt, hidebutton_layer_collection_flag_cb, view_layer, lc);
- UI_but_func_pushed_state_set(bt, layer_collection_pushed_state_cb, lc);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
- else {
- bt = uiDefIconButR_prop(
- block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &collection_ptr, props.collection_hide_viewport, -1, 0, 0, 0, 0, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
-
- bt = uiDefIconButR_prop(
- block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &collection_ptr, props.collection_hide_render, -1, 0, 0, 0, 0, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
- bt = uiDefIconButR_prop(
- block, UI_BTYPE_ICON_TOGGLE, 0, 0,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &collection_ptr, props.collection_hide_select, -1, 0, 0, 0, 0, NULL);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- }
- }
- }
-
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &te->subtree);
- }
- }
+ /* Get RNA properties (once for speed). */
+ static struct RestrictProperties {
+ bool initialized;
+
+ PropertyRNA *object_hide_viewport, *object_hide_select, *object_hide_render;
+ PropertyRNA *collection_hide_viewport, *collection_hide_select, *collection_hide_render;
+ PropertyRNA *modifier_show_viewport, *modifier_show_render;
+ } props = {false};
+
+ if (!props.initialized) {
+ props.object_hide_viewport = RNA_struct_type_find_property(&RNA_Object, "hide_viewport");
+ props.object_hide_select = RNA_struct_type_find_property(&RNA_Object, "hide_select");
+ props.object_hide_render = RNA_struct_type_find_property(&RNA_Object, "hide_render");
+ props.collection_hide_select = RNA_struct_type_find_property(&RNA_Collection, "hide_select");
+ props.collection_hide_viewport = RNA_struct_type_find_property(&RNA_Collection,
+ "hide_viewport");
+ props.collection_hide_render = RNA_struct_type_find_property(&RNA_Collection, "hide_render");
+ props.modifier_show_viewport = RNA_struct_type_find_property(&RNA_Modifier, "show_viewport");
+ props.modifier_show_render = RNA_struct_type_find_property(&RNA_Modifier, "show_render");
+
+ props.initialized = true;
+ }
+
+ /* Create buttons. */
+ uiBut *bt;
+
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if (tselem->type == TSE_R_LAYER && (soops->outlinevis == SO_SCENES)) {
+ /* View layer render toggle. */
+ ViewLayer *layer = te->directdata;
+
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_ICON_TOGGLE_N,
+ VIEW_LAYER_RENDER,
+ 0,
+ ICON_RESTRICT_RENDER_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &layer->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Use view layer for rendering"));
+ UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
+ else if (tselem->type == 0 && te->idcode == ID_OB) {
+ PointerRNA ptr;
+ Object *ob = (Object *)tselem->id;
+ RNA_pointer_create(&ob->id, &RNA_Object, ob, &ptr);
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (base) {
+ int icon = ICON_RESTRICT_VIEW_ON;
+ if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0) {
+ icon = (base->flag & BASE_HIDDEN) != 0 ? ICON_HIDE_ON : ICON_HIDE_OFF;
+ }
+ bt = uiDefIconBut(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ icon,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Hide object in viewport\n"
+ "* Alt to disable for all viewports\n"
+ "* Ctrl to isolate visibility"));
+ UI_but_func_set(bt, hidebutton_base_flag_cb, view_layer, base);
+ UI_but_func_pushed_state_set(bt, base_pushed_state_cb, base);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ else {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_viewport,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_select,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.object_hide_render,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ else if (tselem->type == TSE_MODIFIER) {
+ ModifierData *md = (ModifierData *)te->directdata;
+
+ PointerRNA ptr;
+ RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
+
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.modifier_show_viewport,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.modifier_show_render,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ else if (tselem->type == TSE_POSE_CHANNEL) {
+ bPoseChannel *pchan = (bPoseChannel *)te->directdata;
+ Bone *bone = pchan->bone;
+ Object *ob = (Object *)tselem->id;
+
+ bt = uiDefIconButBitI(block,
+ UI_BTYPE_ICON_TOGGLE,
+ BONE_HIDDEN_P,
+ 0,
+ ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &(bone->flag),
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+
+ bt = uiDefIconButBitI(block,
+ UI_BTYPE_ICON_TOGGLE,
+ BONE_UNSELECTABLE,
+ 0,
+ ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &(bone->flag),
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow selection in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
+ else if (tselem->type == TSE_EBONE) {
+ EditBone *ebone = (EditBone *)te->directdata;
+
+ bt = uiDefIconButBitI(block,
+ UI_BTYPE_ICON_TOGGLE,
+ BONE_HIDDEN_A,
+ 0,
+ ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &(ebone->flag),
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+
+ bt = uiDefIconButBitI(block,
+ UI_BTYPE_ICON_TOGGLE,
+ BONE_UNSELECTABLE,
+ 0,
+ ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &(ebone->flag),
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow selection in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+ }
+ else if (tselem->type == TSE_GP_LAYER) {
+ ID *id = tselem->id;
+ bGPDlayer *gpl = (bGPDlayer *)te->directdata;
+
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_ICON_TOGGLE,
+ GP_LAYER_HIDE,
+ 0,
+ ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &gpl->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
+
+ bt = uiDefIconButBitS(
+ block,
+ UI_BTYPE_ICON_TOGGLE,
+ GP_LAYER_LOCKED,
+ 0,
+ ICON_UNLOCKED,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &gpl->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Restrict/Allow editing of strokes and keyframes in this layer"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ else if (outliner_is_collection_tree_element(te)) {
+ LayerCollection *lc = (tselem->type == TSE_LAYER_COLLECTION) ? te->directdata : NULL;
+ Collection *collection = outliner_collection_from_tree_element(te);
+
+ if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) &&
+ !(collection->flag & COLLECTION_IS_MASTER)) {
+ PointerRNA collection_ptr;
+ RNA_id_pointer_create(&collection->id, &collection_ptr);
+
+ if (lc != NULL) {
+ int icon = ICON_RESTRICT_VIEW_ON;
+ if ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0) {
+ icon = (lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) != 0 ? ICON_HIDE_ON :
+ ICON_HIDE_OFF;
+ }
+ bt = uiDefIconBut(block,
+ UI_BTYPE_TOGGLE,
+ 0,
+ icon,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Hide collection in viewport\n"
+ "* Alt to disable for all viewports\n"
+ "* Ctrl to isolate visibility\n"
+ "* Shift to hide inside objects and collections"));
+ UI_but_func_set(bt, hidebutton_layer_collection_flag_cb, view_layer, lc);
+ UI_but_func_pushed_state_set(bt, layer_collection_pushed_state_cb, lc);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ else {
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &collection_ptr,
+ props.collection_hide_viewport,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &collection_ptr,
+ props.collection_hide_render,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &collection_ptr,
+ props.collection_hide_select,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+ }
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &te->subtree);
+ }
+ }
}
static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *soops, ListBase *lb)
{
- for (TreeElement *te = lb->first; te; te = te->next) {
- TreeStoreElem *tselem = TREESTORE(te);
- if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
- if (tselem->type == 0) {
- uiBut *bt;
- ID *id = tselem->id;
- const char *tip = NULL;
- int icon = ICON_NONE;
- char buf[16] = "";
- int but_flag = UI_BUT_DRAG_LOCK;
-
- if (ID_IS_LINKED(id)) {
- but_flag |= UI_BUT_DISABLED;
- }
-
- if (id->flag & LIB_FAKEUSER) {
- icon = ICON_FILE_TICK;
- tip = TIP_("Data-block will be retained using a fake user");
- }
- else {
- icon = ICON_X;
- tip = TIP_("Data-block has no users and will be deleted");
- }
- bt = uiDefIconButBitS(
- block, UI_BTYPE_TOGGLE, LIB_FAKEUSER, 1, icon,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &id->flag, 0, 0, 0, 0, tip);
- UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
- UI_but_flag_enable(bt, but_flag);
-
-
- BLI_str_format_int_grouped(buf, id->us);
- bt = uiDefBut(
- block, UI_BTYPE_BUT, 1, buf,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys,
- UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0,
- TIP_("Number of users of this data-block"));
- UI_but_flag_enable(bt, but_flag);
-
-
- bt = uiDefButBitS(
- block, UI_BTYPE_TOGGLE, LIB_FAKEUSER, 1, (id->flag & LIB_FAKEUSER) ? "F" : " ",
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
- &id->flag, 0, 0, 0, 0,
- TIP_("Data-block has a 'fake' user which will keep it in the file "
- "even if nothing else uses it"));
- UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
- UI_but_flag_enable(bt, but_flag);
- }
- }
-
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_draw_userbuts(block, ar, soops, &te->subtree);
- }
- }
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if (tselem->type == 0) {
+ uiBut *bt;
+ ID *id = tselem->id;
+ const char *tip = NULL;
+ int icon = ICON_NONE;
+ char buf[16] = "";
+ int but_flag = UI_BUT_DRAG_LOCK;
+
+ if (ID_IS_LINKED(id)) {
+ but_flag |= UI_BUT_DISABLED;
+ }
+
+ if (id->flag & LIB_FAKEUSER) {
+ icon = ICON_FILE_TICK;
+ tip = TIP_("Data-block will be retained using a fake user");
+ }
+ else {
+ icon = ICON_X;
+ tip = TIP_("Data-block has no users and will be deleted");
+ }
+ bt = uiDefIconButBitS(block,
+ UI_BTYPE_TOGGLE,
+ LIB_FAKEUSER,
+ 1,
+ icon,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &id->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ tip);
+ UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
+ UI_but_flag_enable(bt, but_flag);
+
+ BLI_str_format_int_grouped(buf, id->us);
+ bt = uiDefBut(block,
+ UI_BTYPE_BUT,
+ 1,
+ buf,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Number of users of this data-block"));
+ UI_but_flag_enable(bt, but_flag);
+
+ bt = uiDefButBitS(block,
+ UI_BTYPE_TOGGLE,
+ LIB_FAKEUSER,
+ 1,
+ (id->flag & LIB_FAKEUSER) ? "F" : " ",
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &id->flag,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Data-block has a 'fake' user which will keep it in the file "
+ "even if nothing else uses it"));
+ UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
+ UI_but_flag_enable(bt, but_flag);
+ }
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_draw_userbuts(block, ar, soops, &te->subtree);
+ }
+ }
}
static void outliner_draw_rnacols(ARegion *ar, int sizex)
{
- View2D *v2d = &ar->v2d;
+ View2D *v2d = &ar->v2d;
- float miny = v2d->cur.ymin;
- if (miny < v2d->tot.ymin) {
- miny = v2d->tot.ymin;
- }
+ float miny = v2d->cur.ymin;
+ if (miny < v2d->tot.ymin) {
+ miny = v2d->tot.ymin;
+ }
- GPU_line_width(1.0f);
+ GPU_line_width(1.0f);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
- immBegin(GPU_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, sizex, v2d->cur.ymax);
- immVertex2f(pos, sizex, miny);
+ immVertex2f(pos, sizex, v2d->cur.ymax);
+ immVertex2f(pos, sizex, miny);
- immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, v2d->cur.ymax);
- immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, miny);
+ immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, v2d->cur.ymax);
+ immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, miny);
- immEnd();
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
}
-static void outliner_draw_rnabuts(uiBlock *block, ARegion *ar, SpaceOutliner *soops, int sizex, ListBase *lb)
+static void outliner_draw_rnabuts(
+ uiBlock *block, ARegion *ar, SpaceOutliner *soops, int sizex, ListBase *lb)
{
- PointerRNA *ptr;
- PropertyRNA *prop;
-
- for (TreeElement *te = lb->first; te; te = te->next) {
- TreeStoreElem *tselem = TREESTORE(te);
- if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
- if (tselem->type == TSE_RNA_PROPERTY) {
- ptr = &te->rnaptr;
- prop = te->directdata;
-
- if (!TSELEM_OPEN(tselem, soops)) {
- if (RNA_property_type(prop) == PROP_POINTER) {
- uiBut *but = uiDefAutoButR(
- block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys,
- OL_RNA_COL_SIZEX, UI_UNIT_Y - 1);
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- else if (RNA_property_type(prop) == PROP_ENUM) {
- uiDefAutoButR(
- block, ptr, prop, -1, NULL, ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
- UI_UNIT_Y - 1);
- }
- else {
- uiDefAutoButR(
- block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
- UI_UNIT_Y - 1);
- }
- }
- }
- else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
- ptr = &te->rnaptr;
- prop = te->directdata;
-
- uiDefAutoButR(
- block, ptr, prop, te->index, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
- UI_UNIT_Y - 1);
- }
- }
-
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_draw_rnabuts(block, ar, soops, sizex, &te->subtree);
- }
- }
+ PointerRNA *ptr;
+ PropertyRNA *prop;
+
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if (tselem->type == TSE_RNA_PROPERTY) {
+ ptr = &te->rnaptr;
+ prop = te->directdata;
+
+ if (!TSELEM_OPEN(tselem, soops)) {
+ if (RNA_property_type(prop) == PROP_POINTER) {
+ uiBut *but = uiDefAutoButR(block,
+ ptr,
+ prop,
+ -1,
+ "",
+ ICON_NONE,
+ sizex,
+ te->ys,
+ OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ else if (RNA_property_type(prop) == PROP_ENUM) {
+ uiDefAutoButR(block,
+ ptr,
+ prop,
+ -1,
+ NULL,
+ ICON_NONE,
+ sizex,
+ te->ys,
+ OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ }
+ else {
+ uiDefAutoButR(block,
+ ptr,
+ prop,
+ -1,
+ "",
+ ICON_NONE,
+ sizex,
+ te->ys,
+ OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ }
+ }
+ }
+ else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
+ ptr = &te->rnaptr;
+ prop = te->directdata;
+
+ uiDefAutoButR(block,
+ ptr,
+ prop,
+ te->index,
+ "",
+ ICON_NONE,
+ sizex,
+ te->ys,
+ OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ }
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_draw_rnabuts(block, ar, soops, sizex, &te->subtree);
+ }
+ }
}
static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, TreeElement *te)
{
- uiBut *bt;
- TreeStoreElem *tselem;
- int spx, dx, len;
-
- tselem = TREESTORE(te);
-
- BLI_assert(tselem->flag & TSE_TEXTBUT);
- /* If we add support to rename Sequence.
- * need change this.
- */
-
- if (tselem->type == TSE_EBONE) {
- len = sizeof(((EditBone *) 0)->name);
- }
- else if (tselem->type == TSE_MODIFIER) {
- len = sizeof(((ModifierData *) 0)->name);
- }
- else if (tselem->id && GS(tselem->id->name) == ID_LI) {
- len = sizeof(((Library *) 0)->name);
- }
- else {
- len = MAX_ID_NAME - 2;
- }
-
- spx = te->xs + 1.8f * UI_UNIT_X;
- dx = ar->v2d.cur.xmax - (spx + 3.2f * UI_UNIT_X);
-
- bt = uiDefBut(
- block, UI_BTYPE_TEXT, OL_NAMEBUTTON, "", spx, te->ys, dx, UI_UNIT_Y - 1, (void *)te->name,
- 1.0, (float)len, 0, 0, "");
- UI_but_func_rename_set(bt, namebutton_cb, tselem);
-
- /* returns false if button got removed */
- if (false == UI_but_active_only(C, ar, block, bt)) {
- tselem->flag &= ~TSE_TEXTBUT;
-
- /* bad! (notifier within draw) without this, we don't get a refresh */
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
- }
+ uiBut *bt;
+ TreeStoreElem *tselem;
+ int spx, dx, len;
+
+ tselem = TREESTORE(te);
+
+ BLI_assert(tselem->flag & TSE_TEXTBUT);
+ /* If we add support to rename Sequence.
+ * need change this.
+ */
+
+ if (tselem->type == TSE_EBONE) {
+ len = sizeof(((EditBone *)0)->name);
+ }
+ else if (tselem->type == TSE_MODIFIER) {
+ len = sizeof(((ModifierData *)0)->name);
+ }
+ else if (tselem->id && GS(tselem->id->name) == ID_LI) {
+ len = sizeof(((Library *)0)->name);
+ }
+ else {
+ len = MAX_ID_NAME - 2;
+ }
+
+ spx = te->xs + 1.8f * UI_UNIT_X;
+ dx = ar->v2d.cur.xmax - (spx + 3.2f * UI_UNIT_X);
+
+ bt = uiDefBut(block,
+ UI_BTYPE_TEXT,
+ OL_NAMEBUTTON,
+ "",
+ spx,
+ te->ys,
+ dx,
+ UI_UNIT_Y - 1,
+ (void *)te->name,
+ 1.0,
+ (float)len,
+ 0,
+ 0,
+ "");
+ UI_but_func_rename_set(bt, namebutton_cb, tselem);
+
+ /* returns false if button got removed */
+ if (false == UI_but_active_only(C, ar, block, bt)) {
+ tselem->flag &= ~TSE_TEXTBUT;
+
+ /* bad! (notifier within draw) without this, we don't get a refresh */
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+ }
}
/* ****************************************************** */
@@ -972,615 +1234,674 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Tre
TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
{
- TreeElementIcon data = {0};
-
- if (tselem->type) {
- switch (tselem->type) {
- case TSE_ANIM_DATA:
- data.icon = ICON_ANIM_DATA; /* XXX */
- break;
- case TSE_NLA:
- data.icon = ICON_NLA;
- break;
- case TSE_NLA_TRACK:
- data.icon = ICON_NLA; /* XXX */
- break;
- case TSE_NLA_ACTION:
- data.icon = ICON_ACTION;
- break;
- case TSE_DRIVER_BASE:
- data.icon = ICON_DRIVER;
- break;
- case TSE_DEFGROUP_BASE:
- data.icon = ICON_GROUP_VERTEX;
- break;
- case TSE_BONE:
- case TSE_EBONE:
- data.icon = ICON_BONE_DATA;
- break;
- case TSE_CONSTRAINT_BASE:
- data.icon = ICON_CONSTRAINT;
- break;
- case TSE_MODIFIER_BASE:
- data.icon = ICON_MODIFIER_DATA;
- break;
- case TSE_LINKED_OB:
- data.icon = ICON_OBJECT_DATA;
- break;
- case TSE_LINKED_PSYS:
- data.icon = ICON_PARTICLES;
- break;
- case TSE_MODIFIER:
- {
- Object *ob = (Object *)tselem->id;
- if (ob->type != OB_GPENCIL) {
- ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
- switch ((ModifierType)md->type) {
- case eModifierType_Subsurf:
- data.icon = ICON_MOD_SUBSURF;
- break;
- case eModifierType_Armature:
- data.icon = ICON_MOD_ARMATURE;
- break;
- case eModifierType_Lattice:
- data.icon = ICON_MOD_LATTICE;
- break;
- case eModifierType_Curve:
- data.icon = ICON_MOD_CURVE;
- break;
- case eModifierType_Build:
- data.icon = ICON_MOD_BUILD;
- break;
- case eModifierType_Mirror:
- data.icon = ICON_MOD_MIRROR;
- break;
- case eModifierType_Decimate:
- data.icon = ICON_MOD_DECIM;
- break;
- case eModifierType_Wave:
- data.icon = ICON_MOD_WAVE;
- break;
- case eModifierType_Hook:
- data.icon = ICON_HOOK;
- break;
- case eModifierType_Softbody:
- data.icon = ICON_MOD_SOFT;
- break;
- case eModifierType_Boolean:
- data.icon = ICON_MOD_BOOLEAN;
- break;
- case eModifierType_ParticleSystem:
- data.icon = ICON_MOD_PARTICLES;
- break;
- case eModifierType_ParticleInstance:
- data.icon = ICON_MOD_PARTICLES;
- break;
- case eModifierType_EdgeSplit:
- data.icon = ICON_MOD_EDGESPLIT;
- break;
- case eModifierType_Array:
- data.icon = ICON_MOD_ARRAY;
- break;
- case eModifierType_UVProject:
- case eModifierType_UVWarp: /* TODO, get own icon */
- data.icon = ICON_MOD_UVPROJECT;
- break;
- case eModifierType_Displace:
- data.icon = ICON_MOD_DISPLACE;
- break;
- case eModifierType_Shrinkwrap:
- data.icon = ICON_MOD_SHRINKWRAP;
- break;
- case eModifierType_Cast:
- data.icon = ICON_MOD_CAST;
- break;
- case eModifierType_MeshDeform:
- case eModifierType_SurfaceDeform:
- data.icon = ICON_MOD_MESHDEFORM;
- break;
- case eModifierType_Bevel:
- data.icon = ICON_MOD_BEVEL;
- break;
- case eModifierType_Smooth:
- case eModifierType_LaplacianSmooth:
- case eModifierType_CorrectiveSmooth:
- data.icon = ICON_MOD_SMOOTH;
- break;
- case eModifierType_SimpleDeform:
- data.icon = ICON_MOD_SIMPLEDEFORM;
- break;
- case eModifierType_Mask:
- data.icon = ICON_MOD_MASK;
- break;
- case eModifierType_Cloth:
- data.icon = ICON_MOD_CLOTH;
- break;
- case eModifierType_Explode:
- data.icon = ICON_MOD_EXPLODE;
- break;
- case eModifierType_Collision:
- case eModifierType_Surface:
- data.icon = ICON_MOD_PHYSICS;
- break;
- case eModifierType_Fluidsim:
- data.icon = ICON_MOD_FLUIDSIM;
- break;
- case eModifierType_Multires:
- data.icon = ICON_MOD_MULTIRES;
- break;
- case eModifierType_Smoke:
- data.icon = ICON_MOD_SMOKE;
- break;
- case eModifierType_Solidify:
- data.icon = ICON_MOD_SOLIDIFY;
- break;
- case eModifierType_Screw:
- data.icon = ICON_MOD_SCREW;
- break;
- case eModifierType_Remesh:
- data.icon = ICON_MOD_REMESH;
- break;
- case eModifierType_WeightVGEdit:
- case eModifierType_WeightVGMix:
- case eModifierType_WeightVGProximity:
- data.icon = ICON_MOD_VERTEX_WEIGHT;
- break;
- case eModifierType_DynamicPaint:
- data.icon = ICON_MOD_DYNAMICPAINT;
- break;
- case eModifierType_Ocean:
- data.icon = ICON_MOD_OCEAN;
- break;
- case eModifierType_Warp:
- data.icon = ICON_MOD_WARP;
- break;
- case eModifierType_Skin:
- data.icon = ICON_MOD_SKIN;
- break;
- case eModifierType_Triangulate:
- data.icon = ICON_MOD_TRIANGULATE;
- break;
- case eModifierType_MeshCache:
- data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
- break;
- case eModifierType_MeshSequenceCache:
- data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
- break;
- case eModifierType_Wireframe:
- data.icon = ICON_MOD_WIREFRAME;
- break;
- case eModifierType_LaplacianDeform:
- data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
- break;
- case eModifierType_DataTransfer:
- data.icon = ICON_MOD_DATA_TRANSFER;
- break;
- case eModifierType_NormalEdit:
- case eModifierType_WeightedNormal:
- data.icon = ICON_MOD_NORMALEDIT;
- break;
- /* Default */
- case eModifierType_None:
- case eModifierType_ShapeKey:
-
- case NUM_MODIFIER_TYPES:
- data.icon = ICON_DOT;
- break;
- }
- }
- else {
- /* grease pencil modifiers */
- GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, tselem->nr);
- switch ((GpencilModifierType)md->type) {
- case eGpencilModifierType_Noise:
- data.icon = ICON_RNDCURVE;
- break;
- case eGpencilModifierType_Subdiv:
- data.icon = ICON_MOD_SUBSURF;
- break;
- case eGpencilModifierType_Thick:
- data.icon = ICON_MOD_THICKNESS;
- break;
- case eGpencilModifierType_Tint:
- data.icon = ICON_MOD_TINT;
- break;
- case eGpencilModifierType_Array:
- data.icon = ICON_MOD_ARRAY;
- break;
- case eGpencilModifierType_Build:
- data.icon = ICON_MOD_BUILD;
- break;
- case eGpencilModifierType_Opacity:
- data.icon = ICON_MOD_MASK;
- break;
- case eGpencilModifierType_Color:
- data.icon = ICON_MOD_HUE_SATURATION;
- break;
- case eGpencilModifierType_Lattice:
- data.icon = ICON_MOD_LATTICE;
- break;
- case eGpencilModifierType_Mirror:
- data.icon = ICON_MOD_MIRROR;
- break;
- case eGpencilModifierType_Simplify:
- data.icon = ICON_MOD_SIMPLIFY;
- break;
- case eGpencilModifierType_Smooth:
- data.icon = ICON_MOD_SMOOTH;
- break;
- case eGpencilModifierType_Hook:
- data.icon = ICON_HOOK;
- break;
- case eGpencilModifierType_Offset:
- data.icon = ICON_MOD_OFFSET;
- break;
- case eGpencilModifierType_Armature:
- data.icon = ICON_MOD_ARMATURE;
- break;
-
- /* Default */
- default:
- data.icon = ICON_DOT;
- break;
- }
- }
- break;
- }
- case TSE_POSE_BASE:
- data.icon = ICON_ARMATURE_DATA;
- break;
- case TSE_POSE_CHANNEL:
- data.icon = ICON_BONE_DATA;
- break;
- case TSE_PROXY:
- data.icon = ICON_GHOST_ENABLED;
- break;
- case TSE_R_LAYER_BASE:
- data.icon = ICON_RENDERLAYERS;
- break;
- case TSE_SCENE_OBJECTS_BASE:
- data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
- break;
- case TSE_R_LAYER:
- data.icon = ICON_RENDER_RESULT;
- break;
- case TSE_LINKED_LAMP:
- data.icon = ICON_LIGHT_DATA;
- break;
- case TSE_LINKED_MAT:
- data.icon = ICON_MATERIAL_DATA;
- break;
- case TSE_POSEGRP_BASE:
- data.icon = ICON_GROUP_BONE;
- break;
- case TSE_SEQUENCE:
- if (te->idcode == SEQ_TYPE_MOVIE) {
- data.icon = ICON_SEQUENCE;
- }
- else if (te->idcode == SEQ_TYPE_META) {
- data.icon = ICON_DOT;
- }
- else if (te->idcode == SEQ_TYPE_SCENE) {
- data.icon = ICON_SCENE;
- }
- else if (te->idcode == SEQ_TYPE_SOUND_RAM) {
- data.icon = ICON_SOUND;
- }
- else if (te->idcode == SEQ_TYPE_IMAGE) {
- data.icon = ICON_IMAGE;
- }
- else {
- data.icon = ICON_PARTICLES;
- }
- break;
- case TSE_SEQ_STRIP:
- data.icon = ICON_LIBRARY_DATA_DIRECT;
- break;
- case TSE_SEQUENCE_DUP:
- data.icon = ICON_OBJECT_DATA;
- break;
- case TSE_RNA_STRUCT:
- if (RNA_struct_is_ID(te->rnaptr.type)) {
- data.drag_id = (ID *)te->rnaptr.data;
- data.icon = RNA_struct_ui_icon(te->rnaptr.type);
- }
- else {
- data.icon = RNA_struct_ui_icon(te->rnaptr.type);
- }
- break;
- case TSE_LAYER_COLLECTION:
- case TSE_SCENE_COLLECTION_BASE:
- case TSE_VIEW_COLLECTION_BASE:
- {
- Collection *collection = outliner_collection_from_tree_element(te);
- if (collection && !(collection->flag & COLLECTION_IS_MASTER)) {
- data.drag_id = tselem->id;
- data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
- }
-
- data.icon = ICON_GROUP;
- break;
- }
- /* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */
- case TSE_GP_LAYER:
- {
- /* indicate whether layer is active */
- bGPDlayer *gpl = te->directdata;
- if (gpl->flag & GP_LAYER_ACTIVE) {
- data.icon = ICON_GREASEPENCIL;
- }
- else {
- data.icon = ICON_DOT;
- }
- break;
- }
- default:
- data.icon = ICON_DOT;
- break;
- }
- }
- else if (tselem->id) {
- data.drag_id = tselem->id;
- data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
-
- if (GS(tselem->id->name) == ID_OB) {
- Object *ob = (Object *)tselem->id;
- switch (ob->type) {
- case OB_LAMP:
- data.icon = ICON_OUTLINER_OB_LIGHT; break;
- case OB_MESH:
- data.icon = ICON_OUTLINER_OB_MESH; break;
- case OB_CAMERA:
- data.icon = ICON_OUTLINER_OB_CAMERA; break;
- case OB_CURVE:
- data.icon = ICON_OUTLINER_OB_CURVE; break;
- case OB_MBALL:
- data.icon = ICON_OUTLINER_OB_META; break;
- case OB_LATTICE:
- data.icon = ICON_OUTLINER_OB_LATTICE; break;
- case OB_ARMATURE:
- data.icon = ICON_OUTLINER_OB_ARMATURE; break;
- case OB_FONT:
- data.icon = ICON_OUTLINER_OB_FONT; break;
- case OB_SURF:
- data.icon = ICON_OUTLINER_OB_SURFACE; break;
- case OB_SPEAKER:
- data.icon = ICON_OUTLINER_OB_SPEAKER; break;
- case OB_LIGHTPROBE:
- data.icon = ICON_OUTLINER_OB_LIGHTPROBE; break;
- case OB_EMPTY:
- if (ob->instance_collection) {
- data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
- }
- else if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
- data.icon = ICON_OUTLINER_OB_IMAGE;
- }
- else {
- data.icon = ICON_OUTLINER_OB_EMPTY;
- }
- break;
- case OB_GPENCIL:
- data.icon = ICON_OUTLINER_OB_GREASEPENCIL; break;
- break;
- }
- }
- else {
- /* TODO(sergey): Casting to short here just to handle ID_NLA which is
- * NOT inside of IDType enum.
- */
- switch ((short)GS(tselem->id->name)) {
- case ID_SCE:
- data.icon = ICON_SCENE_DATA; break;
- case ID_ME:
- data.icon = ICON_OUTLINER_DATA_MESH; break;
- case ID_CU:
- data.icon = ICON_OUTLINER_DATA_CURVE; break;
- case ID_MB:
- data.icon = ICON_OUTLINER_DATA_META; break;
- case ID_LT:
- data.icon = ICON_OUTLINER_DATA_LATTICE; break;
- case ID_LA:
- {
- Light *la = (Light *)tselem->id;
- switch (la->type) {
- case LA_LOCAL:
- data.icon = ICON_LIGHT_POINT; break;
- case LA_SUN:
- data.icon = ICON_LIGHT_SUN; break;
- case LA_SPOT:
- data.icon = ICON_LIGHT_SPOT; break;
- case LA_AREA:
- data.icon = ICON_LIGHT_AREA; break;
- default:
- data.icon = ICON_OUTLINER_DATA_LIGHT; break;
- }
- break;
- }
- case ID_MA:
- data.icon = ICON_MATERIAL_DATA; break;
- case ID_TE:
- data.icon = ICON_TEXTURE_DATA; break;
- case ID_IM:
- data.icon = ICON_IMAGE_DATA; break;
- case ID_SPK:
- case ID_SO:
- data.icon = ICON_OUTLINER_DATA_SPEAKER; break;
- case ID_AR:
- data.icon = ICON_OUTLINER_DATA_ARMATURE; break;
- case ID_CA:
- data.icon = ICON_OUTLINER_DATA_CAMERA; break;
- case ID_KE:
- data.icon = ICON_SHAPEKEY_DATA; break;
- case ID_WO:
- data.icon = ICON_WORLD_DATA; break;
- case ID_AC:
- data.icon = ICON_ACTION; break;
- case ID_NLA:
- data.icon = ICON_NLA; break;
- case ID_TXT:
- data.icon = ICON_SCRIPT; break;
- case ID_GR:
- data.icon = ICON_GROUP; break;
- case ID_LI:
- if (tselem->id->tag & LIB_TAG_MISSING) {
- data.icon = ICON_LIBRARY_DATA_BROKEN;
- }
- else if (((Library *)tselem->id)->parent) {
- data.icon = ICON_LIBRARY_DATA_INDIRECT;
- }
- else {
- data.icon = ICON_LIBRARY_DATA_DIRECT;
- }
- break;
- case ID_LS:
- data.icon = ICON_LINE_DATA; break;
- case ID_GD:
- data.icon = ICON_OUTLINER_DATA_GREASEPENCIL; break;
- case ID_LP:
- {
- LightProbe *lp = (LightProbe *)tselem->id;
- switch (lp->type) {
- case LIGHTPROBE_TYPE_CUBE:
- data.icon = ICON_LIGHTPROBE_CUBEMAP; break;
- case LIGHTPROBE_TYPE_PLANAR:
- data.icon = ICON_LIGHTPROBE_PLANAR; break;
- case LIGHTPROBE_TYPE_GRID:
- data.icon = ICON_LIGHTPROBE_GRID; break;
- default:
- data.icon = ICON_LIGHTPROBE_CUBEMAP; break;
- }
- break;
- }
- case ID_BR:
- data.icon = ICON_BRUSH_DATA; break;
- case ID_SCR:
- case ID_WS:
- data.icon = ICON_WORKSPACE; break;
- case ID_MSK:
- data.icon = ICON_MOD_MASK; break;
- case ID_MC:
- data.icon = ICON_SEQUENCE; break;
- case ID_PC:
- data.icon = ICON_CURVE_BEZCURVE; break;
- default:
- break;
- }
- }
- }
-
- return data;
+ TreeElementIcon data = {0};
+
+ if (tselem->type) {
+ switch (tselem->type) {
+ case TSE_ANIM_DATA:
+ data.icon = ICON_ANIM_DATA; /* XXX */
+ break;
+ case TSE_NLA:
+ data.icon = ICON_NLA;
+ break;
+ case TSE_NLA_TRACK:
+ data.icon = ICON_NLA; /* XXX */
+ break;
+ case TSE_NLA_ACTION:
+ data.icon = ICON_ACTION;
+ break;
+ case TSE_DRIVER_BASE:
+ data.icon = ICON_DRIVER;
+ break;
+ case TSE_DEFGROUP_BASE:
+ data.icon = ICON_GROUP_VERTEX;
+ break;
+ case TSE_BONE:
+ case TSE_EBONE:
+ data.icon = ICON_BONE_DATA;
+ break;
+ case TSE_CONSTRAINT_BASE:
+ data.icon = ICON_CONSTRAINT;
+ break;
+ case TSE_MODIFIER_BASE:
+ data.icon = ICON_MODIFIER_DATA;
+ break;
+ case TSE_LINKED_OB:
+ data.icon = ICON_OBJECT_DATA;
+ break;
+ case TSE_LINKED_PSYS:
+ data.icon = ICON_PARTICLES;
+ break;
+ case TSE_MODIFIER: {
+ Object *ob = (Object *)tselem->id;
+ if (ob->type != OB_GPENCIL) {
+ ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
+ switch ((ModifierType)md->type) {
+ case eModifierType_Subsurf:
+ data.icon = ICON_MOD_SUBSURF;
+ break;
+ case eModifierType_Armature:
+ data.icon = ICON_MOD_ARMATURE;
+ break;
+ case eModifierType_Lattice:
+ data.icon = ICON_MOD_LATTICE;
+ break;
+ case eModifierType_Curve:
+ data.icon = ICON_MOD_CURVE;
+ break;
+ case eModifierType_Build:
+ data.icon = ICON_MOD_BUILD;
+ break;
+ case eModifierType_Mirror:
+ data.icon = ICON_MOD_MIRROR;
+ break;
+ case eModifierType_Decimate:
+ data.icon = ICON_MOD_DECIM;
+ break;
+ case eModifierType_Wave:
+ data.icon = ICON_MOD_WAVE;
+ break;
+ case eModifierType_Hook:
+ data.icon = ICON_HOOK;
+ break;
+ case eModifierType_Softbody:
+ data.icon = ICON_MOD_SOFT;
+ break;
+ case eModifierType_Boolean:
+ data.icon = ICON_MOD_BOOLEAN;
+ break;
+ case eModifierType_ParticleSystem:
+ data.icon = ICON_MOD_PARTICLES;
+ break;
+ case eModifierType_ParticleInstance:
+ data.icon = ICON_MOD_PARTICLES;
+ break;
+ case eModifierType_EdgeSplit:
+ data.icon = ICON_MOD_EDGESPLIT;
+ break;
+ case eModifierType_Array:
+ data.icon = ICON_MOD_ARRAY;
+ break;
+ case eModifierType_UVProject:
+ case eModifierType_UVWarp: /* TODO, get own icon */
+ data.icon = ICON_MOD_UVPROJECT;
+ break;
+ case eModifierType_Displace:
+ data.icon = ICON_MOD_DISPLACE;
+ break;
+ case eModifierType_Shrinkwrap:
+ data.icon = ICON_MOD_SHRINKWRAP;
+ break;
+ case eModifierType_Cast:
+ data.icon = ICON_MOD_CAST;
+ break;
+ case eModifierType_MeshDeform:
+ case eModifierType_SurfaceDeform:
+ data.icon = ICON_MOD_MESHDEFORM;
+ break;
+ case eModifierType_Bevel:
+ data.icon = ICON_MOD_BEVEL;
+ break;
+ case eModifierType_Smooth:
+ case eModifierType_LaplacianSmooth:
+ case eModifierType_CorrectiveSmooth:
+ data.icon = ICON_MOD_SMOOTH;
+ break;
+ case eModifierType_SimpleDeform:
+ data.icon = ICON_MOD_SIMPLEDEFORM;
+ break;
+ case eModifierType_Mask:
+ data.icon = ICON_MOD_MASK;
+ break;
+ case eModifierType_Cloth:
+ data.icon = ICON_MOD_CLOTH;
+ break;
+ case eModifierType_Explode:
+ data.icon = ICON_MOD_EXPLODE;
+ break;
+ case eModifierType_Collision:
+ case eModifierType_Surface:
+ data.icon = ICON_MOD_PHYSICS;
+ break;
+ case eModifierType_Fluidsim:
+ data.icon = ICON_MOD_FLUIDSIM;
+ break;
+ case eModifierType_Multires:
+ data.icon = ICON_MOD_MULTIRES;
+ break;
+ case eModifierType_Smoke:
+ data.icon = ICON_MOD_SMOKE;
+ break;
+ case eModifierType_Solidify:
+ data.icon = ICON_MOD_SOLIDIFY;
+ break;
+ case eModifierType_Screw:
+ data.icon = ICON_MOD_SCREW;
+ break;
+ case eModifierType_Remesh:
+ data.icon = ICON_MOD_REMESH;
+ break;
+ case eModifierType_WeightVGEdit:
+ case eModifierType_WeightVGMix:
+ case eModifierType_WeightVGProximity:
+ data.icon = ICON_MOD_VERTEX_WEIGHT;
+ break;
+ case eModifierType_DynamicPaint:
+ data.icon = ICON_MOD_DYNAMICPAINT;
+ break;
+ case eModifierType_Ocean:
+ data.icon = ICON_MOD_OCEAN;
+ break;
+ case eModifierType_Warp:
+ data.icon = ICON_MOD_WARP;
+ break;
+ case eModifierType_Skin:
+ data.icon = ICON_MOD_SKIN;
+ break;
+ case eModifierType_Triangulate:
+ data.icon = ICON_MOD_TRIANGULATE;
+ break;
+ case eModifierType_MeshCache:
+ data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
+ break;
+ case eModifierType_MeshSequenceCache:
+ data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
+ break;
+ case eModifierType_Wireframe:
+ data.icon = ICON_MOD_WIREFRAME;
+ break;
+ case eModifierType_LaplacianDeform:
+ data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */
+ break;
+ case eModifierType_DataTransfer:
+ data.icon = ICON_MOD_DATA_TRANSFER;
+ break;
+ case eModifierType_NormalEdit:
+ case eModifierType_WeightedNormal:
+ data.icon = ICON_MOD_NORMALEDIT;
+ break;
+ /* Default */
+ case eModifierType_None:
+ case eModifierType_ShapeKey:
+
+ case NUM_MODIFIER_TYPES:
+ data.icon = ICON_DOT;
+ break;
+ }
+ }
+ else {
+ /* grease pencil modifiers */
+ GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, tselem->nr);
+ switch ((GpencilModifierType)md->type) {
+ case eGpencilModifierType_Noise:
+ data.icon = ICON_RNDCURVE;
+ break;
+ case eGpencilModifierType_Subdiv:
+ data.icon = ICON_MOD_SUBSURF;
+ break;
+ case eGpencilModifierType_Thick:
+ data.icon = ICON_MOD_THICKNESS;
+ break;
+ case eGpencilModifierType_Tint:
+ data.icon = ICON_MOD_TINT;
+ break;
+ case eGpencilModifierType_Array:
+ data.icon = ICON_MOD_ARRAY;
+ break;
+ case eGpencilModifierType_Build:
+ data.icon = ICON_MOD_BUILD;
+ break;
+ case eGpencilModifierType_Opacity:
+ data.icon = ICON_MOD_MASK;
+ break;
+ case eGpencilModifierType_Color:
+ data.icon = ICON_MOD_HUE_SATURATION;
+ break;
+ case eGpencilModifierType_Lattice:
+ data.icon = ICON_MOD_LATTICE;
+ break;
+ case eGpencilModifierType_Mirror:
+ data.icon = ICON_MOD_MIRROR;
+ break;
+ case eGpencilModifierType_Simplify:
+ data.icon = ICON_MOD_SIMPLIFY;
+ break;
+ case eGpencilModifierType_Smooth:
+ data.icon = ICON_MOD_SMOOTH;
+ break;
+ case eGpencilModifierType_Hook:
+ data.icon = ICON_HOOK;
+ break;
+ case eGpencilModifierType_Offset:
+ data.icon = ICON_MOD_OFFSET;
+ break;
+ case eGpencilModifierType_Armature:
+ data.icon = ICON_MOD_ARMATURE;
+ break;
+
+ /* Default */
+ default:
+ data.icon = ICON_DOT;
+ break;
+ }
+ }
+ break;
+ }
+ case TSE_POSE_BASE:
+ data.icon = ICON_ARMATURE_DATA;
+ break;
+ case TSE_POSE_CHANNEL:
+ data.icon = ICON_BONE_DATA;
+ break;
+ case TSE_PROXY:
+ data.icon = ICON_GHOST_ENABLED;
+ break;
+ case TSE_R_LAYER_BASE:
+ data.icon = ICON_RENDERLAYERS;
+ break;
+ case TSE_SCENE_OBJECTS_BASE:
+ data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
+ break;
+ case TSE_R_LAYER:
+ data.icon = ICON_RENDER_RESULT;
+ break;
+ case TSE_LINKED_LAMP:
+ data.icon = ICON_LIGHT_DATA;
+ break;
+ case TSE_LINKED_MAT:
+ data.icon = ICON_MATERIAL_DATA;
+ break;
+ case TSE_POSEGRP_BASE:
+ data.icon = ICON_GROUP_BONE;
+ break;
+ case TSE_SEQUENCE:
+ if (te->idcode == SEQ_TYPE_MOVIE) {
+ data.icon = ICON_SEQUENCE;
+ }
+ else if (te->idcode == SEQ_TYPE_META) {
+ data.icon = ICON_DOT;
+ }
+ else if (te->idcode == SEQ_TYPE_SCENE) {
+ data.icon = ICON_SCENE;
+ }
+ else if (te->idcode == SEQ_TYPE_SOUND_RAM) {
+ data.icon = ICON_SOUND;
+ }
+ else if (te->idcode == SEQ_TYPE_IMAGE) {
+ data.icon = ICON_IMAGE;
+ }
+ else {
+ data.icon = ICON_PARTICLES;
+ }
+ break;
+ case TSE_SEQ_STRIP:
+ data.icon = ICON_LIBRARY_DATA_DIRECT;
+ break;
+ case TSE_SEQUENCE_DUP:
+ data.icon = ICON_OBJECT_DATA;
+ break;
+ case TSE_RNA_STRUCT:
+ if (RNA_struct_is_ID(te->rnaptr.type)) {
+ data.drag_id = (ID *)te->rnaptr.data;
+ data.icon = RNA_struct_ui_icon(te->rnaptr.type);
+ }
+ else {
+ data.icon = RNA_struct_ui_icon(te->rnaptr.type);
+ }
+ break;
+ case TSE_LAYER_COLLECTION:
+ case TSE_SCENE_COLLECTION_BASE:
+ case TSE_VIEW_COLLECTION_BASE: {
+ Collection *collection = outliner_collection_from_tree_element(te);
+ if (collection && !(collection->flag & COLLECTION_IS_MASTER)) {
+ data.drag_id = tselem->id;
+ data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
+ }
+
+ data.icon = ICON_GROUP;
+ break;
+ }
+ /* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */
+ case TSE_GP_LAYER: {
+ /* indicate whether layer is active */
+ bGPDlayer *gpl = te->directdata;
+ if (gpl->flag & GP_LAYER_ACTIVE) {
+ data.icon = ICON_GREASEPENCIL;
+ }
+ else {
+ data.icon = ICON_DOT;
+ }
+ break;
+ }
+ default:
+ data.icon = ICON_DOT;
+ break;
+ }
+ }
+ else if (tselem->id) {
+ data.drag_id = tselem->id;
+ data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
+
+ if (GS(tselem->id->name) == ID_OB) {
+ Object *ob = (Object *)tselem->id;
+ switch (ob->type) {
+ case OB_LAMP:
+ data.icon = ICON_OUTLINER_OB_LIGHT;
+ break;
+ case OB_MESH:
+ data.icon = ICON_OUTLINER_OB_MESH;
+ break;
+ case OB_CAMERA:
+ data.icon = ICON_OUTLINER_OB_CAMERA;
+ break;
+ case OB_CURVE:
+ data.icon = ICON_OUTLINER_OB_CURVE;
+ break;
+ case OB_MBALL:
+ data.icon = ICON_OUTLINER_OB_META;
+ break;
+ case OB_LATTICE:
+ data.icon = ICON_OUTLINER_OB_LATTICE;
+ break;
+ case OB_ARMATURE:
+ data.icon = ICON_OUTLINER_OB_ARMATURE;
+ break;
+ case OB_FONT:
+ data.icon = ICON_OUTLINER_OB_FONT;
+ break;
+ case OB_SURF:
+ data.icon = ICON_OUTLINER_OB_SURFACE;
+ break;
+ case OB_SPEAKER:
+ data.icon = ICON_OUTLINER_OB_SPEAKER;
+ break;
+ case OB_LIGHTPROBE:
+ data.icon = ICON_OUTLINER_OB_LIGHTPROBE;
+ break;
+ case OB_EMPTY:
+ if (ob->instance_collection) {
+ data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
+ }
+ else if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
+ data.icon = ICON_OUTLINER_OB_IMAGE;
+ }
+ else {
+ data.icon = ICON_OUTLINER_OB_EMPTY;
+ }
+ break;
+ case OB_GPENCIL:
+ data.icon = ICON_OUTLINER_OB_GREASEPENCIL;
+ break;
+ break;
+ }
+ }
+ else {
+ /* TODO(sergey): Casting to short here just to handle ID_NLA which is
+ * NOT inside of IDType enum.
+ */
+ switch ((short)GS(tselem->id->name)) {
+ case ID_SCE:
+ data.icon = ICON_SCENE_DATA;
+ break;
+ case ID_ME:
+ data.icon = ICON_OUTLINER_DATA_MESH;
+ break;
+ case ID_CU:
+ data.icon = ICON_OUTLINER_DATA_CURVE;
+ break;
+ case ID_MB:
+ data.icon = ICON_OUTLINER_DATA_META;
+ break;
+ case ID_LT:
+ data.icon = ICON_OUTLINER_DATA_LATTICE;
+ break;
+ case ID_LA: {
+ Light *la = (Light *)tselem->id;
+ switch (la->type) {
+ case LA_LOCAL:
+ data.icon = ICON_LIGHT_POINT;
+ break;
+ case LA_SUN:
+ data.icon = ICON_LIGHT_SUN;
+ break;
+ case LA_SPOT:
+ data.icon = ICON_LIGHT_SPOT;
+ break;
+ case LA_AREA:
+ data.icon = ICON_LIGHT_AREA;
+ break;
+ default:
+ data.icon = ICON_OUTLINER_DATA_LIGHT;
+ break;
+ }
+ break;
+ }
+ case ID_MA:
+ data.icon = ICON_MATERIAL_DATA;
+ break;
+ case ID_TE:
+ data.icon = ICON_TEXTURE_DATA;
+ break;
+ case ID_IM:
+ data.icon = ICON_IMAGE_DATA;
+ break;
+ case ID_SPK:
+ case ID_SO:
+ data.icon = ICON_OUTLINER_DATA_SPEAKER;
+ break;
+ case ID_AR:
+ data.icon = ICON_OUTLINER_DATA_ARMATURE;
+ break;
+ case ID_CA:
+ data.icon = ICON_OUTLINER_DATA_CAMERA;
+ break;
+ case ID_KE:
+ data.icon = ICON_SHAPEKEY_DATA;
+ break;
+ case ID_WO:
+ data.icon = ICON_WORLD_DATA;
+ break;
+ case ID_AC:
+ data.icon = ICON_ACTION;
+ break;
+ case ID_NLA:
+ data.icon = ICON_NLA;
+ break;
+ case ID_TXT:
+ data.icon = ICON_SCRIPT;
+ break;
+ case ID_GR:
+ data.icon = ICON_GROUP;
+ break;
+ case ID_LI:
+ if (tselem->id->tag & LIB_TAG_MISSING) {
+ data.icon = ICON_LIBRARY_DATA_BROKEN;
+ }
+ else if (((Library *)tselem->id)->parent) {
+ data.icon = ICON_LIBRARY_DATA_INDIRECT;
+ }
+ else {
+ data.icon = ICON_LIBRARY_DATA_DIRECT;
+ }
+ break;
+ case ID_LS:
+ data.icon = ICON_LINE_DATA;
+ break;
+ case ID_GD:
+ data.icon = ICON_OUTLINER_DATA_GREASEPENCIL;
+ break;
+ case ID_LP: {
+ LightProbe *lp = (LightProbe *)tselem->id;
+ switch (lp->type) {
+ case LIGHTPROBE_TYPE_CUBE:
+ data.icon = ICON_LIGHTPROBE_CUBEMAP;
+ break;
+ case LIGHTPROBE_TYPE_PLANAR:
+ data.icon = ICON_LIGHTPROBE_PLANAR;
+ break;
+ case LIGHTPROBE_TYPE_GRID:
+ data.icon = ICON_LIGHTPROBE_GRID;
+ break;
+ default:
+ data.icon = ICON_LIGHTPROBE_CUBEMAP;
+ break;
+ }
+ break;
+ }
+ case ID_BR:
+ data.icon = ICON_BRUSH_DATA;
+ break;
+ case ID_SCR:
+ case ID_WS:
+ data.icon = ICON_WORKSPACE;
+ break;
+ case ID_MSK:
+ data.icon = ICON_MOD_MASK;
+ break;
+ case ID_MC:
+ data.icon = ICON_SEQUENCE;
+ break;
+ case ID_PC:
+ data.icon = ICON_CURVE_BEZCURVE;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return data;
}
-static void tselem_draw_icon(
- uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te,
- float alpha, const bool is_clickable)
+static void tselem_draw_icon(uiBlock *block,
+ int xmax,
+ float x,
+ float y,
+ TreeStoreElem *tselem,
+ TreeElement *te,
+ float alpha,
+ const bool is_clickable)
{
- TreeElementIcon data = tree_element_get_icon(tselem, te);
-
- if (data.icon == 0) {
- return;
- }
-
- if (!is_clickable || x >= xmax) {
- /* placement of icons, copied from interface_widgets.c */
- float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
- x += 2.0f * aspect;
- y += 2.0f * aspect;
-
- /* restrict column clip... it has been coded by simply overdrawing,
- * doesn't work for buttons */
- UI_icon_draw_alpha(x, y, data.icon, alpha);
- }
- else {
- uiDefIconBut(
- block, UI_BTYPE_LABEL, 0, data.icon, x, y, UI_UNIT_X, UI_UNIT_Y, NULL,
- 0.0, 0.0, 1.0, alpha,
- (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->name : "");
- }
+ TreeElementIcon data = tree_element_get_icon(tselem, te);
+
+ if (data.icon == 0) {
+ return;
+ }
+
+ if (!is_clickable || x >= xmax) {
+ /* placement of icons, copied from interface_widgets.c */
+ float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
+ x += 2.0f * aspect;
+ y += 2.0f * aspect;
+
+ /* restrict column clip... it has been coded by simply overdrawing,
+ * doesn't work for buttons */
+ UI_icon_draw_alpha(x, y, data.icon, alpha);
+ }
+ else {
+ uiDefIconBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ data.icon,
+ x,
+ y,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 1.0,
+ alpha,
+ (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->name : "");
+ }
}
/**
* For icon-only children of a collapsed tree,
* Draw small number over the icon to show how many items of this type are displayed.
*/
-static void outliner_draw_iconrow_number(
- const uiFontStyle *fstyle,
- int offsx, int ys,
- const int num_elements)
+static void outliner_draw_iconrow_number(const uiFontStyle *fstyle,
+ int offsx,
+ int ys,
+ const int num_elements)
{
- float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- float ufac = 0.25f * UI_UNIT_X;
- float offset_x = (float) offsx + UI_UNIT_X * 0.35f;
-
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- offset_x + ufac,
- (float)ys - UI_UNIT_Y * 0.2f + ufac,
- offset_x + UI_UNIT_X - ufac,
- (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 2.0f - ufac,
- color);
-
- /* Now the numbers. */
- unsigned char text_col[4];
-
- UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
- text_col[3] = 255;
-
- uiFontStyle fstyle_small = *fstyle;
- fstyle_small.points *= 0.8f;
-
- /* We treat +99 as 4 digits to make sure the (eyeballed) alignment looks nice. */
- int num_digits = 4;
- char number_text[4] = "+99\0";
- if (num_elements < 100) {
- BLI_snprintf(number_text, sizeof(number_text), "%d", num_elements);
- num_digits = num_elements < 10 ? 1 : 2;
- }
- UI_fontstyle_draw_simple(&fstyle_small,
- (offset_x + ufac + UI_UNIT_X * (2 - num_digits) * 0.12f),
- (float)ys - UI_UNIT_Y * 0.095f + ufac,
- number_text, text_col);
- UI_fontstyle_set(fstyle);
- GPU_blend(true); /* Roundbox and text drawing disables. */
+ float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ float ufac = 0.25f * UI_UNIT_X;
+ float offset_x = (float)offsx + UI_UNIT_X * 0.35f;
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
+ offset_x + ufac,
+ (float)ys - UI_UNIT_Y * 0.2f + ufac,
+ offset_x + UI_UNIT_X - ufac,
+ (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
+ (float)UI_UNIT_Y / 2.0f - ufac,
+ color);
+
+ /* Now the numbers. */
+ unsigned char text_col[4];
+
+ UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
+ text_col[3] = 255;
+
+ uiFontStyle fstyle_small = *fstyle;
+ fstyle_small.points *= 0.8f;
+
+ /* We treat +99 as 4 digits to make sure the (eyeballed) alignment looks nice. */
+ int num_digits = 4;
+ char number_text[4] = "+99\0";
+ if (num_elements < 100) {
+ BLI_snprintf(number_text, sizeof(number_text), "%d", num_elements);
+ num_digits = num_elements < 10 ? 1 : 2;
+ }
+ UI_fontstyle_draw_simple(&fstyle_small,
+ (offset_x + ufac + UI_UNIT_X * (2 - num_digits) * 0.12f),
+ (float)ys - UI_UNIT_Y * 0.095f + ufac,
+ number_text,
+ text_col);
+ UI_fontstyle_set(fstyle);
+ GPU_blend(true); /* Roundbox and text drawing disables. */
}
-static void outliner_draw_iconrow_doit(
- uiBlock *block, TreeElement *te,
- const uiFontStyle *fstyle,
- int xmax, int *offsx, int ys, float alpha_fac,
- const eOLDrawState active,
- const int num_elements)
+static void outliner_draw_iconrow_doit(uiBlock *block,
+ TreeElement *te,
+ const uiFontStyle *fstyle,
+ int xmax,
+ int *offsx,
+ int ys,
+ float alpha_fac,
+ const eOLDrawState active,
+ const int num_elements)
{
- TreeStoreElem *tselem = TREESTORE(te);
-
- if (active != OL_DRAWSEL_NONE) {
- float ufac = UI_UNIT_X / 20.0f;
- float color[4] = {1.0f, 1.0f, 1.0f, 0.2f};
-
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- color[3] *= alpha_fac;
-
- UI_draw_roundbox_aa(true,
- (float) *offsx + 1.0f * ufac,
- (float)ys + 1.0f * ufac,
- (float)*offsx + UI_UNIT_X - 1.0f * ufac,
- (float)ys + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 2.0f - ufac,
- color);
- GPU_blend(true); /* Roundbox disables. */
- }
-
- /* No inlined icon should be clickable. */
- tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.8f * alpha_fac, false);
- te->xs = *offsx;
- te->ys = ys;
- te->xend = (short)*offsx + UI_UNIT_X;
-
- if (num_elements > 1) {
- outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
- }
- (*offsx) += UI_UNIT_X;
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (active != OL_DRAWSEL_NONE) {
+ float ufac = UI_UNIT_X / 20.0f;
+ float color[4] = {1.0f, 1.0f, 1.0f, 0.2f};
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ color[3] *= alpha_fac;
+
+ UI_draw_roundbox_aa(true,
+ (float)*offsx + 1.0f * ufac,
+ (float)ys + 1.0f * ufac,
+ (float)*offsx + UI_UNIT_X - 1.0f * ufac,
+ (float)ys + UI_UNIT_Y - ufac,
+ (float)UI_UNIT_Y / 2.0f - ufac,
+ color);
+ GPU_blend(true); /* Roundbox disables. */
+ }
+
+ /* No inlined icon should be clickable. */
+ tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.8f * alpha_fac, false);
+ te->xs = *offsx;
+ te->ys = ys;
+ te->xend = (short)*offsx + UI_UNIT_X;
+
+ if (num_elements > 1) {
+ outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
+ }
+ (*offsx) += UI_UNIT_X;
}
/**
@@ -1591,675 +1912,764 @@ static void outliner_draw_iconrow_doit(
*/
static int tree_element_id_type_to_index(TreeElement *te)
{
- TreeStoreElem *tselem = TREESTORE(te);
-
- const int id_index = tselem->type == 0 ? BKE_idcode_to_index(te->idcode) : INDEX_ID_GR;
- if (id_index < INDEX_ID_OB) {
- return id_index;
- }
- else if (id_index == INDEX_ID_OB) {
- const Object *ob = (Object *)tselem->id;
- return INDEX_ID_OB + ob->type;
- }
- else {
- return id_index + OB_TYPE_MAX;
- }
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ const int id_index = tselem->type == 0 ? BKE_idcode_to_index(te->idcode) : INDEX_ID_GR;
+ if (id_index < INDEX_ID_OB) {
+ return id_index;
+ }
+ else if (id_index == INDEX_ID_OB) {
+ const Object *ob = (Object *)tselem->id;
+ return INDEX_ID_OB + ob->type;
+ }
+ else {
+ return id_index + OB_TYPE_MAX;
+ }
}
typedef struct MergedIconRow {
- eOLDrawState active[INDEX_ID_MAX + OB_TYPE_MAX];
- int num_elements[INDEX_ID_MAX + OB_TYPE_MAX];
- TreeElement *tree_element[INDEX_ID_MAX + OB_TYPE_MAX];
+ eOLDrawState active[INDEX_ID_MAX + OB_TYPE_MAX];
+ int num_elements[INDEX_ID_MAX + OB_TYPE_MAX];
+ TreeElement *tree_element[INDEX_ID_MAX + OB_TYPE_MAX];
} MergedIconRow;
-static void outliner_draw_iconrow(
- bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops,
- ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac, MergedIconRow *merged)
+static void outliner_draw_iconrow(bContext *C,
+ uiBlock *block,
+ const uiFontStyle *fstyle,
+ Scene *scene,
+ ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ ListBase *lb,
+ int level,
+ int xmax,
+ int *offsx,
+ int ys,
+ float alpha_fac,
+ MergedIconRow *merged)
{
- eOLDrawState active;
- const Object *obact = OBACT(view_layer);
-
- for (TreeElement *te = lb->first; te; te = te->next) {
- /* exit drawing early */
- if ((*offsx) - UI_UNIT_X > xmax) {
- break;
- }
-
- TreeStoreElem *tselem = TREESTORE(te);
-
- /* object hierarchy always, further constrained on level */
- if (level < 1 || (tselem->type == 0 && te->idcode == ID_OB)) {
- /* active blocks get white circle */
- if (tselem->type == 0) {
- if (te->idcode == ID_OB) {
- active = (OBACT(view_layer) == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
- }
- else if (is_object_data_in_editmode(tselem->id, obact)) {
- active = OL_DRAWSEL_NORMAL;
- }
- else {
- active = tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NONE, false);
- }
- }
- else {
- active = tree_element_type_active(C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false);
- }
-
- if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION, TSE_R_LAYER)) {
- outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1);
- }
- else {
- const int index = tree_element_id_type_to_index(te);
- merged->num_elements[index]++;
- if ((merged->tree_element[index] == NULL) ||
- (active > merged->active[index]))
- {
- merged->tree_element[index] = te;
- }
- merged->active[index] = MAX2(active, merged->active[index]);
- }
- }
-
- /* this tree element always has same amount of branches, so don't draw */
- if (tselem->type != TSE_R_LAYER) {
- outliner_draw_iconrow(
- C, block, fstyle, scene, view_layer, soops,
- &te->subtree, level + 1, xmax, offsx, ys, alpha_fac, merged);
- }
- }
-
- if (level == 0) {
- for (int i = 0; i < INDEX_ID_MAX; i++) {
- const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1;
- /* See tree_element_id_type_to_index for the index logic. */
- int index_base = i;
- if (i > INDEX_ID_OB) {
- index_base += OB_TYPE_MAX;
- }
- for (int j = 0; j < num_subtypes; j++) {
- const int index = index_base + j;
- if (merged->num_elements[index] != 0) {
- outliner_draw_iconrow_doit(block,
- merged->tree_element[index],
- fstyle,
- xmax, offsx, ys, alpha_fac,
- merged->active[index],
- merged->num_elements[index]);
- }
- }
- }
- }
+ eOLDrawState active;
+ const Object *obact = OBACT(view_layer);
+
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ /* exit drawing early */
+ if ((*offsx) - UI_UNIT_X > xmax) {
+ break;
+ }
+
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ /* object hierarchy always, further constrained on level */
+ if (level < 1 || (tselem->type == 0 && te->idcode == ID_OB)) {
+ /* active blocks get white circle */
+ if (tselem->type == 0) {
+ if (te->idcode == ID_OB) {
+ active = (OBACT(view_layer) == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL :
+ OL_DRAWSEL_NONE;
+ }
+ else if (is_object_data_in_editmode(tselem->id, obact)) {
+ active = OL_DRAWSEL_NORMAL;
+ }
+ else {
+ active = tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NONE, false);
+ }
+ }
+ else {
+ active = tree_element_type_active(
+ C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false);
+ }
+
+ if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION, TSE_R_LAYER)) {
+ outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1);
+ }
+ else {
+ const int index = tree_element_id_type_to_index(te);
+ merged->num_elements[index]++;
+ if ((merged->tree_element[index] == NULL) || (active > merged->active[index])) {
+ merged->tree_element[index] = te;
+ }
+ merged->active[index] = MAX2(active, merged->active[index]);
+ }
+ }
+
+ /* this tree element always has same amount of branches, so don't draw */
+ if (tselem->type != TSE_R_LAYER) {
+ outliner_draw_iconrow(C,
+ block,
+ fstyle,
+ scene,
+ view_layer,
+ soops,
+ &te->subtree,
+ level + 1,
+ xmax,
+ offsx,
+ ys,
+ alpha_fac,
+ merged);
+ }
+ }
+
+ if (level == 0) {
+ for (int i = 0; i < INDEX_ID_MAX; i++) {
+ const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1;
+ /* See tree_element_id_type_to_index for the index logic. */
+ int index_base = i;
+ if (i > INDEX_ID_OB) {
+ index_base += OB_TYPE_MAX;
+ }
+ for (int j = 0; j < num_subtypes; j++) {
+ const int index = index_base + j;
+ if (merged->num_elements[index] != 0) {
+ outliner_draw_iconrow_doit(block,
+ merged->tree_element[index],
+ fstyle,
+ xmax,
+ offsx,
+ ys,
+ alpha_fac,
+ merged->active[index],
+ merged->num_elements[index]);
+ }
+ }
+ }
+ }
}
/* closed tree element */
static void outliner_set_coord_tree_element(TreeElement *te, int startx, int starty)
{
- TreeElement *ten;
-
- /* closed items may be displayed in row of parent, don't change their coordinate! */
- if ((te->flag & TE_ICONROW) == 0) {
- /* store coord and continue, we need coordinates for elements outside view too */
- te->xs = startx;
- te->ys = starty;
- }
-
- for (ten = te->subtree.first; ten; ten = ten->next) {
- outliner_set_coord_tree_element(ten, startx + UI_UNIT_X, starty);
- }
+ TreeElement *ten;
+
+ /* closed items may be displayed in row of parent, don't change their coordinate! */
+ if ((te->flag & TE_ICONROW) == 0) {
+ /* store coord and continue, we need coordinates for elements outside view too */
+ te->xs = startx;
+ te->ys = starty;
+ }
+
+ for (ten = te->subtree.first; ten; ten = ten->next) {
+ outliner_set_coord_tree_element(ten, startx + UI_UNIT_X, starty);
+ }
}
-
-static void outliner_draw_tree_element(
- bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer,
- ARegion *ar, SpaceOutliner *soops, TreeElement *te, bool draw_grayed_out,
- int startx, int *starty, TreeElement **te_edit)
+static void outliner_draw_tree_element(bContext *C,
+ uiBlock *block,
+ const uiFontStyle *fstyle,
+ Scene *scene,
+ ViewLayer *view_layer,
+ ARegion *ar,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ bool draw_grayed_out,
+ int startx,
+ int *starty,
+ TreeElement **te_edit)
{
- TreeStoreElem *tselem;
- float ufac = UI_UNIT_X / 20.0f;
- int offsx = 0;
- eOLDrawState active = OL_DRAWSEL_NONE;
- float color[4];
- tselem = TREESTORE(te);
-
- if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) {
- const float alpha_fac = ((te->flag & TE_DISABLED) || draw_grayed_out) ? 0.5f : 1.0f;
- const float alpha = 0.5f * alpha_fac;
- int xmax = ar->v2d.cur.xmax;
-
- if ((tselem->flag & TSE_TEXTBUT) && (*te_edit == NULL)) {
- *te_edit = te;
- }
-
- /* icons can be ui buts, we don't want it to overlap with restrict */
- if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
- xmax -= OL_TOGW + UI_UNIT_X;
- }
-
- GPU_blend(true);
-
- /* colors for active/selected data */
- if (tselem->type == 0) {
- const Object *obact = OBACT(view_layer);
- if (te->idcode == ID_SCE) {
- if (tselem->id == (ID *)scene) {
- rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
- active = OL_DRAWSEL_ACTIVE;
- }
- }
- else if (te->idcode == ID_OB) {
- Object *ob = (Object *)tselem->id;
- Base *base = BKE_view_layer_base_find(view_layer, ob);
- const bool is_selected = (base != NULL) && ((base->flag & BASE_SELECTED) != 0);
-
- if (ob == obact || is_selected) {
- uchar col[4] = {0, 0, 0, 0};
-
- /* outliner active ob: always white text, circle color now similar to view3d */
-
- active = OL_DRAWSEL_ACTIVE;
- if (ob == obact) {
- if (is_selected) {
- UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col);
- col[3] = alpha;
- }
-
- active = OL_DRAWSEL_NORMAL;
- }
- else if (is_selected) {
- UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
- col[3] = alpha;
- }
- rgba_float_args_set(color, (float)col[0] / 255, (float)col[1] / 255, (float)col[2] / 255, alpha);
- }
- }
- else if (is_object_data_in_editmode(tselem->id, obact)) {
- rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
- active = OL_DRAWSEL_ACTIVE;
- }
- else {
- if (tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NONE, false)) {
- rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
- active = OL_DRAWSEL_ACTIVE;
- }
- }
- }
- else {
- active = tree_element_type_active(C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false);
- rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
- }
-
- /* active circle */
- if (active != OL_DRAWSEL_NONE) {
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(
- true,
- (float)startx + UI_UNIT_X + 1.0f * ufac,
- (float)*starty + 1.0f * ufac,
- (float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac,
- (float)*starty + UI_UNIT_Y - 1.0f * ufac,
- UI_UNIT_Y / 2.0f - 1.0f * ufac, color);
- GPU_blend(true); /* roundbox disables it */
-
- te->flag |= TE_ACTIVE; // for lookup in display hierarchies
- }
-
- if (tselem->type == TSE_VIEW_COLLECTION_BASE) {
- /* Scene collection in view layer can't expand/collapse. */
- }
- else if (te->subtree.first || (tselem->type == 0 && te->idcode == ID_SCE) || (te->flag & TE_LAZY_CLOSED)) {
- /* open/close icon, only when sublevels, except for scene */
- int icon_x = startx;
-
- // icons a bit higher
- if (TSELEM_OPEN(tselem, soops)) {
- UI_icon_draw_alpha(
- (float)icon_x + 2 * ufac, (float)*starty + 1 * ufac, ICON_DISCLOSURE_TRI_DOWN,
- alpha_fac);
- }
- else {
- UI_icon_draw_alpha(
- (float)icon_x + 2 * ufac, (float)*starty + 1 * ufac, ICON_DISCLOSURE_TRI_RIGHT,
- alpha_fac);
- }
- }
- offsx += UI_UNIT_X;
-
- /* datatype icon */
-
- if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
- tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac, true);
- offsx += UI_UNIT_X + 4 * ufac;
- }
- else {
- offsx += 2 * ufac;
- }
-
- if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_LINKED(tselem->id)) {
- if (tselem->id->tag & LIB_TAG_MISSING) {
- UI_icon_draw_alpha(
- (float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_BROKEN,
- alpha_fac);
- }
- else if (tselem->id->tag & LIB_TAG_INDIRECT) {
- UI_icon_draw_alpha(
- (float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_INDIRECT,
- alpha_fac);
- }
- else {
- UI_icon_draw_alpha(
- (float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_DIRECT,
- alpha_fac);
- }
- offsx += UI_UNIT_X + 4 * ufac;
- }
- else if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_STATIC_OVERRIDE(tselem->id)) {
- UI_icon_draw_alpha(
- (float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_OVERRIDE,
- alpha_fac);
- offsx += UI_UNIT_X + 4 * ufac;
- }
- GPU_blend(false);
-
- /* name */
- if ((tselem->flag & TSE_TEXTBUT) == 0) {
- unsigned char text_col[4];
-
- if (active == OL_DRAWSEL_NORMAL) {
- UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
- }
- else if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
- UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.75f, text_col);
- text_col[3] = 255;
- }
- else {
- UI_GetThemeColor4ubv(TH_TEXT, text_col);
- }
- text_col[3] *= alpha_fac;
-
- UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name, text_col);
- }
-
- offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
-
- /* closed item, we draw the icons, not when it's a scene, or master-server list though */
- if (!TSELEM_OPEN(tselem, soops)) {
- if (te->subtree.first) {
- if (tselem->type == 0 && te->idcode == ID_SCE) {
- /* pass */
- }
- /* this tree element always has same amount of branches, so don't draw */
- else if (tselem->type != TSE_R_LAYER) {
- int tempx = startx + offsx;
-
- GPU_blend(true);
-
- /* divider */
- {
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- unsigned char col[4];
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- UI_GetThemeColorShade4ubv(TH_BACK, -40, col);
- col[3] *= alpha_fac;
-
- immUniformColor4ubv(col);
- immRecti(pos, tempx - 10.0f * ufac,
- *starty + 4.0f * ufac,
- tempx - 8.0f * ufac,
- *starty + UI_UNIT_Y - 4.0f * ufac);
- immUnbindProgram();
- }
-
- MergedIconRow merged = {{0}};
- outliner_draw_iconrow(
- C, block, fstyle, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx,
- *starty, alpha_fac, &merged);
-
- GPU_blend(false);
- }
- }
- }
- }
- /* store coord and continue, we need coordinates for elements outside view too */
- te->xs = startx;
- te->ys = *starty;
- te->xend = startx + offsx;
-
- if (TSELEM_OPEN(tselem, soops)) {
- *starty -= UI_UNIT_Y;
-
- for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
- /* check if element needs to be drawn grayed out, but also gray out
- * childs of a grayed out parent (pass on draw_grayed_out to childs) */
- bool draw_childs_grayed_out = draw_grayed_out || (ten->flag & TE_DRAGGING);
- outliner_draw_tree_element(
- C, block, fstyle, scene, view_layer,
- ar, soops, ten, draw_childs_grayed_out,
- startx + UI_UNIT_X, starty, te_edit);
- }
- }
- else {
- for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
- outliner_set_coord_tree_element(ten, startx, *starty);
- }
-
- *starty -= UI_UNIT_Y;
- }
+ TreeStoreElem *tselem;
+ float ufac = UI_UNIT_X / 20.0f;
+ int offsx = 0;
+ eOLDrawState active = OL_DRAWSEL_NONE;
+ float color[4];
+ tselem = TREESTORE(te);
+
+ if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) {
+ const float alpha_fac = ((te->flag & TE_DISABLED) || draw_grayed_out) ? 0.5f : 1.0f;
+ const float alpha = 0.5f * alpha_fac;
+ int xmax = ar->v2d.cur.xmax;
+
+ if ((tselem->flag & TSE_TEXTBUT) && (*te_edit == NULL)) {
+ *te_edit = te;
+ }
+
+ /* icons can be ui buts, we don't want it to overlap with restrict */
+ if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
+ xmax -= OL_TOGW + UI_UNIT_X;
+ }
+
+ GPU_blend(true);
+
+ /* colors for active/selected data */
+ if (tselem->type == 0) {
+ const Object *obact = OBACT(view_layer);
+ if (te->idcode == ID_SCE) {
+ if (tselem->id == (ID *)scene) {
+ rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
+ active = OL_DRAWSEL_ACTIVE;
+ }
+ }
+ else if (te->idcode == ID_OB) {
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ const bool is_selected = (base != NULL) && ((base->flag & BASE_SELECTED) != 0);
+
+ if (ob == obact || is_selected) {
+ uchar col[4] = {0, 0, 0, 0};
+
+ /* outliner active ob: always white text, circle color now similar to view3d */
+
+ active = OL_DRAWSEL_ACTIVE;
+ if (ob == obact) {
+ if (is_selected) {
+ UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col);
+ col[3] = alpha;
+ }
+
+ active = OL_DRAWSEL_NORMAL;
+ }
+ else if (is_selected) {
+ UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
+ col[3] = alpha;
+ }
+ rgba_float_args_set(
+ color, (float)col[0] / 255, (float)col[1] / 255, (float)col[2] / 255, alpha);
+ }
+ }
+ else if (is_object_data_in_editmode(tselem->id, obact)) {
+ rgba_float_args_set(color, 1.0f, 1.0f, 1.0f, alpha);
+ active = OL_DRAWSEL_ACTIVE;
+ }
+ else {
+ if (tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NONE, false)) {
+ rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
+ active = OL_DRAWSEL_ACTIVE;
+ }
+ }
+ }
+ else {
+ active = tree_element_type_active(
+ C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false);
+ rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
+ }
+
+ /* active circle */
+ if (active != OL_DRAWSEL_NONE) {
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
+ (float)startx + UI_UNIT_X + 1.0f * ufac,
+ (float)*starty + 1.0f * ufac,
+ (float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac,
+ (float)*starty + UI_UNIT_Y - 1.0f * ufac,
+ UI_UNIT_Y / 2.0f - 1.0f * ufac,
+ color);
+ GPU_blend(true); /* roundbox disables it */
+
+ te->flag |= TE_ACTIVE; // for lookup in display hierarchies
+ }
+
+ if (tselem->type == TSE_VIEW_COLLECTION_BASE) {
+ /* Scene collection in view layer can't expand/collapse. */
+ }
+ else if (te->subtree.first || (tselem->type == 0 && te->idcode == ID_SCE) ||
+ (te->flag & TE_LAZY_CLOSED)) {
+ /* open/close icon, only when sublevels, except for scene */
+ int icon_x = startx;
+
+ // icons a bit higher
+ if (TSELEM_OPEN(tselem, soops)) {
+ UI_icon_draw_alpha((float)icon_x + 2 * ufac,
+ (float)*starty + 1 * ufac,
+ ICON_DISCLOSURE_TRI_DOWN,
+ alpha_fac);
+ }
+ else {
+ UI_icon_draw_alpha((float)icon_x + 2 * ufac,
+ (float)*starty + 1 * ufac,
+ ICON_DISCLOSURE_TRI_RIGHT,
+ alpha_fac);
+ }
+ }
+ offsx += UI_UNIT_X;
+
+ /* datatype icon */
+
+ if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
+ tselem_draw_icon(
+ block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac, true);
+ offsx += UI_UNIT_X + 4 * ufac;
+ }
+ else {
+ offsx += 2 * ufac;
+ }
+
+ if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_LINKED(tselem->id)) {
+ if (tselem->id->tag & LIB_TAG_MISSING) {
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
+ (float)*starty + 2 * ufac,
+ ICON_LIBRARY_DATA_BROKEN,
+ alpha_fac);
+ }
+ else if (tselem->id->tag & LIB_TAG_INDIRECT) {
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
+ (float)*starty + 2 * ufac,
+ ICON_LIBRARY_DATA_INDIRECT,
+ alpha_fac);
+ }
+ else {
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
+ (float)*starty + 2 * ufac,
+ ICON_LIBRARY_DATA_DIRECT,
+ alpha_fac);
+ }
+ offsx += UI_UNIT_X + 4 * ufac;
+ }
+ else if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_STATIC_OVERRIDE(tselem->id)) {
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
+ (float)*starty + 2 * ufac,
+ ICON_LIBRARY_DATA_OVERRIDE,
+ alpha_fac);
+ offsx += UI_UNIT_X + 4 * ufac;
+ }
+ GPU_blend(false);
+
+ /* name */
+ if ((tselem->flag & TSE_TEXTBUT) == 0) {
+ unsigned char text_col[4];
+
+ if (active == OL_DRAWSEL_NORMAL) {
+ UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
+ }
+ else if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
+ UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.75f, text_col);
+ text_col[3] = 255;
+ }
+ else {
+ UI_GetThemeColor4ubv(TH_TEXT, text_col);
+ }
+ text_col[3] *= alpha_fac;
+
+ UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name, text_col);
+ }
+
+ offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
+
+ /* closed item, we draw the icons, not when it's a scene, or master-server list though */
+ if (!TSELEM_OPEN(tselem, soops)) {
+ if (te->subtree.first) {
+ if (tselem->type == 0 && te->idcode == ID_SCE) {
+ /* pass */
+ }
+ /* this tree element always has same amount of branches, so don't draw */
+ else if (tselem->type != TSE_R_LAYER) {
+ int tempx = startx + offsx;
+
+ GPU_blend(true);
+
+ /* divider */
+ {
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(
+ format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ unsigned char col[4];
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ UI_GetThemeColorShade4ubv(TH_BACK, -40, col);
+ col[3] *= alpha_fac;
+
+ immUniformColor4ubv(col);
+ immRecti(pos,
+ tempx - 10.0f * ufac,
+ *starty + 4.0f * ufac,
+ tempx - 8.0f * ufac,
+ *starty + UI_UNIT_Y - 4.0f * ufac);
+ immUnbindProgram();
+ }
+
+ MergedIconRow merged = {{0}};
+ outliner_draw_iconrow(C,
+ block,
+ fstyle,
+ scene,
+ view_layer,
+ soops,
+ &te->subtree,
+ 0,
+ xmax,
+ &tempx,
+ *starty,
+ alpha_fac,
+ &merged);
+
+ GPU_blend(false);
+ }
+ }
+ }
+ }
+ /* store coord and continue, we need coordinates for elements outside view too */
+ te->xs = startx;
+ te->ys = *starty;
+ te->xend = startx + offsx;
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ *starty -= UI_UNIT_Y;
+
+ for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
+ /* check if element needs to be drawn grayed out, but also gray out
+ * childs of a grayed out parent (pass on draw_grayed_out to childs) */
+ bool draw_childs_grayed_out = draw_grayed_out || (ten->flag & TE_DRAGGING);
+ outliner_draw_tree_element(C,
+ block,
+ fstyle,
+ scene,
+ view_layer,
+ ar,
+ soops,
+ ten,
+ draw_childs_grayed_out,
+ startx + UI_UNIT_X,
+ starty,
+ te_edit);
+ }
+ }
+ else {
+ for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
+ outliner_set_coord_tree_element(ten, startx, *starty);
+ }
+
+ *starty -= UI_UNIT_Y;
+ }
}
-static void outliner_draw_hierarchy_lines_recursive(
- unsigned pos, SpaceOutliner *soops, ListBase *lb, int startx,
- const unsigned char col[4], bool draw_grayed_out,
- int *starty)
+static void outliner_draw_hierarchy_lines_recursive(unsigned pos,
+ SpaceOutliner *soops,
+ ListBase *lb,
+ int startx,
+ const unsigned char col[4],
+ bool draw_grayed_out,
+ int *starty)
{
- TreeElement *te, *te_vertical_line_last = NULL;
- int y1, y2;
-
- if (BLI_listbase_is_empty(lb)) {
- return;
- }
-
- const unsigned char grayed_alpha = col[3] / 2;
-
- /* For vertical lines between objects. */
- y1 = y2 = *starty;
- for (te = lb->first; te; te = te->next) {
- bool draw_childs_grayed_out = draw_grayed_out || (te->flag & TE_DRAGGING);
- TreeStoreElem *tselem = TREESTORE(te);
-
- if (draw_childs_grayed_out) {
- immUniformColor3ubvAlpha(col, grayed_alpha);
- }
- else {
- immUniformColor4ubv(col);
- }
-
- /* Horizontal Line? */
- if (tselem->type == 0 && (te->idcode == ID_OB || te->idcode == ID_SCE)) {
- immRecti(pos, startx, *starty, startx + UI_UNIT_X, *starty - 1);
-
- /* Vertical Line? */
- if (te->idcode == ID_OB) {
- te_vertical_line_last = te;
- y2 = *starty;
- }
- }
-
- *starty -= UI_UNIT_Y;
-
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_draw_hierarchy_lines_recursive(
- pos, soops, &te->subtree, startx + UI_UNIT_X,
- col, draw_childs_grayed_out, starty);
- }
- }
-
- if (draw_grayed_out) {
- immUniformColor3ubvAlpha(col, grayed_alpha);
- }
- else {
- immUniformColor4ubv(col);
- }
-
- /* Vertical line. */
- te = te_vertical_line_last;
- if ((te != NULL) && (te->parent || lb->first != lb->last)) {
- immRecti(pos, startx, y1 + UI_UNIT_Y, startx + 1, y2);
- }
+ TreeElement *te, *te_vertical_line_last = NULL;
+ int y1, y2;
+
+ if (BLI_listbase_is_empty(lb)) {
+ return;
+ }
+
+ const unsigned char grayed_alpha = col[3] / 2;
+
+ /* For vertical lines between objects. */
+ y1 = y2 = *starty;
+ for (te = lb->first; te; te = te->next) {
+ bool draw_childs_grayed_out = draw_grayed_out || (te->flag & TE_DRAGGING);
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (draw_childs_grayed_out) {
+ immUniformColor3ubvAlpha(col, grayed_alpha);
+ }
+ else {
+ immUniformColor4ubv(col);
+ }
+
+ /* Horizontal Line? */
+ if (tselem->type == 0 && (te->idcode == ID_OB || te->idcode == ID_SCE)) {
+ immRecti(pos, startx, *starty, startx + UI_UNIT_X, *starty - 1);
+
+ /* Vertical Line? */
+ if (te->idcode == ID_OB) {
+ te_vertical_line_last = te;
+ y2 = *starty;
+ }
+ }
+
+ *starty -= UI_UNIT_Y;
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_draw_hierarchy_lines_recursive(
+ pos, soops, &te->subtree, startx + UI_UNIT_X, col, draw_childs_grayed_out, starty);
+ }
+ }
+
+ if (draw_grayed_out) {
+ immUniformColor3ubvAlpha(col, grayed_alpha);
+ }
+ else {
+ immUniformColor4ubv(col);
+ }
+
+ /* Vertical line. */
+ te = te_vertical_line_last;
+ if ((te != NULL) && (te->parent || lb->first != lb->last)) {
+ immRecti(pos, startx, y1 + UI_UNIT_Y, startx + 1, y2);
+ }
}
-static void outliner_draw_hierarchy_lines(SpaceOutliner *soops, ListBase *lb, int startx, int *starty)
+static void outliner_draw_hierarchy_lines(SpaceOutliner *soops,
+ ListBase *lb,
+ int startx,
+ int *starty)
{
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- unsigned char col[4];
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ unsigned char col[4];
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.4f, col);
- col[3] = 255;
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.4f, col);
+ col[3] = 255;
- GPU_blend(true);
- outliner_draw_hierarchy_lines_recursive(pos, soops, lb, startx, col, false, starty);
- GPU_blend(false);
+ GPU_blend(true);
+ outliner_draw_hierarchy_lines_recursive(pos, soops, lb, startx, col, false, starty);
+ GPU_blend(false);
- immUnbindProgram();
+ immUnbindProgram();
}
-static void outliner_draw_struct_marks(ARegion *ar, SpaceOutliner *soops, ListBase *lb, int *starty)
+static void outliner_draw_struct_marks(ARegion *ar,
+ SpaceOutliner *soops,
+ ListBase *lb,
+ int *starty)
{
- for (TreeElement *te = lb->first; te; te = te->next) {
- TreeStoreElem *tselem = TREESTORE(te);
-
- /* selection status */
- if (TSELEM_OPEN(tselem, soops)) {
- if (tselem->type == TSE_RNA_STRUCT) {
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immThemeColorShadeAlpha(TH_BACK, -15, -200);
- immRecti(pos, 0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
- immUnbindProgram();
- }
- }
-
- *starty -= UI_UNIT_Y;
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
- if (tselem->type == TSE_RNA_STRUCT) {
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immThemeColorShadeAlpha(TH_BACK, -15, -200);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, 0, (float)*starty + UI_UNIT_Y);
- immVertex2f(pos, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
- immEnd();
-
- immUnbindProgram();
- }
- }
- }
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ /* selection status */
+ if (TSELEM_OPEN(tselem, soops)) {
+ if (tselem->type == TSE_RNA_STRUCT) {
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immThemeColorShadeAlpha(TH_BACK, -15, -200);
+ immRecti(pos, 0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
+ immUnbindProgram();
+ }
+ }
+
+ *starty -= UI_UNIT_Y;
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
+ if (tselem->type == TSE_RNA_STRUCT) {
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immThemeColorShadeAlpha(TH_BACK, -15, -200);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, 0, (float)*starty + UI_UNIT_Y);
+ immVertex2f(pos, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
+ immEnd();
+
+ immUnbindProgram();
+ }
+ }
+ }
}
-static void outliner_draw_highlights_recursive(
- unsigned pos, const ARegion *ar, const SpaceOutliner *soops, const ListBase *lb,
- const float col_selection[4], const float col_highlight[4], const float col_searchmatch[4],
- int start_x, int *io_start_y)
+static void outliner_draw_highlights_recursive(unsigned pos,
+ const ARegion *ar,
+ const SpaceOutliner *soops,
+ const ListBase *lb,
+ const float col_selection[4],
+ const float col_highlight[4],
+ const float col_searchmatch[4],
+ int start_x,
+ int *io_start_y)
{
- const bool is_searching = (
- SEARCHING_OUTLINER(soops) ||
- (soops->outlinevis == SO_DATA_API &&
- soops->search_string[0] != 0));
-
- for (TreeElement *te = lb->first; te; te = te->next) {
- const TreeStoreElem *tselem = TREESTORE(te);
- const int start_y = *io_start_y;
-
- /* selection status */
- if (tselem->flag & TSE_SELECTED) {
- immUniformColor4fv(col_selection);
- immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
- }
-
- /* highlights */
- if (tselem->flag & (TSE_DRAG_ANY | TSE_HIGHLIGHTED | TSE_SEARCHMATCH)) {
- const int end_x = (int)ar->v2d.cur.xmax;
-
- if (tselem->flag & TSE_DRAG_ANY) {
- /* drag and drop highlight */
- float col[4];
- UI_GetThemeColorShade4fv(TH_BACK, -40, col);
-
- if (tselem->flag & TSE_DRAG_BEFORE) {
- immUniformColor4fv(col);
- immRecti(pos, start_x, start_y + UI_UNIT_Y - 1, end_x, start_y + UI_UNIT_Y + 1);
- }
- else if (tselem->flag & TSE_DRAG_AFTER) {
- immUniformColor4fv(col);
- immRecti(pos, start_x, start_y - 1, end_x, start_y + 1);
- }
- else {
- immUniformColor3fvAlpha(col, col[3] * 0.5f);
- immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
- }
- }
- else {
- if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) {
- /* search match highlights
- * we don't expand items when searching in the datablocks but we
- * still want to highlight any filter matches. */
- immUniformColor4fv(col_searchmatch);
- immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
- }
- else if (tselem->flag & TSE_HIGHLIGHTED) {
- /* mouse hover highlight */
- immUniformColor4fv(col_highlight);
- immRecti(pos, 0, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
- }
- }
- }
-
- *io_start_y -= UI_UNIT_Y;
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_draw_highlights_recursive(
- pos, ar, soops, &te->subtree, col_selection, col_highlight, col_searchmatch,
- start_x + UI_UNIT_X, io_start_y);
- }
- }
+ const bool is_searching = (SEARCHING_OUTLINER(soops) ||
+ (soops->outlinevis == SO_DATA_API && soops->search_string[0] != 0));
+
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ const TreeStoreElem *tselem = TREESTORE(te);
+ const int start_y = *io_start_y;
+
+ /* selection status */
+ if (tselem->flag & TSE_SELECTED) {
+ immUniformColor4fv(col_selection);
+ immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1);
+ }
+
+ /* highlights */
+ if (tselem->flag & (TSE_DRAG_ANY | TSE_HIGHLIGHTED | TSE_SEARCHMATCH)) {
+ const int end_x = (int)ar->v2d.cur.xmax;
+
+ if (tselem->flag & TSE_DRAG_ANY) {
+ /* drag and drop highlight */
+ float col[4];
+ UI_GetThemeColorShade4fv(TH_BACK, -40, col);
+
+ if (tselem->flag & TSE_DRAG_BEFORE) {
+ immUniformColor4fv(col);
+ immRecti(pos, start_x, start_y + UI_UNIT_Y - 1, end_x, start_y + UI_UNIT_Y + 1);
+ }
+ else if (tselem->flag & TSE_DRAG_AFTER) {
+ immUniformColor4fv(col);
+ immRecti(pos, start_x, start_y - 1, end_x, start_y + 1);
+ }
+ else {
+ immUniformColor3fvAlpha(col, col[3] * 0.5f);
+ immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
+ }
+ }
+ else {
+ if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) {
+ /* search match highlights
+ * we don't expand items when searching in the datablocks but we
+ * still want to highlight any filter matches. */
+ immUniformColor4fv(col_searchmatch);
+ immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
+ }
+ else if (tselem->flag & TSE_HIGHLIGHTED) {
+ /* mouse hover highlight */
+ immUniformColor4fv(col_highlight);
+ immRecti(pos, 0, start_y + 1, end_x, start_y + UI_UNIT_Y - 1);
+ }
+ }
+ }
+
+ *io_start_y -= UI_UNIT_Y;
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_draw_highlights_recursive(pos,
+ ar,
+ soops,
+ &te->subtree,
+ col_selection,
+ col_highlight,
+ col_searchmatch,
+ start_x + UI_UNIT_X,
+ io_start_y);
+ }
+ }
}
static void outliner_draw_highlights(ARegion *ar, SpaceOutliner *soops, int startx, int *starty)
{
- const float col_highlight[4] = {1.0f, 1.0f, 1.0f, 0.13f};
- float col_selection[4], col_searchmatch[4];
-
- UI_GetThemeColor3fv(TH_SELECT_HIGHLIGHT, col_selection);
- col_selection[3] = 1.0f; /* no alpha */
- UI_GetThemeColor4fv(TH_MATCH, col_searchmatch);
- col_searchmatch[3] = 0.5f;
-
- GPU_blend(true);
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- outliner_draw_highlights_recursive(
- pos, ar, soops, &soops->tree, col_selection, col_highlight, col_searchmatch,
- startx, starty);
- immUnbindProgram();
- GPU_blend(false);
+ const float col_highlight[4] = {1.0f, 1.0f, 1.0f, 0.13f};
+ float col_selection[4], col_searchmatch[4];
+
+ UI_GetThemeColor3fv(TH_SELECT_HIGHLIGHT, col_selection);
+ col_selection[3] = 1.0f; /* no alpha */
+ UI_GetThemeColor4fv(TH_MATCH, col_searchmatch);
+ col_searchmatch[3] = 0.5f;
+
+ GPU_blend(true);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ outliner_draw_highlights_recursive(
+ pos, ar, soops, &soops->tree, col_selection, col_highlight, col_searchmatch, startx, starty);
+ immUnbindProgram();
+ GPU_blend(false);
}
-static void outliner_draw_tree(
- bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer,
- ARegion *ar, SpaceOutliner *soops, const bool has_restrict_icons,
- TreeElement **te_edit)
+static void outliner_draw_tree(bContext *C,
+ uiBlock *block,
+ Scene *scene,
+ ViewLayer *view_layer,
+ ARegion *ar,
+ SpaceOutliner *soops,
+ const bool has_restrict_icons,
+ TreeElement **te_edit)
{
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- int starty, startx;
-
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); // only once
-
- if (soops->outlinevis == SO_DATA_API) {
- /* struct marks */
- starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
- outliner_draw_struct_marks(ar, soops, &soops->tree, &starty);
- }
-
- /* draw highlights before hierarchy */
- starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
- startx = 0;
- outliner_draw_highlights(ar, soops, startx, &starty);
-
- /* set scissor so tree elements or lines can't overlap restriction icons */
- float scissor[4] = {0};
- if (has_restrict_icons) {
- int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)OL_TOGW + 1;
- CLAMP_MIN(mask_x, 0);
-
- GPU_scissor_get_f(scissor);
- GPU_scissor(0, 0, mask_x, ar->winy);
- }
-
- // gray hierarchy lines
-
- starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET;
- startx = UI_UNIT_X / 2 - 1.0f;
- outliner_draw_hierarchy_lines(soops, &soops->tree, startx, &starty);
-
- // items themselves
- starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
- startx = 0;
- for (TreeElement *te = soops->tree.first; te; te = te->next) {
- outliner_draw_tree_element(
- C, block, fstyle, scene, view_layer,
- ar, soops, te, (te->flag & TE_DRAGGING) != 0,
- startx, &starty, te_edit);
- }
-
- if (has_restrict_icons) {
- /* reset scissor */
- GPU_scissor(UNPACK4(scissor));
- }
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ int starty, startx;
+
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); // only once
+
+ if (soops->outlinevis == SO_DATA_API) {
+ /* struct marks */
+ starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
+ outliner_draw_struct_marks(ar, soops, &soops->tree, &starty);
+ }
+
+ /* draw highlights before hierarchy */
+ starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
+ startx = 0;
+ outliner_draw_highlights(ar, soops, startx, &starty);
+
+ /* set scissor so tree elements or lines can't overlap restriction icons */
+ float scissor[4] = {0};
+ if (has_restrict_icons) {
+ int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)OL_TOGW + 1;
+ CLAMP_MIN(mask_x, 0);
+
+ GPU_scissor_get_f(scissor);
+ GPU_scissor(0, 0, mask_x, ar->winy);
+ }
+
+ // gray hierarchy lines
+
+ starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET;
+ startx = UI_UNIT_X / 2 - 1.0f;
+ outliner_draw_hierarchy_lines(soops, &soops->tree, startx, &starty);
+
+ // items themselves
+ starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
+ startx = 0;
+ for (TreeElement *te = soops->tree.first; te; te = te->next) {
+ outliner_draw_tree_element(C,
+ block,
+ fstyle,
+ scene,
+ view_layer,
+ ar,
+ soops,
+ te,
+ (te->flag & TE_DRAGGING) != 0,
+ startx,
+ &starty,
+ te_edit);
+ }
+
+ if (has_restrict_icons) {
+ /* reset scissor */
+ GPU_scissor(UNPACK4(scissor));
+ }
}
-
static void outliner_back(ARegion *ar)
{
- int ystart;
-
- ystart = (int)ar->v2d.tot.ymax;
- ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColorShade(TH_BACK, 6);
-
- const float x1 = 0.0f, x2 = ar->v2d.cur.xmax;
- float y1 = ystart, y2;
- int tot = (int)floor(ystart - ar->v2d.cur.ymin + 2 * UI_UNIT_Y) / (2 * UI_UNIT_Y);
-
- if (tot > 0) {
- immBegin(GPU_PRIM_TRIS, 6 * tot);
- while (tot--) {
- y1 -= 2 * UI_UNIT_Y;
- y2 = y1 + UI_UNIT_Y;
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x2, y1);
- immVertex2f(pos, x2, y2);
-
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x2, y2);
- immVertex2f(pos, x1, y2);
- }
- immEnd();
- }
- immUnbindProgram();
+ int ystart;
+
+ ystart = (int)ar->v2d.tot.ymax;
+ ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShade(TH_BACK, 6);
+
+ const float x1 = 0.0f, x2 = ar->v2d.cur.xmax;
+ float y1 = ystart, y2;
+ int tot = (int)floor(ystart - ar->v2d.cur.ymin + 2 * UI_UNIT_Y) / (2 * UI_UNIT_Y);
+
+ if (tot > 0) {
+ immBegin(GPU_PRIM_TRIS, 6 * tot);
+ while (tot--) {
+ y1 -= 2 * UI_UNIT_Y;
+ y2 = y1 + UI_UNIT_Y;
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x2, y2);
+
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x1, y2);
+ }
+ immEnd();
+ }
+ immUnbindProgram();
}
static void outliner_draw_restrictcols(ARegion *ar)
{
- GPU_line_width(1.0f);
+ GPU_line_width(1.0f);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
- immBegin(GPU_PRIM_LINES, 6);
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
+ immBegin(GPU_PRIM_LINES, 6);
- immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymax);
- immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymin);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymin);
- immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)ar->v2d.cur.ymax);
- immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)ar->v2d.cur.ymin);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)ar->v2d.cur.ymin);
- immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)ar->v2d.cur.ymax);
- immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)ar->v2d.cur.ymin);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)ar->v2d.cur.ymin);
- immEnd();
- immUnbindProgram();
+ immEnd();
+ immUnbindProgram();
}
/* ****************************************************** */
@@ -2267,106 +2677,105 @@ static void outliner_draw_restrictcols(ARegion *ar)
void draw_outliner(const bContext *C)
{
- Main *mainvar = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- uiBlock *block;
- int sizey = 0, sizex = 0, sizex_rna = 0;
- TreeElement *te_edit = NULL;
- bool has_restrict_icons;
-
- outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always
-
- /* get extents of data */
- outliner_height(soops, &soops->tree, &sizey);
-
- /* extend size to allow for horizontal scrollbar */
- sizey += V2D_SCROLL_HEIGHT;
-
- if (soops->outlinevis == SO_DATA_API) {
- /* RNA has two columns:
- * - column 1 is (max_width + OL_RNA_COL_SPACEX) or
- * (OL_RNA_COL_X), whichever is wider...
- * - column 2 is fixed at OL_RNA_COL_SIZEX
- *
- * (*) XXX max width for now is a fixed factor of (UI_UNIT_X * (max_indention + 100))
- */
-
- /* get actual width of column 1 */
- outliner_rna_width(soops, &soops->tree, &sizex_rna, 0);
- sizex_rna = max_ii(OL_RNA_COLX, sizex_rna + OL_RNA_COL_SPACEX);
-
- /* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
- sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
- has_restrict_icons = false;
- }
- else {
- /* width must take into account restriction columns (if visible)
- * so that entries will still be visible */
- //outliner_width(soops, &soops->tree, &sizex);
- // XXX should use outliner_width instead when te->xend will be set correctly...
- outliner_rna_width(soops, &soops->tree, &sizex, 0);
-
- /* constant offset for restriction columns */
- // XXX this isn't that great yet...
- if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
- sizex += OL_TOGW * 3;
- }
-
- has_restrict_icons = !(soops->flag & SO_HIDE_RESTRICTCOLS);
- }
-
- /* adds vertical offset */
- sizey += OL_Y_OFFSET;
-
- /* update size of tot-rect (extents of data/viewable area) */
- UI_view2d_totRect_set(v2d, sizex, sizey);
-
- /* force display to pixel coords */
- v2d->flag |= (V2D_PIXELOFS_X | V2D_PIXELOFS_Y);
- /* set matrix for 2d-view controls */
- UI_view2d_view_ortho(v2d);
-
- /* draw outliner stuff (background, hierarchy lines and names) */
- outliner_back(ar);
- block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
- outliner_draw_tree(
- (bContext *)C, block, scene, view_layer,
- ar, soops, has_restrict_icons, &te_edit);
-
- /* Default to no emboss for outliner UI. */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- if (soops->outlinevis == SO_DATA_API) {
- /* draw rna buttons */
- outliner_draw_rnacols(ar, sizex_rna);
-
- UI_block_emboss_set(block, UI_EMBOSS);
- outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree);
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- }
- else if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) {
- /* draw user toggle columns */
- outliner_draw_restrictcols(ar);
- outliner_draw_userbuts(block, ar, soops, &soops->tree);
- }
- else if (has_restrict_icons) {
- /* draw restriction columns */
- outliner_draw_restrictcols(ar);
-
- outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &soops->tree);
- }
-
- UI_block_emboss_set(block, UI_EMBOSS);
-
- /* draw edit buttons if nessecery */
- if (te_edit) {
- outliner_buttons(C, block, ar, te_edit);
- }
-
- UI_block_end(C, block);
- UI_block_draw(C, block);
+ Main *mainvar = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ uiBlock *block;
+ int sizey = 0, sizex = 0, sizex_rna = 0;
+ TreeElement *te_edit = NULL;
+ bool has_restrict_icons;
+
+ outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always
+
+ /* get extents of data */
+ outliner_height(soops, &soops->tree, &sizey);
+
+ /* extend size to allow for horizontal scrollbar */
+ sizey += V2D_SCROLL_HEIGHT;
+
+ if (soops->outlinevis == SO_DATA_API) {
+ /* RNA has two columns:
+ * - column 1 is (max_width + OL_RNA_COL_SPACEX) or
+ * (OL_RNA_COL_X), whichever is wider...
+ * - column 2 is fixed at OL_RNA_COL_SIZEX
+ *
+ * (*) XXX max width for now is a fixed factor of (UI_UNIT_X * (max_indention + 100))
+ */
+
+ /* get actual width of column 1 */
+ outliner_rna_width(soops, &soops->tree, &sizex_rna, 0);
+ sizex_rna = max_ii(OL_RNA_COLX, sizex_rna + OL_RNA_COL_SPACEX);
+
+ /* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
+ sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
+ has_restrict_icons = false;
+ }
+ else {
+ /* width must take into account restriction columns (if visible)
+ * so that entries will still be visible */
+ //outliner_width(soops, &soops->tree, &sizex);
+ // XXX should use outliner_width instead when te->xend will be set correctly...
+ outliner_rna_width(soops, &soops->tree, &sizex, 0);
+
+ /* constant offset for restriction columns */
+ // XXX this isn't that great yet...
+ if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
+ sizex += OL_TOGW * 3;
+ }
+
+ has_restrict_icons = !(soops->flag & SO_HIDE_RESTRICTCOLS);
+ }
+
+ /* adds vertical offset */
+ sizey += OL_Y_OFFSET;
+
+ /* update size of tot-rect (extents of data/viewable area) */
+ UI_view2d_totRect_set(v2d, sizex, sizey);
+
+ /* force display to pixel coords */
+ v2d->flag |= (V2D_PIXELOFS_X | V2D_PIXELOFS_Y);
+ /* set matrix for 2d-view controls */
+ UI_view2d_view_ortho(v2d);
+
+ /* draw outliner stuff (background, hierarchy lines and names) */
+ outliner_back(ar);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ outliner_draw_tree(
+ (bContext *)C, block, scene, view_layer, ar, soops, has_restrict_icons, &te_edit);
+
+ /* Default to no emboss for outliner UI. */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ if (soops->outlinevis == SO_DATA_API) {
+ /* draw rna buttons */
+ outliner_draw_rnacols(ar, sizex_rna);
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+ outliner_draw_rnabuts(block, ar, soops, sizex_rna, &soops->tree);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ }
+ else if ((soops->outlinevis == SO_ID_ORPHANS) && has_restrict_icons) {
+ /* draw user toggle columns */
+ outliner_draw_restrictcols(ar);
+ outliner_draw_userbuts(block, ar, soops, &soops->tree);
+ }
+ else if (has_restrict_icons) {
+ /* draw restriction columns */
+ outliner_draw_restrictcols(ar);
+
+ outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &soops->tree);
+ }
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* draw edit buttons if nessecery */
+ if (te_edit) {
+ outliner_buttons(C, block, ar, te_edit);
+ }
+
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 8b8dff9dc27..11d01931945 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -88,773 +88,840 @@
static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- /* Drag and drop does own highlighting. */
- wmWindowManager *wm = CTX_wm_manager(C);
- if (wm->drags.first) {
- return OPERATOR_PASS_THROUGH;
- }
+ /* Drag and drop does own highlighting. */
+ wmWindowManager *wm = CTX_wm_manager(C);
+ if (wm->drags.first) {
+ return OPERATOR_PASS_THROUGH;
+ }
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
- TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, my);
- bool changed = false;
+ TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, my);
+ bool changed = false;
- if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
- changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
- if (hovered_te) {
- hovered_te->store_elem->flag |= TSE_HIGHLIGHTED;
- changed = true;
- }
- }
+ if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
+ changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
+ if (hovered_te) {
+ hovered_te->store_elem->flag |= TSE_HIGHLIGHTED;
+ changed = true;
+ }
+ }
- if (changed) {
- ED_region_tag_redraw_no_rebuild(ar);
- }
+ if (changed) {
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
- return OPERATOR_PASS_THROUGH;
+ return OPERATOR_PASS_THROUGH;
}
void OUTLINER_OT_highlight_update(wmOperatorType *ot)
{
- ot->name = "Update Highlight";
- ot->idname = "OUTLINER_OT_highlight_update";
- ot->description = "Update the item highlight based on the current mouse position";
+ ot->name = "Update Highlight";
+ ot->idname = "OUTLINER_OT_highlight_update";
+ ot->description = "Update the item highlight based on the current mouse position";
- ot->invoke = outliner_highlight_update;
+ ot->invoke = outliner_highlight_update;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
}
/* Toggle Open/Closed ------------------------------------------- */
-static int do_outliner_item_openclose(bContext *C, SpaceOutliner *soops, TreeElement *te, const bool all, const float mval[2])
+static int do_outliner_item_openclose(
+ bContext *C, SpaceOutliner *soops, TreeElement *te, const bool all, const float mval[2])
{
- if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
- TreeStoreElem *tselem = TREESTORE(te);
+ if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
+ TreeStoreElem *tselem = TREESTORE(te);
- /* all below close/open? */
- if (all) {
- tselem->flag &= ~TSE_CLOSED;
- outliner_flag_set(&te->subtree, TSE_CLOSED, !outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1));
- }
- else {
- if (tselem->flag & TSE_CLOSED) {
- tselem->flag &= ~TSE_CLOSED;
- }
- else {
- tselem->flag |= TSE_CLOSED;
- }
- }
+ /* all below close/open? */
+ if (all) {
+ tselem->flag &= ~TSE_CLOSED;
+ outliner_flag_set(
+ &te->subtree, TSE_CLOSED, !outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1));
+ }
+ else {
+ if (tselem->flag & TSE_CLOSED) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ else {
+ tselem->flag |= TSE_CLOSED;
+ }
+ }
- return 1;
- }
-
- for (te = te->subtree.first; te; te = te->next) {
- if (do_outliner_item_openclose(C, soops, te, all, mval)) {
- return 1;
- }
- }
- return 0;
+ return 1;
+ }
+ for (te = te->subtree.first; te; te = te->next) {
+ if (do_outliner_item_openclose(C, soops, te, all, mval)) {
+ return 1;
+ }
+ }
+ return 0;
}
/* event can enterkey, then it opens/closes */
static int outliner_item_openclose(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te;
- float fmval[2];
- const bool all = RNA_boolean_get(op->ptr, "all");
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te;
+ float fmval[2];
+ const bool all = RNA_boolean_get(op->ptr, "all");
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_openclose(C, soops, te, all, fmval)) {
- break;
- }
- }
+ for (te = soops->tree.first; te; te = te->next) {
+ if (do_outliner_item_openclose(C, soops, te, all, fmval)) {
+ break;
+ }
+ }
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_item_openclose(wmOperatorType *ot)
{
- ot->name = "Open/Close";
- ot->idname = "OUTLINER_OT_item_openclose";
- ot->description = "Toggle whether item under cursor is enabled or closed";
+ ot->name = "Open/Close";
+ ot->idname = "OUTLINER_OT_item_openclose";
+ ot->description = "Toggle whether item under cursor is enabled or closed";
- ot->invoke = outliner_item_openclose;
+ ot->invoke = outliner_item_openclose;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
- RNA_def_boolean(ot->srna, "all", 1, "All", "Close or open all items");
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Close or open all items");
}
/* -------------------------------------------------------------------- */
/** \name Object Mode Enter/Exit
* \{ */
-static void item_object_mode_enter_exit(
- bContext *C, ReportList *reports, Object *ob,
- bool enter)
+static void item_object_mode_enter_exit(bContext *C, ReportList *reports, Object *ob, bool enter)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *obact = OBACT(view_layer);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obact = OBACT(view_layer);
- if ((ob->type != obact->type) || ID_IS_LINKED(ob->data)) {
- return;
- }
- if (((ob->mode & obact->mode) != 0) == enter) {
- return;
- }
+ if ((ob->type != obact->type) || ID_IS_LINKED(ob->data)) {
+ return;
+ }
+ if (((ob->mode & obact->mode) != 0) == enter) {
+ return;
+ }
- if (ob == obact) {
- BKE_report(reports, RPT_WARNING, "Active object mode not changed");
- return;
- }
+ if (ob == obact) {
+ BKE_report(reports, RPT_WARNING, "Active object mode not changed");
+ return;
+ }
- Base *base = BKE_view_layer_base_find(view_layer, ob);
- if (base == NULL) {
- return;
- }
- Scene *scene = CTX_data_scene(C);
- outliner_object_mode_toggle(C, scene, view_layer, base);
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ if (base == NULL) {
+ return;
+ }
+ Scene *scene = CTX_data_scene(C);
+ outliner_object_mode_toggle(C, scene, view_layer, base);
}
-void item_object_mode_enter_cb(
- bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+void item_object_mode_enter_cb(bContext *C,
+ ReportList *reports,
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- Object *ob = (Object *)tselem->id;
- item_object_mode_enter_exit(C, reports, ob, true);
+ Object *ob = (Object *)tselem->id;
+ item_object_mode_enter_exit(C, reports, ob, true);
}
-void item_object_mode_exit_cb(
- bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+void item_object_mode_exit_cb(bContext *C,
+ ReportList *reports,
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- Object *ob = (Object *)tselem->id;
- item_object_mode_enter_exit(C, reports, ob, false);
+ Object *ob = (Object *)tselem->id;
+ item_object_mode_enter_exit(C, reports, ob, false);
}
/** \} */
/* Rename --------------------------------------------------- */
-static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem,
+static void do_item_rename(ARegion *ar,
+ TreeElement *te,
+ TreeStoreElem *tselem,
ReportList *reports)
{
- bool add_textbut = false;
-
- /* can't rename rna datablocks entries or listbases */
- if (ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE, TSE_SCENE_OBJECTS_BASE)) {
- /* do nothing */
- }
- else if (ELEM(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE,
- TSE_DRIVER_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_SCENE_COLLECTION_BASE,
- TSE_VIEW_COLLECTION_BASE))
- {
- BKE_report(reports, RPT_WARNING, "Cannot edit builtin name");
- }
- else if (ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
- BKE_report(reports, RPT_WARNING, "Cannot edit sequence name");
- }
- else if (outliner_is_collection_tree_element(te)) {
- Collection *collection = outliner_collection_from_tree_element(te);
-
- if (collection->flag & COLLECTION_IS_MASTER) {
- BKE_report(reports, RPT_WARNING, "Cannot edit name of master collection");
- }
- else {
- add_textbut = true;
- }
- }
- else if (ID_IS_LINKED(tselem->id)) {
- BKE_report(reports, RPT_WARNING, "Cannot edit external library data");
- }
- else if (te->idcode == ID_LI && ((Library *)tselem->id)->parent) {
- BKE_report(reports, RPT_WARNING, "Cannot edit the path of an indirectly linked library");
- }
- else {
- add_textbut = true;
- }
-
- if (add_textbut) {
- tselem->flag |= TSE_TEXTBUT;
- ED_region_tag_redraw(ar);
- }
-}
-
-void item_rename_cb(
- bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- ARegion *ar = CTX_wm_region(C);
- do_item_rename(ar, te, tselem, reports);
-}
-
-static int do_outliner_item_rename(ReportList *reports, ARegion *ar, TreeElement *te,
+ bool add_textbut = false;
+
+ /* can't rename rna datablocks entries or listbases */
+ if (ELEM(tselem->type,
+ TSE_RNA_STRUCT,
+ TSE_RNA_PROPERTY,
+ TSE_RNA_ARRAY_ELEM,
+ TSE_ID_BASE,
+ TSE_SCENE_OBJECTS_BASE)) {
+ /* do nothing */
+ }
+ else if (ELEM(tselem->type,
+ TSE_ANIM_DATA,
+ TSE_NLA,
+ TSE_DEFGROUP_BASE,
+ TSE_CONSTRAINT_BASE,
+ TSE_MODIFIER_BASE,
+ TSE_DRIVER_BASE,
+ TSE_POSE_BASE,
+ TSE_POSEGRP_BASE,
+ TSE_R_LAYER_BASE,
+ TSE_SCENE_COLLECTION_BASE,
+ TSE_VIEW_COLLECTION_BASE)) {
+ BKE_report(reports, RPT_WARNING, "Cannot edit builtin name");
+ }
+ else if (ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
+ BKE_report(reports, RPT_WARNING, "Cannot edit sequence name");
+ }
+ else if (outliner_is_collection_tree_element(te)) {
+ Collection *collection = outliner_collection_from_tree_element(te);
+
+ if (collection->flag & COLLECTION_IS_MASTER) {
+ BKE_report(reports, RPT_WARNING, "Cannot edit name of master collection");
+ }
+ else {
+ add_textbut = true;
+ }
+ }
+ else if (ID_IS_LINKED(tselem->id)) {
+ BKE_report(reports, RPT_WARNING, "Cannot edit external library data");
+ }
+ else if (te->idcode == ID_LI && ((Library *)tselem->id)->parent) {
+ BKE_report(reports, RPT_WARNING, "Cannot edit the path of an indirectly linked library");
+ }
+ else {
+ add_textbut = true;
+ }
+
+ if (add_textbut) {
+ tselem->flag |= TSE_TEXTBUT;
+ ED_region_tag_redraw(ar);
+ }
+}
+
+void item_rename_cb(bContext *C,
+ ReportList *reports,
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ ARegion *ar = CTX_wm_region(C);
+ do_item_rename(ar, te, tselem, reports);
+}
+
+static int do_outliner_item_rename(ReportList *reports,
+ ARegion *ar,
+ TreeElement *te,
const float mval[2])
{
- if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
- TreeStoreElem *tselem = TREESTORE(te);
+ if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
+ TreeStoreElem *tselem = TREESTORE(te);
- /* click on name */
- if (mval[0] > te->xs + UI_UNIT_X * 2 && mval[0] < te->xend) {
- do_item_rename(ar, te, tselem, reports);
- return 1;
- }
- return 0;
- }
+ /* click on name */
+ if (mval[0] > te->xs + UI_UNIT_X * 2 && mval[0] < te->xend) {
+ do_item_rename(ar, te, tselem, reports);
+ return 1;
+ }
+ return 0;
+ }
- for (te = te->subtree.first; te; te = te->next) {
- if (do_outliner_item_rename(reports, ar, te, mval)) {
- return 1;
- }
- }
- return 0;
+ for (te = te->subtree.first; te; te = te->next) {
+ if (do_outliner_item_rename(reports, ar, te, mval)) {
+ return 1;
+ }
+ }
+ return 0;
}
static int outliner_item_rename(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te;
- float fmval[2];
- bool changed = false;
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te;
+ float fmval[2];
+ bool changed = false;
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_rename(op->reports, ar, te, fmval)) {
- changed = true;
- break;
- }
- }
+ for (te = soops->tree.first; te; te = te->next) {
+ if (do_outliner_item_rename(op->reports, ar, te, fmval)) {
+ changed = true;
+ break;
+ }
+ }
- return changed ? OPERATOR_FINISHED : OPERATOR_PASS_THROUGH;
+ return changed ? OPERATOR_FINISHED : OPERATOR_PASS_THROUGH;
}
-
void OUTLINER_OT_item_rename(wmOperatorType *ot)
{
- ot->name = "Rename";
- ot->idname = "OUTLINER_OT_item_rename";
- ot->description = "Rename item under cursor";
+ ot->name = "Rename";
+ ot->idname = "OUTLINER_OT_item_rename";
+ ot->description = "Rename item under cursor";
- ot->invoke = outliner_item_rename;
+ ot->invoke = outliner_item_rename;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
}
/* ID delete --------------------------------------------------- */
static void id_delete(bContext *C, ReportList *reports, TreeElement *te, TreeStoreElem *tselem)
{
- Main *bmain = CTX_data_main(C);
- ID *id = tselem->id;
-
- BLI_assert(te->idcode != 0 && id != NULL);
- UNUSED_VARS_NDEBUG(te);
-
- if (te->idcode == ID_LI && ((Library *)id)->parent != NULL) {
- BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked library '%s'", id->name);
- return;
- }
- if (id->tag & LIB_TAG_INDIRECT) {
- BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked id '%s'", id->name);
- return;
- }
- else if (BKE_library_ID_is_indirectly_used(bmain, id) && ID_REAL_USERS(id) <= 1) {
- BKE_reportf(reports, RPT_WARNING,
- "Cannot delete id '%s', indirectly used data-blocks need at least one user",
- id->name);
- return;
- }
-
-
- BKE_id_delete(bmain, id);
-
- WM_event_add_notifier(C, NC_WINDOW, NULL);
-}
-
-void id_delete_cb(
- bContext *C, ReportList *reports, Scene *UNUSED(scene),
- TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- id_delete(C, reports, te, tselem);
-}
-
-static int outliner_id_delete_invoke_do(bContext *C, ReportList *reports, TreeElement *te, const float mval[2])
-{
- if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
- TreeStoreElem *tselem = TREESTORE(te);
-
- if (te->idcode != 0 && tselem->id) {
- if (te->idcode == ID_LI && ((Library *)tselem->id)->parent) {
- BKE_reportf(reports, RPT_ERROR_INVALID_INPUT,
- "Cannot delete indirectly linked library '%s'", ((Library *)tselem->id)->filepath);
- return OPERATOR_CANCELLED;
- }
- id_delete(C, reports, te, tselem);
- return OPERATOR_FINISHED;
- }
- }
- else {
- for (te = te->subtree.first; te; te = te->next) {
- int ret;
- if ((ret = outliner_id_delete_invoke_do(C, reports, te, mval))) {
- return ret;
- }
- }
- }
-
- return 0;
+ Main *bmain = CTX_data_main(C);
+ ID *id = tselem->id;
+
+ BLI_assert(te->idcode != 0 && id != NULL);
+ UNUSED_VARS_NDEBUG(te);
+
+ if (te->idcode == ID_LI && ((Library *)id)->parent != NULL) {
+ BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked library '%s'", id->name);
+ return;
+ }
+ if (id->tag & LIB_TAG_INDIRECT) {
+ BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked id '%s'", id->name);
+ return;
+ }
+ else if (BKE_library_ID_is_indirectly_used(bmain, id) && ID_REAL_USERS(id) <= 1) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete id '%s', indirectly used data-blocks need at least one user",
+ id->name);
+ return;
+ }
+
+ BKE_id_delete(bmain, id);
+
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+}
+
+void id_delete_cb(bContext *C,
+ ReportList *reports,
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ id_delete(C, reports, te, tselem);
+}
+
+static int outliner_id_delete_invoke_do(bContext *C,
+ ReportList *reports,
+ TreeElement *te,
+ const float mval[2])
+{
+ if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (te->idcode != 0 && tselem->id) {
+ if (te->idcode == ID_LI && ((Library *)tselem->id)->parent) {
+ BKE_reportf(reports,
+ RPT_ERROR_INVALID_INPUT,
+ "Cannot delete indirectly linked library '%s'",
+ ((Library *)tselem->id)->filepath);
+ return OPERATOR_CANCELLED;
+ }
+ id_delete(C, reports, te, tselem);
+ return OPERATOR_FINISHED;
+ }
+ }
+ else {
+ for (te = te->subtree.first; te; te = te->next) {
+ int ret;
+ if ((ret = outliner_id_delete_invoke_do(C, reports, te, mval))) {
+ return ret;
+ }
+ }
+ }
+
+ return 0;
}
static int outliner_id_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te;
- float fmval[2];
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te;
+ float fmval[2];
- BLI_assert(ar && soops);
+ BLI_assert(ar && soops);
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- for (te = soops->tree.first; te; te = te->next) {
- int ret;
+ for (te = soops->tree.first; te; te = te->next) {
+ int ret;
- if ((ret = outliner_id_delete_invoke_do(C, op->reports, te, fmval))) {
- return ret;
- }
- }
+ if ((ret = outliner_id_delete_invoke_do(C, op->reports, te, fmval))) {
+ return ret;
+ }
+ }
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
void OUTLINER_OT_id_delete(wmOperatorType *ot)
{
- ot->name = "Delete Data-Block";
- ot->idname = "OUTLINER_OT_id_delete";
- ot->description = "Delete the ID under cursor";
+ ot->name = "Delete Data-Block";
+ ot->idname = "OUTLINER_OT_id_delete";
+ ot->description = "Delete the ID under cursor";
- ot->invoke = outliner_id_delete_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->invoke = outliner_id_delete_invoke;
+ ot->poll = ED_operator_outliner_active;
}
/* ID remap --------------------------------------------------- */
static int outliner_id_remap_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
- const short id_type = (short)RNA_enum_get(op->ptr, "id_type");
- ID *old_id = BLI_findlink(which_libbase(CTX_data_main(C), id_type), RNA_enum_get(op->ptr, "old_id"));
- ID *new_id = BLI_findlink(which_libbase(CTX_data_main(C), id_type), RNA_enum_get(op->ptr, "new_id"));
+ const short id_type = (short)RNA_enum_get(op->ptr, "id_type");
+ ID *old_id = BLI_findlink(which_libbase(CTX_data_main(C), id_type),
+ RNA_enum_get(op->ptr, "old_id"));
+ ID *new_id = BLI_findlink(which_libbase(CTX_data_main(C), id_type),
+ RNA_enum_get(op->ptr, "new_id"));
- /* check for invalid states */
- if (soops == NULL) {
- return OPERATOR_CANCELLED;
- }
+ /* check for invalid states */
+ if (soops == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- if (!(old_id && new_id && (old_id != new_id) && (GS(old_id->name) == GS(new_id->name)))) {
- BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT, "Invalid old/new ID pair ('%s' / '%s')",
- old_id ? old_id->name : "Invalid ID", new_id ? new_id->name : "Invalid ID");
- return OPERATOR_CANCELLED;
- }
+ if (!(old_id && new_id && (old_id != new_id) && (GS(old_id->name) == GS(new_id->name)))) {
+ BKE_reportf(op->reports,
+ RPT_ERROR_INVALID_INPUT,
+ "Invalid old/new ID pair ('%s' / '%s')",
+ old_id ? old_id->name : "Invalid ID",
+ new_id ? new_id->name : "Invalid ID");
+ return OPERATOR_CANCELLED;
+ }
- if (ID_IS_LINKED(old_id)) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Old ID '%s' is linked from a library, indirect usages of this data-block will not be remapped",
- old_id->name);
- }
+ if (ID_IS_LINKED(old_id)) {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Old ID '%s' is linked from a library, indirect usages of this data-block will "
+ "not be remapped",
+ old_id->name);
+ }
- BKE_libblock_remap(bmain, old_id, new_id,
- ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
+ BKE_libblock_remap(
+ bmain, old_id, new_id, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
- BKE_main_lib_objects_recalc_all(bmain);
+ BKE_main_lib_objects_recalc_all(bmain);
- /* recreate dependency graph to include new objects */
- DEG_relations_tag_update(bmain);
+ /* recreate dependency graph to include new objects */
+ DEG_relations_tag_update(bmain);
- /* Free gpu materials, some materials depend on existing objects,
- * such as lights so freeing correctly refreshes. */
- GPU_materials_free(bmain);
+ /* Free gpu materials, some materials depend on existing objects,
+ * such as lights so freeing correctly refreshes. */
+ GPU_materials_free(bmain);
- WM_event_add_notifier(C, NC_WINDOW, NULL);
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
-static bool outliner_id_remap_find_tree_element(bContext *C, wmOperator *op, ListBase *tree, const float y)
+static bool outliner_id_remap_find_tree_element(bContext *C,
+ wmOperator *op,
+ ListBase *tree,
+ const float y)
{
- TreeElement *te;
+ TreeElement *te;
- for (te = tree->first; te; te = te->next) {
- if (y > te->ys && y < te->ys + UI_UNIT_Y) {
- TreeStoreElem *tselem = TREESTORE(te);
+ for (te = tree->first; te; te = te->next) {
+ if (y > te->ys && y < te->ys + UI_UNIT_Y) {
+ TreeStoreElem *tselem = TREESTORE(te);
- if (tselem->type == 0 && tselem->id) {
- printf("found id %s (%p)!\n", tselem->id->name, tselem->id);
+ if (tselem->type == 0 && tselem->id) {
+ printf("found id %s (%p)!\n", tselem->id->name, tselem->id);
- RNA_enum_set(op->ptr, "id_type", GS(tselem->id->name));
- RNA_enum_set_identifier(C, op->ptr, "new_id", tselem->id->name + 2);
- RNA_enum_set_identifier(C, op->ptr, "old_id", tselem->id->name + 2);
- return true;
- }
- }
- if (outliner_id_remap_find_tree_element(C, op, &te->subtree, y)) {
- return true;
- }
- }
- return false;
+ RNA_enum_set(op->ptr, "id_type", GS(tselem->id->name));
+ RNA_enum_set_identifier(C, op->ptr, "new_id", tselem->id->name + 2);
+ RNA_enum_set_identifier(C, op->ptr, "old_id", tselem->id->name + 2);
+ return true;
+ }
+ }
+ if (outliner_id_remap_find_tree_element(C, op, &te->subtree, y)) {
+ return true;
+ }
+ }
+ return false;
}
static int outliner_id_remap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- float fmval[2];
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ float fmval[2];
- if (!RNA_property_is_set(op->ptr, RNA_struct_find_property(op->ptr, "id_type"))) {
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ if (!RNA_property_is_set(op->ptr, RNA_struct_find_property(op->ptr, "id_type"))) {
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- outliner_id_remap_find_tree_element(C, op, &soops->tree, fmval[1]);
- }
+ outliner_id_remap_find_tree_element(C, op, &soops->tree, fmval[1]);
+ }
- return WM_operator_props_dialog_popup(C, op, 200, 100);
+ return WM_operator_props_dialog_popup(C, op, 200, 100);
}
-static const EnumPropertyItem *outliner_id_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
+static const EnumPropertyItem *outliner_id_itemf(bContext *C,
+ PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
- EnumPropertyItem item_tmp = {0}, *item = NULL;
- int totitem = 0;
- int i = 0;
+ EnumPropertyItem item_tmp = {0}, *item = NULL;
+ int totitem = 0;
+ int i = 0;
- short id_type = (short)RNA_enum_get(ptr, "id_type");
- ID *id = which_libbase(CTX_data_main(C), id_type)->first;
+ short id_type = (short)RNA_enum_get(ptr, "id_type");
+ ID *id = which_libbase(CTX_data_main(C), id_type)->first;
- for (; id; id = id->next) {
- item_tmp.identifier = item_tmp.name = id->name + 2;
- item_tmp.value = i++;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
- }
+ for (; id; id = id->next) {
+ item_tmp.identifier = item_tmp.name = id->name + 2;
+ item_tmp.value = i++;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+ }
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
- return item;
+ return item;
}
void OUTLINER_OT_id_remap(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Outliner ID data Remap";
- ot->idname = "OUTLINER_OT_id_remap";
+ /* identifiers */
+ ot->name = "Outliner ID data Remap";
+ ot->idname = "OUTLINER_OT_id_remap";
- /* callbacks */
- ot->invoke = outliner_id_remap_invoke;
- ot->exec = outliner_id_remap_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = outliner_id_remap_invoke;
+ ot->exec = outliner_id_remap_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- prop = RNA_def_enum(ot->srna, "id_type", rna_enum_id_type_items, ID_OB, "ID Type", "");
- RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
+ prop = RNA_def_enum(ot->srna, "id_type", rna_enum_id_type_items, ID_OB, "ID Type", "");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
- prop = RNA_def_enum(ot->srna, "old_id", DummyRNA_NULL_items, 0, "Old ID", "Old ID to replace");
- RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, outliner_id_itemf);
- RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE | PROP_HIDDEN);
+ prop = RNA_def_enum(ot->srna, "old_id", DummyRNA_NULL_items, 0, "Old ID", "Old ID to replace");
+ RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, outliner_id_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE | PROP_HIDDEN);
- ot->prop = RNA_def_enum(ot->srna, "new_id", DummyRNA_NULL_items, 0,
- "New ID", "New ID to remap all selected IDs' users to");
- RNA_def_property_enum_funcs_runtime(ot->prop, NULL, NULL, outliner_id_itemf);
- RNA_def_property_flag(ot->prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = RNA_def_enum(ot->srna,
+ "new_id",
+ DummyRNA_NULL_items,
+ 0,
+ "New ID",
+ "New ID to remap all selected IDs' users to");
+ RNA_def_property_enum_funcs_runtime(ot->prop, NULL, NULL, outliner_id_itemf);
+ RNA_def_property_flag(ot->prop, PROP_ENUM_NO_TRANSLATE);
}
-void id_remap_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+void id_remap_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_id_remap", false);
- PointerRNA op_props;
+ wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_id_remap", false);
+ PointerRNA op_props;
- BLI_assert(tselem->id != NULL);
+ BLI_assert(tselem->id != NULL);
- WM_operator_properties_create_ptr(&op_props, ot);
+ WM_operator_properties_create_ptr(&op_props, ot);
- RNA_enum_set(&op_props, "id_type", GS(tselem->id->name));
- RNA_enum_set_identifier(C, &op_props, "old_id", tselem->id->name + 2);
+ RNA_enum_set(&op_props, "id_type", GS(tselem->id->name));
+ RNA_enum_set_identifier(C, &op_props, "old_id", tselem->id->name + 2);
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_props);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_props);
- WM_operator_properties_free(&op_props);
+ WM_operator_properties_free(&op_props);
}
/* ID copy/Paste ------------------------------------------------------------- */
static int outliner_id_copy_tag(SpaceOutliner *soops, ListBase *tree)
{
- TreeElement *te;
- TreeStoreElem *tselem;
- int num_ids = 0;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+ int num_ids = 0;
- for (te = tree->first; te; te = te->next) {
- tselem = TREESTORE(te);
+ for (te = tree->first; te; te = te->next) {
+ tselem = TREESTORE(te);
- /* if item is selected and is an ID, tag it as needing to be copied. */
- if (tselem->flag & TSE_SELECTED && ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
- ID *id = tselem->id;
- if (!(id->tag & LIB_TAG_DOIT)) {
- BKE_copybuffer_tag_ID(tselem->id);
- num_ids++;
- }
- }
+ /* if item is selected and is an ID, tag it as needing to be copied. */
+ if (tselem->flag & TSE_SELECTED && ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+ ID *id = tselem->id;
+ if (!(id->tag & LIB_TAG_DOIT)) {
+ BKE_copybuffer_tag_ID(tselem->id);
+ num_ids++;
+ }
+ }
- /* go over sub-tree */
- if (TSELEM_OPEN(tselem, soops)) {
- num_ids += outliner_id_copy_tag(soops, &te->subtree);
- }
- }
+ /* go over sub-tree */
+ if (TSELEM_OPEN(tselem, soops)) {
+ num_ids += outliner_id_copy_tag(soops, &te->subtree);
+ }
+ }
- return num_ids;
+ return num_ids;
}
static int outliner_id_copy_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- char str[FILE_MAX];
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ char str[FILE_MAX];
- BKE_copybuffer_begin(bmain);
+ BKE_copybuffer_begin(bmain);
- const int num_ids = outliner_id_copy_tag(soops, &soops->tree);
- if (num_ids == 0) {
- BKE_report(op->reports, RPT_INFO, "No selected data-blocks to copy");
- return OPERATOR_CANCELLED;
- }
+ const int num_ids = outliner_id_copy_tag(soops, &soops->tree);
+ if (num_ids == 0) {
+ BKE_report(op->reports, RPT_INFO, "No selected data-blocks to copy");
+ return OPERATOR_CANCELLED;
+ }
- BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
- BKE_copybuffer_save(bmain, str, op->reports);
+ BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
+ BKE_copybuffer_save(bmain, str, op->reports);
- BKE_reportf(op->reports, RPT_INFO, "Copied %d selected data-blocks", num_ids);
+ BKE_reportf(op->reports, RPT_INFO, "Copied %d selected data-blocks", num_ids);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_id_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner ID Data Copy";
- ot->idname = "OUTLINER_OT_id_copy";
- ot->description = "Selected data-blocks are copied to the clipboard";
+ /* identifiers */
+ ot->name = "Outliner ID Data Copy";
+ ot->idname = "OUTLINER_OT_id_copy";
+ ot->description = "Selected data-blocks are copied to the clipboard";
- /* callbacks */
- ot->exec = outliner_id_copy_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->exec = outliner_id_copy_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
}
static int outliner_id_paste_exec(bContext *C, wmOperator *op)
{
- char str[FILE_MAX];
- const short flag = FILE_AUTOSELECT | FILE_ACTIVE_COLLECTION;
+ char str[FILE_MAX];
+ const short flag = FILE_AUTOSELECT | FILE_ACTIVE_COLLECTION;
- BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
+ BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
- const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, 0);
- if (num_pasted == 0) {
- BKE_report(op->reports, RPT_INFO, "No data to paste");
- return OPERATOR_CANCELLED;
- }
+ const int num_pasted = BKE_copybuffer_paste(C, str, flag, op->reports, 0);
+ if (num_pasted == 0) {
+ BKE_report(op->reports, RPT_INFO, "No data to paste");
+ return OPERATOR_CANCELLED;
+ }
- WM_event_add_notifier(C, NC_WINDOW, NULL);
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
- BKE_reportf(op->reports, RPT_INFO, "%d data-blocks pasted", num_pasted);
- return OPERATOR_FINISHED;
+ BKE_reportf(op->reports, RPT_INFO, "%d data-blocks pasted", num_pasted);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_id_paste(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner ID Data Paste";
- ot->idname = "OUTLINER_OT_id_paste";
- ot->description = "Data-blocks from the clipboard are pasted";
+ /* identifiers */
+ ot->name = "Outliner ID Data Paste";
+ ot->idname = "OUTLINER_OT_id_paste";
+ ot->description = "Data-blocks from the clipboard are pasted";
- /* callbacks */
- ot->exec = outliner_id_paste_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->exec = outliner_id_paste_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
}
/* Library relocate/reload --------------------------------------------------- */
static int lib_relocate(
- bContext *C, TreeElement *te, TreeStoreElem *tselem, wmOperatorType *ot, const bool reload)
+ bContext *C, TreeElement *te, TreeStoreElem *tselem, wmOperatorType *ot, const bool reload)
{
- PointerRNA op_props;
- int ret = 0;
+ PointerRNA op_props;
+ int ret = 0;
- BLI_assert(te->idcode == ID_LI && tselem->id != NULL);
- UNUSED_VARS_NDEBUG(te);
+ BLI_assert(te->idcode == ID_LI && tselem->id != NULL);
+ UNUSED_VARS_NDEBUG(te);
- WM_operator_properties_create_ptr(&op_props, ot);
+ WM_operator_properties_create_ptr(&op_props, ot);
- RNA_string_set(&op_props, "library", tselem->id->name + 2);
+ RNA_string_set(&op_props, "library", tselem->id->name + 2);
- if (reload) {
- Library *lib = (Library *)tselem->id;
- char dir[FILE_MAXDIR], filename[FILE_MAX];
+ if (reload) {
+ Library *lib = (Library *)tselem->id;
+ char dir[FILE_MAXDIR], filename[FILE_MAX];
- BLI_split_dirfile(lib->filepath, dir, filename, sizeof(dir), sizeof(filename));
+ BLI_split_dirfile(lib->filepath, dir, filename, sizeof(dir), sizeof(filename));
- printf("%s, %s\n", tselem->id->name, lib->filepath);
+ printf("%s, %s\n", tselem->id->name, lib->filepath);
- /* We assume if both paths in lib are not the same then lib->name was relative... */
- RNA_boolean_set(&op_props, "relative_path", BLI_path_cmp(lib->filepath, lib->name) != 0);
+ /* We assume if both paths in lib are not the same then lib->name was relative... */
+ RNA_boolean_set(&op_props, "relative_path", BLI_path_cmp(lib->filepath, lib->name) != 0);
- RNA_string_set(&op_props, "directory", dir);
- RNA_string_set(&op_props, "filename", filename);
+ RNA_string_set(&op_props, "directory", dir);
+ RNA_string_set(&op_props, "filename", filename);
- ret = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &op_props);
- }
- else {
- ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_props);
- }
+ ret = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &op_props);
+ }
+ else {
+ ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_props);
+ }
- WM_operator_properties_free(&op_props);
+ WM_operator_properties_free(&op_props);
- return ret;
+ return ret;
}
static int outliner_lib_relocate_invoke_do(
- bContext *C, ReportList *reports, TreeElement *te, const float mval[2], const bool reload)
-{
- if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
- TreeStoreElem *tselem = TREESTORE(te);
-
- if (te->idcode == ID_LI && tselem->id) {
- if (((Library *)tselem->id)->parent && !reload) {
- BKE_reportf(reports, RPT_ERROR_INVALID_INPUT,
- "Cannot relocate indirectly linked library '%s'", ((Library *)tselem->id)->filepath);
- return OPERATOR_CANCELLED;
- }
- else {
- wmOperatorType *ot = WM_operatortype_find(reload ? "WM_OT_lib_reload" : "WM_OT_lib_relocate", false);
-
- return lib_relocate(C, te, tselem, ot, reload);
- }
- }
- }
- else {
- for (te = te->subtree.first; te; te = te->next) {
- int ret;
- if ((ret = outliner_lib_relocate_invoke_do(C, reports, te, mval, reload))) {
- return ret;
- }
- }
- }
-
- return 0;
+ bContext *C, ReportList *reports, TreeElement *te, const float mval[2], const bool reload)
+{
+ if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (te->idcode == ID_LI && tselem->id) {
+ if (((Library *)tselem->id)->parent && !reload) {
+ BKE_reportf(reports,
+ RPT_ERROR_INVALID_INPUT,
+ "Cannot relocate indirectly linked library '%s'",
+ ((Library *)tselem->id)->filepath);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ wmOperatorType *ot = WM_operatortype_find(
+ reload ? "WM_OT_lib_reload" : "WM_OT_lib_relocate", false);
+
+ return lib_relocate(C, te, tselem, ot, reload);
+ }
+ }
+ }
+ else {
+ for (te = te->subtree.first; te; te = te->next) {
+ int ret;
+ if ((ret = outliner_lib_relocate_invoke_do(C, reports, te, mval, reload))) {
+ return ret;
+ }
+ }
+ }
+
+ return 0;
}
static int outliner_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te;
- float fmval[2];
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te;
+ float fmval[2];
- BLI_assert(ar && soops);
+ BLI_assert(ar && soops);
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- for (te = soops->tree.first; te; te = te->next) {
- int ret;
+ for (te = soops->tree.first; te; te = te->next) {
+ int ret;
- if ((ret = outliner_lib_relocate_invoke_do(C, op->reports, te, fmval, false))) {
- return ret;
- }
- }
+ if ((ret = outliner_lib_relocate_invoke_do(C, op->reports, te, fmval, false))) {
+ return ret;
+ }
+ }
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
void OUTLINER_OT_lib_relocate(wmOperatorType *ot)
{
- ot->name = "Relocate Library";
- ot->idname = "OUTLINER_OT_lib_relocate";
- ot->description = "Relocate the library under cursor";
+ ot->name = "Relocate Library";
+ ot->idname = "OUTLINER_OT_lib_relocate";
+ ot->description = "Relocate the library under cursor";
- ot->invoke = outliner_lib_relocate_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->invoke = outliner_lib_relocate_invoke;
+ ot->poll = ED_operator_outliner_active;
}
/* XXX This does not work with several items
* (it is only called once in the end, due to the 'deferred'
* filebrowser invocation through event system...). */
-void lib_relocate_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+void lib_relocate_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- wmOperatorType *ot = WM_operatortype_find("WM_OT_lib_relocate", false);
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_lib_relocate", false);
- lib_relocate(C, te, tselem, ot, false);
+ lib_relocate(C, te, tselem, ot, false);
}
-
static int outliner_lib_reload_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te;
- float fmval[2];
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te;
+ float fmval[2];
- BLI_assert(ar && soops);
+ BLI_assert(ar && soops);
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- for (te = soops->tree.first; te; te = te->next) {
- int ret;
+ for (te = soops->tree.first; te; te = te->next) {
+ int ret;
- if ((ret = outliner_lib_relocate_invoke_do(C, op->reports, te, fmval, true))) {
- return ret;
- }
- }
+ if ((ret = outliner_lib_relocate_invoke_do(C, op->reports, te, fmval, true))) {
+ return ret;
+ }
+ }
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
void OUTLINER_OT_lib_reload(wmOperatorType *ot)
{
- ot->name = "Reload Library";
- ot->idname = "OUTLINER_OT_lib_reload";
- ot->description = "Reload the library under cursor";
+ ot->name = "Reload Library";
+ ot->idname = "OUTLINER_OT_lib_reload";
+ ot->description = "Reload the library under cursor";
- ot->invoke = outliner_lib_reload_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->invoke = outliner_lib_reload_invoke;
+ ot->poll = ED_operator_outliner_active;
}
-void lib_reload_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+void lib_reload_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- wmOperatorType *ot = WM_operatortype_find("WM_OT_lib_reload", false);
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_lib_reload", false);
- lib_relocate(C, te, tselem, ot, true);
+ lib_relocate(C, te, tselem, ot, true);
}
/* ************************************************************** */
@@ -867,37 +934,37 @@ void lib_reload_cb(
static int outliner_count_levels(ListBase *lb, const int curlevel)
{
- TreeElement *te;
- int level = curlevel, lev;
+ TreeElement *te;
+ int level = curlevel, lev;
- for (te = lb->first; te; te = te->next) {
+ for (te = lb->first; te; te = te->next) {
- lev = outliner_count_levels(&te->subtree, curlevel + 1);
- if (lev > level) {
- level = lev;
- }
- }
- return level;
+ lev = outliner_count_levels(&te->subtree, curlevel + 1);
+ if (lev > level) {
+ level = lev;
+ }
+ }
+ return level;
}
int outliner_flag_is_any_test(ListBase *lb, short flag, const int curlevel)
{
- TreeElement *te;
- TreeStoreElem *tselem;
- int level;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+ int level;
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->flag & flag) {
- return curlevel;
- }
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & flag) {
+ return curlevel;
+ }
- level = outliner_flag_is_any_test(&te->subtree, flag, curlevel + 1);
- if (level) {
- return level;
- }
- }
- return 0;
+ level = outliner_flag_is_any_test(&te->subtree, flag, curlevel + 1);
+ if (level) {
+ return level;
+ }
+ }
+ return 0;
}
/**
@@ -906,43 +973,43 @@ int outliner_flag_is_any_test(ListBase *lb, short flag, const int curlevel)
*/
bool outliner_flag_set(ListBase *lb, short flag, short set)
{
- TreeElement *te;
- TreeStoreElem *tselem;
- bool changed = false;
- bool has_flag;
-
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- has_flag = (tselem->flag & flag);
- if (set == 0) {
- if (has_flag) {
- tselem->flag &= ~flag;
- changed = true;
- }
- }
- else if (!has_flag) {
- tselem->flag |= flag;
- changed = true;
- }
- changed |= outliner_flag_set(&te->subtree, flag, set);
- }
-
- return changed;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+ bool changed = false;
+ bool has_flag;
+
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ has_flag = (tselem->flag & flag);
+ if (set == 0) {
+ if (has_flag) {
+ tselem->flag &= ~flag;
+ changed = true;
+ }
+ }
+ else if (!has_flag) {
+ tselem->flag |= flag;
+ changed = true;
+ }
+ changed |= outliner_flag_set(&te->subtree, flag, set);
+ }
+
+ return changed;
}
bool outliner_flag_flip(ListBase *lb, short flag)
{
- TreeElement *te;
- TreeStoreElem *tselem;
- bool changed = false;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+ bool changed = false;
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- tselem->flag ^= flag;
- changed |= outliner_flag_flip(&te->subtree, flag);
- }
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ tselem->flag ^= flag;
+ changed |= outliner_flag_flip(&te->subtree, flag);
+ }
- return changed;
+ return changed;
}
/* Restriction Columns ------------------------------- */
@@ -952,23 +1019,23 @@ bool outliner_flag_flip(ListBase *lb, short flag)
* otherwise return 1 */
int common_restrict_check(bContext *C, Object *ob)
{
- /* Don't allow hide an object in edit mode,
- * check the bug #22153 and #21609, #23977
- */
- Object *obedit = CTX_data_edit_object(C);
- if (obedit && obedit == ob) {
- /* found object is hidden, reset */
- if (ob->restrictflag & OB_RESTRICT_VIEW) {
- ob->restrictflag &= ~OB_RESTRICT_VIEW;
- }
- /* found object is unselectable, reset */
- if (ob->restrictflag & OB_RESTRICT_SELECT) {
- ob->restrictflag &= ~OB_RESTRICT_SELECT;
- }
- return 0;
- }
-
- return 1;
+ /* Don't allow hide an object in edit mode,
+ * check the bug #22153 and #21609, #23977
+ */
+ Object *obedit = CTX_data_edit_object(C);
+ if (obedit && obedit == ob) {
+ /* found object is hidden, reset */
+ if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ ob->restrictflag &= ~OB_RESTRICT_VIEW;
+ }
+ /* found object is unselectable, reset */
+ if (ob->restrictflag & OB_RESTRICT_SELECT) {
+ ob->restrictflag &= ~OB_RESTRICT_SELECT;
+ }
+ return 0;
+ }
+
+ return 1;
}
/* =============================================== */
@@ -978,81 +1045,81 @@ int common_restrict_check(bContext *C, Object *ob)
static int outliner_toggle_expanded_exec(bContext *C, wmOperator *UNUSED(op))
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
- if (outliner_flag_is_any_test(&soops->tree, TSE_CLOSED, 1)) {
- outliner_flag_set(&soops->tree, TSE_CLOSED, 0);
- }
- else {
- outliner_flag_set(&soops->tree, TSE_CLOSED, 1);
- }
+ if (outliner_flag_is_any_test(&soops->tree, TSE_CLOSED, 1)) {
+ outliner_flag_set(&soops->tree, TSE_CLOSED, 0);
+ }
+ else {
+ outliner_flag_set(&soops->tree, TSE_CLOSED, 1);
+ }
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_expanded_toggle(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Expand/Collapse All";
- ot->idname = "OUTLINER_OT_expanded_toggle";
- ot->description = "Expand/Collapse all items";
+ /* identifiers */
+ ot->name = "Expand/Collapse All";
+ ot->idname = "OUTLINER_OT_expanded_toggle";
+ ot->description = "Expand/Collapse all items";
- /* callbacks */
- ot->exec = outliner_toggle_expanded_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->exec = outliner_toggle_expanded_exec;
+ ot->poll = ED_operator_outliner_active;
- /* no undo or registry, UI option */
+ /* no undo or registry, UI option */
}
/* Toggle Selected (Outliner) ---------------------------------------- */
static int outliner_select_all_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- int action = RNA_enum_get(op->ptr, "action");
- if (action == SEL_TOGGLE) {
- action = outliner_flag_is_any_test(&soops->tree, TSE_SELECTED, 1) ? SEL_DESELECT : SEL_SELECT;
- }
-
- switch (action) {
- case SEL_SELECT:
- outliner_flag_set(&soops->tree, TSE_SELECTED, 1);
- break;
- case SEL_DESELECT:
- outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
- break;
- case SEL_INVERT:
- outliner_flag_flip(&soops->tree, TSE_SELECTED);
- break;
- }
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- ED_region_tag_redraw_no_rebuild(ar);
-
- return OPERATOR_FINISHED;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ int action = RNA_enum_get(op->ptr, "action");
+ if (action == SEL_TOGGLE) {
+ action = outliner_flag_is_any_test(&soops->tree, TSE_SELECTED, 1) ? SEL_DESELECT : SEL_SELECT;
+ }
+
+ switch (action) {
+ case SEL_SELECT:
+ outliner_flag_set(&soops->tree, TSE_SELECTED, 1);
+ break;
+ case SEL_DESELECT:
+ outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
+ break;
+ case SEL_INVERT:
+ outliner_flag_flip(&soops->tree, TSE_SELECTED);
+ break;
+ }
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ ED_region_tag_redraw_no_rebuild(ar);
+
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Toggle Selected";
- ot->idname = "OUTLINER_OT_select_all";
- ot->description = "Toggle the Outliner selection of items";
+ /* identifiers */
+ ot->name = "Toggle Selected";
+ ot->idname = "OUTLINER_OT_select_all";
+ ot->description = "Toggle the Outliner selection of items";
- /* callbacks */
- ot->exec = outliner_select_all_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->exec = outliner_select_all_exec;
+ ot->poll = ED_operator_outliner_active;
- /* no undo or registry */
+ /* no undo or registry */
- /* rna */
- WM_operator_properties_select_all(ot);
+ /* rna */
+ WM_operator_properties_select_all(ot);
}
/* ************************************************************** */
@@ -1060,165 +1127,167 @@ void OUTLINER_OT_select_all(wmOperatorType *ot)
/* Show Active --------------------------------------------------- */
-static void outliner_set_coordinates_element_recursive(SpaceOutliner *soops, TreeElement *te, int startx, int *starty)
+static void outliner_set_coordinates_element_recursive(SpaceOutliner *soops,
+ TreeElement *te,
+ int startx,
+ int *starty)
{
- TreeStoreElem *tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
- /* store coord and continue, we need coordinates for elements outside view too */
- te->xs = (float)startx;
- te->ys = (float)(*starty);
- *starty -= UI_UNIT_Y;
+ /* store coord and continue, we need coordinates for elements outside view too */
+ te->xs = (float)startx;
+ te->ys = (float)(*starty);
+ *starty -= UI_UNIT_Y;
- if (TSELEM_OPEN(tselem, soops)) {
- TreeElement *ten;
- for (ten = te->subtree.first; ten; ten = ten->next) {
- outliner_set_coordinates_element_recursive(soops, ten, startx + UI_UNIT_X, starty);
- }
- }
+ if (TSELEM_OPEN(tselem, soops)) {
+ TreeElement *ten;
+ for (ten = te->subtree.first; ten; ten = ten->next) {
+ outliner_set_coordinates_element_recursive(soops, ten, startx + UI_UNIT_X, starty);
+ }
+ }
}
/* to retrieve coordinates with redrawing the entire tree */
void outliner_set_coordinates(ARegion *ar, SpaceOutliner *soops)
{
- TreeElement *te;
- int starty = (int)(ar->v2d.tot.ymax) - UI_UNIT_Y;
+ TreeElement *te;
+ int starty = (int)(ar->v2d.tot.ymax) - UI_UNIT_Y;
- for (te = soops->tree.first; te; te = te->next) {
- outliner_set_coordinates_element_recursive(soops, te, 0, &starty);
- }
+ for (te = soops->tree.first; te; te = te->next) {
+ outliner_set_coordinates_element_recursive(soops, te, 0, &starty);
+ }
}
/* return 1 when levels were opened */
static int outliner_open_back(TreeElement *te)
{
- TreeStoreElem *tselem;
- int retval = 0;
+ TreeStoreElem *tselem;
+ int retval = 0;
- for (te = te->parent; te; te = te->parent) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_CLOSED) {
- tselem->flag &= ~TSE_CLOSED;
- retval = 1;
- }
- }
- return retval;
+ for (te = te->parent; te; te = te->parent) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & TSE_CLOSED) {
+ tselem->flag &= ~TSE_CLOSED;
+ retval = 1;
+ }
+ }
+ return retval;
}
static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
{
- SpaceOutliner *so = CTX_wm_space_outliner(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
-
- TreeElement *te;
- int xdelta, ytop;
+ SpaceOutliner *so = CTX_wm_space_outliner(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
- Object *obact = OBACT(view_layer);
+ TreeElement *te;
+ int xdelta, ytop;
- if (!obact) {
- return OPERATOR_CANCELLED;
- }
+ Object *obact = OBACT(view_layer);
+ if (!obact) {
+ return OPERATOR_CANCELLED;
+ }
- te = outliner_find_id(so, &so->tree, &obact->id);
+ te = outliner_find_id(so, &so->tree, &obact->id);
- if (te != NULL && obact->type == OB_ARMATURE) {
- /* traverse down the bone hierarchy in case of armature */
- TreeElement *te_obact = te;
+ if (te != NULL && obact->type == OB_ARMATURE) {
+ /* traverse down the bone hierarchy in case of armature */
+ TreeElement *te_obact = te;
- if (obact->mode & OB_MODE_POSE) {
- bPoseChannel *pchan = CTX_data_active_pose_bone(C);
- if (pchan) {
- te = outliner_find_posechannel(&te_obact->subtree, pchan);
- }
- }
- else if (obact->mode & OB_MODE_EDIT) {
- EditBone *ebone = CTX_data_active_bone(C);
- if (ebone) {
- te = outliner_find_editbone(&te_obact->subtree, ebone);
- }
- }
- }
+ if (obact->mode & OB_MODE_POSE) {
+ bPoseChannel *pchan = CTX_data_active_pose_bone(C);
+ if (pchan) {
+ te = outliner_find_posechannel(&te_obact->subtree, pchan);
+ }
+ }
+ else if (obact->mode & OB_MODE_EDIT) {
+ EditBone *ebone = CTX_data_active_bone(C);
+ if (ebone) {
+ te = outliner_find_editbone(&te_obact->subtree, ebone);
+ }
+ }
+ }
- if (te) {
- /* open up tree to active object/bone */
- if (outliner_open_back(te)) {
- outliner_set_coordinates(ar, so);
- }
+ if (te) {
+ /* open up tree to active object/bone */
+ if (outliner_open_back(te)) {
+ outliner_set_coordinates(ar, so);
+ }
- /* make te->ys center of view */
- ytop = te->ys + BLI_rcti_size_y(&v2d->mask) / 2;
- if (ytop > 0) {
- ytop = 0;
- }
+ /* make te->ys center of view */
+ ytop = te->ys + BLI_rcti_size_y(&v2d->mask) / 2;
+ if (ytop > 0) {
+ ytop = 0;
+ }
- v2d->cur.ymax = (float)ytop;
- v2d->cur.ymin = (float)(ytop - BLI_rcti_size_y(&v2d->mask));
+ v2d->cur.ymax = (float)ytop;
+ v2d->cur.ymin = (float)(ytop - BLI_rcti_size_y(&v2d->mask));
- /* make te->xs ==> te->xend center of view */
- xdelta = (int)(te->xs - v2d->cur.xmin);
- v2d->cur.xmin += xdelta;
- v2d->cur.xmax += xdelta;
- }
+ /* make te->xs ==> te->xend center of view */
+ xdelta = (int)(te->xs - v2d->cur.xmin);
+ v2d->cur.xmin += xdelta;
+ v2d->cur.xmax += xdelta;
+ }
- ED_region_tag_redraw_no_rebuild(ar);
+ ED_region_tag_redraw_no_rebuild(ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_show_active(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Show Active";
- ot->idname = "OUTLINER_OT_show_active";
- ot->description = "Open up the tree and adjust the view so that the active Object is shown centered";
+ /* identifiers */
+ ot->name = "Show Active";
+ ot->idname = "OUTLINER_OT_show_active";
+ ot->description =
+ "Open up the tree and adjust the view so that the active Object is shown centered";
- /* callbacks */
- ot->exec = outliner_show_active_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->exec = outliner_show_active_exec;
+ ot->poll = ED_operator_outliner_active;
}
/* View Panning --------------------------------------------------- */
static int outliner_scroll_page_exec(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- int dy = BLI_rcti_size_y(&ar->v2d.mask);
- int up = 0;
+ ARegion *ar = CTX_wm_region(C);
+ int dy = BLI_rcti_size_y(&ar->v2d.mask);
+ int up = 0;
- if (RNA_boolean_get(op->ptr, "up")) {
- up = 1;
- }
+ if (RNA_boolean_get(op->ptr, "up")) {
+ up = 1;
+ }
- if (up == 0) {
- dy = -dy;
- }
- ar->v2d.cur.ymin += dy;
- ar->v2d.cur.ymax += dy;
+ if (up == 0) {
+ dy = -dy;
+ }
+ ar->v2d.cur.ymin += dy;
+ ar->v2d.cur.ymax += dy;
- ED_region_tag_redraw_no_rebuild(ar);
+ ED_region_tag_redraw_no_rebuild(ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
-
void OUTLINER_OT_scroll_page(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Scroll Page";
- ot->idname = "OUTLINER_OT_scroll_page";
- ot->description = "Scroll page up or down";
+ /* identifiers */
+ ot->name = "Scroll Page";
+ ot->idname = "OUTLINER_OT_scroll_page";
+ ot->description = "Scroll page up or down";
- /* callbacks */
- ot->exec = outliner_scroll_page_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->exec = outliner_scroll_page_exec;
+ ot->poll = ED_operator_outliner_active;
- /* properties */
- prop = RNA_def_boolean(ot->srna, "up", 0, "Up", "Scroll up one page");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "up", 0, "Up", "Scroll up one page");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* Search ------------------------------------------------------- */
@@ -1230,104 +1299,104 @@ void OUTLINER_OT_scroll_page(wmOperatorType *ot)
static TreeElement *outliner_find_name(SpaceOutliner *soops, ListBase *lb, char *name, int flags,
TreeElement *prev, int *prevFound)
{
- TreeElement *te, *tes;
+ TreeElement *te, *tes;
- for (te = lb->first; te; te = te->next) {
- int found = outliner_filter_has_name(te, name, flags);
+ for (te = lb->first; te; te = te->next) {
+ int found = outliner_filter_has_name(te, name, flags);
- if (found) {
- /* name is right, but is element the previous one? */
- if (prev) {
- if ((te != prev) && (*prevFound))
- return te;
- if (te == prev) {
- *prevFound = 1;
- }
- }
- else
- return te;
- }
+ if (found) {
+ /* name is right, but is element the previous one? */
+ if (prev) {
+ if ((te != prev) && (*prevFound))
+ return te;
+ if (te == prev) {
+ *prevFound = 1;
+ }
+ }
+ else
+ return te;
+ }
- tes = outliner_find_name(soops, &te->subtree, name, flags, prev, prevFound);
- if (tes) return tes;
- }
+ tes = outliner_find_name(soops, &te->subtree, name, flags, prev, prevFound);
+ if (tes) return tes;
+ }
- /* nothing valid found */
- return NULL;
+ /* nothing valid found */
+ return NULL;
}
static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOutliner *soops, int again, int flags)
{
- ReportList *reports = NULL; // CTX_wm_reports(C);
- TreeElement *te = NULL;
- TreeElement *last_find;
- TreeStoreElem *tselem;
- int ytop, xdelta, prevFound = 0;
- char name[sizeof(soops->search_string)];
-
- /* get last found tree-element based on stored search_tse */
- last_find = outliner_find_tse(soops, &soops->search_tse);
-
- /* determine which type of search to do */
- if (again && last_find) {
- /* no popup panel - previous + user wanted to search for next after previous */
- BLI_strncpy(name, soops->search_string, sizeof(name));
- flags = soops->search_flags;
-
- /* try to find matching element */
- te = outliner_find_name(soops, &soops->tree, name, flags, last_find, &prevFound);
- if (te == NULL) {
- /* no more matches after previous, start from beginning again */
- prevFound = 1;
- te = outliner_find_name(soops, &soops->tree, name, flags, last_find, &prevFound);
- }
- }
- else {
- /* pop up panel - no previous, or user didn't want search after previous */
- name[0] = '\0';
-// XXX if (sbutton(name, 0, sizeof(name) - 1, "Find: ") && name[0]) {
-// te = outliner_find_name(soops, &soops->tree, name, flags, NULL, &prevFound);
-// }
-// else return; /* XXX RETURN! XXX */
- }
-
- /* do selection and reveal */
- if (te) {
- tselem = TREESTORE(te);
- if (tselem) {
- /* expand branches so that it will be visible, we need to get correct coordinates */
- if (outliner_open_back(soops, te))
- outliner_set_coordinates(ar, soops);
-
- /* deselect all visible, and select found element */
- outliner_flag_set(soops, &soops->tree, TSE_SELECTED, 0);
- tselem->flag |= TSE_SELECTED;
-
- /* make te->ys center of view */
- ytop = (int)(te->ys + BLI_rctf_size_y(&ar->v2d.mask) / 2);
- if (ytop > 0) ytop = 0;
- ar->v2d.cur.ymax = (float)ytop;
- ar->v2d.cur.ymin = (float)(ytop - BLI_rctf_size_y(&ar->v2d.mask));
-
- /* make te->xs ==> te->xend center of view */
- xdelta = (int)(te->xs - ar->v2d.cur.xmin);
- ar->v2d.cur.xmin += xdelta;
- ar->v2d.cur.xmax += xdelta;
-
- /* store selection */
- soops->search_tse = *tselem;
-
- BLI_strncpy(soops->search_string, name, sizeof(soops->search_string));
- soops->search_flags = flags;
-
- /* redraw */
- ED_region_tag_redraw_no_rebuild(ar);
- }
- }
- else {
- /* no tree-element found */
- BKE_reportf(reports, RPT_WARNING, "Not found: %s", name);
- }
+ ReportList *reports = NULL; // CTX_wm_reports(C);
+ TreeElement *te = NULL;
+ TreeElement *last_find;
+ TreeStoreElem *tselem;
+ int ytop, xdelta, prevFound = 0;
+ char name[sizeof(soops->search_string)];
+
+ /* get last found tree-element based on stored search_tse */
+ last_find = outliner_find_tse(soops, &soops->search_tse);
+
+ /* determine which type of search to do */
+ if (again && last_find) {
+ /* no popup panel - previous + user wanted to search for next after previous */
+ BLI_strncpy(name, soops->search_string, sizeof(name));
+ flags = soops->search_flags;
+
+ /* try to find matching element */
+ te = outliner_find_name(soops, &soops->tree, name, flags, last_find, &prevFound);
+ if (te == NULL) {
+ /* no more matches after previous, start from beginning again */
+ prevFound = 1;
+ te = outliner_find_name(soops, &soops->tree, name, flags, last_find, &prevFound);
+ }
+ }
+ else {
+ /* pop up panel - no previous, or user didn't want search after previous */
+ name[0] = '\0';
+// XXX if (sbutton(name, 0, sizeof(name) - 1, "Find: ") && name[0]) {
+// te = outliner_find_name(soops, &soops->tree, name, flags, NULL, &prevFound);
+// }
+// else return; /* XXX RETURN! XXX */
+ }
+
+ /* do selection and reveal */
+ if (te) {
+ tselem = TREESTORE(te);
+ if (tselem) {
+ /* expand branches so that it will be visible, we need to get correct coordinates */
+ if (outliner_open_back(soops, te))
+ outliner_set_coordinates(ar, soops);
+
+ /* deselect all visible, and select found element */
+ outliner_flag_set(soops, &soops->tree, TSE_SELECTED, 0);
+ tselem->flag |= TSE_SELECTED;
+
+ /* make te->ys center of view */
+ ytop = (int)(te->ys + BLI_rctf_size_y(&ar->v2d.mask) / 2);
+ if (ytop > 0) ytop = 0;
+ ar->v2d.cur.ymax = (float)ytop;
+ ar->v2d.cur.ymin = (float)(ytop - BLI_rctf_size_y(&ar->v2d.mask));
+
+ /* make te->xs ==> te->xend center of view */
+ xdelta = (int)(te->xs - ar->v2d.cur.xmin);
+ ar->v2d.cur.xmin += xdelta;
+ ar->v2d.cur.xmax += xdelta;
+
+ /* store selection */
+ soops->search_tse = *tselem;
+
+ BLI_strncpy(soops->search_string, name, sizeof(soops->search_string));
+ soops->search_flags = flags;
+
+ /* redraw */
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+ }
+ else {
+ /* no tree-element found */
+ BKE_reportf(reports, RPT_WARNING, "Not found: %s", name);
+ }
}
#endif
@@ -1336,72 +1405,72 @@ static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOutliner
/* helper function for Show/Hide one level operator */
static void outliner_openclose_level(ListBase *lb, int curlevel, int level, int open)
{
- TreeElement *te;
- TreeStoreElem *tselem;
+ TreeElement *te;
+ TreeStoreElem *tselem;
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
- if (open) {
- if (curlevel <= level) {
- tselem->flag &= ~TSE_CLOSED;
- }
- }
- else {
- if (curlevel >= level) {
- tselem->flag |= TSE_CLOSED;
- }
- }
+ if (open) {
+ if (curlevel <= level) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ }
+ else {
+ if (curlevel >= level) {
+ tselem->flag |= TSE_CLOSED;
+ }
+ }
- outliner_openclose_level(&te->subtree, curlevel + 1, level, open);
- }
+ outliner_openclose_level(&te->subtree, curlevel + 1, level, open);
+ }
}
static int outliner_one_level_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- const bool add = RNA_boolean_get(op->ptr, "open");
- int level;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ const bool add = RNA_boolean_get(op->ptr, "open");
+ int level;
- level = outliner_flag_is_any_test(&soops->tree, TSE_CLOSED, 1);
- if (add == 1) {
- if (level) {
- outliner_openclose_level(&soops->tree, 1, level, 1);
- }
- }
- else {
- if (level == 0) {
- level = outliner_count_levels(&soops->tree, 0);
- }
- if (level) {
- outliner_openclose_level(&soops->tree, 1, level - 1, 0);
- }
- }
+ level = outliner_flag_is_any_test(&soops->tree, TSE_CLOSED, 1);
+ if (add == 1) {
+ if (level) {
+ outliner_openclose_level(&soops->tree, 1, level, 1);
+ }
+ }
+ else {
+ if (level == 0) {
+ level = outliner_count_levels(&soops->tree, 0);
+ }
+ if (level) {
+ outliner_openclose_level(&soops->tree, 1, level - 1, 0);
+ }
+ }
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_show_one_level(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Show/Hide One Level";
- ot->idname = "OUTLINER_OT_show_one_level";
- ot->description = "Expand/collapse all entries by one level";
+ /* identifiers */
+ ot->name = "Show/Hide One Level";
+ ot->idname = "OUTLINER_OT_show_one_level";
+ ot->description = "Expand/collapse all entries by one level";
- /* callbacks */
- ot->exec = outliner_one_level_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->exec = outliner_one_level_exec;
+ ot->poll = ED_operator_outliner_active;
- /* no undo or registry, UI option */
+ /* no undo or registry, UI option */
- /* properties */
- prop = RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* Show Hierarchy ----------------------------------------------- */
@@ -1409,86 +1478,86 @@ void OUTLINER_OT_show_one_level(wmOperatorType *ot)
/* helper function for tree_element_shwo_hierarchy() - recursively checks whether subtrees have any objects*/
static int subtree_has_objects(ListBase *lb)
{
- TreeElement *te;
- TreeStoreElem *tselem;
+ TreeElement *te;
+ TreeStoreElem *tselem;
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->type == 0 && te->idcode == ID_OB) {
- return 1;
- }
- if (subtree_has_objects(&te->subtree)) {
- return 1;
- }
- }
- return 0;
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (tselem->type == 0 && te->idcode == ID_OB) {
+ return 1;
+ }
+ if (subtree_has_objects(&te->subtree)) {
+ return 1;
+ }
+ }
+ return 0;
}
/* recursive helper function for Show Hierarchy operator */
static void tree_element_show_hierarchy(Scene *scene, SpaceOutliner *soops, ListBase *lb)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- /* open all object elems, close others */
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
-
- if (tselem->type == 0) {
- if (te->idcode == ID_SCE) {
- if (tselem->id != (ID *)scene) {
- tselem->flag |= TSE_CLOSED;
- }
- else {
- tselem->flag &= ~TSE_CLOSED;
- }
- }
- else if (te->idcode == ID_OB) {
- if (subtree_has_objects(&te->subtree)) {
- tselem->flag &= ~TSE_CLOSED;
- }
- else {
- tselem->flag |= TSE_CLOSED;
- }
- }
- }
- else {
- tselem->flag |= TSE_CLOSED;
- }
-
- if (TSELEM_OPEN(tselem, soops)) {
- tree_element_show_hierarchy(scene, soops, &te->subtree);
- }
- }
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ /* open all object elems, close others */
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+
+ if (tselem->type == 0) {
+ if (te->idcode == ID_SCE) {
+ if (tselem->id != (ID *)scene) {
+ tselem->flag |= TSE_CLOSED;
+ }
+ else {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ }
+ else if (te->idcode == ID_OB) {
+ if (subtree_has_objects(&te->subtree)) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ else {
+ tselem->flag |= TSE_CLOSED;
+ }
+ }
+ }
+ else {
+ tselem->flag |= TSE_CLOSED;
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ tree_element_show_hierarchy(scene, soops, &te->subtree);
+ }
+ }
}
/* show entire object level hierarchy */
static int outliner_show_hierarchy_exec(bContext *C, wmOperator *UNUSED(op))
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
- /* recursively open/close levels */
- tree_element_show_hierarchy(scene, soops, &soops->tree);
+ /* recursively open/close levels */
+ tree_element_show_hierarchy(scene, soops, &soops->tree);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_show_hierarchy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Show Hierarchy";
- ot->idname = "OUTLINER_OT_show_hierarchy";
- ot->description = "Open all object entries and close all others";
+ /* identifiers */
+ ot->name = "Show Hierarchy";
+ ot->idname = "OUTLINER_OT_show_hierarchy";
+ ot->description = "Open all object entries and close all others";
- /* callbacks */
- ot->exec = outliner_show_hierarchy_exec;
- ot->poll = ED_operator_outliner_active; // TODO: shouldn't be allowed in RNA views...
+ /* callbacks */
+ ot->exec = outliner_show_hierarchy_exec;
+ ot->poll = ED_operator_outliner_active; // TODO: shouldn't be allowed in RNA views...
- /* no undo or registry, UI option */
+ /* no undo or registry, UI option */
}
/* ************************************************************** */
@@ -1498,157 +1567,161 @@ void OUTLINER_OT_show_hierarchy(wmOperatorType *ot)
/* specialized poll callback for these operators to work in Datablocks view only */
static bool ed_operator_outliner_datablocks_active(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- if ((sa) && (sa->spacetype == SPACE_OUTLINER)) {
- SpaceOutliner *so = CTX_wm_space_outliner(C);
- return (so->outlinevis == SO_DATA_API);
- }
- return 0;
+ ScrArea *sa = CTX_wm_area(C);
+ if ((sa) && (sa->spacetype == SPACE_OUTLINER)) {
+ SpaceOutliner *so = CTX_wm_space_outliner(C);
+ return (so->outlinevis == SO_DATA_API);
+ }
+ return 0;
}
-
/* Helper func to extract an RNA path from selected tree element
* NOTE: the caller must zero-out all values of the pointers that it passes here first, as
* this function does not do that yet
*/
-static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
- ID **id, char **path, int *array_index, short *flag, short *UNUSED(groupmode))
-{
- ListBase hierarchy = {NULL, NULL};
- LinkData *ld;
- TreeElement *tem, *temnext, *temsub;
- TreeStoreElem *tse /* , *tsenext */ /* UNUSED */;
- PointerRNA *ptr, *nextptr;
- PropertyRNA *prop;
- char *newpath = NULL;
-
- /* optimize tricks:
- * - Don't do anything if the selected item is a 'struct', but arrays are allowed
- */
- if (tselem->type == TSE_RNA_STRUCT) {
- return;
- }
-
- /* Overview of Algorithm:
- * 1. Go up the chain of parents until we find the 'root', taking note of the
- * levels encountered in reverse-order (i.e. items are added to the start of the list
- * for more convenient looping later)
- * 2. Walk down the chain, adding from the first ID encountered
- * (which will become the 'ID' for the KeyingSet Path), and build a
- * path as we step through the chain
- */
-
- /* step 1: flatten out hierarchy of parents into a flat chain */
- for (tem = te->parent; tem; tem = tem->parent) {
- ld = MEM_callocN(sizeof(LinkData), "LinkData for tree_element_to_path()");
- ld->data = tem;
- BLI_addhead(&hierarchy, ld);
- }
-
- /* step 2: step down hierarchy building the path
- * (NOTE: addhead in previous loop was needed so that we can loop like this) */
- for (ld = hierarchy.first; ld; ld = ld->next) {
- /* get data */
- tem = (TreeElement *)ld->data;
- tse = TREESTORE(tem);
- ptr = &tem->rnaptr;
- prop = tem->directdata;
-
- /* check if we're looking for first ID, or appending to path */
- if (*id) {
- /* just 'append' property to path
- * - to prevent memory leaks, we must write to newpath not path, then free old path + swap them
- */
- if (tse->type == TSE_RNA_PROPERTY) {
- if (RNA_property_type(prop) == PROP_POINTER) {
- /* for pointer we just append property name */
- newpath = RNA_path_append(*path, ptr, prop, 0, NULL);
- }
- else if (RNA_property_type(prop) == PROP_COLLECTION) {
- char buf[128], *name;
-
- temnext = (TreeElement *)(ld->next->data);
- /* tsenext = TREESTORE(temnext); */ /* UNUSED */
-
- nextptr = &temnext->rnaptr;
- name = RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf), NULL);
-
- if (name) {
- /* if possible, use name as a key in the path */
- newpath = RNA_path_append(*path, NULL, prop, 0, name);
-
- if (name != buf) {
- MEM_freeN(name);
- }
- }
- else {
- /* otherwise use index */
- int index = 0;
-
- for (temsub = tem->subtree.first; temsub; temsub = temsub->next, index++) {
- if (temsub == temnext) {
- break;
- }
- }
- newpath = RNA_path_append(*path, NULL, prop, index, NULL);
- }
-
- ld = ld->next;
- }
- }
-
- if (newpath) {
- if (*path) {
- MEM_freeN(*path);
- }
- *path = newpath;
- newpath = NULL;
- }
- }
- else {
- /* no ID, so check if entry is RNA-struct, and if that RNA-struct is an ID datablock to extract info from */
- if (tse->type == TSE_RNA_STRUCT) {
- /* ptr->data not ptr->id.data seems to be the one we want,
- * since ptr->data is sometimes the owner of this ID? */
- if (RNA_struct_is_ID(ptr->type)) {
- *id = (ID *)ptr->data;
-
- /* clear path */
- if (*path) {
- MEM_freeN(*path);
- path = NULL;
- }
- }
- }
- }
- }
-
- /* step 3: if we've got an ID, add the current item to the path */
- if (*id) {
- /* add the active property to the path */
- ptr = &te->rnaptr;
- prop = te->directdata;
-
- /* array checks */
- if (tselem->type == TSE_RNA_ARRAY_ELEM) {
- /* item is part of an array, so must set the array_index */
- *array_index = te->index;
- }
- else if (RNA_property_array_check(prop)) {
- /* entire array was selected, so keyframe all */
- *flag |= KSP_FLAG_WHOLE_ARRAY;
- }
-
- /* path */
- newpath = RNA_path_append(*path, NULL, prop, 0, NULL);
- if (*path) {
- MEM_freeN(*path);
- }
- *path = newpath;
- }
-
- /* free temp data */
- BLI_freelistN(&hierarchy);
+static void tree_element_to_path(TreeElement *te,
+ TreeStoreElem *tselem,
+ ID **id,
+ char **path,
+ int *array_index,
+ short *flag,
+ short *UNUSED(groupmode))
+{
+ ListBase hierarchy = {NULL, NULL};
+ LinkData *ld;
+ TreeElement *tem, *temnext, *temsub;
+ TreeStoreElem *tse /* , *tsenext */ /* UNUSED */;
+ PointerRNA *ptr, *nextptr;
+ PropertyRNA *prop;
+ char *newpath = NULL;
+
+ /* optimize tricks:
+ * - Don't do anything if the selected item is a 'struct', but arrays are allowed
+ */
+ if (tselem->type == TSE_RNA_STRUCT) {
+ return;
+ }
+
+ /* Overview of Algorithm:
+ * 1. Go up the chain of parents until we find the 'root', taking note of the
+ * levels encountered in reverse-order (i.e. items are added to the start of the list
+ * for more convenient looping later)
+ * 2. Walk down the chain, adding from the first ID encountered
+ * (which will become the 'ID' for the KeyingSet Path), and build a
+ * path as we step through the chain
+ */
+
+ /* step 1: flatten out hierarchy of parents into a flat chain */
+ for (tem = te->parent; tem; tem = tem->parent) {
+ ld = MEM_callocN(sizeof(LinkData), "LinkData for tree_element_to_path()");
+ ld->data = tem;
+ BLI_addhead(&hierarchy, ld);
+ }
+
+ /* step 2: step down hierarchy building the path
+ * (NOTE: addhead in previous loop was needed so that we can loop like this) */
+ for (ld = hierarchy.first; ld; ld = ld->next) {
+ /* get data */
+ tem = (TreeElement *)ld->data;
+ tse = TREESTORE(tem);
+ ptr = &tem->rnaptr;
+ prop = tem->directdata;
+
+ /* check if we're looking for first ID, or appending to path */
+ if (*id) {
+ /* just 'append' property to path
+ * - to prevent memory leaks, we must write to newpath not path, then free old path + swap them
+ */
+ if (tse->type == TSE_RNA_PROPERTY) {
+ if (RNA_property_type(prop) == PROP_POINTER) {
+ /* for pointer we just append property name */
+ newpath = RNA_path_append(*path, ptr, prop, 0, NULL);
+ }
+ else if (RNA_property_type(prop) == PROP_COLLECTION) {
+ char buf[128], *name;
+
+ temnext = (TreeElement *)(ld->next->data);
+ /* tsenext = TREESTORE(temnext); */ /* UNUSED */
+
+ nextptr = &temnext->rnaptr;
+ name = RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf), NULL);
+
+ if (name) {
+ /* if possible, use name as a key in the path */
+ newpath = RNA_path_append(*path, NULL, prop, 0, name);
+
+ if (name != buf) {
+ MEM_freeN(name);
+ }
+ }
+ else {
+ /* otherwise use index */
+ int index = 0;
+
+ for (temsub = tem->subtree.first; temsub; temsub = temsub->next, index++) {
+ if (temsub == temnext) {
+ break;
+ }
+ }
+ newpath = RNA_path_append(*path, NULL, prop, index, NULL);
+ }
+
+ ld = ld->next;
+ }
+ }
+
+ if (newpath) {
+ if (*path) {
+ MEM_freeN(*path);
+ }
+ *path = newpath;
+ newpath = NULL;
+ }
+ }
+ else {
+ /* no ID, so check if entry is RNA-struct, and if that RNA-struct is an ID datablock to extract info from */
+ if (tse->type == TSE_RNA_STRUCT) {
+ /* ptr->data not ptr->id.data seems to be the one we want,
+ * since ptr->data is sometimes the owner of this ID? */
+ if (RNA_struct_is_ID(ptr->type)) {
+ *id = (ID *)ptr->data;
+
+ /* clear path */
+ if (*path) {
+ MEM_freeN(*path);
+ path = NULL;
+ }
+ }
+ }
+ }
+ }
+
+ /* step 3: if we've got an ID, add the current item to the path */
+ if (*id) {
+ /* add the active property to the path */
+ ptr = &te->rnaptr;
+ prop = te->directdata;
+
+ /* array checks */
+ if (tselem->type == TSE_RNA_ARRAY_ELEM) {
+ /* item is part of an array, so must set the array_index */
+ *array_index = te->index;
+ }
+ else if (RNA_property_array_check(prop)) {
+ /* entire array was selected, so keyframe all */
+ *flag |= KSP_FLAG_WHOLE_ARRAY;
+ }
+
+ /* path */
+ newpath = RNA_path_append(*path, NULL, prop, 0, NULL);
+ if (*path) {
+ MEM_freeN(*path);
+ }
+ *path = newpath;
+ }
+
+ /* free temp data */
+ BLI_freelistN(&hierarchy);
}
/* =============================================== */
@@ -1658,159 +1731,155 @@ static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
* they depend on having RNA paths and/or hierarchies available.
*/
enum {
- DRIVERS_EDITMODE_ADD = 0,
- DRIVERS_EDITMODE_REMOVE,
+ DRIVERS_EDITMODE_ADD = 0,
+ DRIVERS_EDITMODE_REMOVE,
} /*eDrivers_EditModes*/;
/* Utilities ---------------------------------- */
/* Recursively iterate over tree, finding and working on selected items */
-static void do_outliner_drivers_editop(SpaceOutliner *soops, ListBase *tree, ReportList *reports, short mode)
-{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = tree->first; te; te = te->next) {
- tselem = TREESTORE(te);
-
- /* if item is selected, perform operation */
- if (tselem->flag & TSE_SELECTED) {
- ID *id = NULL;
- char *path = NULL;
- int array_index = 0;
- short flag = 0;
- short groupmode = KSP_GROUP_KSNAME;
-
- /* check if RNA-property described by this selected element is an animatable prop */
- if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
- RNA_property_animateable(&te->rnaptr, te->directdata))
- {
- /* get id + path + index info from the selected element */
- tree_element_to_path(te, tselem,
- &id, &path, &array_index, &flag, &groupmode);
- }
-
- /* only if ID and path were set, should we perform any actions */
- if (id && path) {
- short dflags = CREATEDRIVER_WITH_DEFAULT_DVAR;
- int arraylen = 1;
-
- /* array checks */
- if (flag & KSP_FLAG_WHOLE_ARRAY) {
- /* entire array was selected, so add drivers for all */
- arraylen = RNA_property_array_length(&te->rnaptr, te->directdata);
- }
- else {
- arraylen = array_index;
- }
-
- /* we should do at least one step */
- if (arraylen == array_index) {
- arraylen++;
- }
-
- /* for each array element we should affect, add driver */
- for (; array_index < arraylen; array_index++) {
- /* action depends on mode */
- switch (mode) {
- case DRIVERS_EDITMODE_ADD:
- {
- /* add a new driver with the information obtained (only if valid) */
- ANIM_add_driver(reports, id, path, array_index, dflags, DRIVER_TYPE_PYTHON);
- break;
- }
- case DRIVERS_EDITMODE_REMOVE:
- {
- /* remove driver matching the information obtained (only if valid) */
- ANIM_remove_driver(reports, id, path, array_index, dflags);
- break;
- }
- }
- }
-
- /* free path, since it had to be generated */
- MEM_freeN(path);
- }
-
-
- }
-
- /* go over sub-tree */
- if (TSELEM_OPEN(tselem, soops)) {
- do_outliner_drivers_editop(soops, &te->subtree, reports, mode);
- }
- }
+static void do_outliner_drivers_editop(SpaceOutliner *soops,
+ ListBase *tree,
+ ReportList *reports,
+ short mode)
+{
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ for (te = tree->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+
+ /* if item is selected, perform operation */
+ if (tselem->flag & TSE_SELECTED) {
+ ID *id = NULL;
+ char *path = NULL;
+ int array_index = 0;
+ short flag = 0;
+ short groupmode = KSP_GROUP_KSNAME;
+
+ /* check if RNA-property described by this selected element is an animatable prop */
+ if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
+ RNA_property_animateable(&te->rnaptr, te->directdata)) {
+ /* get id + path + index info from the selected element */
+ tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode);
+ }
+
+ /* only if ID and path were set, should we perform any actions */
+ if (id && path) {
+ short dflags = CREATEDRIVER_WITH_DEFAULT_DVAR;
+ int arraylen = 1;
+
+ /* array checks */
+ if (flag & KSP_FLAG_WHOLE_ARRAY) {
+ /* entire array was selected, so add drivers for all */
+ arraylen = RNA_property_array_length(&te->rnaptr, te->directdata);
+ }
+ else {
+ arraylen = array_index;
+ }
+
+ /* we should do at least one step */
+ if (arraylen == array_index) {
+ arraylen++;
+ }
+
+ /* for each array element we should affect, add driver */
+ for (; array_index < arraylen; array_index++) {
+ /* action depends on mode */
+ switch (mode) {
+ case DRIVERS_EDITMODE_ADD: {
+ /* add a new driver with the information obtained (only if valid) */
+ ANIM_add_driver(reports, id, path, array_index, dflags, DRIVER_TYPE_PYTHON);
+ break;
+ }
+ case DRIVERS_EDITMODE_REMOVE: {
+ /* remove driver matching the information obtained (only if valid) */
+ ANIM_remove_driver(reports, id, path, array_index, dflags);
+ break;
+ }
+ }
+ }
+
+ /* free path, since it had to be generated */
+ MEM_freeN(path);
+ }
+ }
+
+ /* go over sub-tree */
+ if (TSELEM_OPEN(tselem, soops)) {
+ do_outliner_drivers_editop(soops, &te->subtree, reports, mode);
+ }
+ }
}
/* Add Operator ---------------------------------- */
static int outliner_drivers_addsel_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
+ SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
- /* check for invalid states */
- if (soutliner == NULL) {
- return OPERATOR_CANCELLED;
- }
+ /* check for invalid states */
+ if (soutliner == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- /* recursively go into tree, adding selected items */
- do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_ADD);
+ /* recursively go into tree, adding selected items */
+ do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_ADD);
- /* send notifiers */
- WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_drivers_add_selected(wmOperatorType *ot)
{
- /* api callbacks */
- ot->idname = "OUTLINER_OT_drivers_add_selected";
- ot->name = "Add Drivers for Selected";
- ot->description = "Add drivers to selected items";
+ /* api callbacks */
+ ot->idname = "OUTLINER_OT_drivers_add_selected";
+ ot->name = "Add Drivers for Selected";
+ ot->description = "Add drivers to selected items";
- /* api callbacks */
- ot->exec = outliner_drivers_addsel_exec;
- ot->poll = ed_operator_outliner_datablocks_active;
+ /* api callbacks */
+ ot->exec = outliner_drivers_addsel_exec;
+ ot->poll = ed_operator_outliner_datablocks_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
/* Remove Operator ---------------------------------- */
static int outliner_drivers_deletesel_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
+ SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
- /* check for invalid states */
- if (soutliner == NULL) {
- return OPERATOR_CANCELLED;
- }
+ /* check for invalid states */
+ if (soutliner == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- /* recursively go into tree, adding selected items */
- do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_REMOVE);
+ /* recursively go into tree, adding selected items */
+ do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_REMOVE);
- /* send notifiers */
- WM_event_add_notifier(C, ND_KEYS, NULL); // XXX
+ /* send notifiers */
+ WM_event_add_notifier(C, ND_KEYS, NULL); // XXX
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_drivers_delete_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->idname = "OUTLINER_OT_drivers_delete_selected";
- ot->name = "Delete Drivers for Selected";
- ot->description = "Delete drivers assigned to selected items";
+ /* identifiers */
+ ot->idname = "OUTLINER_OT_drivers_delete_selected";
+ ot->name = "Delete Drivers for Selected";
+ ot->description = "Delete drivers assigned to selected items";
- /* api callbacks */
- ot->exec = outliner_drivers_deletesel_exec;
- ot->poll = ed_operator_outliner_datablocks_active;
+ /* api callbacks */
+ ot->exec = outliner_drivers_deletesel_exec;
+ ot->poll = ed_operator_outliner_datablocks_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* =============================================== */
@@ -1820,8 +1889,8 @@ void OUTLINER_OT_drivers_delete_selected(wmOperatorType *ot)
* they depend on having RNA paths and/or hierarchies available.
*/
enum {
- KEYINGSET_EDITMODE_ADD = 0,
- KEYINGSET_EDITMODE_REMOVE,
+ KEYINGSET_EDITMODE_ADD = 0,
+ KEYINGSET_EDITMODE_REMOVE,
} /*eKeyingSet_EditModes*/;
/* Utilities ---------------------------------- */
@@ -1830,300 +1899,298 @@ enum {
// TODO: should this be an API func?
static KeyingSet *verify_active_keyingset(Scene *scene, short add)
{
- KeyingSet *ks = NULL;
+ KeyingSet *ks = NULL;
- /* sanity check */
- if (scene == NULL) {
- return NULL;
- }
+ /* sanity check */
+ if (scene == NULL) {
+ return NULL;
+ }
- /* try to find one from scene */
- if (scene->active_keyingset > 0) {
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- }
+ /* try to find one from scene */
+ if (scene->active_keyingset > 0) {
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+ }
- /* add if none found */
- // XXX the default settings have yet to evolve
- if ((add) && (ks == NULL)) {
- ks = BKE_keyingset_add(&scene->keyingsets, NULL, NULL, KEYINGSET_ABSOLUTE, 0);
- scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
- }
+ /* add if none found */
+ // XXX the default settings have yet to evolve
+ if ((add) && (ks == NULL)) {
+ ks = BKE_keyingset_add(&scene->keyingsets, NULL, NULL, KEYINGSET_ABSOLUTE, 0);
+ scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
+ }
- return ks;
+ return ks;
}
/* Recursively iterate over tree, finding and working on selected items */
-static void do_outliner_keyingset_editop(SpaceOutliner *soops, KeyingSet *ks, ListBase *tree, short mode)
-{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = tree->first; te; te = te->next) {
- tselem = TREESTORE(te);
-
- /* if item is selected, perform operation */
- if (tselem->flag & TSE_SELECTED) {
- ID *id = NULL;
- char *path = NULL;
- int array_index = 0;
- short flag = 0;
- short groupmode = KSP_GROUP_KSNAME;
-
- /* check if RNA-property described by this selected element is an animatable prop */
- if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
- RNA_property_animateable(&te->rnaptr, te->directdata))
- {
- /* get id + path + index info from the selected element */
- tree_element_to_path(te, tselem,
- &id, &path, &array_index, &flag, &groupmode);
- }
-
- /* only if ID and path were set, should we perform any actions */
- if (id && path) {
- /* action depends on mode */
- switch (mode) {
- case KEYINGSET_EDITMODE_ADD:
- {
- /* add a new path with the information obtained (only if valid) */
- /* TODO: what do we do with group name?
- * for now, we don't supply one, and just let this use the KeyingSet name */
- BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode);
- ks->active_path = BLI_listbase_count(&ks->paths);
- break;
- }
- case KEYINGSET_EDITMODE_REMOVE:
- {
- /* find the relevant path, then remove it from the KeyingSet */
- KS_Path *ksp = BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode);
-
- if (ksp) {
- /* free path's data */
- BKE_keyingset_free_path(ks, ksp);
-
- ks->active_path = 0;
- }
- break;
- }
- }
-
- /* free path, since it had to be generated */
- MEM_freeN(path);
- }
- }
-
- /* go over sub-tree */
- if (TSELEM_OPEN(tselem, soops)) {
- do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
- }
- }
+static void do_outliner_keyingset_editop(SpaceOutliner *soops,
+ KeyingSet *ks,
+ ListBase *tree,
+ short mode)
+{
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ for (te = tree->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+
+ /* if item is selected, perform operation */
+ if (tselem->flag & TSE_SELECTED) {
+ ID *id = NULL;
+ char *path = NULL;
+ int array_index = 0;
+ short flag = 0;
+ short groupmode = KSP_GROUP_KSNAME;
+
+ /* check if RNA-property described by this selected element is an animatable prop */
+ if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
+ RNA_property_animateable(&te->rnaptr, te->directdata)) {
+ /* get id + path + index info from the selected element */
+ tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode);
+ }
+
+ /* only if ID and path were set, should we perform any actions */
+ if (id && path) {
+ /* action depends on mode */
+ switch (mode) {
+ case KEYINGSET_EDITMODE_ADD: {
+ /* add a new path with the information obtained (only if valid) */
+ /* TODO: what do we do with group name?
+ * for now, we don't supply one, and just let this use the KeyingSet name */
+ BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode);
+ ks->active_path = BLI_listbase_count(&ks->paths);
+ break;
+ }
+ case KEYINGSET_EDITMODE_REMOVE: {
+ /* find the relevant path, then remove it from the KeyingSet */
+ KS_Path *ksp = BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode);
+
+ if (ksp) {
+ /* free path's data */
+ BKE_keyingset_free_path(ks, ksp);
+
+ ks->active_path = 0;
+ }
+ break;
+ }
+ }
+
+ /* free path, since it had to be generated */
+ MEM_freeN(path);
+ }
+ }
+
+ /* go over sub-tree */
+ if (TSELEM_OPEN(tselem, soops)) {
+ do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
+ }
+ }
}
/* Add Operator ---------------------------------- */
static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks = verify_active_keyingset(scene, 1);
+ SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks = verify_active_keyingset(scene, 1);
- /* check for invalid states */
- if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Operation requires an active keying set");
- return OPERATOR_CANCELLED;
- }
- if (soutliner == NULL) {
- return OPERATOR_CANCELLED;
- }
+ /* check for invalid states */
+ if (ks == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Operation requires an active keying set");
+ return OPERATOR_CANCELLED;
+ }
+ if (soutliner == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- /* recursively go into tree, adding selected items */
- do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_ADD);
+ /* recursively go into tree, adding selected items */
+ do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_ADD);
- /* send notifiers */
- WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->idname = "OUTLINER_OT_keyingset_add_selected";
- ot->name = "Keying Set Add Selected";
- ot->description = "Add selected items (blue-gray rows) to active Keying Set";
+ /* identifiers */
+ ot->idname = "OUTLINER_OT_keyingset_add_selected";
+ ot->name = "Keying Set Add Selected";
+ ot->description = "Add selected items (blue-gray rows) to active Keying Set";
- /* api callbacks */
- ot->exec = outliner_keyingset_additems_exec;
- ot->poll = ed_operator_outliner_datablocks_active;
+ /* api callbacks */
+ ot->exec = outliner_keyingset_additems_exec;
+ ot->poll = ed_operator_outliner_datablocks_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
/* Remove Operator ---------------------------------- */
static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator *UNUSED(op))
{
- SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks = verify_active_keyingset(scene, 1);
+ SpaceOutliner *soutliner = CTX_wm_space_outliner(C);
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks = verify_active_keyingset(scene, 1);
- /* check for invalid states */
- if (soutliner == NULL) {
- return OPERATOR_CANCELLED;
- }
+ /* check for invalid states */
+ if (soutliner == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- /* recursively go into tree, adding selected items */
- do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_REMOVE);
+ /* recursively go into tree, adding selected items */
+ do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_REMOVE);
- /* send notifiers */
- WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->idname = "OUTLINER_OT_keyingset_remove_selected";
- ot->name = "Keying Set Remove Selected";
- ot->description = "Remove selected items (blue-gray rows) from active Keying Set";
+ /* identifiers */
+ ot->idname = "OUTLINER_OT_keyingset_remove_selected";
+ ot->name = "Keying Set Remove Selected";
+ ot->description = "Remove selected items (blue-gray rows) from active Keying Set";
- /* api callbacks */
- ot->exec = outliner_keyingset_removeitems_exec;
- ot->poll = ed_operator_outliner_datablocks_active;
+ /* api callbacks */
+ ot->exec = outliner_keyingset_removeitems_exec;
+ ot->poll = ed_operator_outliner_datablocks_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
/* ************************************************************** */
/* ORPHANED DATABLOCKS */
static bool ed_operator_outliner_id_orphans_active(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- if ((sa) && (sa->spacetype == SPACE_OUTLINER)) {
- SpaceOutliner *so = CTX_wm_space_outliner(C);
- return (so->outlinevis == SO_ID_ORPHANS);
- }
- return 0;
+ ScrArea *sa = CTX_wm_area(C);
+ if ((sa) && (sa->spacetype == SPACE_OUTLINER)) {
+ SpaceOutliner *so = CTX_wm_space_outliner(C);
+ return (so->outlinevis == SO_ID_ORPHANS);
+ }
+ return 0;
}
/* Purge Orphans Operator --------------------------------------- */
static void outliner_orphans_purge_tag(ID *id, int *num_tagged)
{
- if (id->us == 0) {
- id->tag |= LIB_TAG_DOIT;
- num_tagged[INDEX_ID_NULL]++;
- num_tagged[BKE_idcode_to_index(GS(id->name))]++;
- }
- else {
- id->tag &= ~LIB_TAG_DOIT;
- }
+ if (id->us == 0) {
+ id->tag |= LIB_TAG_DOIT;
+ num_tagged[INDEX_ID_NULL]++;
+ num_tagged[BKE_idcode_to_index(GS(id->name))]++;
+ }
+ else {
+ id->tag &= ~LIB_TAG_DOIT;
+ }
}
static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
{
- Main *bmain = CTX_data_main(C);
- int num_tagged[INDEX_ID_MAX] = {0};
-
- /* Tag all IDs having zero users. */
- ID *id;
- FOREACH_MAIN_ID_BEGIN(bmain, id)
- {
- outliner_orphans_purge_tag(id, num_tagged);
- }
- FOREACH_MAIN_ID_END;
- RNA_int_set(op->ptr, "num_deleted", num_tagged[INDEX_ID_NULL]);
-
- if (num_tagged[INDEX_ID_NULL] == 0) {
- BKE_report(op->reports, RPT_INFO, "No orphanned data-blocks to purge");
- return OPERATOR_CANCELLED;
- }
-
- DynStr *dyn_str = BLI_dynstr_new();
- BLI_dynstr_append(dyn_str, "Purging unused data-blocks (");
- bool is_first = true;
- for (int i = 0; i < INDEX_ID_MAX - 2; i++) {
- if (num_tagged[i] != 0) {
- if (!is_first) {
- BLI_dynstr_append(dyn_str, ", ");
- }
- else {
- is_first = false;
- }
- BLI_dynstr_appendf(
- dyn_str, "%d %s",
- num_tagged[i], TIP_(BKE_idcode_to_name_plural(BKE_idcode_from_index(i))));
- }
- }
- BLI_dynstr_append(dyn_str, TIP_("). Click here to proceed..."));
-
- char *message = BLI_dynstr_get_cstring(dyn_str);
- int ret = WM_operator_confirm_message(C, op, message);
-
- MEM_freeN(message);
- BLI_dynstr_free(dyn_str);
- return ret;
+ Main *bmain = CTX_data_main(C);
+ int num_tagged[INDEX_ID_MAX] = {0};
+
+ /* Tag all IDs having zero users. */
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN(bmain, id)
+ {
+ outliner_orphans_purge_tag(id, num_tagged);
+ }
+ FOREACH_MAIN_ID_END;
+ RNA_int_set(op->ptr, "num_deleted", num_tagged[INDEX_ID_NULL]);
+
+ if (num_tagged[INDEX_ID_NULL] == 0) {
+ BKE_report(op->reports, RPT_INFO, "No orphanned data-blocks to purge");
+ return OPERATOR_CANCELLED;
+ }
+
+ DynStr *dyn_str = BLI_dynstr_new();
+ BLI_dynstr_append(dyn_str, "Purging unused data-blocks (");
+ bool is_first = true;
+ for (int i = 0; i < INDEX_ID_MAX - 2; i++) {
+ if (num_tagged[i] != 0) {
+ if (!is_first) {
+ BLI_dynstr_append(dyn_str, ", ");
+ }
+ else {
+ is_first = false;
+ }
+ BLI_dynstr_appendf(dyn_str,
+ "%d %s",
+ num_tagged[i],
+ TIP_(BKE_idcode_to_name_plural(BKE_idcode_from_index(i))));
+ }
+ }
+ BLI_dynstr_append(dyn_str, TIP_("). Click here to proceed..."));
+
+ char *message = BLI_dynstr_get_cstring(dyn_str);
+ int ret = WM_operator_confirm_message(C, op, message);
+
+ MEM_freeN(message);
+ BLI_dynstr_free(dyn_str);
+ return ret;
}
static int outliner_orphans_purge_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int num_tagged[INDEX_ID_MAX] = {0};
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int num_tagged[INDEX_ID_MAX] = {0};
- if ((num_tagged[INDEX_ID_NULL] = RNA_int_get(op->ptr, "num_deleted")) == 0) {
- /* Tag all IDs having zero users. */
- ID *id;
- FOREACH_MAIN_ID_BEGIN(bmain, id)
- {
- outliner_orphans_purge_tag(id, num_tagged);
- }
- FOREACH_MAIN_ID_END;
+ if ((num_tagged[INDEX_ID_NULL] = RNA_int_get(op->ptr, "num_deleted")) == 0) {
+ /* Tag all IDs having zero users. */
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN(bmain, id)
+ {
+ outliner_orphans_purge_tag(id, num_tagged);
+ }
+ FOREACH_MAIN_ID_END;
- if (num_tagged[INDEX_ID_NULL] == 0) {
- BKE_report(op->reports, RPT_INFO, "No orphanned data-blocks to purge");
- return OPERATOR_CANCELLED;
- }
- }
+ if (num_tagged[INDEX_ID_NULL] == 0) {
+ BKE_report(op->reports, RPT_INFO, "No orphanned data-blocks to purge");
+ return OPERATOR_CANCELLED;
+ }
+ }
- BKE_id_multi_tagged_delete(bmain);
+ BKE_id_multi_tagged_delete(bmain);
- BKE_reportf(op->reports, RPT_INFO, "Deleted %d data-blocks", num_tagged[INDEX_ID_NULL]);
+ BKE_reportf(op->reports, RPT_INFO, "Deleted %d data-blocks", num_tagged[INDEX_ID_NULL]);
- /* XXX: tree management normally happens from draw_outliner(), but when
- * you're clicking to fast on Delete object from context menu in
- * outliner several mouse events can be handled in one cycle without
- * handling notifiers/redraw which leads to deleting the same object twice.
- * cleanup tree here to prevent such cases. */
- outliner_cleanup_tree(soops);
+ /* XXX: tree management normally happens from draw_outliner(), but when
+ * you're clicking to fast on Delete object from context menu in
+ * outliner several mouse events can be handled in one cycle without
+ * handling notifiers/redraw which leads to deleting the same object twice.
+ * cleanup tree here to prevent such cases. */
+ outliner_cleanup_tree(soops);
- DEG_relations_tag_update(bmain);
- WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
- return OPERATOR_FINISHED;
+ DEG_relations_tag_update(bmain);
+ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
{
- /* identifiers */
- ot->idname = "OUTLINER_OT_orphans_purge";
- ot->name = "Purge All";
- ot->description = "Clear all orphaned data-blocks without any users from the file";
+ /* identifiers */
+ ot->idname = "OUTLINER_OT_orphans_purge";
+ ot->name = "Purge All";
+ ot->description = "Clear all orphaned data-blocks without any users from the file";
- /* callbacks */
- ot->invoke = outliner_orphans_purge_invoke;
- ot->exec = outliner_orphans_purge_exec;
- ot->poll = ed_operator_outliner_id_orphans_active;
+ /* callbacks */
+ ot->invoke = outliner_orphans_purge_invoke;
+ ot->exec = outliner_orphans_purge_exec;
+ ot->poll = ed_operator_outliner_id_orphans_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- PropertyRNA *prop = RNA_def_int(ot->srna, "num_deleted", 0, 0, INT_MAX, "", "", 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+ /* properties */
+ PropertyRNA *prop = RNA_def_int(ot->srna, "num_deleted", 0, 0, INT_MAX, "", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 57fed22d36b..d382384076b 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -21,7 +21,6 @@
* \ingroup spoutliner
*/
-
#ifndef __OUTLINER_INTERN_H__
#define __OUTLINER_INTERN_H__
@@ -46,73 +45,106 @@ struct wmKeyConfig;
struct wmOperatorType;
typedef enum TreeElementInsertType {
- TE_INSERT_BEFORE,
- TE_INSERT_AFTER,
- TE_INSERT_INTO,
+ TE_INSERT_BEFORE,
+ TE_INSERT_AFTER,
+ TE_INSERT_INTO,
} TreeElementInsertType;
typedef enum TreeTraversalAction {
- /* Continue traversal regularly, don't skip children. */
- TRAVERSE_CONTINUE = 0,
- /* Stop traversal */
- TRAVERSE_BREAK,
- /* Continue traversal, but skip childs of traversed element */
- TRAVERSE_SKIP_CHILDS,
+ /* Continue traversal regularly, don't skip children. */
+ TRAVERSE_CONTINUE = 0,
+ /* Stop traversal */
+ TRAVERSE_BREAK,
+ /* Continue traversal, but skip childs of traversed element */
+ TRAVERSE_SKIP_CHILDS,
} TreeTraversalAction;
typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *customdata);
-
typedef struct TreeElement {
- struct TreeElement *next, *prev, *parent;
- ListBase subtree;
- int xs, ys; // do selection
- TreeStoreElem *store_elem; // element in tree store
- short flag; // flag for non-saved stuff
- short index; // index for data arrays
- short idcode; // from TreeStore id
- short xend; // width of item display, for select
- const char *name;
- void *directdata; // Armature Bones, Base, Sequence, Strip...
- PointerRNA rnaptr; // RNA Pointer
+ struct TreeElement *next, *prev, *parent;
+ ListBase subtree;
+ int xs, ys; // do selection
+ TreeStoreElem *store_elem; // element in tree store
+ short flag; // flag for non-saved stuff
+ short index; // index for data arrays
+ short idcode; // from TreeStore id
+ short xend; // width of item display, for select
+ const char *name;
+ void *directdata; // Armature Bones, Base, Sequence, Strip...
+ PointerRNA rnaptr; // RNA Pointer
} TreeElement;
typedef struct TreeElementIcon {
- struct ID *drag_id, *drag_parent;
- int icon;
+ struct ID *drag_id, *drag_parent;
+ int icon;
} TreeElementIcon;
#define TREESTORE_ID_TYPE(_id) \
- (ELEM(GS((_id)->name), ID_SCE, ID_LI, ID_OB, ID_ME, ID_CU, ID_MB, ID_NT, ID_MA, ID_TE, ID_IM, ID_LT, ID_LA, ID_CA) || \
- ELEM(GS((_id)->name), ID_KE, ID_WO, ID_SPK, ID_GR, ID_AR, ID_AC, ID_BR, ID_PA, ID_GD, ID_LS, ID_LP) || \
- /* Only in 'blendfile' mode ... :/ */ \
- ELEM(GS((_id)->name), ID_SCR, ID_WM, ID_TXT, ID_VF, ID_SO, ID_CF, ID_PAL, ID_MC, ID_WS, ID_MSK, ID_PC))
+ (ELEM(GS((_id)->name), \
+ ID_SCE, \
+ ID_LI, \
+ ID_OB, \
+ ID_ME, \
+ ID_CU, \
+ ID_MB, \
+ ID_NT, \
+ ID_MA, \
+ ID_TE, \
+ ID_IM, \
+ ID_LT, \
+ ID_LA, \
+ ID_CA) || \
+ ELEM(GS((_id)->name), \
+ ID_KE, \
+ ID_WO, \
+ ID_SPK, \
+ ID_GR, \
+ ID_AR, \
+ ID_AC, \
+ ID_BR, \
+ ID_PA, \
+ ID_GD, \
+ ID_LS, \
+ ID_LP) || /* Only in 'blendfile' mode ... :/ */ \
+ ELEM(GS((_id)->name), \
+ ID_SCR, \
+ ID_WM, \
+ ID_TXT, \
+ ID_VF, \
+ ID_SO, \
+ ID_CF, \
+ ID_PAL, \
+ ID_MC, \
+ ID_WS, \
+ ID_MSK, \
+ ID_PC))
/* TreeElement->flag */
enum {
- TE_ACTIVE = (1 << 0),
- /* Closed items display their children as icon within the row. TE_ICONROW is for
- * these child-items that are visible but only within the row of the closed parent. */
- TE_ICONROW = (1 << 1),
- TE_LAZY_CLOSED = (1 << 2),
- TE_FREE_NAME = (1 << 3),
- TE_DISABLED = (1 << 4),
- TE_DRAGGING = (1 << 5),
+ TE_ACTIVE = (1 << 0),
+ /* Closed items display their children as icon within the row. TE_ICONROW is for
+ * these child-items that are visible but only within the row of the closed parent. */
+ TE_ICONROW = (1 << 1),
+ TE_LAZY_CLOSED = (1 << 2),
+ TE_FREE_NAME = (1 << 3),
+ TE_DISABLED = (1 << 4),
+ TE_DRAGGING = (1 << 5),
};
/* button events */
-#define OL_NAMEBUTTON 1
+#define OL_NAMEBUTTON 1
typedef enum {
- OL_DRAWSEL_NONE = 0, /* inactive (regular black text) */
- OL_DRAWSEL_NORMAL = 1, /* active object (draws white text) */
- OL_DRAWSEL_ACTIVE = 2, /* active obdata (draws a circle around the icon) */
+ OL_DRAWSEL_NONE = 0, /* inactive (regular black text) */
+ OL_DRAWSEL_NORMAL = 1, /* active object (draws white text) */
+ OL_DRAWSEL_ACTIVE = 2, /* active obdata (draws a circle around the icon) */
} eOLDrawState;
typedef enum {
- OL_SETSEL_NONE = 0, /* don't change the selection state */
- OL_SETSEL_NORMAL = 1, /* select the item */
- OL_SETSEL_EXTEND = 2, /* select the item and extend (also toggles selection) */
+ OL_SETSEL_NONE = 0, /* don't change the selection state */
+ OL_SETSEL_NORMAL = 1, /* select the item */
+ OL_SETSEL_EXTEND = 2, /* select the item and extend (also toggles selection) */
} eOLSetState;
/* get TreeStoreElem associated with a TreeElement
@@ -124,14 +156,14 @@ typedef enum {
#define OL_Y_OFFSET 2
#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 3.0f + V2D_SCROLL_WIDTH)
-#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH)
+#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH)
#define OL_TOG_RESTRICT_RENDERX (UI_UNIT_X + V2D_SCROLL_WIDTH)
#define OL_TOGW OL_TOG_RESTRICT_SELECTX
-#define OL_RNA_COLX (UI_UNIT_X * 15)
-#define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)
-#define OL_RNA_COL_SPACEX (UI_UNIT_X * 2.5f)
+#define OL_RNA_COLX (UI_UNIT_X * 15)
+#define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)
+#define OL_RNA_COL_SPACEX (UI_UNIT_X * 2.5f)
/* The outliner display modes that support the filter system.
* Note: keep it synced with space_outliner.py */
@@ -153,10 +185,11 @@ typedef enum {
* - not searching into RNA items helps but isn't the complete solution
*/
-#define SEARCHING_OUTLINER(sov) (sov->search_flags & SO_SEARCH_RECURSIVE)
+#define SEARCHING_OUTLINER(sov) (sov->search_flags & SO_SEARCH_RECURSIVE)
/* is the current element open? if so we also show children */
-#define TSELEM_OPEN(telm, sv) ( (telm->flag & TSE_CLOSED) == 0 || (SEARCHING_OUTLINER(sv) && (telm->flag & TSE_CHILDSEARCH)) )
+#define TSELEM_OPEN(telm, sv) \
+ ((telm->flag & TSE_CLOSED) == 0 || (SEARCHING_OUTLINER(sv) && (telm->flag & TSE_CHILDSEARCH)))
/* outliner_tree.c ----------------------------------------------- */
@@ -164,13 +197,14 @@ void outliner_free_tree(ListBase *tree);
void outliner_cleanup_tree(struct SpaceOutliner *soops);
void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree);
-void outliner_build_tree(
- struct Main *mainvar,
- struct Scene *scene, struct ViewLayer *view_layer,
- struct SpaceOutliner *soops, struct ARegion *ar);
+void outliner_build_tree(struct Main *mainvar,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct SpaceOutliner *soops,
+ struct ARegion *ar);
typedef struct IDsSelectedData {
- struct ListBase selected_array;
+ struct ListBase selected_array;
} IDsSelectedData;
TreeTraversalAction outliner_find_selected_collections(struct TreeElement *te, void *customdata);
@@ -183,38 +217,62 @@ void draw_outliner(const struct bContext *C);
TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te);
/* outliner_select.c -------------------------------------------- */
-eOLDrawState tree_element_type_active(
- struct bContext *C, struct Scene *scene, struct ViewLayer *view_layer, struct SpaceOutliner *soops,
- TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive);
-eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, struct ViewLayer *view_layer, SpaceOutliner *soops,
- TreeElement *te, const eOLSetState set, const bool handle_all_types);
+eOLDrawState tree_element_type_active(struct bContext *C,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct SpaceOutliner *soops,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set,
+ bool recursive);
+eOLDrawState tree_element_active(struct bContext *C,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ const eOLSetState set,
+ const bool handle_all_types);
void outliner_item_do_activate_from_tree_element(
- struct bContext *C, TreeElement *te, TreeStoreElem *tselem,
- bool extend, bool recursive);
-int outliner_item_do_activate_from_cursor(
- struct bContext *C, const int mval[2],
- bool extend, bool recursive);
-
-void outliner_item_select(
- struct SpaceOutliner *soops, const struct TreeElement *te,
- const bool extend, const bool toggle);
-
-void outliner_object_mode_toggle(
- struct bContext *C, Scene *scene, ViewLayer *view_layer,
- Base *base);
+ struct bContext *C, TreeElement *te, TreeStoreElem *tselem, bool extend, bool recursive);
+int outliner_item_do_activate_from_cursor(struct bContext *C,
+ const int mval[2],
+ bool extend,
+ bool recursive);
+
+void outliner_item_select(struct SpaceOutliner *soops,
+ const struct TreeElement *te,
+ const bool extend,
+ const bool toggle);
+
+void outliner_object_mode_toggle(struct bContext *C,
+ Scene *scene,
+ ViewLayer *view_layer,
+ Base *base);
/* outliner_edit.c ---------------------------------------------- */
-typedef void (*outliner_operation_cb)(
- struct bContext *C, struct ReportList *, struct Scene *scene,
- struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *, void *);
-
-void outliner_do_object_operation_ex(
- struct bContext *C, struct ReportList *reports, struct Scene *scene, struct SpaceOutliner *soops,
- struct ListBase *lb, outliner_operation_cb operation_cb, void *user_data, bool recurse_selected);
-void outliner_do_object_operation(
- struct bContext *C, struct ReportList *reports, struct Scene *scene, struct SpaceOutliner *soops,
- struct ListBase *lb, outliner_operation_cb operation_cb);
+typedef void (*outliner_operation_cb)(struct bContext *C,
+ struct ReportList *,
+ struct Scene *scene,
+ struct TreeElement *,
+ struct TreeStoreElem *,
+ TreeStoreElem *,
+ void *);
+
+void outliner_do_object_operation_ex(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ struct SpaceOutliner *soops,
+ struct ListBase *lb,
+ outliner_operation_cb operation_cb,
+ void *user_data,
+ bool recurse_selected);
+void outliner_do_object_operation(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ struct SpaceOutliner *soops,
+ struct ListBase *lb,
+ outliner_operation_cb operation_cb);
int common_restrict_check(struct bContext *C, struct Object *ob);
@@ -222,29 +280,57 @@ int outliner_flag_is_any_test(ListBase *lb, short flag, const int curlevel);
bool outliner_flag_set(ListBase *lb, short flag, short set);
bool outliner_flag_flip(ListBase *lb, short flag);
-void item_rename_cb(
- struct bContext *C, struct ReportList *reports, struct Scene *scene,
- TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
-void lib_relocate_cb(
- struct bContext *C, struct ReportList *reports, struct Scene *scene, struct TreeElement *te,
- struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
-void lib_reload_cb(
- struct bContext *C, struct ReportList *reports, struct Scene *scene, struct TreeElement *te,
- struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
-
-void id_delete_cb(
- struct bContext *C, struct ReportList *reports, struct Scene *scene, struct TreeElement *te,
- struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
-void id_remap_cb(
- struct bContext *C, struct ReportList *reports, struct Scene *scene, struct TreeElement *te,
- struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
-
-void item_object_mode_enter_cb(
- struct bContext *C, struct ReportList *reports, struct Scene *scene,
- TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
-void item_object_mode_exit_cb(
- struct bContext *C, struct ReportList *reports, struct Scene *scene,
- TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+void item_rename_cb(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ TreeElement *te,
+ struct TreeStoreElem *tsep,
+ struct TreeStoreElem *tselem,
+ void *user_data);
+void lib_relocate_cb(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ struct TreeElement *te,
+ struct TreeStoreElem *tsep,
+ struct TreeStoreElem *tselem,
+ void *user_data);
+void lib_reload_cb(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ struct TreeElement *te,
+ struct TreeStoreElem *tsep,
+ struct TreeStoreElem *tselem,
+ void *user_data);
+
+void id_delete_cb(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ struct TreeElement *te,
+ struct TreeStoreElem *tsep,
+ struct TreeStoreElem *tselem,
+ void *user_data);
+void id_remap_cb(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ struct TreeElement *te,
+ struct TreeStoreElem *tsep,
+ struct TreeStoreElem *tselem,
+ void *user_data);
+
+void item_object_mode_enter_cb(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ TreeElement *te,
+ struct TreeStoreElem *tsep,
+ struct TreeStoreElem *tselem,
+ void *user_data);
+void item_object_mode_exit_cb(struct bContext *C,
+ struct ReportList *reports,
+ struct Scene *scene,
+ TreeElement *te,
+ struct TreeStoreElem *tsep,
+ struct TreeStoreElem *tselem,
+ void *user_data);
void outliner_set_coordinates(struct ARegion *ar, struct SpaceOutliner *soops);
@@ -345,17 +431,26 @@ void OUTLINER_OT_unhide_all(struct wmOperatorType *ot);
/* outliner_utils.c ---------------------------------------------- */
-TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops, const ListBase *tree, float view_co_y);
-TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops, const TreeElement *parent_te, float view_co_x);
+TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops,
+ const ListBase *tree,
+ float view_co_y);
+TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops,
+ const TreeElement *parent_te,
+ float view_co_x);
TreeElement *outliner_find_tse(struct SpaceOutliner *soops, const TreeStoreElem *tse);
TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem);
-TreeElement *outliner_find_parent_element(ListBase *lb, TreeElement *parent_te, const TreeElement *child_te);
+TreeElement *outliner_find_parent_element(ListBase *lb,
+ TreeElement *parent_te,
+ const TreeElement *child_te);
TreeElement *outliner_find_id(struct SpaceOutliner *soops, ListBase *lb, const struct ID *id);
TreeElement *outliner_find_posechannel(ListBase *lb, const struct bPoseChannel *pchan);
TreeElement *outliner_find_editbone(ListBase *lb, const struct EditBone *ebone);
struct ID *outliner_search_back(SpaceOutliner *soops, TreeElement *te, short idcode);
-bool outliner_tree_traverse(const SpaceOutliner *soops, ListBase *tree, int filter_te_flag, int filter_tselem_flag,
- TreeTraversalFunc func, void *customdata);
-
+bool outliner_tree_traverse(const SpaceOutliner *soops,
+ ListBase *tree,
+ int filter_te_flag,
+ int filter_tselem_flag,
+ TreeTraversalFunc func,
+ void *customdata);
#endif /* __OUTLINER_INTERN_H__ */
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index c14a5eace91..f155a2d5f89 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -23,12 +23,10 @@
#include "MEM_guardedalloc.h"
-
#include "DNA_collection_types.h"
#include "BLT_translation.h"
-
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -49,80 +47,80 @@
void outliner_operatortypes(void)
{
- WM_operatortype_append(OUTLINER_OT_highlight_update);
- WM_operatortype_append(OUTLINER_OT_item_activate);
- WM_operatortype_append(OUTLINER_OT_select_box);
- WM_operatortype_append(OUTLINER_OT_item_openclose);
- WM_operatortype_append(OUTLINER_OT_item_rename);
- WM_operatortype_append(OUTLINER_OT_item_drag_drop);
- WM_operatortype_append(OUTLINER_OT_operation);
- WM_operatortype_append(OUTLINER_OT_scene_operation);
- WM_operatortype_append(OUTLINER_OT_object_operation);
- WM_operatortype_append(OUTLINER_OT_lib_operation);
- WM_operatortype_append(OUTLINER_OT_lib_relocate);
- WM_operatortype_append(OUTLINER_OT_id_operation);
- WM_operatortype_append(OUTLINER_OT_id_delete);
- WM_operatortype_append(OUTLINER_OT_id_remap);
- WM_operatortype_append(OUTLINER_OT_id_copy);
- WM_operatortype_append(OUTLINER_OT_id_paste);
- WM_operatortype_append(OUTLINER_OT_data_operation);
- WM_operatortype_append(OUTLINER_OT_animdata_operation);
- WM_operatortype_append(OUTLINER_OT_action_set);
- WM_operatortype_append(OUTLINER_OT_constraint_operation);
- WM_operatortype_append(OUTLINER_OT_modifier_operation);
-
- WM_operatortype_append(OUTLINER_OT_show_one_level);
- WM_operatortype_append(OUTLINER_OT_show_active);
- WM_operatortype_append(OUTLINER_OT_show_hierarchy);
- WM_operatortype_append(OUTLINER_OT_scroll_page);
-
- WM_operatortype_append(OUTLINER_OT_select_all);
- WM_operatortype_append(OUTLINER_OT_expanded_toggle);
-
- WM_operatortype_append(OUTLINER_OT_keyingset_add_selected);
- WM_operatortype_append(OUTLINER_OT_keyingset_remove_selected);
-
- WM_operatortype_append(OUTLINER_OT_drivers_add_selected);
- WM_operatortype_append(OUTLINER_OT_drivers_delete_selected);
-
- WM_operatortype_append(OUTLINER_OT_orphans_purge);
-
- WM_operatortype_append(OUTLINER_OT_parent_drop);
- WM_operatortype_append(OUTLINER_OT_parent_clear);
- WM_operatortype_append(OUTLINER_OT_scene_drop);
- WM_operatortype_append(OUTLINER_OT_material_drop);
- WM_operatortype_append(OUTLINER_OT_collection_drop);
-
- /* collections */
- WM_operatortype_append(OUTLINER_OT_collection_new);
- WM_operatortype_append(OUTLINER_OT_collection_duplicate_linked);
- WM_operatortype_append(OUTLINER_OT_collection_duplicate);
- WM_operatortype_append(OUTLINER_OT_collection_delete);
- WM_operatortype_append(OUTLINER_OT_collection_objects_select);
- WM_operatortype_append(OUTLINER_OT_collection_objects_deselect);
- WM_operatortype_append(OUTLINER_OT_collection_link);
- WM_operatortype_append(OUTLINER_OT_collection_instance);
- WM_operatortype_append(OUTLINER_OT_collection_exclude_set);
- WM_operatortype_append(OUTLINER_OT_collection_exclude_clear);
- WM_operatortype_append(OUTLINER_OT_collection_holdout_set);
- WM_operatortype_append(OUTLINER_OT_collection_holdout_clear);
- WM_operatortype_append(OUTLINER_OT_collection_indirect_only_set);
- WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear);
-
- WM_operatortype_append(OUTLINER_OT_collection_isolate);
- WM_operatortype_append(OUTLINER_OT_collection_disable);
- WM_operatortype_append(OUTLINER_OT_collection_enable);
- WM_operatortype_append(OUTLINER_OT_collection_hide);
- WM_operatortype_append(OUTLINER_OT_collection_show);
- WM_operatortype_append(OUTLINER_OT_collection_disable_render);
- WM_operatortype_append(OUTLINER_OT_collection_enable_render);
- WM_operatortype_append(OUTLINER_OT_collection_hide_inside);
- WM_operatortype_append(OUTLINER_OT_collection_show_inside);
- WM_operatortype_append(OUTLINER_OT_hide);
- WM_operatortype_append(OUTLINER_OT_unhide_all);
+ WM_operatortype_append(OUTLINER_OT_highlight_update);
+ WM_operatortype_append(OUTLINER_OT_item_activate);
+ WM_operatortype_append(OUTLINER_OT_select_box);
+ WM_operatortype_append(OUTLINER_OT_item_openclose);
+ WM_operatortype_append(OUTLINER_OT_item_rename);
+ WM_operatortype_append(OUTLINER_OT_item_drag_drop);
+ WM_operatortype_append(OUTLINER_OT_operation);
+ WM_operatortype_append(OUTLINER_OT_scene_operation);
+ WM_operatortype_append(OUTLINER_OT_object_operation);
+ WM_operatortype_append(OUTLINER_OT_lib_operation);
+ WM_operatortype_append(OUTLINER_OT_lib_relocate);
+ WM_operatortype_append(OUTLINER_OT_id_operation);
+ WM_operatortype_append(OUTLINER_OT_id_delete);
+ WM_operatortype_append(OUTLINER_OT_id_remap);
+ WM_operatortype_append(OUTLINER_OT_id_copy);
+ WM_operatortype_append(OUTLINER_OT_id_paste);
+ WM_operatortype_append(OUTLINER_OT_data_operation);
+ WM_operatortype_append(OUTLINER_OT_animdata_operation);
+ WM_operatortype_append(OUTLINER_OT_action_set);
+ WM_operatortype_append(OUTLINER_OT_constraint_operation);
+ WM_operatortype_append(OUTLINER_OT_modifier_operation);
+
+ WM_operatortype_append(OUTLINER_OT_show_one_level);
+ WM_operatortype_append(OUTLINER_OT_show_active);
+ WM_operatortype_append(OUTLINER_OT_show_hierarchy);
+ WM_operatortype_append(OUTLINER_OT_scroll_page);
+
+ WM_operatortype_append(OUTLINER_OT_select_all);
+ WM_operatortype_append(OUTLINER_OT_expanded_toggle);
+
+ WM_operatortype_append(OUTLINER_OT_keyingset_add_selected);
+ WM_operatortype_append(OUTLINER_OT_keyingset_remove_selected);
+
+ WM_operatortype_append(OUTLINER_OT_drivers_add_selected);
+ WM_operatortype_append(OUTLINER_OT_drivers_delete_selected);
+
+ WM_operatortype_append(OUTLINER_OT_orphans_purge);
+
+ WM_operatortype_append(OUTLINER_OT_parent_drop);
+ WM_operatortype_append(OUTLINER_OT_parent_clear);
+ WM_operatortype_append(OUTLINER_OT_scene_drop);
+ WM_operatortype_append(OUTLINER_OT_material_drop);
+ WM_operatortype_append(OUTLINER_OT_collection_drop);
+
+ /* collections */
+ WM_operatortype_append(OUTLINER_OT_collection_new);
+ WM_operatortype_append(OUTLINER_OT_collection_duplicate_linked);
+ WM_operatortype_append(OUTLINER_OT_collection_duplicate);
+ WM_operatortype_append(OUTLINER_OT_collection_delete);
+ WM_operatortype_append(OUTLINER_OT_collection_objects_select);
+ WM_operatortype_append(OUTLINER_OT_collection_objects_deselect);
+ WM_operatortype_append(OUTLINER_OT_collection_link);
+ WM_operatortype_append(OUTLINER_OT_collection_instance);
+ WM_operatortype_append(OUTLINER_OT_collection_exclude_set);
+ WM_operatortype_append(OUTLINER_OT_collection_exclude_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_set);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_set);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear);
+
+ WM_operatortype_append(OUTLINER_OT_collection_isolate);
+ WM_operatortype_append(OUTLINER_OT_collection_disable);
+ WM_operatortype_append(OUTLINER_OT_collection_enable);
+ WM_operatortype_append(OUTLINER_OT_collection_hide);
+ WM_operatortype_append(OUTLINER_OT_collection_show);
+ WM_operatortype_append(OUTLINER_OT_collection_disable_render);
+ WM_operatortype_append(OUTLINER_OT_collection_enable_render);
+ WM_operatortype_append(OUTLINER_OT_collection_hide_inside);
+ WM_operatortype_append(OUTLINER_OT_collection_show_inside);
+ WM_operatortype_append(OUTLINER_OT_hide);
+ WM_operatortype_append(OUTLINER_OT_unhide_all);
}
void outliner_keymap(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "Outliner", SPACE_OUTLINER, 0);
+ WM_keymap_ensure(keyconf, "Outliner", SPACE_OUTLINER, 0);
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 9866b43a6a6..bab5ee02916 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -63,7 +63,6 @@
#include "WM_api.h"
#include "WM_types.h"
-
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -72,38 +71,36 @@
#include "outliner_intern.h"
-static bool do_outliner_activate_common(
- bContext *C,
- Main *bmain,
- Depsgraph *depsgraph,
- Scene *scene,
- ViewLayer *view_layer,
- Base *base,
- const bool extend,
- const bool do_exit)
+static bool do_outliner_activate_common(bContext *C,
+ Main *bmain,
+ Depsgraph *depsgraph,
+ Scene *scene,
+ ViewLayer *view_layer,
+ Base *base,
+ const bool extend,
+ const bool do_exit)
{
- bool use_all = false;
-
- if (do_exit) {
- FOREACH_OBJECT_BEGIN(view_layer, ob_iter)
- {
- ED_object_mode_generic_exit(bmain, depsgraph, scene, ob_iter);
- }
- FOREACH_OBJECT_END;
- }
-
- /* Just like clicking in the object changes the active object,
- * clicking on the object data should change it as well. */
- ED_object_base_activate(C, base);
-
- if (extend) {
- use_all = true;
- }
- else {
- ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT);
- }
-
- return use_all;
+ bool use_all = false;
+
+ if (do_exit) {
+ FOREACH_OBJECT_BEGIN (view_layer, ob_iter) {
+ ED_object_mode_generic_exit(bmain, depsgraph, scene, ob_iter);
+ }
+ FOREACH_OBJECT_END;
+ }
+
+ /* Just like clicking in the object changes the active object,
+ * clicking on the object data should change it as well. */
+ ED_object_base_activate(C, base);
+
+ if (extend) {
+ use_all = true;
+ }
+ else {
+ ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT);
+ }
+
+ return use_all;
}
/**
@@ -112,142 +109,145 @@ static bool do_outliner_activate_common(
* If extend is used, we try to have the other compatible selected objects in the new mode as well.
* Otherwise only the new object will be active, selected and in the edit mode.
*/
-static void do_outliner_activate_obdata(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
+static void do_outliner_activate_obdata(
+ bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
{
- Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Object *obact = OBACT(view_layer);
- Object *ob = base->object;
- bool use_all = false;
-
- if (obact == NULL) {
- ED_object_base_activate(C, base);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- obact = ob;
- use_all = true;
- }
- else if (obact->data == ob->data) {
- use_all = true;
- }
- else if (obact->mode == OB_MODE_OBJECT) {
- use_all = do_outliner_activate_common(C, bmain, depsgraph, scene, view_layer, base, extend, false);
- }
- else if ((ob->type != obact->type) ||
- ((obact->mode & OB_MODE_EDIT) == 0) ||
- ((obact->mode & OB_MODE_POSE) && ELEM(OB_ARMATURE, ob->type, obact->type)) ||
- !extend)
- {
- use_all = do_outliner_activate_common(C, bmain, depsgraph, scene, view_layer, base, extend, true);
- }
-
- if (use_all) {
- WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
- }
- else {
- bool ok;
- if (BKE_object_is_in_editmode(ob)) {
- ok = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
- }
- else {
- ok = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT);
- }
- if (ok) {
- ED_object_base_select(base, (ob->mode & OB_MODE_EDIT) ? BA_SELECT : BA_DESELECT);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- }
+ Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Object *obact = OBACT(view_layer);
+ Object *ob = base->object;
+ bool use_all = false;
+
+ if (obact == NULL) {
+ ED_object_base_activate(C, base);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ obact = ob;
+ use_all = true;
+ }
+ else if (obact->data == ob->data) {
+ use_all = true;
+ }
+ else if (obact->mode == OB_MODE_OBJECT) {
+ use_all = do_outliner_activate_common(
+ C, bmain, depsgraph, scene, view_layer, base, extend, false);
+ }
+ else if ((ob->type != obact->type) || ((obact->mode & OB_MODE_EDIT) == 0) ||
+ ((obact->mode & OB_MODE_POSE) && ELEM(OB_ARMATURE, ob->type, obact->type)) || !extend) {
+ use_all = do_outliner_activate_common(
+ C, bmain, depsgraph, scene, view_layer, base, extend, true);
+ }
+
+ if (use_all) {
+ WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
+ else {
+ bool ok;
+ if (BKE_object_is_in_editmode(ob)) {
+ ok = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
+ }
+ else {
+ ok = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT);
+ }
+ if (ok) {
+ ED_object_base_select(base, (ob->mode & OB_MODE_EDIT) ? BA_SELECT : BA_DESELECT);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ }
}
-static void do_outliner_activate_pose(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
+static void do_outliner_activate_pose(
+ bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
{
- Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Object *obact = OBACT(view_layer);
- Object *ob = base->object;
- bool use_all = false;
-
- if (obact == NULL) {
- ED_object_base_activate(C, base);
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- obact = ob;
- use_all = true;
- }
- else if (obact->data == ob->data) {
- use_all = true;
- }
- else if (obact->mode == OB_MODE_OBJECT) {
- use_all = do_outliner_activate_common(C, bmain, depsgraph, scene, view_layer, base, extend, false);
- }
- else if ((!ELEM(ob->type, obact->type)) ||
- ((obact->mode & OB_MODE_EDIT) && ELEM(OB_ARMATURE, ob->type, obact->type)))
- {
- use_all = do_outliner_activate_common(C, bmain, depsgraph, scene, view_layer, base, extend, true);
- }
-
- if (use_all) {
- WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
- }
- else {
- bool ok = false;
- if (ob->mode & OB_MODE_POSE) {
- ok = ED_object_posemode_exit_ex(bmain, ob);
- }
- else {
- ok = ED_object_posemode_enter_ex(bmain, ob);
- }
- if (ok) {
- ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT);
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- }
+ Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Object *obact = OBACT(view_layer);
+ Object *ob = base->object;
+ bool use_all = false;
+
+ if (obact == NULL) {
+ ED_object_base_activate(C, base);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ obact = ob;
+ use_all = true;
+ }
+ else if (obact->data == ob->data) {
+ use_all = true;
+ }
+ else if (obact->mode == OB_MODE_OBJECT) {
+ use_all = do_outliner_activate_common(
+ C, bmain, depsgraph, scene, view_layer, base, extend, false);
+ }
+ else if ((!ELEM(ob->type, obact->type)) ||
+ ((obact->mode & OB_MODE_EDIT) && ELEM(OB_ARMATURE, ob->type, obact->type))) {
+ use_all = do_outliner_activate_common(
+ C, bmain, depsgraph, scene, view_layer, base, extend, true);
+ }
+
+ if (use_all) {
+ WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
+ else {
+ bool ok = false;
+ if (ob->mode & OB_MODE_POSE) {
+ ok = ED_object_posemode_exit_ex(bmain, ob);
+ }
+ else {
+ ok = ED_object_posemode_enter_ex(bmain, ob);
+ }
+ if (ok) {
+ ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT);
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ }
}
/* For draw callback to run mode switching */
-void outliner_object_mode_toggle(
- bContext *C, Scene *scene, ViewLayer *view_layer,
- Base *base)
+void outliner_object_mode_toggle(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base)
{
- Object *obact = OBACT(view_layer);
- if (obact->mode & OB_MODE_EDIT) {
- do_outliner_activate_obdata(C, scene, view_layer, base, true);
- }
- else if (obact->mode & OB_MODE_POSE) {
- do_outliner_activate_pose(C, scene, view_layer, base, true);
- }
+ Object *obact = OBACT(view_layer);
+ if (obact->mode & OB_MODE_EDIT) {
+ do_outliner_activate_obdata(C, scene, view_layer, base, true);
+ }
+ else if (obact->mode & OB_MODE_POSE) {
+ do_outliner_activate_pose(C, scene, view_layer, base, true);
+ }
}
/* ****************************************************** */
/* Outliner Element Selection/Activation on Click */
-static eOLDrawState active_viewlayer(
- bContext *C, Scene *UNUSED(scene), ViewLayer *UNUSED(sl), TreeElement *te, const eOLSetState set)
+static eOLDrawState active_viewlayer(bContext *C,
+ Scene *UNUSED(scene),
+ ViewLayer *UNUSED(sl),
+ TreeElement *te,
+ const eOLSetState set)
{
- /* paranoia check */
- if (te->idcode != ID_SCE) {
- return OL_DRAWSEL_NONE;
- }
-
- ViewLayer *view_layer = te->directdata;
-
- if (set != OL_SETSEL_NONE) {
- wmWindow *win = CTX_wm_window(C);
- Scene *scene = WM_window_get_active_scene(win);
-
- if (BLI_findindex(&scene->view_layers, view_layer) != -1) {
- WM_window_set_active_view_layer(win, view_layer);
- WM_event_add_notifier(C, NC_SCREEN | ND_LAYER, NULL);
- }
- }
- else {
- return CTX_data_view_layer(C) == view_layer;
- }
- return OL_DRAWSEL_NONE;
+ /* paranoia check */
+ if (te->idcode != ID_SCE) {
+ return OL_DRAWSEL_NONE;
+ }
+
+ ViewLayer *view_layer = te->directdata;
+
+ if (set != OL_SETSEL_NONE) {
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = WM_window_get_active_scene(win);
+
+ if (BLI_findindex(&scene->view_layers, view_layer) != -1) {
+ WM_window_set_active_view_layer(win, view_layer);
+ WM_event_add_notifier(C, NC_SCREEN | ND_LAYER, NULL);
+ }
+ }
+ else {
+ return CTX_data_view_layer(C) == view_layer;
+ }
+ return OL_DRAWSEL_NONE;
}
/**
@@ -255,772 +255,856 @@ static eOLDrawState active_viewlayer(
* CTRL+LMB: Select/Deselect object and all children.
* CTRL+SHIFT+LMB: Add/Remove object and all children.
*/
-static void do_outliner_object_select_recursive(ViewLayer *view_layer, Object *ob_parent, bool select)
+static void do_outliner_object_select_recursive(ViewLayer *view_layer,
+ Object *ob_parent,
+ bool select)
{
- Base *base;
-
- for (base = FIRSTBASE(view_layer); base; base = base->next) {
- Object *ob = base->object;
- if ((((base->flag & BASE_VISIBLE) != 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
- ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
- }
- }
+ Base *base;
+
+ for (base = FIRSTBASE(view_layer); base; base = base->next) {
+ Object *ob = base->object;
+ if ((((base->flag & BASE_VISIBLE) != 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
+ ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
+ }
+ }
}
static void do_outliner_bone_select_recursive(bArmature *arm, Bone *bone_parent, bool select)
{
- Bone *bone;
- for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
- if (select && PBONE_SELECTABLE(arm, bone)) {
- bone->flag |= BONE_SELECTED;
- }
- else {
- bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
- }
- do_outliner_bone_select_recursive(arm, bone, select);
- }
+ Bone *bone;
+ for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
+ if (select && PBONE_SELECTABLE(arm, bone)) {
+ bone->flag |= BONE_SELECTED;
+ }
+ else {
+ bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
+ do_outliner_bone_select_recursive(arm, bone, select);
+ }
}
static void do_outliner_ebone_select_recursive(bArmature *arm, EditBone *ebone_parent, bool select)
{
- EditBone *ebone;
- for (ebone = ebone_parent->next; ebone; ebone = ebone->next) {
- if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
- if (select && EBONE_SELECTABLE(arm, ebone)) {
- ebone->flag |= BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL;
- }
- else {
- ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
- }
- }
- }
+ EditBone *ebone;
+ for (ebone = ebone_parent->next; ebone; ebone = ebone->next) {
+ if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
+ if (select && EBONE_SELECTABLE(arm, ebone)) {
+ ebone->flag |= BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL;
+ }
+ else {
+ ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
+ }
+ }
}
-static eOLDrawState tree_element_set_active_object(
- bContext *C, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops,
- TreeElement *te, const eOLSetState set, bool recursive)
+static eOLDrawState tree_element_set_active_object(bContext *C,
+ Scene *scene,
+ ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ const eOLSetState set,
+ bool recursive)
{
- TreeStoreElem *tselem = TREESTORE(te);
- Scene *sce;
- Base *base;
- Object *ob = NULL;
-
- /* if id is not object, we search back */
- if (te->idcode == ID_OB) {
- ob = (Object *)tselem->id;
- }
- else {
- ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (ob == OBACT(view_layer)) {
- return OL_DRAWSEL_NONE;
- }
- }
- if (ob == NULL) {
- return OL_DRAWSEL_NONE;
- }
-
- sce = (Scene *)outliner_search_back(soops, te, ID_SCE);
- if (sce && scene != sce) {
- WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
- scene = sce;
- }
-
- /* find associated base in current scene */
- base = BKE_view_layer_base_find(view_layer, ob);
-
- if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
- if (base != NULL) {
- Object *obact = OBACT(view_layer);
- const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
- if (base && !BKE_object_is_mode_compat(base->object, object_mode)) {
- if (object_mode == OB_MODE_OBJECT) {
- struct Main *bmain = CTX_data_main(C);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ED_object_mode_generic_exit(bmain, depsgraph, scene, base->object);
- }
- if (!BKE_object_is_mode_compat(base->object, object_mode)) {
- base = NULL;
- }
- }
- }
- }
-
- if (base) {
- if (set == OL_SETSEL_EXTEND) {
- /* swap select */
- if (base->flag & BASE_SELECTED) {
- ED_object_base_select(base, BA_DESELECT);
- }
- else {
- ED_object_base_select(base, BA_SELECT);
- }
- }
- else {
- /* deleselect all */
-
- /* Only in object mode so we can switch the active object,
- * keeping all objects in the current 'mode' selected, useful for multi-pose/edit mode.
- * This keeps the convention that all objects in the current mode are also selected.
- * see T55246. */
- if ((scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) ? (ob->mode == OB_MODE_OBJECT) : true) {
- BKE_view_layer_base_deselect_all(view_layer);
- }
- ED_object_base_select(base, BA_SELECT);
- }
-
- if (recursive) {
- /* Recursive select/deselect for Object hierarchies */
- do_outliner_object_select_recursive(view_layer, ob, (base->flag & BASE_SELECTED) != 0);
- }
-
- if (set != OL_SETSEL_NONE) {
- ED_object_base_activate(C, base); /* adds notifier */
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
-
- if (ob != OBEDIT_FROM_VIEW_LAYER(view_layer)) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- }
- }
- return OL_DRAWSEL_NORMAL;
+ TreeStoreElem *tselem = TREESTORE(te);
+ Scene *sce;
+ Base *base;
+ Object *ob = NULL;
+
+ /* if id is not object, we search back */
+ if (te->idcode == ID_OB) {
+ ob = (Object *)tselem->id;
+ }
+ else {
+ ob = (Object *)outliner_search_back(soops, te, ID_OB);
+ if (ob == OBACT(view_layer)) {
+ return OL_DRAWSEL_NONE;
+ }
+ }
+ if (ob == NULL) {
+ return OL_DRAWSEL_NONE;
+ }
+
+ sce = (Scene *)outliner_search_back(soops, te, ID_SCE);
+ if (sce && scene != sce) {
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
+ scene = sce;
+ }
+
+ /* find associated base in current scene */
+ base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
+ if (base != NULL) {
+ Object *obact = OBACT(view_layer);
+ const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
+ if (base && !BKE_object_is_mode_compat(base->object, object_mode)) {
+ if (object_mode == OB_MODE_OBJECT) {
+ struct Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ED_object_mode_generic_exit(bmain, depsgraph, scene, base->object);
+ }
+ if (!BKE_object_is_mode_compat(base->object, object_mode)) {
+ base = NULL;
+ }
+ }
+ }
+ }
+
+ if (base) {
+ if (set == OL_SETSEL_EXTEND) {
+ /* swap select */
+ if (base->flag & BASE_SELECTED) {
+ ED_object_base_select(base, BA_DESELECT);
+ }
+ else {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
+ else {
+ /* deleselect all */
+
+ /* Only in object mode so we can switch the active object,
+ * keeping all objects in the current 'mode' selected, useful for multi-pose/edit mode.
+ * This keeps the convention that all objects in the current mode are also selected.
+ * see T55246. */
+ if ((scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) ?
+ (ob->mode == OB_MODE_OBJECT) :
+ true) {
+ BKE_view_layer_base_deselect_all(view_layer);
+ }
+ ED_object_base_select(base, BA_SELECT);
+ }
+
+ if (recursive) {
+ /* Recursive select/deselect for Object hierarchies */
+ do_outliner_object_select_recursive(view_layer, ob, (base->flag & BASE_SELECTED) != 0);
+ }
+
+ if (set != OL_SETSEL_NONE) {
+ ED_object_base_activate(C, base); /* adds notifier */
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+
+ if (ob != OBEDIT_FROM_VIEW_LAYER(view_layer)) {
+ ED_object_editmode_exit(C, EM_FREEDATA);
+ }
+ }
+ return OL_DRAWSEL_NORMAL;
}
-static eOLDrawState tree_element_active_material(
- bContext *C, Scene *UNUSED(scene), ViewLayer *view_layer, SpaceOutliner *soops,
- TreeElement *te, const eOLSetState set)
+static eOLDrawState tree_element_active_material(bContext *C,
+ Scene *UNUSED(scene),
+ ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ const eOLSetState set)
{
- TreeElement *tes;
- Object *ob;
-
- /* we search for the object parent */
- ob = (Object *)outliner_search_back(soops, te, ID_OB);
- // note: ob->matbits can be NULL when a local object points to a library mesh.
- if (ob == NULL || ob != OBACT(view_layer) || ob->matbits == NULL) {
- return OL_DRAWSEL_NONE; /* just paranoia */
- }
-
- /* searching in ob mat array? */
- tes = te->parent;
- if (tes->idcode == ID_OB) {
- if (set != OL_SETSEL_NONE) {
- ob->actcol = te->index + 1;
- ob->matbits[te->index] = 1; // make ob material active too
- }
- else {
- if (ob->actcol == te->index + 1) {
- if (ob->matbits[te->index]) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- }
- }
- /* or we search for obdata material */
- else {
- if (set != OL_SETSEL_NONE) {
- ob->actcol = te->index + 1;
- ob->matbits[te->index] = 0; // make obdata material active too
- }
- else {
- if (ob->actcol == te->index + 1) {
- if (ob->matbits[te->index] == 0) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- }
- }
- if (set != OL_SETSEL_NONE) {
- /* Tagging object for update seems a bit stupid here, but looks like we have to do it
- * for render views to update. See T42973.
- * Note that RNA material update does it too, see e.g. rna_MaterialSlot_update(). */
- DEG_id_tag_update((ID *)ob, ID_RECALC_TRANSFORM);
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
- }
- return OL_DRAWSEL_NONE;
+ TreeElement *tes;
+ Object *ob;
+
+ /* we search for the object parent */
+ ob = (Object *)outliner_search_back(soops, te, ID_OB);
+ // note: ob->matbits can be NULL when a local object points to a library mesh.
+ if (ob == NULL || ob != OBACT(view_layer) || ob->matbits == NULL) {
+ return OL_DRAWSEL_NONE; /* just paranoia */
+ }
+
+ /* searching in ob mat array? */
+ tes = te->parent;
+ if (tes->idcode == ID_OB) {
+ if (set != OL_SETSEL_NONE) {
+ ob->actcol = te->index + 1;
+ ob->matbits[te->index] = 1; // make ob material active too
+ }
+ else {
+ if (ob->actcol == te->index + 1) {
+ if (ob->matbits[te->index]) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ }
+ }
+ /* or we search for obdata material */
+ else {
+ if (set != OL_SETSEL_NONE) {
+ ob->actcol = te->index + 1;
+ ob->matbits[te->index] = 0; // make obdata material active too
+ }
+ else {
+ if (ob->actcol == te->index + 1) {
+ if (ob->matbits[te->index] == 0) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ }
+ }
+ if (set != OL_SETSEL_NONE) {
+ /* Tagging object for update seems a bit stupid here, but looks like we have to do it
+ * for render views to update. See T42973.
+ * Note that RNA material update does it too, see e.g. rna_MaterialSlot_update(). */
+ DEG_id_tag_update((ID *)ob, ID_RECALC_TRANSFORM);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_light(
- bContext *UNUSED(C), Scene *UNUSED(scene), ViewLayer *view_layer, SpaceOutliner *soops,
- TreeElement *te, const eOLSetState set)
+static eOLDrawState tree_element_active_light(bContext *UNUSED(C),
+ Scene *UNUSED(scene),
+ ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ const eOLSetState set)
{
- Object *ob;
-
- /* we search for the object parent */
- ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (ob == NULL || ob != OBACT(view_layer)) {
- /* just paranoia */
- return OL_DRAWSEL_NONE;
- }
-
- if (set != OL_SETSEL_NONE) {
-// XXX extern_set_butspace(F5KEY, 0);
- }
- else {
- return OL_DRAWSEL_NORMAL;
- }
-
- return OL_DRAWSEL_NONE;
+ Object *ob;
+
+ /* we search for the object parent */
+ ob = (Object *)outliner_search_back(soops, te, ID_OB);
+ if (ob == NULL || ob != OBACT(view_layer)) {
+ /* just paranoia */
+ return OL_DRAWSEL_NONE;
+ }
+
+ if (set != OL_SETSEL_NONE) {
+ // XXX extern_set_butspace(F5KEY, 0);
+ }
+ else {
+ return OL_DRAWSEL_NORMAL;
+ }
+
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_camera(
- bContext *UNUSED(C), Scene *scene, ViewLayer *UNUSED(sl), SpaceOutliner *soops,
- TreeElement *te, const eOLSetState set)
+static eOLDrawState tree_element_active_camera(bContext *UNUSED(C),
+ Scene *scene,
+ ViewLayer *UNUSED(sl),
+ SpaceOutliner *soops,
+ TreeElement *te,
+ const eOLSetState set)
{
- Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
+ Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (set != OL_SETSEL_NONE) {
- return OL_DRAWSEL_NONE;
- }
+ if (set != OL_SETSEL_NONE) {
+ return OL_DRAWSEL_NONE;
+ }
- return scene->camera == ob;
+ return scene->camera == ob;
}
-static eOLDrawState tree_element_active_world(
- bContext *C, Scene *scene, ViewLayer *UNUSED(sl), SpaceOutliner *UNUSED(soops),
- TreeElement *te, const eOLSetState set)
+static eOLDrawState tree_element_active_world(bContext *C,
+ Scene *scene,
+ ViewLayer *UNUSED(sl),
+ SpaceOutliner *UNUSED(soops),
+ TreeElement *te,
+ const eOLSetState set)
{
- TreeElement *tep;
- TreeStoreElem *tselem = NULL;
- Scene *sce = NULL;
-
- tep = te->parent;
- if (tep) {
- tselem = TREESTORE(tep);
- if (tselem->type == 0) {
- sce = (Scene *)tselem->id;
- }
- }
-
- if (set != OL_SETSEL_NONE) {
- /* make new scene active */
- if (sce && scene != sce) {
- WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
- }
- }
-
- if (tep == NULL || tselem->id == (ID *)scene) {
- if (set != OL_SETSEL_NONE) {
-// XXX extern_set_butspace(F8KEY, 0);
- }
- else {
- return OL_DRAWSEL_NORMAL;
- }
- }
- return OL_DRAWSEL_NONE;
+ TreeElement *tep;
+ TreeStoreElem *tselem = NULL;
+ Scene *sce = NULL;
+
+ tep = te->parent;
+ if (tep) {
+ tselem = TREESTORE(tep);
+ if (tselem->type == 0) {
+ sce = (Scene *)tselem->id;
+ }
+ }
+
+ if (set != OL_SETSEL_NONE) {
+ /* make new scene active */
+ if (sce && scene != sce) {
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
+ }
+ }
+
+ if (tep == NULL || tselem->id == (ID *)scene) {
+ if (set != OL_SETSEL_NONE) {
+ // XXX extern_set_butspace(F8KEY, 0);
+ }
+ else {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_defgroup(
- bContext *C, ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+static eOLDrawState tree_element_active_defgroup(bContext *C,
+ ViewLayer *view_layer,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set)
{
- Object *ob;
-
- /* id in tselem is object */
- ob = (Object *)tselem->id;
- if (set != OL_SETSEL_NONE) {
- BLI_assert(te->index + 1 >= 0);
- ob->actdef = te->index + 1;
-
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
- }
- else {
- if (ob == OBACT(view_layer))
- if (ob->actdef == te->index + 1) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- return OL_DRAWSEL_NONE;
+ Object *ob;
+
+ /* id in tselem is object */
+ ob = (Object *)tselem->id;
+ if (set != OL_SETSEL_NONE) {
+ BLI_assert(te->index + 1 >= 0);
+ ob->actdef = te->index + 1;
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
+ }
+ else {
+ if (ob == OBACT(view_layer))
+ if (ob->actdef == te->index + 1) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_gplayer(
- bContext *C, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+static eOLDrawState tree_element_active_gplayer(bContext *C,
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set)
{
- bGPdata *gpd = (bGPdata *)tselem->id;
- bGPDlayer *gpl = te->directdata;
-
- /* We can only have a single "active" layer at a time
- * and there must always be an active layer...
- */
- if (set != OL_SETSEL_NONE) {
- if (gpl) {
- BKE_gpencil_layer_setactive(gpd, gpl);
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, gpd);
- }
- }
- else {
- return OL_DRAWSEL_NORMAL;
- }
-
- return OL_DRAWSEL_NONE;
+ bGPdata *gpd = (bGPdata *)tselem->id;
+ bGPDlayer *gpl = te->directdata;
+
+ /* We can only have a single "active" layer at a time
+ * and there must always be an active layer...
+ */
+ if (set != OL_SETSEL_NONE) {
+ if (gpl) {
+ BKE_gpencil_layer_setactive(gpd, gpl);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, gpd);
+ }
+ }
+ else {
+ return OL_DRAWSEL_NORMAL;
+ }
+
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_posegroup(
- bContext *C, Scene *UNUSED(scene), ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
+static eOLDrawState tree_element_active_posegroup(bContext *C,
+ Scene *UNUSED(scene),
+ ViewLayer *view_layer,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set)
{
- Object *ob = (Object *)tselem->id;
-
- if (set != OL_SETSEL_NONE) {
- if (ob->pose) {
- ob->pose->active_group = te->index + 1;
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- }
- }
- else {
- if (ob == OBACT(view_layer) && ob->pose) {
- if (ob->pose->active_group == te->index + 1) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- }
- return OL_DRAWSEL_NONE;
+ Object *ob = (Object *)tselem->id;
+
+ if (set != OL_SETSEL_NONE) {
+ if (ob->pose) {
+ ob->pose->active_group = te->index + 1;
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ }
+ else {
+ if (ob == OBACT(view_layer) && ob->pose) {
+ if (ob->pose->active_group == te->index + 1) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_posechannel(
- bContext *C, Scene *UNUSED(scene), ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
+static eOLDrawState tree_element_active_posechannel(bContext *C,
+ Scene *UNUSED(scene),
+ ViewLayer *view_layer,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set,
+ bool recursive)
{
- Object *ob = (Object *)tselem->id;
- bArmature *arm = ob->data;
- bPoseChannel *pchan = te->directdata;
-
- if (set != OL_SETSEL_NONE) {
- if (!(pchan->bone->flag & BONE_HIDDEN_P)) {
-
- if (set != OL_SETSEL_EXTEND) {
- /* Single select forces all other bones to get unselected. */
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(view_layer, NULL, &objects_len, OB_MODE_POSE);
- for (uint object_index = 0; object_index < objects_len; object_index++) {
- Object *ob_iter = BKE_object_pose_armature_get(objects[object_index]);
-
- /* Sanity checks. */
- if (ELEM(NULL, ob_iter, ob_iter->pose, ob_iter->data)) {
- continue;
- }
-
- bPoseChannel *pchannel;
- for (pchannel = ob_iter->pose->chanbase.first; pchannel; pchannel = pchannel->next) {
- pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
- }
-
- if (ob != ob_iter) {
- DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
- }
- }
- MEM_freeN(objects);
- }
-
- if ((set == OL_SETSEL_EXTEND) && (pchan->bone->flag & BONE_SELECTED)) {
- pchan->bone->flag &= ~BONE_SELECTED;
- }
- else {
- pchan->bone->flag |= BONE_SELECTED;
- arm->act_bone = pchan->bone;
- }
-
- if (recursive) {
- /* Recursive select/deselect */
- do_outliner_bone_select_recursive(arm, pchan->bone, (pchan->bone->flag & BONE_SELECTED) != 0);
- }
-
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
- DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
- }
- }
- else {
- if (ob == OBACT(view_layer) && ob->pose) {
- if (pchan->bone->flag & BONE_SELECTED) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- }
- return OL_DRAWSEL_NONE;
+ Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+ bPoseChannel *pchan = te->directdata;
+
+ if (set != OL_SETSEL_NONE) {
+ if (!(pchan->bone->flag & BONE_HIDDEN_P)) {
+
+ if (set != OL_SETSEL_EXTEND) {
+ /* Single select forces all other bones to get unselected. */
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
+ view_layer, NULL, &objects_len, OB_MODE_POSE);
+ for (uint object_index = 0; object_index < objects_len; object_index++) {
+ Object *ob_iter = BKE_object_pose_armature_get(objects[object_index]);
+
+ /* Sanity checks. */
+ if (ELEM(NULL, ob_iter, ob_iter->pose, ob_iter->data)) {
+ continue;
+ }
+
+ bPoseChannel *pchannel;
+ for (pchannel = ob_iter->pose->chanbase.first; pchannel; pchannel = pchannel->next) {
+ pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
+
+ if (ob != ob_iter) {
+ DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
+ }
+ }
+ MEM_freeN(objects);
+ }
+
+ if ((set == OL_SETSEL_EXTEND) && (pchan->bone->flag & BONE_SELECTED)) {
+ pchan->bone->flag &= ~BONE_SELECTED;
+ }
+ else {
+ pchan->bone->flag |= BONE_SELECTED;
+ arm->act_bone = pchan->bone;
+ }
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_bone_select_recursive(
+ arm, pchan->bone, (pchan->bone->flag & BONE_SELECTED) != 0);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
+ DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
+ }
+ }
+ else {
+ if (ob == OBACT(view_layer) && ob->pose) {
+ if (pchan->bone->flag & BONE_SELECTED) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_bone(
- bContext *C, ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
+static eOLDrawState tree_element_active_bone(bContext *C,
+ ViewLayer *view_layer,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set,
+ bool recursive)
{
- bArmature *arm = (bArmature *)tselem->id;
- Bone *bone = te->directdata;
-
- if (set != OL_SETSEL_NONE) {
- if (!(bone->flag & BONE_HIDDEN_P)) {
- Object *ob = OBACT(view_layer);
- if (ob) {
- if (set != OL_SETSEL_EXTEND) {
- /* single select forces all other bones to get unselected */
- for (Bone *bone_iter = arm->bonebase.first; bone_iter != NULL; bone_iter = bone_iter->next) {
- bone_iter->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
- do_outliner_bone_select_recursive(arm, bone_iter, false);
- }
- }
- }
-
- if (set == OL_SETSEL_EXTEND && (bone->flag & BONE_SELECTED)) {
- bone->flag &= ~BONE_SELECTED;
- }
- else {
- bone->flag |= BONE_SELECTED;
- arm->act_bone = bone;
- }
-
- if (recursive) {
- /* Recursive select/deselect */
- do_outliner_bone_select_recursive(arm, bone, (bone->flag & BONE_SELECTED) != 0);
- }
-
-
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
- }
- }
- else {
- Object *ob = OBACT(view_layer);
-
- if (ob && ob->data == arm) {
- if (bone->flag & BONE_SELECTED) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- }
- return OL_DRAWSEL_NONE;
+ bArmature *arm = (bArmature *)tselem->id;
+ Bone *bone = te->directdata;
+
+ if (set != OL_SETSEL_NONE) {
+ if (!(bone->flag & BONE_HIDDEN_P)) {
+ Object *ob = OBACT(view_layer);
+ if (ob) {
+ if (set != OL_SETSEL_EXTEND) {
+ /* single select forces all other bones to get unselected */
+ for (Bone *bone_iter = arm->bonebase.first; bone_iter != NULL;
+ bone_iter = bone_iter->next) {
+ bone_iter->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ do_outliner_bone_select_recursive(arm, bone_iter, false);
+ }
+ }
+ }
+
+ if (set == OL_SETSEL_EXTEND && (bone->flag & BONE_SELECTED)) {
+ bone->flag &= ~BONE_SELECTED;
+ }
+ else {
+ bone->flag |= BONE_SELECTED;
+ arm->act_bone = bone;
+ }
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_bone_select_recursive(arm, bone, (bone->flag & BONE_SELECTED) != 0);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
+ }
+ }
+ else {
+ Object *ob = OBACT(view_layer);
+
+ if (ob && ob->data == arm) {
+ if (bone->flag & BONE_SELECTED) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ }
+ return OL_DRAWSEL_NONE;
}
-
/* ebones only draw in editmode armature */
static void tree_element_active_ebone__sel(bContext *C, bArmature *arm, EditBone *ebone, short sel)
{
- if (sel) {
- ebone->flag |= BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL;
- arm->act_edbone = ebone;
- // flush to parent?
- if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
- ebone->parent->flag |= BONE_TIPSEL;
- }
- }
- else {
- ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
- // flush to parent?
- if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
- ebone->parent->flag &= ~BONE_TIPSEL;
- }
- }
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, CTX_data_edit_object(C));
+ if (sel) {
+ ebone->flag |= BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL;
+ arm->act_edbone = ebone;
+ // flush to parent?
+ if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
+ ebone->parent->flag |= BONE_TIPSEL;
+ }
+ }
+ else {
+ ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
+ // flush to parent?
+ if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
+ ebone->parent->flag &= ~BONE_TIPSEL;
+ }
+ }
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, CTX_data_edit_object(C));
}
-static eOLDrawState tree_element_active_ebone(
- bContext *C, ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
+static eOLDrawState tree_element_active_ebone(bContext *C,
+ ViewLayer *view_layer,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set,
+ bool recursive)
{
- bArmature *arm = (bArmature *)tselem->id;
- EditBone *ebone = te->directdata;
- eOLDrawState status = OL_DRAWSEL_NONE;
-
- if (set != OL_SETSEL_NONE) {
- if (set == OL_SETSEL_NORMAL) {
- if (!(ebone->flag & BONE_HIDDEN_A)) {
- uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(view_layer, NULL, &bases_len);
- ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
- MEM_freeN(bases);
-
- tree_element_active_ebone__sel(C, arm, ebone, true);
- status = OL_DRAWSEL_NORMAL;
- }
- }
- else if (set == OL_SETSEL_EXTEND) {
- if (!(ebone->flag & BONE_HIDDEN_A)) {
- if (!(ebone->flag & BONE_SELECTED)) {
- tree_element_active_ebone__sel(C, arm, ebone, true);
- status = OL_DRAWSEL_NORMAL;
- }
- else {
- /* entirely selected, so de-select */
- tree_element_active_ebone__sel(C, arm, ebone, false);
- status = OL_DRAWSEL_NONE;
- }
- }
- }
-
- if (recursive) {
- /* Recursive select/deselect */
- do_outliner_ebone_select_recursive(arm, ebone, (ebone->flag & BONE_SELECTED) != 0);
- }
- }
- else if (ebone->flag & BONE_SELECTED) {
- status = OL_DRAWSEL_NORMAL;
- }
-
- return status;
+ bArmature *arm = (bArmature *)tselem->id;
+ EditBone *ebone = te->directdata;
+ eOLDrawState status = OL_DRAWSEL_NONE;
+
+ if (set != OL_SETSEL_NONE) {
+ if (set == OL_SETSEL_NORMAL) {
+ if (!(ebone->flag & BONE_HIDDEN_A)) {
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ view_layer, NULL, &bases_len);
+ ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
+ MEM_freeN(bases);
+
+ tree_element_active_ebone__sel(C, arm, ebone, true);
+ status = OL_DRAWSEL_NORMAL;
+ }
+ }
+ else if (set == OL_SETSEL_EXTEND) {
+ if (!(ebone->flag & BONE_HIDDEN_A)) {
+ if (!(ebone->flag & BONE_SELECTED)) {
+ tree_element_active_ebone__sel(C, arm, ebone, true);
+ status = OL_DRAWSEL_NORMAL;
+ }
+ else {
+ /* entirely selected, so de-select */
+ tree_element_active_ebone__sel(C, arm, ebone, false);
+ status = OL_DRAWSEL_NONE;
+ }
+ }
+ }
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_ebone_select_recursive(arm, ebone, (ebone->flag & BONE_SELECTED) != 0);
+ }
+ }
+ else if (ebone->flag & BONE_SELECTED) {
+ status = OL_DRAWSEL_NORMAL;
+ }
+
+ return status;
}
-static eOLDrawState tree_element_active_modifier(
- bContext *C, Scene *UNUSED(scene), ViewLayer *UNUSED(sl), TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+static eOLDrawState tree_element_active_modifier(bContext *C,
+ Scene *UNUSED(scene),
+ ViewLayer *UNUSED(sl),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ const eOLSetState set)
{
- if (set != OL_SETSEL_NONE) {
- Object *ob = (Object *)tselem->id;
+ if (set != OL_SETSEL_NONE) {
+ Object *ob = (Object *)tselem->id;
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-// XXX extern_set_butspace(F9KEY, 0);
- }
+ // XXX extern_set_butspace(F9KEY, 0);
+ }
- return OL_DRAWSEL_NONE;
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_psys(
- bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+static eOLDrawState tree_element_active_psys(bContext *C,
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ const eOLSetState set)
{
- if (set != OL_SETSEL_NONE) {
- Object *ob = (Object *)tselem->id;
+ if (set != OL_SETSEL_NONE) {
+ Object *ob = (Object *)tselem->id;
- WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_EDITED, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_EDITED, ob);
-// XXX extern_set_butspace(F7KEY, 0);
- }
+ // XXX extern_set_butspace(F7KEY, 0);
+ }
- return OL_DRAWSEL_NONE;
+ return OL_DRAWSEL_NONE;
}
-static int tree_element_active_constraint(
- bContext *C, Scene *UNUSED(scene), ViewLayer *UNUSED(sl), TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+static int tree_element_active_constraint(bContext *C,
+ Scene *UNUSED(scene),
+ ViewLayer *UNUSED(sl),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ const eOLSetState set)
{
- if (set != OL_SETSEL_NONE) {
- Object *ob = (Object *)tselem->id;
+ if (set != OL_SETSEL_NONE) {
+ Object *ob = (Object *)tselem->id;
- WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
-// XXX extern_set_butspace(F7KEY, 0);
- }
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
+ // XXX extern_set_butspace(F7KEY, 0);
+ }
- return OL_DRAWSEL_NONE;
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_text(
- bContext *UNUSED(C), Scene *UNUSED(scene), ViewLayer *UNUSED(sl), SpaceOutliner *UNUSED(soops),
- TreeElement *UNUSED(te), int UNUSED(set))
+static eOLDrawState tree_element_active_text(bContext *UNUSED(C),
+ Scene *UNUSED(scene),
+ ViewLayer *UNUSED(sl),
+ SpaceOutliner *UNUSED(soops),
+ TreeElement *UNUSED(te),
+ int UNUSED(set))
{
- // XXX removed
- return OL_DRAWSEL_NONE;
+ // XXX removed
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_pose(
- bContext *C, Scene *scene, ViewLayer *view_layer, TreeElement *UNUSED(te), TreeStoreElem *tselem, const eOLSetState set)
+static eOLDrawState tree_element_active_pose(bContext *C,
+ Scene *scene,
+ ViewLayer *view_layer,
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ const eOLSetState set)
{
- Object *ob = (Object *)tselem->id;
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
- if (base == NULL) {
- /* Armature not instantiated in current scene (e.g. inside an appended group...). */
- return OL_DRAWSEL_NONE;
- }
-
- if (set != OL_SETSEL_NONE) {
- do_outliner_activate_pose(C, scene, view_layer, base, (set == OL_SETSEL_EXTEND));
- }
- else {
- if (ob->mode & OB_MODE_POSE) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- return OL_DRAWSEL_NONE;
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (base == NULL) {
+ /* Armature not instantiated in current scene (e.g. inside an appended group...). */
+ return OL_DRAWSEL_NONE;
+ }
+
+ if (set != OL_SETSEL_NONE) {
+ do_outliner_activate_pose(C, scene, view_layer, base, (set == OL_SETSEL_EXTEND));
+ }
+ else {
+ if (ob->mode & OB_MODE_POSE) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_sequence(
- bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set)
+static eOLDrawState tree_element_active_sequence(bContext *C,
+ Scene *scene,
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tselem),
+ const eOLSetState set)
{
- Sequence *seq = (Sequence *) te->directdata;
- Editing *ed = BKE_sequencer_editing_get(scene, false);
-
- if (set != OL_SETSEL_NONE) {
- /* only check on setting */
- if (BLI_findindex(ed->seqbasep, seq) != -1) {
- if (set == OL_SETSEL_EXTEND) {
- BKE_sequencer_active_set(scene, NULL);
- }
- ED_sequencer_deselect_all(scene);
-
- if ((set == OL_SETSEL_EXTEND) && seq->flag & SELECT) {
- seq->flag &= ~SELECT;
- }
- else {
- seq->flag |= SELECT;
- BKE_sequencer_active_set(scene, seq);
- }
- }
-
- WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
- }
- else {
- if (ed->act_seq == seq && seq->flag & SELECT) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- return OL_DRAWSEL_NONE;
+ Sequence *seq = (Sequence *)te->directdata;
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+
+ if (set != OL_SETSEL_NONE) {
+ /* only check on setting */
+ if (BLI_findindex(ed->seqbasep, seq) != -1) {
+ if (set == OL_SETSEL_EXTEND) {
+ BKE_sequencer_active_set(scene, NULL);
+ }
+ ED_sequencer_deselect_all(scene);
+
+ if ((set == OL_SETSEL_EXTEND) && seq->flag & SELECT) {
+ seq->flag &= ~SELECT;
+ }
+ else {
+ seq->flag |= SELECT;
+ BKE_sequencer_active_set(scene, seq);
+ }
+ }
+
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
+ }
+ else {
+ if (ed->act_seq == seq && seq->flag & SELECT) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_sequence_dup(
- Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set)
+static eOLDrawState tree_element_active_sequence_dup(Scene *scene,
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tselem),
+ const eOLSetState set)
{
- Sequence *seq, *p;
- Editing *ed = BKE_sequencer_editing_get(scene, false);
-
- seq = (Sequence *)te->directdata;
- if (set == OL_SETSEL_NONE) {
- if (seq->flag & SELECT) {
- return OL_DRAWSEL_NORMAL;
- }
- return OL_DRAWSEL_NONE;
- }
-
-// XXX select_single_seq(seq, 1);
- p = ed->seqbasep->first;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
- p = p->next;
- continue;
- }
-
-// if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
-// XXX select_single_seq(p, 0);
- p = p->next;
- }
- return OL_DRAWSEL_NONE;
+ Sequence *seq, *p;
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+
+ seq = (Sequence *)te->directdata;
+ if (set == OL_SETSEL_NONE) {
+ if (seq->flag & SELECT) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ return OL_DRAWSEL_NONE;
+ }
+
+ // XXX select_single_seq(seq, 1);
+ p = ed->seqbasep->first;
+ while (p) {
+ if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
+ p = p->next;
+ continue;
+ }
+
+ // if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
+ // XXX select_single_seq(p, 0);
+ p = p->next;
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_keymap_item(
- bContext *UNUSED(C), Scene *UNUSED(scene), ViewLayer *UNUSED(sl), TreeElement *te, TreeStoreElem *UNUSED(tselem), const eOLSetState set)
+static eOLDrawState tree_element_active_keymap_item(bContext *UNUSED(C),
+ Scene *UNUSED(scene),
+ ViewLayer *UNUSED(sl),
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tselem),
+ const eOLSetState set)
{
- wmKeyMapItem *kmi = te->directdata;
-
- if (set == OL_SETSEL_NONE) {
- if (kmi->flag & KMI_INACTIVE) {
- return OL_DRAWSEL_NONE;
- }
- return OL_DRAWSEL_NORMAL;
- }
- else {
- kmi->flag ^= KMI_INACTIVE;
- }
- return OL_DRAWSEL_NONE;
+ wmKeyMapItem *kmi = te->directdata;
+
+ if (set == OL_SETSEL_NONE) {
+ if (kmi->flag & KMI_INACTIVE) {
+ return OL_DRAWSEL_NONE;
+ }
+ return OL_DRAWSEL_NORMAL;
+ }
+ else {
+ kmi->flag ^= KMI_INACTIVE;
+ }
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_master_collection(
- bContext *C, TreeElement *UNUSED(te), const eOLSetState set)
+static eOLDrawState tree_element_active_master_collection(bContext *C,
+ TreeElement *UNUSED(te),
+ const eOLSetState set)
{
- if (set == OL_SETSEL_NONE) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- LayerCollection *active = CTX_data_layer_collection(C);
-
- if (active == view_layer->layer_collections.first) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- else {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- LayerCollection *layer_collection = view_layer->layer_collections.first;
- BKE_layer_collection_activate(view_layer, layer_collection);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
- }
-
- return OL_DRAWSEL_NONE;
+ if (set == OL_SETSEL_NONE) {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ LayerCollection *active = CTX_data_layer_collection(C);
+
+ if (active == view_layer->layer_collections.first) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ else {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ LayerCollection *layer_collection = view_layer->layer_collections.first;
+ BKE_layer_collection_activate(view_layer, layer_collection);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ }
+
+ return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_layer_collection(
- bContext *C, TreeElement *te, const eOLSetState set)
+static eOLDrawState tree_element_active_layer_collection(bContext *C,
+ TreeElement *te,
+ const eOLSetState set)
{
- if (set == OL_SETSEL_NONE) {
- LayerCollection *active = CTX_data_layer_collection(C);
-
- if (active == te->directdata) {
- return OL_DRAWSEL_NORMAL;
- }
- }
- else {
- Scene *scene = CTX_data_scene(C);
- LayerCollection *layer_collection = te->directdata;
- ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
- BKE_layer_collection_activate(view_layer, layer_collection);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
- }
-
- return OL_DRAWSEL_NONE;
+ if (set == OL_SETSEL_NONE) {
+ LayerCollection *active = CTX_data_layer_collection(C);
+
+ if (active == te->directdata) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ }
+ else {
+ Scene *scene = CTX_data_scene(C);
+ LayerCollection *layer_collection = te->directdata;
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
+ BKE_layer_collection_activate(view_layer, layer_collection);
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ }
+
+ return OL_DRAWSEL_NONE;
}
/* ---------------------------------------------- */
/* generic call for ID data check or make/check active in UI */
-eOLDrawState tree_element_active(bContext *C, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops, TreeElement *te,
- const eOLSetState set, const bool handle_all_types)
+eOLDrawState tree_element_active(bContext *C,
+ Scene *scene,
+ ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ const eOLSetState set,
+ const bool handle_all_types)
{
- switch (te->idcode) {
- /* Note: ID_OB only if handle_all_type is true, else objects are handled specially to allow multiple
- * selection. See do_outliner_item_activate. */
- case ID_OB:
- if (handle_all_types) {
- return tree_element_set_active_object(C, scene, view_layer, soops, te, set, false);
- }
- break;
- case ID_MA:
- return tree_element_active_material(C, scene, view_layer, soops, te, set);
- case ID_WO:
- return tree_element_active_world(C, scene, view_layer, soops, te, set);
- case ID_LA:
- return tree_element_active_light(C, scene, view_layer, soops, te, set);
- case ID_TXT:
- return tree_element_active_text(C, scene, view_layer, soops, te, set);
- case ID_CA:
- return tree_element_active_camera(C, scene, view_layer, soops, te, set);
- }
- return OL_DRAWSEL_NONE;
+ switch (te->idcode) {
+ /* Note: ID_OB only if handle_all_type is true, else objects are handled specially to allow multiple
+ * selection. See do_outliner_item_activate. */
+ case ID_OB:
+ if (handle_all_types) {
+ return tree_element_set_active_object(C, scene, view_layer, soops, te, set, false);
+ }
+ break;
+ case ID_MA:
+ return tree_element_active_material(C, scene, view_layer, soops, te, set);
+ case ID_WO:
+ return tree_element_active_world(C, scene, view_layer, soops, te, set);
+ case ID_LA:
+ return tree_element_active_light(C, scene, view_layer, soops, te, set);
+ case ID_TXT:
+ return tree_element_active_text(C, scene, view_layer, soops, te, set);
+ case ID_CA:
+ return tree_element_active_camera(C, scene, view_layer, soops, te, set);
+ }
+ return OL_DRAWSEL_NONE;
}
/**
* Generic call for non-id data to make/check active in UI
*/
-eOLDrawState tree_element_type_active(
- bContext *C, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops,
- TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive)
+eOLDrawState tree_element_type_active(bContext *C,
+ Scene *scene,
+ ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const eOLSetState set,
+ bool recursive)
{
- switch (tselem->type) {
- case TSE_DEFGROUP:
- return tree_element_active_defgroup(C, view_layer, te, tselem, set);
- case TSE_BONE:
- return tree_element_active_bone(C, view_layer, te, tselem, set, recursive);
- case TSE_EBONE:
- return tree_element_active_ebone(C, view_layer, te, tselem, set, recursive);
- case TSE_MODIFIER:
- return tree_element_active_modifier(C, scene, view_layer, te, tselem, set);
- case TSE_LINKED_OB:
- if (set != OL_SETSEL_NONE) {
- tree_element_set_active_object(C, scene, view_layer, soops, te, set, false);
- }
- else if (tselem->id == (ID *)OBACT(view_layer)) {
- return OL_DRAWSEL_NORMAL;
- }
- break;
- case TSE_LINKED_PSYS:
- return tree_element_active_psys(C, scene, te, tselem, set);
- case TSE_POSE_BASE:
- return tree_element_active_pose(C, scene, view_layer, te, tselem, set);
- case TSE_POSE_CHANNEL:
- return tree_element_active_posechannel(C, scene, view_layer, te, tselem, set, recursive);
- case TSE_CONSTRAINT:
- return tree_element_active_constraint(C, scene, view_layer, te, tselem, set);
- case TSE_R_LAYER:
- return active_viewlayer(C, scene, view_layer, te, set);
- case TSE_POSEGRP:
- return tree_element_active_posegroup(C, scene, view_layer, te, tselem, set);
- case TSE_SEQUENCE:
- return tree_element_active_sequence(C, scene, te, tselem, set);
- case TSE_SEQUENCE_DUP:
- return tree_element_active_sequence_dup(scene, te, tselem, set);
- case TSE_KEYMAP_ITEM:
- return tree_element_active_keymap_item(C, scene, view_layer, te, tselem, set);
- case TSE_GP_LAYER:
- return tree_element_active_gplayer(C, scene, te, tselem, set);
- break;
- case TSE_VIEW_COLLECTION_BASE:
- return tree_element_active_master_collection(C, te, set);
- case TSE_LAYER_COLLECTION:
- return tree_element_active_layer_collection(C, te, set);
- }
- return OL_DRAWSEL_NONE;
+ switch (tselem->type) {
+ case TSE_DEFGROUP:
+ return tree_element_active_defgroup(C, view_layer, te, tselem, set);
+ case TSE_BONE:
+ return tree_element_active_bone(C, view_layer, te, tselem, set, recursive);
+ case TSE_EBONE:
+ return tree_element_active_ebone(C, view_layer, te, tselem, set, recursive);
+ case TSE_MODIFIER:
+ return tree_element_active_modifier(C, scene, view_layer, te, tselem, set);
+ case TSE_LINKED_OB:
+ if (set != OL_SETSEL_NONE) {
+ tree_element_set_active_object(C, scene, view_layer, soops, te, set, false);
+ }
+ else if (tselem->id == (ID *)OBACT(view_layer)) {
+ return OL_DRAWSEL_NORMAL;
+ }
+ break;
+ case TSE_LINKED_PSYS:
+ return tree_element_active_psys(C, scene, te, tselem, set);
+ case TSE_POSE_BASE:
+ return tree_element_active_pose(C, scene, view_layer, te, tselem, set);
+ case TSE_POSE_CHANNEL:
+ return tree_element_active_posechannel(C, scene, view_layer, te, tselem, set, recursive);
+ case TSE_CONSTRAINT:
+ return tree_element_active_constraint(C, scene, view_layer, te, tselem, set);
+ case TSE_R_LAYER:
+ return active_viewlayer(C, scene, view_layer, te, set);
+ case TSE_POSEGRP:
+ return tree_element_active_posegroup(C, scene, view_layer, te, tselem, set);
+ case TSE_SEQUENCE:
+ return tree_element_active_sequence(C, scene, te, tselem, set);
+ case TSE_SEQUENCE_DUP:
+ return tree_element_active_sequence_dup(scene, te, tselem, set);
+ case TSE_KEYMAP_ITEM:
+ return tree_element_active_keymap_item(C, scene, view_layer, te, tselem, set);
+ case TSE_GP_LAYER:
+ return tree_element_active_gplayer(C, scene, te, tselem, set);
+ break;
+ case TSE_VIEW_COLLECTION_BASE:
+ return tree_element_active_master_collection(C, te, set);
+ case TSE_LAYER_COLLECTION:
+ return tree_element_active_layer_collection(C, te, set);
+ }
+ return OL_DRAWSEL_NONE;
}
/* ================================================ */
@@ -1031,143 +1115,162 @@ eOLDrawState tree_element_type_active(
*
* Needed to run from operators accessed from a menu.
*/
-static void do_outliner_item_activate_tree_element(
- bContext *C, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops,
- TreeElement *te, TreeStoreElem *tselem,
- const bool extend, const bool recursive)
+static void do_outliner_item_activate_tree_element(bContext *C,
+ Scene *scene,
+ ViewLayer *view_layer,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ const bool extend,
+ const bool recursive)
{
- /* Always makes active object, except for some specific types. */
- if (ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE, TSE_LAYER_COLLECTION)) {
- /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want
- * to switch out of edit mode (see T48328 for details). */
- }
- else if (tselem->id && OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
- /* Support edit-mode toggle, keeping the active object as is. */
- }
- else if (tselem->type == TSE_POSE_BASE) {
- /* Support pose mode toggle, keeping the active object as is. */
- }
- else {
- tree_element_set_active_object(
- C, scene, view_layer, soops, te,
- (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
- recursive && tselem->type == 0);
- }
-
- if (tselem->type == 0) { // the lib blocks
- /* editmode? */
- if (te->idcode == ID_SCE) {
- if (scene != (Scene *)tselem->id) {
- WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), (Scene *)tselem->id);
- }
- }
- else if (te->idcode == ID_GR) {
- Collection *gr = (Collection *)tselem->id;
-
- if (extend) {
- int sel = BA_SELECT;
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(gr, object)
- {
- Base *base = BKE_view_layer_base_find(view_layer, object);
- if (base && (base->flag & BASE_SELECTED)) {
- sel = BA_DESELECT;
- break;
- }
- }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
-
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(gr, object)
- {
- Base *base = BKE_view_layer_base_find(view_layer, object);
- if (base) {
- ED_object_base_select(base, sel);
- }
- }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
- }
- else {
- BKE_view_layer_base_deselect_all(view_layer);
-
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(gr, object)
- {
- Base *base = BKE_view_layer_base_find(view_layer, object);
- /* Object may not be in this scene */
- if (base != NULL) {
- if ((base->flag & BASE_SELECTED) == 0) {
- ED_object_base_select(base, BA_SELECT);
- }
- }
- }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
- }
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- else if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
- Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if ((ob != NULL) && (ob->data == tselem->id)) {
- Base *base = BKE_view_layer_base_find(view_layer, ob);
- if ((base != NULL) && (base->flag & BASE_VISIBLE)) {
- do_outliner_activate_obdata(C, scene, view_layer, base, extend);
- }
- }
- }
- else if (ELEM(te->idcode, ID_GD)) {
- /* set grease pencil to object mode */
- WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
- }
- else { // rest of types
- tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, false);
- }
-
- }
- else {
- tree_element_type_active(C, scene, view_layer, soops, te, tselem,
- extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
- recursive);
- }
+ /* Always makes active object, except for some specific types. */
+ if (ELEM(tselem->type,
+ TSE_SEQUENCE,
+ TSE_SEQ_STRIP,
+ TSE_SEQUENCE_DUP,
+ TSE_EBONE,
+ TSE_LAYER_COLLECTION)) {
+ /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want
+ * to switch out of edit mode (see T48328 for details). */
+ }
+ else if (tselem->id && OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
+ /* Support edit-mode toggle, keeping the active object as is. */
+ }
+ else if (tselem->type == TSE_POSE_BASE) {
+ /* Support pose mode toggle, keeping the active object as is. */
+ }
+ else {
+ tree_element_set_active_object(C,
+ scene,
+ view_layer,
+ soops,
+ te,
+ (extend && tselem->type == 0) ? OL_SETSEL_EXTEND :
+ OL_SETSEL_NORMAL,
+ recursive && tselem->type == 0);
+ }
+
+ if (tselem->type == 0) { // the lib blocks
+ /* editmode? */
+ if (te->idcode == ID_SCE) {
+ if (scene != (Scene *)tselem->id) {
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), (Scene *)tselem->id);
+ }
+ }
+ else if (te->idcode == ID_GR) {
+ Collection *gr = (Collection *)tselem->id;
+
+ if (extend) {
+ int sel = BA_SELECT;
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) {
+ Base *base = BKE_view_layer_base_find(view_layer, object);
+ if (base && (base->flag & BASE_SELECTED)) {
+ sel = BA_DESELECT;
+ break;
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) {
+ Base *base = BKE_view_layer_base_find(view_layer, object);
+ if (base) {
+ ED_object_base_select(base, sel);
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
+ else {
+ BKE_view_layer_base_deselect_all(view_layer);
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) {
+ Base *base = BKE_view_layer_base_find(view_layer, object);
+ /* Object may not be in this scene */
+ if (base != NULL) {
+ if ((base->flag & BASE_SELECTED) == 0) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
+ Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
+ if ((ob != NULL) && (ob->data == tselem->id)) {
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ if ((base != NULL) && (base->flag & BASE_VISIBLE)) {
+ do_outliner_activate_obdata(C, scene, view_layer, base, extend);
+ }
+ }
+ }
+ else if (ELEM(te->idcode, ID_GD)) {
+ /* set grease pencil to object mode */
+ WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
+ else { // rest of types
+ tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, false);
+ }
+ }
+ else {
+ tree_element_type_active(C,
+ scene,
+ view_layer,
+ soops,
+ te,
+ tselem,
+ extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
+ recursive);
+ }
}
/**
* \param extend: Don't deselect other items, only modify \a te.
* \param toggle: Select \a te when not selected, deselect when selected.
*/
-void outliner_item_select(SpaceOutliner *soops, const TreeElement *te, const bool extend, const bool toggle)
+void outliner_item_select(SpaceOutliner *soops,
+ const TreeElement *te,
+ const bool extend,
+ const bool toggle)
{
- TreeStoreElem *tselem = TREESTORE(te);
- const short new_flag = toggle ? (tselem->flag ^ TSE_SELECTED) : (tselem->flag | TSE_SELECTED);
+ TreeStoreElem *tselem = TREESTORE(te);
+ const short new_flag = toggle ? (tselem->flag ^ TSE_SELECTED) : (tselem->flag | TSE_SELECTED);
- if (extend == false) {
- outliner_flag_set(&soops->tree, TSE_SELECTED, false);
- }
- tselem->flag = new_flag;
+ if (extend == false) {
+ outliner_flag_set(&soops->tree, TSE_SELECTED, false);
+ }
+ tselem->flag = new_flag;
}
static void outliner_item_toggle_closed(TreeElement *te, const bool toggle_children)
{
- TreeStoreElem *tselem = TREESTORE(te);
- if (toggle_children) {
- tselem->flag &= ~TSE_CLOSED;
-
- const bool all_opened = !outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1);
- outliner_flag_set(&te->subtree, TSE_CLOSED, all_opened);
- }
- else {
- tselem->flag ^= TSE_CLOSED;
- }
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (toggle_children) {
+ tselem->flag &= ~TSE_CLOSED;
+
+ const bool all_opened = !outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1);
+ outliner_flag_set(&te->subtree, TSE_CLOSED, all_opened);
+ }
+ else {
+ tselem->flag ^= TSE_CLOSED;
+ }
}
static bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x)
{
- return ((te->flag & TE_ICONROW) == 0) && (view_co_x > te->xs) && (view_co_x < te->xs + UI_UNIT_X);
+ return ((te->flag & TE_ICONROW) == 0) && (view_co_x > te->xs) &&
+ (view_co_x < te->xs + UI_UNIT_X);
}
-static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops, const ARegion *ar, float view_co_x)
+static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops,
+ const ARegion *ar,
+ float view_co_x)
{
- return ((soops->outlinevis != SO_DATA_API) &&
- !(soops->flag & SO_HIDE_RESTRICTCOLS) &&
- (view_co_x > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX));
+ return ((soops->outlinevis != SO_DATA_API) && !(soops->flag & SO_HIDE_RESTRICTCOLS) &&
+ (view_co_x > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX));
}
/**
@@ -1177,17 +1280,14 @@ static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops, c
* This allows us to simulate clicking on an item without dealing with the mouse cursor.
*/
void outliner_item_do_activate_from_tree_element(
- bContext *C, TreeElement *te, TreeStoreElem *tselem,
- bool extend, bool recursive)
+ bContext *C, TreeElement *te, TreeStoreElem *tselem, bool extend, bool recursive)
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
-
- do_outliner_item_activate_tree_element(
- C, scene, view_layer, soops,
- te, tselem,
- extend, recursive);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+ do_outliner_item_activate_tree_element(
+ C, scene, view_layer, soops, te, tselem, extend, recursive);
}
/**
@@ -1195,149 +1295,152 @@ void outliner_item_do_activate_from_tree_element(
*
* May expend/collapse branches or activate items.
* */
-int outliner_item_do_activate_from_cursor(
- bContext *C, const int mval[2],
- bool extend, bool recursive)
+int outliner_item_do_activate_from_cursor(bContext *C,
+ const int mval[2],
+ bool extend,
+ bool recursive)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- TreeElement *te;
- float view_mval[2];
- bool changed = false, rebuild_tree = false;
-
- UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &view_mval[0], &view_mval[1]);
-
- if (outliner_is_co_within_restrict_columns(soops, ar, view_mval[0])) {
- return OPERATOR_CANCELLED;
- }
-
- if (!(te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]))) {
- /* skip */
- }
- else if (outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
- outliner_item_toggle_closed(te, extend);
- changed = true;
- rebuild_tree = true;
- }
- else {
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- /* the row may also contain children, if one is hovered we want this instead of current te */
- TreeElement *activate_te = outliner_find_item_at_x_in_row(soops, te, view_mval[0]);
- TreeStoreElem *activate_tselem = TREESTORE(activate_te);
-
- outliner_item_select(soops, activate_te, extend, extend);
- do_outliner_item_activate_tree_element(C, scene, view_layer, soops, activate_te, activate_tselem, extend, recursive);
- changed = true;
- }
-
- if (changed) {
- if (rebuild_tree) {
- ED_region_tag_redraw(ar);
- }
- else {
- ED_region_tag_redraw_no_rebuild(ar);
- }
- ED_undo_push(C, "Outliner selection change");
- }
-
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ TreeElement *te;
+ float view_mval[2];
+ bool changed = false, rebuild_tree = false;
+
+ UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &view_mval[0], &view_mval[1]);
+
+ if (outliner_is_co_within_restrict_columns(soops, ar, view_mval[0])) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!(te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]))) {
+ /* skip */
+ }
+ else if (outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
+ outliner_item_toggle_closed(te, extend);
+ changed = true;
+ rebuild_tree = true;
+ }
+ else {
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ /* the row may also contain children, if one is hovered we want this instead of current te */
+ TreeElement *activate_te = outliner_find_item_at_x_in_row(soops, te, view_mval[0]);
+ TreeStoreElem *activate_tselem = TREESTORE(activate_te);
+
+ outliner_item_select(soops, activate_te, extend, extend);
+ do_outliner_item_activate_tree_element(
+ C, scene, view_layer, soops, activate_te, activate_tselem, extend, recursive);
+ changed = true;
+ }
+
+ if (changed) {
+ if (rebuild_tree) {
+ ED_region_tag_redraw(ar);
+ }
+ else {
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+ ED_undo_push(C, "Outliner selection change");
+ }
+
+ return OPERATOR_FINISHED;
}
/* event can enterkey, then it opens/closes */
static int outliner_item_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bool extend = RNA_boolean_get(op->ptr, "extend");
- bool recursive = RNA_boolean_get(op->ptr, "recursive");
- return outliner_item_do_activate_from_cursor(C, event->mval, extend, recursive);
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool recursive = RNA_boolean_get(op->ptr, "recursive");
+ return outliner_item_do_activate_from_cursor(C, event->mval, extend, recursive);
}
void OUTLINER_OT_item_activate(wmOperatorType *ot)
{
- ot->name = "Select";
- ot->idname = "OUTLINER_OT_item_activate";
- ot->description = "Handle mouse clicks to select and activate items";
+ ot->name = "Select";
+ ot->idname = "OUTLINER_OT_item_activate";
+ ot->description = "Handle mouse clicks to select and activate items";
- ot->invoke = outliner_item_activate_invoke;
+ ot->invoke = outliner_item_activate_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
- RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection for activation");
- RNA_def_boolean(ot->srna, "recursive", false, "Recursive", "Select Objects and their children");
+ RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection for activation");
+ RNA_def_boolean(ot->srna, "recursive", false, "Recursive", "Select Objects and their children");
}
/* ****************************************************** */
/* **************** Box Select Tool ****************** */
-static void outliner_item_box_select(SpaceOutliner *soops, Scene *scene, rctf *rectf, TreeElement *te, bool select)
+static void outliner_item_box_select(
+ SpaceOutliner *soops, Scene *scene, rctf *rectf, TreeElement *te, bool select)
{
- TreeStoreElem *tselem = TREESTORE(te);
-
- if (te->ys <= rectf->ymax && te->ys + UI_UNIT_Y >= rectf->ymin) {
- if (select) {
- tselem->flag |= TSE_SELECTED;
- }
- else {
- tselem->flag &= ~TSE_SELECTED;
- }
- }
-
- /* Look at its children. */
- if (TSELEM_OPEN(tselem, soops)) {
- for (te = te->subtree.first; te; te = te->next) {
- outliner_item_box_select(soops, scene, rectf, te, select);
- }
- }
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (te->ys <= rectf->ymax && te->ys + UI_UNIT_Y >= rectf->ymin) {
+ if (select) {
+ tselem->flag |= TSE_SELECTED;
+ }
+ else {
+ tselem->flag &= ~TSE_SELECTED;
+ }
+ }
+
+ /* Look at its children. */
+ if (TSELEM_OPEN(tselem, soops)) {
+ for (te = te->subtree.first; te; te = te->next) {
+ outliner_item_box_select(soops, scene, rectf, te, select);
+ }
+ }
}
static int outliner_box_select_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ARegion *ar = CTX_wm_region(C);
- rctf rectf;
+ Scene *scene = CTX_data_scene(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ rctf rectf;
- const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
- const bool select = (sel_op != SEL_OP_SUB);
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
- }
+ const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ const bool select = (sel_op != SEL_OP_SUB);
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
+ }
- WM_operator_properties_border_to_rctf(op, &rectf);
- UI_view2d_region_to_view_rctf(&ar->v2d, &rectf, &rectf);
+ WM_operator_properties_border_to_rctf(op, &rectf);
+ UI_view2d_region_to_view_rctf(&ar->v2d, &rectf, &rectf);
- for (TreeElement *te = soops->tree.first; te; te = te->next) {
- outliner_item_box_select(soops, scene, &rectf, te, select);
- }
+ for (TreeElement *te = soops->tree.first; te; te = te->next) {
+ outliner_item_box_select(soops, scene, &rectf, te, select);
+ }
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- ED_region_tag_redraw(ar);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ ED_region_tag_redraw(ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_select_box(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Box Select";
- ot->idname = "OUTLINER_OT_select_box";
- ot->description = "Use box selection to select tree elements";
+ /* identifiers */
+ ot->name = "Box Select";
+ ot->idname = "OUTLINER_OT_select_box";
+ ot->description = "Use box selection to select tree elements";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = outliner_box_select_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = outliner_box_select_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_gesture_box(ot);
- WM_operator_properties_select_operation_simple(ot);
+ /* properties */
+ WM_operator_properties_gesture_box(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/* ****************************************************** */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 083ae3a048c..ad4661102bc 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -82,2041 +82,2222 @@
#include "outliner_intern.h"
-
/* ****************************************************** */
/* ************ SELECTION OPERATIONS ********* */
-static void set_operation_types(SpaceOutliner *soops, ListBase *lb,
+static void set_operation_types(SpaceOutliner *soops,
+ ListBase *lb,
int *scenelevel,
int *objectlevel,
int *idlevel,
int *datalevel)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_SELECTED) {
- /* Layer collection points to collection ID. */
- if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
- if (*datalevel == 0) {
- *datalevel = tselem->type;
- }
- else if (*datalevel != tselem->type) {
- *datalevel = -1;
- }
- }
- else {
- int idcode = GS(tselem->id->name);
- switch (idcode) {
- case ID_SCE:
- *scenelevel = 1;
- break;
- case ID_OB:
- *objectlevel = 1;
- break;
-
- case ID_ME: case ID_CU: case ID_MB: case ID_LT:
- case ID_LA: case ID_AR: case ID_CA: case ID_SPK:
- case ID_MA: case ID_TE: case ID_IP: case ID_IM:
- case ID_SO: case ID_KE: case ID_WO: case ID_AC:
- case ID_NLA: case ID_TXT: case ID_GR: case ID_LS:
- case ID_LI:
- if (*idlevel == 0) {
- *idlevel = idcode;
- }
- else if (*idlevel != idcode) {
- *idlevel = -1;
- }
- if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) {
- *datalevel = 0;
- }
- break;
- }
- }
- }
- if (TSELEM_OPEN(tselem, soops)) {
- set_operation_types(soops, &te->subtree,
- scenelevel, objectlevel, idlevel, datalevel);
- }
- }
-}
-
-static void unlink_action_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data))
-{
- /* just set action to NULL */
- BKE_animdata_set_action(CTX_wm_reports(C), tsep->id, NULL);
-}
-
-static void unlink_material_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te,
- TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data))
-{
- Material **matar = NULL;
- int a, totcol = 0;
-
- if (GS(tsep->id->name) == ID_OB) {
- Object *ob = (Object *)tsep->id;
- totcol = ob->totcol;
- matar = ob->mat;
- }
- else if (GS(tsep->id->name) == ID_ME) {
- Mesh *me = (Mesh *)tsep->id;
- totcol = me->totcol;
- matar = me->mat;
- }
- else if (GS(tsep->id->name) == ID_CU) {
- Curve *cu = (Curve *)tsep->id;
- totcol = cu->totcol;
- matar = cu->mat;
- }
- else if (GS(tsep->id->name) == ID_MB) {
- MetaBall *mb = (MetaBall *)tsep->id;
- totcol = mb->totcol;
- matar = mb->mat;
- }
- else {
- BLI_assert(0);
- }
-
- if (LIKELY(matar != NULL)) {
- for (a = 0; a < totcol; a++) {
- if (a == te->index && matar[a]) {
- id_us_min(&matar[a]->id);
- matar[a] = NULL;
- }
- }
- }
-}
-
-static void unlink_texture_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te,
- TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data))
-{
- MTex **mtex = NULL;
- int a;
-
- if (GS(tsep->id->name) == ID_LS) {
- FreestyleLineStyle *ls = (FreestyleLineStyle *)tsep->id;
- mtex = ls->mtex;
- }
- else {
- return;
- }
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (a == te->index && mtex[a]) {
- if (mtex[a]->tex) {
- id_us_min(&mtex[a]->tex->id);
- mtex[a]->tex = NULL;
- }
- }
- }
-}
-
-static void unlink_collection_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Main *bmain = CTX_data_main(C);
- Collection *collection = (Collection *)tselem->id;
-
- if (tsep) {
- if (GS(tsep->id->name) == ID_OB) {
- Object *ob = (Object *)tsep->id;
- ob->instance_collection = NULL;
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- DEG_relations_tag_update(bmain);
- }
- else if (GS(tsep->id->name) == ID_GR) {
- Collection *parent = (Collection *)tsep->id;
- id_fake_user_set(&collection->id);
- BKE_collection_child_remove(bmain, parent, collection);
- DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- }
- else if (GS(tsep->id->name) == ID_SCE) {
- Scene *scene = (Scene *)tsep->id;
- Collection *parent = BKE_collection_master(scene);
- id_fake_user_set(&collection->id);
- BKE_collection_child_remove(bmain, parent, collection);
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- }
- }
-}
-
-static void unlink_object_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Main *bmain = CTX_data_main(C);
- Object *ob = (Object *)tselem->id;
-
- if (tsep) {
- if (GS(tsep->id->name) == ID_GR) {
- Collection *parent = (Collection *)tsep->id;
- BKE_collection_object_remove(bmain, parent, ob, true);
- DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- }
- else if (GS(tsep->id->name) == ID_SCE) {
- Scene *scene = (Scene *)tsep->id;
- Collection *parent = BKE_collection_master(scene);
- BKE_collection_object_remove(bmain, parent, ob, true);
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- }
- }
-}
-
-static void unlink_world_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Scene *parscene = (Scene *)tsep->id;
- World *wo = (World *)tselem->id;
-
- /* need to use parent scene not just scene, otherwise may end up getting wrong one */
- id_us_min(&wo->id);
- parscene->world = NULL;
-}
-
-static void outliner_do_libdata_operation(
- bContext *C, ReportList *reports, Scene *scene, SpaceOutliner *soops, ListBase *lb,
- outliner_operation_cb operation_cb,
- void *user_data)
-{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_SELECTED) {
- if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
- TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
- operation_cb(C, reports, scene, te, tsep, tselem, user_data);
- }
- }
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_do_libdata_operation(C, reports, scene, soops, &te->subtree, operation_cb, user_data);
- }
- }
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & TSE_SELECTED) {
+ /* Layer collection points to collection ID. */
+ if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+ if (*datalevel == 0) {
+ *datalevel = tselem->type;
+ }
+ else if (*datalevel != tselem->type) {
+ *datalevel = -1;
+ }
+ }
+ else {
+ int idcode = GS(tselem->id->name);
+ switch (idcode) {
+ case ID_SCE:
+ *scenelevel = 1;
+ break;
+ case ID_OB:
+ *objectlevel = 1;
+ break;
+
+ case ID_ME:
+ case ID_CU:
+ case ID_MB:
+ case ID_LT:
+ case ID_LA:
+ case ID_AR:
+ case ID_CA:
+ case ID_SPK:
+ case ID_MA:
+ case ID_TE:
+ case ID_IP:
+ case ID_IM:
+ case ID_SO:
+ case ID_KE:
+ case ID_WO:
+ case ID_AC:
+ case ID_NLA:
+ case ID_TXT:
+ case ID_GR:
+ case ID_LS:
+ case ID_LI:
+ if (*idlevel == 0) {
+ *idlevel = idcode;
+ }
+ else if (*idlevel != idcode) {
+ *idlevel = -1;
+ }
+ if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) {
+ *datalevel = 0;
+ }
+ break;
+ }
+ }
+ }
+ if (TSELEM_OPEN(tselem, soops)) {
+ set_operation_types(soops, &te->subtree, scenelevel, objectlevel, idlevel, datalevel);
+ }
+ }
+}
+
+static void unlink_action_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tsep,
+ TreeStoreElem *UNUSED(tselem),
+ void *UNUSED(user_data))
+{
+ /* just set action to NULL */
+ BKE_animdata_set_action(CTX_wm_reports(C), tsep->id, NULL);
+}
+
+static void unlink_material_cb(bContext *UNUSED(C),
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *tsep,
+ TreeStoreElem *UNUSED(tselem),
+ void *UNUSED(user_data))
+{
+ Material **matar = NULL;
+ int a, totcol = 0;
+
+ if (GS(tsep->id->name) == ID_OB) {
+ Object *ob = (Object *)tsep->id;
+ totcol = ob->totcol;
+ matar = ob->mat;
+ }
+ else if (GS(tsep->id->name) == ID_ME) {
+ Mesh *me = (Mesh *)tsep->id;
+ totcol = me->totcol;
+ matar = me->mat;
+ }
+ else if (GS(tsep->id->name) == ID_CU) {
+ Curve *cu = (Curve *)tsep->id;
+ totcol = cu->totcol;
+ matar = cu->mat;
+ }
+ else if (GS(tsep->id->name) == ID_MB) {
+ MetaBall *mb = (MetaBall *)tsep->id;
+ totcol = mb->totcol;
+ matar = mb->mat;
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ if (LIKELY(matar != NULL)) {
+ for (a = 0; a < totcol; a++) {
+ if (a == te->index && matar[a]) {
+ id_us_min(&matar[a]->id);
+ matar[a] = NULL;
+ }
+ }
+ }
+}
+
+static void unlink_texture_cb(bContext *UNUSED(C),
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *tsep,
+ TreeStoreElem *UNUSED(tselem),
+ void *UNUSED(user_data))
+{
+ MTex **mtex = NULL;
+ int a;
+
+ if (GS(tsep->id->name) == ID_LS) {
+ FreestyleLineStyle *ls = (FreestyleLineStyle *)tsep->id;
+ mtex = ls->mtex;
+ }
+ else {
+ return;
+ }
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (a == te->index && mtex[a]) {
+ if (mtex[a]->tex) {
+ id_us_min(&mtex[a]->tex->id);
+ mtex[a]->tex = NULL;
+ }
+ }
+ }
+}
+
+static void unlink_collection_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tsep,
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ Main *bmain = CTX_data_main(C);
+ Collection *collection = (Collection *)tselem->id;
+
+ if (tsep) {
+ if (GS(tsep->id->name) == ID_OB) {
+ Object *ob = (Object *)tsep->id;
+ ob->instance_collection = NULL;
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+ DEG_relations_tag_update(bmain);
+ }
+ else if (GS(tsep->id->name) == ID_GR) {
+ Collection *parent = (Collection *)tsep->id;
+ id_fake_user_set(&collection->id);
+ BKE_collection_child_remove(bmain, parent, collection);
+ DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ }
+ else if (GS(tsep->id->name) == ID_SCE) {
+ Scene *scene = (Scene *)tsep->id;
+ Collection *parent = BKE_collection_master(scene);
+ id_fake_user_set(&collection->id);
+ BKE_collection_child_remove(bmain, parent, collection);
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ }
+ }
+}
+
+static void unlink_object_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tsep,
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = (Object *)tselem->id;
+
+ if (tsep) {
+ if (GS(tsep->id->name) == ID_GR) {
+ Collection *parent = (Collection *)tsep->id;
+ BKE_collection_object_remove(bmain, parent, ob, true);
+ DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ }
+ else if (GS(tsep->id->name) == ID_SCE) {
+ Scene *scene = (Scene *)tsep->id;
+ Collection *parent = BKE_collection_master(scene);
+ BKE_collection_object_remove(bmain, parent, ob, true);
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ }
+ }
+}
+
+static void unlink_world_cb(bContext *UNUSED(C),
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tsep,
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ Scene *parscene = (Scene *)tsep->id;
+ World *wo = (World *)tselem->id;
+
+ /* need to use parent scene not just scene, otherwise may end up getting wrong one */
+ id_us_min(&wo->id);
+ parscene->world = NULL;
+}
+
+static void outliner_do_libdata_operation(bContext *C,
+ ReportList *reports,
+ Scene *scene,
+ SpaceOutliner *soops,
+ ListBase *lb,
+ outliner_operation_cb operation_cb,
+ void *user_data)
+{
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & TSE_SELECTED) {
+ if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+ TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
+ operation_cb(C, reports, scene, te, tsep, tselem, user_data);
+ }
+ }
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_do_libdata_operation(
+ C, reports, scene, soops, &te->subtree, operation_cb, user_data);
+ }
+ }
}
/* ******************************************** */
typedef enum eOutliner_PropSceneOps {
- OL_SCENE_OP_DELETE = 1,
+ OL_SCENE_OP_DELETE = 1,
} eOutliner_PropSceneOps;
static const EnumPropertyItem prop_scene_op_types[] = {
- {OL_SCENE_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
- {0, NULL, 0, NULL, NULL},
+ {OL_SCENE_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
+ {0, NULL, 0, NULL, NULL},
};
static bool outliner_do_scene_operation(
- bContext *C, eOutliner_PropSceneOps event, ListBase *lb,
- bool (*operation_cb)(bContext *, eOutliner_PropSceneOps, TreeElement *, TreeStoreElem *))
+ bContext *C,
+ eOutliner_PropSceneOps event,
+ ListBase *lb,
+ bool (*operation_cb)(bContext *, eOutliner_PropSceneOps, TreeElement *, TreeStoreElem *))
{
- TreeElement *te;
- TreeStoreElem *tselem;
- bool success = false;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+ bool success = false;
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_SELECTED) {
- if (operation_cb(C, event, te, tselem)) {
- success = true;
- }
- }
- }
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & TSE_SELECTED) {
+ if (operation_cb(C, event, te, tselem)) {
+ success = true;
+ }
+ }
+ }
- return success;
+ return success;
}
-static bool scene_cb(bContext *C, eOutliner_PropSceneOps event, TreeElement *UNUSED(te), TreeStoreElem *tselem)
+static bool scene_cb(bContext *C,
+ eOutliner_PropSceneOps event,
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem)
{
- Scene *scene = (Scene *)tselem->id;
+ Scene *scene = (Scene *)tselem->id;
- if (event == OL_SCENE_OP_DELETE) {
- if (ED_scene_delete(C, CTX_data_main(C), CTX_wm_window(C), scene)) {
- WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, scene);
- }
- else {
- return false;
- }
- }
+ if (event == OL_SCENE_OP_DELETE) {
+ if (ED_scene_delete(C, CTX_data_main(C), CTX_wm_window(C), scene)) {
+ WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, scene);
+ }
+ else {
+ return false;
+ }
+ }
- return true;
+ return true;
}
static int outliner_scene_operation_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- const eOutliner_PropSceneOps event = RNA_enum_get(op->ptr, "type");
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ const eOutliner_PropSceneOps event = RNA_enum_get(op->ptr, "type");
- if (outliner_do_scene_operation(C, event, &soops->tree, scene_cb) == false) {
- return OPERATOR_CANCELLED;
- }
+ if (outliner_do_scene_operation(C, event, &soops->tree, scene_cb) == false) {
+ return OPERATOR_CANCELLED;
+ }
- if (event == OL_SCENE_OP_DELETE) {
- outliner_cleanup_tree(soops);
- ED_undo_push(C, "Delete Scene(s)");
- }
- else {
- BLI_assert(0);
- return OPERATOR_CANCELLED;
- }
+ if (event == OL_SCENE_OP_DELETE) {
+ outliner_cleanup_tree(soops);
+ ED_undo_push(C, "Delete Scene(s)");
+ }
+ else {
+ BLI_assert(0);
+ return OPERATOR_CANCELLED;
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_scene_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner Scene Operation";
- ot->idname = "OUTLINER_OT_scene_operation";
- ot->description = "Context menu for scene operations";
+ /* identifiers */
+ ot->name = "Outliner Scene Operation";
+ ot->idname = "OUTLINER_OT_scene_operation";
+ ot->description = "Context menu for scene operations";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_scene_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_scene_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_scene_op_types, 0, "Scene Operation", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_scene_op_types, 0, "Scene Operation", "");
}
/* ******************************************** */
-static void object_select_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = (Object *)tselem->id;
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
- if (base && ((base->flag & BASE_VISIBLE) != 0)) {
- base->flag |= BASE_SELECTED;
- }
-}
-
-static void object_select_hierarchy_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- /* Don't extend because this toggles, which is nice for Ctrl-Click but not for a menu item.
- * it's especially confusing when multiple items are selected since some toggle on/off. */
- outliner_item_do_activate_from_tree_element(C, te, tselem, false, true);
-}
-
-static void object_deselect_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = (Object *)tselem->id;
- Base *base = BKE_view_layer_base_find(view_layer, ob);
-
- if (base) {
- base->flag &= ~BASE_SELECTED;
- }
-}
-
-static void object_delete_cb(
- bContext *C, ReportList *reports, Scene *scene, TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- Object *ob = (Object *)tselem->id;
- if (ob) {
- Main *bmain = CTX_data_main(C);
- if (ob->id.tag & LIB_TAG_INDIRECT) {
- BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
- return;
- }
- else if (BKE_library_ID_is_indirectly_used(bmain, ob) &&
- ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0)
- {
- BKE_reportf(reports, RPT_WARNING,
- "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
- ob->id.name + 2, scene->id.name + 2);
- return;
- }
-
- // check also library later
- if (ob == CTX_data_edit_object(C)) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- }
- ED_object_base_free_and_unlink(CTX_data_main(C), scene, ob);
- /* leave for ED_outliner_id_unref to handle */
+static void object_select_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (base && ((base->flag & BASE_VISIBLE) != 0)) {
+ base->flag |= BASE_SELECTED;
+ }
+}
+
+static void object_select_hierarchy_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ /* Don't extend because this toggles, which is nice for Ctrl-Click but not for a menu item.
+ * it's especially confusing when multiple items are selected since some toggle on/off. */
+ outliner_item_do_activate_from_tree_element(C, te, tselem, false, true);
+}
+
+static void object_deselect_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (base) {
+ base->flag &= ~BASE_SELECTED;
+ }
+}
+
+static void object_delete_cb(bContext *C,
+ ReportList *reports,
+ Scene *scene,
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ Object *ob = (Object *)tselem->id;
+ if (ob) {
+ Main *bmain = CTX_data_main(C);
+ if (ob->id.tag & LIB_TAG_INDIRECT) {
+ BKE_reportf(
+ reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
+ return;
+ }
+ else if (BKE_library_ID_is_indirectly_used(bmain, ob) && ID_REAL_USERS(ob) <= 1 &&
+ ID_EXTRA_USERS(ob) == 0) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete object '%s' from scene '%s', indirectly used objects need at "
+ "least one user",
+ ob->id.name + 2,
+ scene->id.name + 2);
+ return;
+ }
+
+ // check also library later
+ if (ob == CTX_data_edit_object(C)) {
+ ED_object_editmode_exit(C, EM_FREEDATA);
+ }
+ ED_object_base_free_and_unlink(CTX_data_main(C), scene, ob);
+ /* leave for ED_outliner_id_unref to handle */
#if 0
- te->directdata = NULL;
- tselem->id = NULL;
+ te->directdata = NULL;
+ tselem->id = NULL;
#endif
- }
+ }
}
-static void id_local_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+static void id_local_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
- Main *bmain = CTX_data_main(C);
- /* if the ID type has no special local function,
- * just clear the lib */
- if (id_make_local(bmain, tselem->id, false, false) == false) {
- id_clear_lib_data(bmain, tselem->id);
- }
- else {
- BKE_main_id_clear_newpoins(bmain);
- }
- }
+ if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
+ Main *bmain = CTX_data_main(C);
+ /* if the ID type has no special local function,
+ * just clear the lib */
+ if (id_make_local(bmain, tselem->id, false, false) == false) {
+ id_clear_lib_data(bmain, tselem->id);
+ }
+ else {
+ BKE_main_id_clear_newpoins(bmain);
+ }
+ }
}
-static void id_static_override_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+static void id_static_override_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
- Main *bmain = CTX_data_main(C);
- ID *override_id = BKE_override_static_create_from_id(bmain, tselem->id);
- if (override_id != NULL) {
- BKE_main_id_clear_newpoins(bmain);
- }
- }
+ if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
+ Main *bmain = CTX_data_main(C);
+ ID *override_id = BKE_override_static_create_from_id(bmain, tselem->id);
+ if (override_id != NULL) {
+ BKE_main_id_clear_newpoins(bmain);
+ }
+ }
}
-static void id_fake_user_set_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+static void id_fake_user_set_cb(bContext *UNUSED(C),
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- ID *id = tselem->id;
+ ID *id = tselem->id;
- id_fake_user_set(id);
+ id_fake_user_set(id);
}
-static void id_fake_user_clear_cb(
- bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+static void id_fake_user_clear_cb(bContext *UNUSED(C),
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- ID *id = tselem->id;
+ ID *id = tselem->id;
- id_fake_user_clear(id);
+ id_fake_user_clear(id);
}
-static void id_select_linked_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+static void id_select_linked_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- ID *id = tselem->id;
+ ID *id = tselem->id;
- ED_object_select_linked_by_id(C, id);
+ ED_object_select_linked_by_id(C, id);
}
-static void singleuser_action_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
+static void singleuser_action_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tsep,
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- ID *id = tselem->id;
+ ID *id = tselem->id;
- if (id) {
- IdAdtTemplate *iat = (IdAdtTemplate *)tsep->id;
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop;
+ if (id) {
+ IdAdtTemplate *iat = (IdAdtTemplate *)tsep->id;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop;
- RNA_pointer_create(&iat->id, &RNA_AnimData, iat->adt, &ptr);
- prop = RNA_struct_find_property(&ptr, "action");
+ RNA_pointer_create(&iat->id, &RNA_AnimData, iat->adt, &ptr);
+ prop = RNA_struct_find_property(&ptr, "action");
- id_single_user(C, id, &ptr, prop);
- }
+ id_single_user(C, id, &ptr, prop);
+ }
}
-static void singleuser_world_cb(
- bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
- TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
+static void singleuser_world_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tsep,
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
{
- ID *id = tselem->id;
+ ID *id = tselem->id;
- /* need to use parent scene not just scene, otherwise may end up getting wrong one */
- if (id) {
- Scene *parscene = (Scene *)tsep->id;
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop;
+ /* need to use parent scene not just scene, otherwise may end up getting wrong one */
+ if (id) {
+ Scene *parscene = (Scene *)tsep->id;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop;
- RNA_id_pointer_create(&parscene->id, &ptr);
- prop = RNA_struct_find_property(&ptr, "world");
+ RNA_id_pointer_create(&parscene->id, &ptr);
+ prop = RNA_struct_find_property(&ptr, "world");
- id_single_user(C, id, &ptr, prop);
- }
+ id_single_user(C, id, &ptr, prop);
+ }
}
/**
* \param select_recurse: Set to false for operations which are already recursively operating on their children.
*/
-void outliner_do_object_operation_ex(
- bContext *C, ReportList *reports, Scene *scene_act, SpaceOutliner *soops, ListBase *lb,
- outliner_operation_cb operation_cb, void *user_data, bool select_recurse)
-{
- TreeElement *te;
-
- for (te = lb->first; te; te = te->next) {
- TreeStoreElem *tselem = TREESTORE(te);
- bool select_handled = false;
- if (tselem->flag & TSE_SELECTED) {
- if (tselem->type == 0 && te->idcode == ID_OB) {
- // when objects selected in other scenes... dunno if that should be allowed
- Scene *scene_owner = (Scene *)outliner_search_back(soops, te, ID_SCE);
- if (scene_owner && scene_act != scene_owner) {
- WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), scene_owner);
- }
- /* important to use 'scene_owner' not scene_act else deleting objects can crash.
- * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
- * outliner isn't showing scenes: Visible Layer draw mode for eg. */
- operation_cb(C, reports, scene_owner ? scene_owner : scene_act, te, NULL, tselem, user_data);
- select_handled = true;
- }
- }
- if (TSELEM_OPEN(tselem, soops)) {
- if ((select_handled == false) || select_recurse) {
- outliner_do_object_operation_ex(
- C, reports, scene_act, soops, &te->subtree, operation_cb, NULL, select_recurse);
- }
- }
- }
-}
-
-void outliner_do_object_operation(
- bContext *C, ReportList *reports, Scene *scene_act, SpaceOutliner *soops, ListBase *lb,
- outliner_operation_cb operation_cb)
-{
- outliner_do_object_operation_ex(C, reports, scene_act, soops, lb, operation_cb, NULL, true);
+void outliner_do_object_operation_ex(bContext *C,
+ ReportList *reports,
+ Scene *scene_act,
+ SpaceOutliner *soops,
+ ListBase *lb,
+ outliner_operation_cb operation_cb,
+ void *user_data,
+ bool select_recurse)
+{
+ TreeElement *te;
+
+ for (te = lb->first; te; te = te->next) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ bool select_handled = false;
+ if (tselem->flag & TSE_SELECTED) {
+ if (tselem->type == 0 && te->idcode == ID_OB) {
+ // when objects selected in other scenes... dunno if that should be allowed
+ Scene *scene_owner = (Scene *)outliner_search_back(soops, te, ID_SCE);
+ if (scene_owner && scene_act != scene_owner) {
+ WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), scene_owner);
+ }
+ /* important to use 'scene_owner' not scene_act else deleting objects can crash.
+ * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
+ * outliner isn't showing scenes: Visible Layer draw mode for eg. */
+ operation_cb(
+ C, reports, scene_owner ? scene_owner : scene_act, te, NULL, tselem, user_data);
+ select_handled = true;
+ }
+ }
+ if (TSELEM_OPEN(tselem, soops)) {
+ if ((select_handled == false) || select_recurse) {
+ outliner_do_object_operation_ex(
+ C, reports, scene_act, soops, &te->subtree, operation_cb, NULL, select_recurse);
+ }
+ }
+ }
+}
+
+void outliner_do_object_operation(bContext *C,
+ ReportList *reports,
+ Scene *scene_act,
+ SpaceOutliner *soops,
+ ListBase *lb,
+ outliner_operation_cb operation_cb)
+{
+ outliner_do_object_operation_ex(C, reports, scene_act, soops, lb, operation_cb, NULL, true);
}
/* ******************************************** */
-static void clear_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te),
- TreeStoreElem *tselem, void *UNUSED(arg))
+static void clear_animdata_cb(int UNUSED(event),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ void *UNUSED(arg))
{
- BKE_animdata_free(tselem->id, true);
+ BKE_animdata_free(tselem->id, true);
}
-
-static void unlinkact_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te),
- TreeStoreElem *tselem, void *UNUSED(arg))
+static void unlinkact_animdata_cb(int UNUSED(event),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ void *UNUSED(arg))
{
- /* just set action to NULL */
- BKE_animdata_set_action(NULL, tselem->id, NULL);
+ /* just set action to NULL */
+ BKE_animdata_set_action(NULL, tselem->id, NULL);
}
-static void cleardrivers_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te),
- TreeStoreElem *tselem, void *UNUSED(arg))
+static void cleardrivers_animdata_cb(int UNUSED(event),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ void *UNUSED(arg))
{
- IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
+ IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
- /* just free drivers - stored as a list of F-Curves */
- free_fcurves(&iat->adt->drivers);
+ /* just free drivers - stored as a list of F-Curves */
+ free_fcurves(&iat->adt->drivers);
}
-static void refreshdrivers_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te),
- TreeStoreElem *tselem, void *UNUSED(arg))
+static void refreshdrivers_animdata_cb(int UNUSED(event),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ void *UNUSED(arg))
{
- IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
- FCurve *fcu;
+ IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
+ FCurve *fcu;
- /* loop over drivers, performing refresh (i.e. check graph_buttons.c and rna_fcurve.c for details) */
- for (fcu = iat->adt->drivers.first; fcu; fcu = fcu->next) {
- fcu->flag &= ~FCURVE_DISABLED;
+ /* loop over drivers, performing refresh (i.e. check graph_buttons.c and rna_fcurve.c for details) */
+ for (fcu = iat->adt->drivers.first; fcu; fcu = fcu->next) {
+ fcu->flag &= ~FCURVE_DISABLED;
- if (fcu->driver) {
- fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
- }
- }
+ if (fcu->driver) {
+ fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
+ }
+ }
}
/* --------------------------------- */
typedef enum eOutliner_PropDataOps {
- OL_DOP_SELECT = 1,
- OL_DOP_DESELECT,
- OL_DOP_HIDE,
- OL_DOP_UNHIDE,
- OL_DOP_SELECT_LINKED,
+ OL_DOP_SELECT = 1,
+ OL_DOP_DESELECT,
+ OL_DOP_HIDE,
+ OL_DOP_UNHIDE,
+ OL_DOP_SELECT_LINKED,
} eOutliner_PropDataOps;
typedef enum eOutliner_PropConstraintOps {
- OL_CONSTRAINTOP_ENABLE = 1,
- OL_CONSTRAINTOP_DISABLE,
- OL_CONSTRAINTOP_DELETE,
+ OL_CONSTRAINTOP_ENABLE = 1,
+ OL_CONSTRAINTOP_DISABLE,
+ OL_CONSTRAINTOP_DELETE,
} eOutliner_PropConstraintOps;
typedef enum eOutliner_PropModifierOps {
- OL_MODIFIER_OP_TOGVIS = 1,
- OL_MODIFIER_OP_TOGREN,
- OL_MODIFIER_OP_DELETE,
+ OL_MODIFIER_OP_TOGVIS = 1,
+ OL_MODIFIER_OP_TOGREN,
+ OL_MODIFIER_OP_DELETE,
} eOutliner_PropModifierOps;
static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
- bPoseChannel *pchan = (bPoseChannel *)te->directdata;
+ bPoseChannel *pchan = (bPoseChannel *)te->directdata;
- if (event == OL_DOP_SELECT) {
- pchan->bone->flag |= BONE_SELECTED;
- }
- else if (event == OL_DOP_DESELECT) {
- pchan->bone->flag &= ~BONE_SELECTED;
- }
- else if (event == OL_DOP_HIDE) {
- pchan->bone->flag |= BONE_HIDDEN_P;
- pchan->bone->flag &= ~BONE_SELECTED;
- }
- else if (event == OL_DOP_UNHIDE) {
- pchan->bone->flag &= ~BONE_HIDDEN_P;
- }
+ if (event == OL_DOP_SELECT) {
+ pchan->bone->flag |= BONE_SELECTED;
+ }
+ else if (event == OL_DOP_DESELECT) {
+ pchan->bone->flag &= ~BONE_SELECTED;
+ }
+ else if (event == OL_DOP_HIDE) {
+ pchan->bone->flag |= BONE_HIDDEN_P;
+ pchan->bone->flag &= ~BONE_SELECTED;
+ }
+ else if (event == OL_DOP_UNHIDE) {
+ pchan->bone->flag &= ~BONE_HIDDEN_P;
+ }
}
static void bone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
- Bone *bone = (Bone *)te->directdata;
+ Bone *bone = (Bone *)te->directdata;
- if (event == OL_DOP_SELECT) {
- bone->flag |= BONE_SELECTED;
- }
- else if (event == OL_DOP_DESELECT) {
- bone->flag &= ~BONE_SELECTED;
- }
- else if (event == OL_DOP_HIDE) {
- bone->flag |= BONE_HIDDEN_P;
- bone->flag &= ~BONE_SELECTED;
- }
- else if (event == OL_DOP_UNHIDE) {
- bone->flag &= ~BONE_HIDDEN_P;
- }
+ if (event == OL_DOP_SELECT) {
+ bone->flag |= BONE_SELECTED;
+ }
+ else if (event == OL_DOP_DESELECT) {
+ bone->flag &= ~BONE_SELECTED;
+ }
+ else if (event == OL_DOP_HIDE) {
+ bone->flag |= BONE_HIDDEN_P;
+ bone->flag &= ~BONE_SELECTED;
+ }
+ else if (event == OL_DOP_UNHIDE) {
+ bone->flag &= ~BONE_HIDDEN_P;
+ }
}
static void ebone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
- EditBone *ebone = (EditBone *)te->directdata;
+ EditBone *ebone = (EditBone *)te->directdata;
- if (event == OL_DOP_SELECT) {
- ebone->flag |= BONE_SELECTED;
- }
- else if (event == OL_DOP_DESELECT) {
- ebone->flag &= ~BONE_SELECTED;
- }
- else if (event == OL_DOP_HIDE) {
- ebone->flag |= BONE_HIDDEN_A;
- ebone->flag &= ~BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
- }
- else if (event == OL_DOP_UNHIDE) {
- ebone->flag &= ~BONE_HIDDEN_A;
- }
+ if (event == OL_DOP_SELECT) {
+ ebone->flag |= BONE_SELECTED;
+ }
+ else if (event == OL_DOP_DESELECT) {
+ ebone->flag &= ~BONE_SELECTED;
+ }
+ else if (event == OL_DOP_HIDE) {
+ ebone->flag |= BONE_HIDDEN_A;
+ ebone->flag &= ~BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
+ }
+ else if (event == OL_DOP_UNHIDE) {
+ ebone->flag &= ~BONE_HIDDEN_A;
+ }
}
static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem, void *scene_ptr)
{
- Sequence *seq = (Sequence *)te->directdata;
- if (event == OL_DOP_SELECT) {
- Scene *scene = (Scene *)scene_ptr;
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- if (BLI_findindex(ed->seqbasep, seq) != -1) {
- ED_sequencer_select_sequence_single(scene, seq, true);
- }
- }
+ Sequence *seq = (Sequence *)te->directdata;
+ if (event == OL_DOP_SELECT) {
+ Scene *scene = (Scene *)scene_ptr;
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ if (BLI_findindex(ed->seqbasep, seq) != -1) {
+ ED_sequencer_select_sequence_single(scene, seq, true);
+ }
+ }
- (void)tselem;
+ (void)tselem;
}
-static void gp_layer_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
+static void gp_layer_cb(int event,
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tselem),
+ void *UNUSED(arg))
{
- bGPDlayer *gpl = (bGPDlayer *)te->directdata;
+ bGPDlayer *gpl = (bGPDlayer *)te->directdata;
- if (event == OL_DOP_SELECT) {
- gpl->flag |= GP_LAYER_SELECT;
- }
- else if (event == OL_DOP_DESELECT) {
- gpl->flag &= ~GP_LAYER_SELECT;
- }
- else if (event == OL_DOP_HIDE) {
- gpl->flag |= GP_LAYER_HIDE;
- }
- else if (event == OL_DOP_UNHIDE) {
- gpl->flag &= ~GP_LAYER_HIDE;
- }
+ if (event == OL_DOP_SELECT) {
+ gpl->flag |= GP_LAYER_SELECT;
+ }
+ else if (event == OL_DOP_DESELECT) {
+ gpl->flag &= ~GP_LAYER_SELECT;
+ }
+ else if (event == OL_DOP_HIDE) {
+ gpl->flag |= GP_LAYER_HIDE;
+ }
+ else if (event == OL_DOP_UNHIDE) {
+ gpl->flag &= ~GP_LAYER_HIDE;
+ }
}
-static void data_select_linked_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
+static void data_select_linked_cb(int event,
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tselem),
+ void *C_v)
{
- if (event == OL_DOP_SELECT_LINKED) {
- if (RNA_struct_is_ID(te->rnaptr.type)) {
- bContext *C = (bContext *) C_v;
- ID *id = te->rnaptr.data;
+ if (event == OL_DOP_SELECT_LINKED) {
+ if (RNA_struct_is_ID(te->rnaptr.type)) {
+ bContext *C = (bContext *)C_v;
+ ID *id = te->rnaptr.data;
- ED_object_select_linked_by_id(C, id);
- }
- }
+ ED_object_select_linked_by_id(C, id);
+ }
+ }
}
static void constraint_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
{
- bContext *C = C_v;
- Main *bmain = CTX_data_main(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- bConstraint *constraint = (bConstraint *)te->directdata;
- Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
-
- if (event == OL_CONSTRAINTOP_ENABLE) {
- constraint->flag &= ~CONSTRAINT_OFF;
- ED_object_constraint_update(bmain, ob);
- WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
- }
- else if (event == OL_CONSTRAINTOP_DISABLE) {
- constraint->flag = CONSTRAINT_OFF;
- ED_object_constraint_update(bmain, ob);
- WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
- }
- else if (event == OL_CONSTRAINTOP_DELETE) {
- ListBase *lb = NULL;
-
- if (TREESTORE(te->parent->parent)->type == TSE_POSE_CHANNEL) {
- lb = &((bPoseChannel *)te->parent->parent->directdata)->constraints;
- }
- else {
- lb = &ob->constraints;
- }
-
- if (BKE_constraint_remove_ex(lb, ob, constraint, true)) {
- /* there's no active constraint now, so make sure this is the case */
- BKE_constraints_active_set(&ob->constraints, NULL);
-
- /* needed to set the flags on posebones correctly */
- ED_object_constraint_update(bmain, ob);
-
- WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
- te->store_elem->flag &= ~TSE_SELECTED;
- }
- }
+ bContext *C = C_v;
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ bConstraint *constraint = (bConstraint *)te->directdata;
+ Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
+
+ if (event == OL_CONSTRAINTOP_ENABLE) {
+ constraint->flag &= ~CONSTRAINT_OFF;
+ ED_object_constraint_update(bmain, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
+ }
+ else if (event == OL_CONSTRAINTOP_DISABLE) {
+ constraint->flag = CONSTRAINT_OFF;
+ ED_object_constraint_update(bmain, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
+ }
+ else if (event == OL_CONSTRAINTOP_DELETE) {
+ ListBase *lb = NULL;
+
+ if (TREESTORE(te->parent->parent)->type == TSE_POSE_CHANNEL) {
+ lb = &((bPoseChannel *)te->parent->parent->directdata)->constraints;
+ }
+ else {
+ lb = &ob->constraints;
+ }
+
+ if (BKE_constraint_remove_ex(lb, ob, constraint, true)) {
+ /* there's no active constraint now, so make sure this is the case */
+ BKE_constraints_active_set(&ob->constraints, NULL);
+
+ /* needed to set the flags on posebones correctly */
+ ED_object_constraint_update(bmain, ob);
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
+ te->store_elem->flag &= ~TSE_SELECTED;
+ }
+ }
}
static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg)
{
- bContext *C = (bContext *)Carg;
- Main *bmain = CTX_data_main(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- ModifierData *md = (ModifierData *)te->directdata;
- Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
-
- if (event == OL_MODIFIER_OP_TOGVIS) {
- md->mode ^= eModifierMode_Realtime;
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
- }
- else if (event == OL_MODIFIER_OP_TOGREN) {
- md->mode ^= eModifierMode_Render;
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
- }
- else if (event == OL_MODIFIER_OP_DELETE) {
- ED_object_modifier_remove(NULL, bmain, ob, md);
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob);
- te->store_elem->flag &= ~TSE_SELECTED;
- }
-}
-
-static void outliner_do_data_operation(SpaceOutliner *soops, int type, int event, ListBase *lb,
- void (*operation_cb)(int, TreeElement *, TreeStoreElem *, void *),
- void *arg)
-{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_SELECTED) {
- if (tselem->type == type) {
- operation_cb(event, te, tselem, arg);
- }
- }
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb, arg);
- }
- }
+ bContext *C = (bContext *)Carg;
+ Main *bmain = CTX_data_main(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ ModifierData *md = (ModifierData *)te->directdata;
+ Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
+
+ if (event == OL_MODIFIER_OP_TOGVIS) {
+ md->mode ^= eModifierMode_Realtime;
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ }
+ else if (event == OL_MODIFIER_OP_TOGREN) {
+ md->mode ^= eModifierMode_Render;
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ }
+ else if (event == OL_MODIFIER_OP_DELETE) {
+ ED_object_modifier_remove(NULL, bmain, ob, md);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob);
+ te->store_elem->flag &= ~TSE_SELECTED;
+ }
+}
+
+static void outliner_do_data_operation(
+ SpaceOutliner *soops,
+ int type,
+ int event,
+ ListBase *lb,
+ void (*operation_cb)(int, TreeElement *, TreeStoreElem *, void *),
+ void *arg)
+{
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & TSE_SELECTED) {
+ if (tselem->type == type) {
+ operation_cb(event, te, tselem, arg);
+ }
+ }
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb, arg);
+ }
+ }
}
static Base *outline_delete_hierarchy(bContext *C, ReportList *reports, Scene *scene, Base *base)
{
- Base *child_base, *base_next;
- Object *parent;
- ViewLayer *view_layer = CTX_data_view_layer(C);
-
- if (!base) {
- return NULL;
- }
-
- for (child_base = view_layer->object_bases.first; child_base; child_base = base_next) {
- base_next = child_base->next;
- for (parent = child_base->object->parent; parent && (parent != base->object); parent = parent->parent) {
- /* pass */
- }
- if (parent) {
- base_next = outline_delete_hierarchy(C, reports, scene, child_base);
- }
- }
-
- base_next = base->next;
-
- Main *bmain = CTX_data_main(C);
- if (base->object->id.tag & LIB_TAG_INDIRECT) {
- BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2);
- return base_next;
- }
- else if (BKE_library_ID_is_indirectly_used(bmain, base->object) &&
- ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0)
- {
- BKE_reportf(reports, RPT_WARNING,
- "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
- base->object->id.name + 2, scene->id.name + 2);
- return base_next;
- }
- ED_object_base_free_and_unlink(CTX_data_main(C), scene, base->object);
- return base_next;
-}
-
-static void object_delete_hierarchy_cb(
- bContext *C, ReportList *reports, Scene *scene,
- TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = (Base *)te->directdata;
- Object *obedit = CTX_data_edit_object(C);
-
- if (!base) {
- base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
- }
- if (base) {
- /* Check also library later. */
- for (; obedit && (obedit != base->object); obedit = obedit->parent) {
- /* pass */
- }
- if (obedit == base->object) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- }
-
- outline_delete_hierarchy(C, reports, scene, base);
- /* leave for ED_outliner_id_unref to handle */
+ Base *child_base, *base_next;
+ Object *parent;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ if (!base) {
+ return NULL;
+ }
+
+ for (child_base = view_layer->object_bases.first; child_base; child_base = base_next) {
+ base_next = child_base->next;
+ for (parent = child_base->object->parent; parent && (parent != base->object);
+ parent = parent->parent) {
+ /* pass */
+ }
+ if (parent) {
+ base_next = outline_delete_hierarchy(C, reports, scene, child_base);
+ }
+ }
+
+ base_next = base->next;
+
+ Main *bmain = CTX_data_main(C);
+ if (base->object->id.tag & LIB_TAG_INDIRECT) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete indirectly linked object '%s'",
+ base->object->id.name + 2);
+ return base_next;
+ }
+ else if (BKE_library_ID_is_indirectly_used(bmain, base->object) &&
+ ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete object '%s' from scene '%s', indirectly used objects need at least "
+ "one user",
+ base->object->id.name + 2,
+ scene->id.name + 2);
+ return base_next;
+ }
+ ED_object_base_free_and_unlink(CTX_data_main(C), scene, base->object);
+ return base_next;
+}
+
+static void object_delete_hierarchy_cb(bContext *C,
+ ReportList *reports,
+ Scene *scene,
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = (Base *)te->directdata;
+ Object *obedit = CTX_data_edit_object(C);
+
+ if (!base) {
+ base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
+ }
+ if (base) {
+ /* Check also library later. */
+ for (; obedit && (obedit != base->object); obedit = obedit->parent) {
+ /* pass */
+ }
+ if (obedit == base->object) {
+ ED_object_editmode_exit(C, EM_FREEDATA);
+ }
+
+ outline_delete_hierarchy(C, reports, scene, base);
+ /* leave for ED_outliner_id_unref to handle */
#if 0
- te->directdata = NULL;
- tselem->id = NULL;
+ te->directdata = NULL;
+ tselem->id = NULL;
#endif
- }
+ }
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
static Base *outline_batch_delete_hierarchy(
- ReportList *reports, Main *bmain, ViewLayer *view_layer, Scene *scene, Base *base)
-{
- Base *child_base, *base_next;
- Object *object, *parent;
-
- if (!base) {
- return NULL;
- }
-
- object = base->object;
- for (child_base = view_layer->object_bases.first; child_base; child_base = base_next) {
- base_next = child_base->next;
- for (parent = child_base->object->parent; parent && (parent != object); parent = parent->parent) {
- /* pass */
- }
- if (parent) {
- base_next = outline_batch_delete_hierarchy(reports, bmain, view_layer, scene, child_base);
- }
- }
-
- base_next = base->next;
-
- if (object->id.tag & LIB_TAG_INDIRECT) {
- BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2);
- return base_next;
- }
- else if (BKE_library_ID_is_indirectly_used(bmain, object) &&
- ID_REAL_USERS(object) <= 1 && ID_EXTRA_USERS(object) == 0)
- {
- BKE_reportf(reports, RPT_WARNING,
- "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
- object->id.name + 2, scene->id.name + 2);
- return base_next;
- }
-
- DEG_id_tag_update_ex(bmain, &object->id, ID_RECALC_BASE_FLAGS);
- BKE_scene_collections_object_remove(bmain, scene, object, false);
-
- if (object->id.us == 0) {
- object->id.tag |= LIB_TAG_DOIT;
- }
-
- return base_next;
-}
-
-static void object_batch_delete_hierarchy_cb(
- bContext *C, ReportList *reports, Scene *scene,
- TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
-{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = (Base *)te->directdata;
- Object *obedit = CTX_data_edit_object(C);
-
- if (!base) {
- base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
- }
- if (base) {
- /* Check also library later. */
- for (; obedit && (obedit != base->object); obedit = obedit->parent) {
- /* pass */
- }
- if (obedit == base->object) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- }
-
- outline_batch_delete_hierarchy(reports, CTX_data_main(C), view_layer, scene, base);
- /* leave for ED_outliner_id_unref to handle */
+ ReportList *reports, Main *bmain, ViewLayer *view_layer, Scene *scene, Base *base)
+{
+ Base *child_base, *base_next;
+ Object *object, *parent;
+
+ if (!base) {
+ return NULL;
+ }
+
+ object = base->object;
+ for (child_base = view_layer->object_bases.first; child_base; child_base = base_next) {
+ base_next = child_base->next;
+ for (parent = child_base->object->parent; parent && (parent != object);
+ parent = parent->parent) {
+ /* pass */
+ }
+ if (parent) {
+ base_next = outline_batch_delete_hierarchy(reports, bmain, view_layer, scene, child_base);
+ }
+ }
+
+ base_next = base->next;
+
+ if (object->id.tag & LIB_TAG_INDIRECT) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete indirectly linked object '%s'",
+ base->object->id.name + 2);
+ return base_next;
+ }
+ else if (BKE_library_ID_is_indirectly_used(bmain, object) && ID_REAL_USERS(object) <= 1 &&
+ ID_EXTRA_USERS(object) == 0) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete object '%s' from scene '%s', indirectly used objects need at least "
+ "one user",
+ object->id.name + 2,
+ scene->id.name + 2);
+ return base_next;
+ }
+
+ DEG_id_tag_update_ex(bmain, &object->id, ID_RECALC_BASE_FLAGS);
+ BKE_scene_collections_object_remove(bmain, scene, object, false);
+
+ if (object->id.us == 0) {
+ object->id.tag |= LIB_TAG_DOIT;
+ }
+
+ return base_next;
+}
+
+static void object_batch_delete_hierarchy_cb(bContext *C,
+ ReportList *reports,
+ Scene *scene,
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = (Base *)te->directdata;
+ Object *obedit = CTX_data_edit_object(C);
+
+ if (!base) {
+ base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
+ }
+ if (base) {
+ /* Check also library later. */
+ for (; obedit && (obedit != base->object); obedit = obedit->parent) {
+ /* pass */
+ }
+ if (obedit == base->object) {
+ ED_object_editmode_exit(C, EM_FREEDATA);
+ }
+
+ outline_batch_delete_hierarchy(reports, CTX_data_main(C), view_layer, scene, base);
+ /* leave for ED_outliner_id_unref to handle */
#if 0
- te->directdata = NULL;
- tselem->id = NULL;
+ te->directdata = NULL;
+ tselem->id = NULL;
#endif
- }
+ }
}
/* **************************************** */
enum {
- OL_OP_SELECT = 1,
- OL_OP_DESELECT,
- OL_OP_SELECT_HIERARCHY,
- OL_OP_DELETE,
- OL_OP_DELETE_HIERARCHY,
- OL_OP_REMAP,
- OL_OP_LOCALIZED, /* disabled, see below */
- OL_OP_TOGVIS,
- OL_OP_TOGSEL,
- OL_OP_TOGREN,
- OL_OP_RENAME,
- OL_OP_OBJECT_MODE_ENTER,
- OL_OP_OBJECT_MODE_EXIT,
+ OL_OP_SELECT = 1,
+ OL_OP_DESELECT,
+ OL_OP_SELECT_HIERARCHY,
+ OL_OP_DELETE,
+ OL_OP_DELETE_HIERARCHY,
+ OL_OP_REMAP,
+ OL_OP_LOCALIZED, /* disabled, see below */
+ OL_OP_TOGVIS,
+ OL_OP_TOGSEL,
+ OL_OP_TOGREN,
+ OL_OP_RENAME,
+ OL_OP_OBJECT_MODE_ENTER,
+ OL_OP_OBJECT_MODE_EXIT,
};
static const EnumPropertyItem prop_object_op_types[] = {
- {OL_OP_SELECT, "SELECT", ICON_RESTRICT_SELECT_OFF, "Select", ""},
- {OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""},
- {OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""},
- {OL_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
- {OL_OP_DELETE_HIERARCHY, "DELETE_HIERARCHY", 0, "Delete Hierarchy", ""},
- {OL_OP_REMAP, "REMAP", 0, "Remap Users",
- "Make all users of selected data-blocks to use instead a new chosen one"},
- {OL_OP_RENAME, "RENAME", 0, "Rename", ""},
- {OL_OP_OBJECT_MODE_ENTER, "OBJECT_MODE_ENTER", 0, "Enter Mode", ""},
- {OL_OP_OBJECT_MODE_EXIT, "OBJECT_MODE_EXIT", 0, "Exit Mode", ""},
- {0, NULL, 0, NULL, NULL},
+ {OL_OP_SELECT, "SELECT", ICON_RESTRICT_SELECT_OFF, "Select", ""},
+ {OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""},
+ {OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""},
+ {OL_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
+ {OL_OP_DELETE_HIERARCHY, "DELETE_HIERARCHY", 0, "Delete Hierarchy", ""},
+ {OL_OP_REMAP,
+ "REMAP",
+ 0,
+ "Remap Users",
+ "Make all users of selected data-blocks to use instead a new chosen one"},
+ {OL_OP_RENAME, "RENAME", 0, "Rename", ""},
+ {OL_OP_OBJECT_MODE_ENTER, "OBJECT_MODE_ENTER", 0, "Enter Mode", ""},
+ {OL_OP_OBJECT_MODE_EXIT, "OBJECT_MODE_EXIT", 0, "Exit Mode", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int outliner_object_operation_exec(bContext *C, wmOperator *op)
{
- struct wmMsgBus *mbus = CTX_wm_message_bus(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- wmWindow *win = CTX_wm_window(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int event;
- const char *str = NULL;
-
- /* check for invalid states */
- if (soops == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- event = RNA_enum_get(op->ptr, "type");
-
- if (event == OL_OP_SELECT) {
- Scene *sce = scene; // to be able to delete, scenes are set...
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_select_cb);
- if (scene != sce) {
- WM_window_set_active_scene(bmain, C, win, sce);
- }
-
- str = "Select Objects";
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- else if (event == OL_OP_SELECT_HIERARCHY) {
- Scene *sce = scene; // to be able to delete, scenes are set...
- outliner_do_object_operation_ex(
- C, op->reports, scene, soops, &soops->tree, object_select_hierarchy_cb, NULL, false);
- if (scene != sce) {
- WM_window_set_active_scene(bmain, C, win, sce);
- }
- str = "Select Object Hierarchy";
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- else if (event == OL_OP_DESELECT) {
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_deselect_cb);
- str = "Deselect Objects";
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
- else if (event == OL_OP_DELETE) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- const Base *basact_prev = BASACT(view_layer);
-
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_delete_cb);
-
- /* XXX: tree management normally happens from draw_outliner(), but when
- * you're clicking to fast on Delete object from context menu in
- * outliner several mouse events can be handled in one cycle without
- * handling notifiers/redraw which leads to deleting the same object twice.
- * cleanup tree here to prevent such cases. */
- outliner_cleanup_tree(soops);
-
- DEG_relations_tag_update(bmain);
- str = "Delete Objects";
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- if (basact_prev != BASACT(view_layer)) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
- WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
- }
- }
- else if (event == OL_OP_DELETE_HIERARCHY) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- const Base *basact_prev = BASACT(view_layer);
-
- /* Keeping old 'safe and slow' code for a bit (new one enabled on 28/01/2019). */
- if (G.debug_value == 666) {
- outliner_do_object_operation_ex(
- C, op->reports, scene, soops, &soops->tree, object_delete_hierarchy_cb, NULL, false);
- }
- else {
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
-
- outliner_do_object_operation_ex(
- C, op->reports, scene, soops, &soops->tree, object_batch_delete_hierarchy_cb, NULL, false);
-
- BKE_id_multi_tagged_delete(bmain);
- }
-
- /* XXX: See OL_OP_DELETE comment above. */
- outliner_cleanup_tree(soops);
-
- DEG_relations_tag_update(bmain);
- str = "Delete Object Hierarchy";
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- if (basact_prev != BASACT(view_layer)) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
- WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
- }
- }
- else if (event == OL_OP_REMAP) {
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
- str = "Remap ID";
- }
- else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb);
- str = "Localized Objects";
- }
- else if (event == OL_OP_RENAME) {
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb);
- str = "Rename Object";
- }
- else if (event == OL_OP_OBJECT_MODE_ENTER) {
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_object_mode_enter_cb);
- str = "Enter Current Mode";
- }
- else if (event == OL_OP_OBJECT_MODE_EXIT) {
- outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_object_mode_exit_cb);
- str = "Exit Current Mode";
- }
- else {
- BLI_assert(0);
- return OPERATOR_CANCELLED;
- }
-
- ED_undo_push(C, str);
-
- return OPERATOR_FINISHED;
+ struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ wmWindow *win = CTX_wm_window(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int event;
+ const char *str = NULL;
+
+ /* check for invalid states */
+ if (soops == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ event = RNA_enum_get(op->ptr, "type");
+
+ if (event == OL_OP_SELECT) {
+ Scene *sce = scene; // to be able to delete, scenes are set...
+ outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_select_cb);
+ if (scene != sce) {
+ WM_window_set_active_scene(bmain, C, win, sce);
+ }
+
+ str = "Select Objects";
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else if (event == OL_OP_SELECT_HIERARCHY) {
+ Scene *sce = scene; // to be able to delete, scenes are set...
+ outliner_do_object_operation_ex(
+ C, op->reports, scene, soops, &soops->tree, object_select_hierarchy_cb, NULL, false);
+ if (scene != sce) {
+ WM_window_set_active_scene(bmain, C, win, sce);
+ }
+ str = "Select Object Hierarchy";
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else if (event == OL_OP_DESELECT) {
+ outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_deselect_cb);
+ str = "Deselect Objects";
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else if (event == OL_OP_DELETE) {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const Base *basact_prev = BASACT(view_layer);
+
+ outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_delete_cb);
+
+ /* XXX: tree management normally happens from draw_outliner(), but when
+ * you're clicking to fast on Delete object from context menu in
+ * outliner several mouse events can be handled in one cycle without
+ * handling notifiers/redraw which leads to deleting the same object twice.
+ * cleanup tree here to prevent such cases. */
+ outliner_cleanup_tree(soops);
+
+ DEG_relations_tag_update(bmain);
+ str = "Delete Objects";
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ if (basact_prev != BASACT(view_layer)) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
+ }
+ }
+ else if (event == OL_OP_DELETE_HIERARCHY) {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const Base *basact_prev = BASACT(view_layer);
+
+ /* Keeping old 'safe and slow' code for a bit (new one enabled on 28/01/2019). */
+ if (G.debug_value == 666) {
+ outliner_do_object_operation_ex(
+ C, op->reports, scene, soops, &soops->tree, object_delete_hierarchy_cb, NULL, false);
+ }
+ else {
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+ outliner_do_object_operation_ex(C,
+ op->reports,
+ scene,
+ soops,
+ &soops->tree,
+ object_batch_delete_hierarchy_cb,
+ NULL,
+ false);
+
+ BKE_id_multi_tagged_delete(bmain);
+ }
+
+ /* XXX: See OL_OP_DELETE comment above. */
+ outliner_cleanup_tree(soops);
+
+ DEG_relations_tag_update(bmain);
+ str = "Delete Object Hierarchy";
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ if (basact_prev != BASACT(view_layer)) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
+ }
+ }
+ else if (event == OL_OP_REMAP) {
+ outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
+ str = "Remap ID";
+ }
+ else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
+ outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb);
+ str = "Localized Objects";
+ }
+ else if (event == OL_OP_RENAME) {
+ outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb);
+ str = "Rename Object";
+ }
+ else if (event == OL_OP_OBJECT_MODE_ENTER) {
+ outliner_do_object_operation(
+ C, op->reports, scene, soops, &soops->tree, item_object_mode_enter_cb);
+ str = "Enter Current Mode";
+ }
+ else if (event == OL_OP_OBJECT_MODE_EXIT) {
+ outliner_do_object_operation(
+ C, op->reports, scene, soops, &soops->tree, item_object_mode_exit_cb);
+ str = "Exit Current Mode";
+ }
+ else {
+ BLI_assert(0);
+ return OPERATOR_CANCELLED;
+ }
+
+ ED_undo_push(C, str);
+
+ return OPERATOR_FINISHED;
}
-
void OUTLINER_OT_object_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner Object Operation";
- ot->idname = "OUTLINER_OT_object_operation";
+ /* identifiers */
+ ot->name = "Outliner Object Operation";
+ ot->idname = "OUTLINER_OT_object_operation";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_object_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_object_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_object_op_types, 0, "Object Operation", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_object_op_types, 0, "Object Operation", "");
}
/* **************************************** */
typedef enum eOutlinerIdOpTypes {
- OUTLINER_IDOP_INVALID = 0,
+ OUTLINER_IDOP_INVALID = 0,
- OUTLINER_IDOP_UNLINK,
- OUTLINER_IDOP_LOCAL,
- OUTLINER_IDOP_STATIC_OVERRIDE,
- OUTLINER_IDOP_SINGLE,
- OUTLINER_IDOP_DELETE,
- OUTLINER_IDOP_REMAP,
+ OUTLINER_IDOP_UNLINK,
+ OUTLINER_IDOP_LOCAL,
+ OUTLINER_IDOP_STATIC_OVERRIDE,
+ OUTLINER_IDOP_SINGLE,
+ OUTLINER_IDOP_DELETE,
+ OUTLINER_IDOP_REMAP,
- OUTLINER_IDOP_COPY,
- OUTLINER_IDOP_PASTE,
+ OUTLINER_IDOP_COPY,
+ OUTLINER_IDOP_PASTE,
- OUTLINER_IDOP_FAKE_ADD,
- OUTLINER_IDOP_FAKE_CLEAR,
- OUTLINER_IDOP_RENAME,
+ OUTLINER_IDOP_FAKE_ADD,
+ OUTLINER_IDOP_FAKE_CLEAR,
+ OUTLINER_IDOP_RENAME,
- OUTLINER_IDOP_SELECT_LINKED,
+ OUTLINER_IDOP_SELECT_LINKED,
} eOutlinerIdOpTypes;
// TODO: implement support for changing the ID-block used
static const EnumPropertyItem prop_id_op_types[] = {
- {OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""},
- {OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
- {OUTLINER_IDOP_STATIC_OVERRIDE, "STATIC_OVERRIDE", 0, "Add Static Override",
- "Add a local static override of this data-block"},
- {OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
- {OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""},
- {OUTLINER_IDOP_REMAP, "REMAP", 0, "Remap Users",
- "Make all users of selected data-blocks to use instead current (clicked) one"},
- {0, "", 0, NULL, NULL},
- {OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""},
- {OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""},
- {0, "", 0, NULL, NULL},
- {OUTLINER_IDOP_FAKE_ADD, "ADD_FAKE", 0, "Add Fake User",
- "Ensure data-block gets saved even if it isn't in use (e.g. for motion and material libraries)"},
- {OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""},
- {OUTLINER_IDOP_RENAME, "RENAME", 0, "Rename", ""},
- {OUTLINER_IDOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
- {0, NULL, 0, NULL, NULL},
+ {OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""},
+ {OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
+ {OUTLINER_IDOP_STATIC_OVERRIDE,
+ "STATIC_OVERRIDE",
+ 0,
+ "Add Static Override",
+ "Add a local static override of this data-block"},
+ {OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
+ {OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""},
+ {OUTLINER_IDOP_REMAP,
+ "REMAP",
+ 0,
+ "Remap Users",
+ "Make all users of selected data-blocks to use instead current (clicked) one"},
+ {0, "", 0, NULL, NULL},
+ {OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""},
+ {OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""},
+ {0, "", 0, NULL, NULL},
+ {OUTLINER_IDOP_FAKE_ADD,
+ "ADD_FAKE",
+ 0,
+ "Add Fake User",
+ "Ensure data-block gets saved even if it isn't in use (e.g. for motion and material "
+ "libraries)"},
+ {OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""},
+ {OUTLINER_IDOP_RENAME, "RENAME", 0, "Rename", ""},
+ {OUTLINER_IDOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
+ {0, NULL, 0, NULL, NULL},
};
-static const EnumPropertyItem *outliner_id_operation_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+static const EnumPropertyItem *outliner_id_operation_itemf(bContext *UNUSED(C),
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
- if (BKE_override_static_is_enabled()) {
- *r_free = false;
- return prop_id_op_types;
- }
+ if (BKE_override_static_is_enabled()) {
+ *r_free = false;
+ return prop_id_op_types;
+ }
- EnumPropertyItem *items = NULL;
- int totitem = 0;
+ EnumPropertyItem *items = NULL;
+ int totitem = 0;
- for (const EnumPropertyItem *it = prop_id_op_types; it->identifier != NULL; it++) {
- if (it->value == OUTLINER_IDOP_STATIC_OVERRIDE) {
- continue;
- }
- RNA_enum_item_add(&items, &totitem, it);
- }
- RNA_enum_item_end(&items, &totitem);
- *r_free = true;
+ for (const EnumPropertyItem *it = prop_id_op_types; it->identifier != NULL; it++) {
+ if (it->value == OUTLINER_IDOP_STATIC_OVERRIDE) {
+ continue;
+ }
+ RNA_enum_item_add(&items, &totitem, it);
+ }
+ RNA_enum_item_end(&items, &totitem);
+ *r_free = true;
- return items;
+ return items;
}
static int outliner_id_operation_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutlinerIdOpTypes event;
-
- /* check for invalid states */
- if (soops == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- event = RNA_enum_get(op->ptr, "type");
-
- switch (event) {
- case OUTLINER_IDOP_UNLINK:
- {
- /* unlink datablock from its parent */
- if (objectlevel) {
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_object_cb, NULL);
-
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER, NULL);
- ED_undo_push(C, "Unlink Object");
- break;
- }
-
- switch (idlevel) {
- case ID_AC:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_action_cb, NULL);
-
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- ED_undo_push(C, "Unlink action");
- break;
- case ID_MA:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_material_cb, NULL);
-
- WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL);
- ED_undo_push(C, "Unlink material");
- break;
- case ID_TE:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_texture_cb, NULL);
-
- WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL);
- ED_undo_push(C, "Unlink texture");
- break;
- case ID_WO:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_world_cb, NULL);
-
- WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL);
- ED_undo_push(C, "Unlink world");
- break;
- case ID_GR:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_collection_cb, NULL);
-
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER, NULL);
- ED_undo_push(C, "Unlink Collection");
- break;
- default:
- BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
- break;
- }
- break;
- }
- case OUTLINER_IDOP_LOCAL:
- {
- /* make local */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb, NULL);
- ED_undo_push(C, "Localized Data");
- break;
- }
- case OUTLINER_IDOP_STATIC_OVERRIDE:
- {
- if (BKE_override_static_is_enabled()) {
- /* make local */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_static_override_cb, NULL);
- ED_undo_push(C, "Overridden Data");
- }
- break;
- }
- case OUTLINER_IDOP_SINGLE:
- {
- /* make single user */
- switch (idlevel) {
- case ID_AC:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, singleuser_action_cb, NULL);
-
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- ED_undo_push(C, "Single-User Action");
- break;
-
- case ID_WO:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, singleuser_world_cb, NULL);
-
- WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL);
- ED_undo_push(C, "Single-User World");
- break;
-
- default:
- BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
- break;
- }
- break;
- }
- case OUTLINER_IDOP_DELETE:
- {
- if (idlevel > 0) {
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_delete_cb, NULL);
- ED_undo_push(C, "Delete");
- }
- break;
- }
- case OUTLINER_IDOP_REMAP:
- {
- if (idlevel > 0) {
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
- ED_undo_push(C, "Remap");
- }
- break;
- }
- case OUTLINER_IDOP_COPY:
- {
- WM_operator_name_call(C, "OUTLINER_OT_id_copy", WM_OP_INVOKE_DEFAULT, NULL);
- break;
- }
- case OUTLINER_IDOP_PASTE:
- {
- WM_operator_name_call(C, "OUTLINER_OT_id_paste", WM_OP_INVOKE_DEFAULT, NULL);
- ED_undo_push(C, "Paste");
- break;
- }
- case OUTLINER_IDOP_FAKE_ADD:
- {
- /* set fake user */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_fake_user_set_cb, NULL);
-
- WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
- ED_undo_push(C, "Add Fake User");
- break;
- }
- case OUTLINER_IDOP_FAKE_CLEAR:
- {
- /* clear fake user */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_fake_user_clear_cb, NULL);
-
- WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
- ED_undo_push(C, "Clear Fake User");
- break;
- }
- case OUTLINER_IDOP_RENAME:
- {
- /* rename */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb, NULL);
-
- WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
- ED_undo_push(C, "Rename");
- break;
- }
- case OUTLINER_IDOP_SELECT_LINKED:
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_select_linked_cb, NULL);
- ED_undo_push(C, "Select");
- break;
-
- default:
- // invalid - unhandled
- break;
- }
-
- /* wrong notifier still... */
- WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
-
- // XXX: this is just so that outliner is always up to date
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutlinerIdOpTypes event;
+
+ /* check for invalid states */
+ if (soops == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ event = RNA_enum_get(op->ptr, "type");
+
+ switch (event) {
+ case OUTLINER_IDOP_UNLINK: {
+ /* unlink datablock from its parent */
+ if (objectlevel) {
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, unlink_object_cb, NULL);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, NULL);
+ ED_undo_push(C, "Unlink Object");
+ break;
+ }
+
+ switch (idlevel) {
+ case ID_AC:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, unlink_action_cb, NULL);
+
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ ED_undo_push(C, "Unlink action");
+ break;
+ case ID_MA:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, unlink_material_cb, NULL);
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL);
+ ED_undo_push(C, "Unlink material");
+ break;
+ case ID_TE:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, unlink_texture_cb, NULL);
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL);
+ ED_undo_push(C, "Unlink texture");
+ break;
+ case ID_WO:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, unlink_world_cb, NULL);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL);
+ ED_undo_push(C, "Unlink world");
+ break;
+ case ID_GR:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, unlink_collection_cb, NULL);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, NULL);
+ ED_undo_push(C, "Unlink Collection");
+ break;
+ default:
+ BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
+ break;
+ }
+ break;
+ }
+ case OUTLINER_IDOP_LOCAL: {
+ /* make local */
+ outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb, NULL);
+ ED_undo_push(C, "Localized Data");
+ break;
+ }
+ case OUTLINER_IDOP_STATIC_OVERRIDE: {
+ if (BKE_override_static_is_enabled()) {
+ /* make local */
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, id_static_override_cb, NULL);
+ ED_undo_push(C, "Overridden Data");
+ }
+ break;
+ }
+ case OUTLINER_IDOP_SINGLE: {
+ /* make single user */
+ switch (idlevel) {
+ case ID_AC:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, singleuser_action_cb, NULL);
+
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ ED_undo_push(C, "Single-User Action");
+ break;
+
+ case ID_WO:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, singleuser_world_cb, NULL);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL);
+ ED_undo_push(C, "Single-User World");
+ break;
+
+ default:
+ BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
+ break;
+ }
+ break;
+ }
+ case OUTLINER_IDOP_DELETE: {
+ if (idlevel > 0) {
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, id_delete_cb, NULL);
+ ED_undo_push(C, "Delete");
+ }
+ break;
+ }
+ case OUTLINER_IDOP_REMAP: {
+ if (idlevel > 0) {
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
+ ED_undo_push(C, "Remap");
+ }
+ break;
+ }
+ case OUTLINER_IDOP_COPY: {
+ WM_operator_name_call(C, "OUTLINER_OT_id_copy", WM_OP_INVOKE_DEFAULT, NULL);
+ break;
+ }
+ case OUTLINER_IDOP_PASTE: {
+ WM_operator_name_call(C, "OUTLINER_OT_id_paste", WM_OP_INVOKE_DEFAULT, NULL);
+ ED_undo_push(C, "Paste");
+ break;
+ }
+ case OUTLINER_IDOP_FAKE_ADD: {
+ /* set fake user */
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, id_fake_user_set_cb, NULL);
+
+ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
+ ED_undo_push(C, "Add Fake User");
+ break;
+ }
+ case OUTLINER_IDOP_FAKE_CLEAR: {
+ /* clear fake user */
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, id_fake_user_clear_cb, NULL);
+
+ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
+ ED_undo_push(C, "Clear Fake User");
+ break;
+ }
+ case OUTLINER_IDOP_RENAME: {
+ /* rename */
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, item_rename_cb, NULL);
+
+ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
+ ED_undo_push(C, "Rename");
+ break;
+ }
+ case OUTLINER_IDOP_SELECT_LINKED:
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, id_select_linked_cb, NULL);
+ ED_undo_push(C, "Select");
+ break;
+
+ default:
+ // invalid - unhandled
+ break;
+ }
+
+ /* wrong notifier still... */
+ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
+
+ // XXX: this is just so that outliner is always up to date
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ return OPERATOR_FINISHED;
}
-
void OUTLINER_OT_id_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner ID data Operation";
- ot->idname = "OUTLINER_OT_id_operation";
+ /* identifiers */
+ ot->name = "Outliner ID data Operation";
+ ot->idname = "OUTLINER_OT_id_operation";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_id_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_id_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_id_op_types, 0, "ID data Operation", "");
- RNA_def_enum_funcs(ot->prop, outliner_id_operation_itemf);
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_id_op_types, 0, "ID data Operation", "");
+ RNA_def_enum_funcs(ot->prop, outliner_id_operation_itemf);
}
/* **************************************** */
typedef enum eOutlinerLibOpTypes {
- OL_LIB_INVALID = 0,
+ OL_LIB_INVALID = 0,
- OL_LIB_RENAME,
- OL_LIB_DELETE,
- OL_LIB_RELOCATE,
- OL_LIB_RELOAD,
+ OL_LIB_RENAME,
+ OL_LIB_DELETE,
+ OL_LIB_RELOCATE,
+ OL_LIB_RELOAD,
} eOutlinerLibOpTypes;
static const EnumPropertyItem outliner_lib_op_type_items[] = {
- {OL_LIB_RENAME, "RENAME", 0, "Rename", ""},
- {OL_LIB_DELETE, "DELETE", ICON_X, "Delete", "Delete this library and all its item from Blender - WARNING: no undo"},
- {OL_LIB_RELOCATE, "RELOCATE", 0, "Relocate", "Select a new path for this library, and reload all its data"},
- {OL_LIB_RELOAD, "RELOAD", ICON_FILE_REFRESH, "Reload", "Reload all data from this library"},
- {0, NULL, 0, NULL, NULL},
+ {OL_LIB_RENAME, "RENAME", 0, "Rename", ""},
+ {OL_LIB_DELETE,
+ "DELETE",
+ ICON_X,
+ "Delete",
+ "Delete this library and all its item from Blender - WARNING: no undo"},
+ {OL_LIB_RELOCATE,
+ "RELOCATE",
+ 0,
+ "Relocate",
+ "Select a new path for this library, and reload all its data"},
+ {OL_LIB_RELOAD, "RELOAD", ICON_FILE_REFRESH, "Reload", "Reload all data from this library"},
+ {0, NULL, 0, NULL, NULL},
};
static int outliner_lib_operation_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutlinerLibOpTypes event;
-
- /* check for invalid states */
- if (soops == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- event = RNA_enum_get(op->ptr, "type");
-
- switch (event) {
- case OL_LIB_RENAME:
- {
- /* rename */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb, NULL);
-
- WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
- ED_undo_push(C, "Rename Library");
- break;
- }
- case OL_LIB_DELETE:
- {
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_delete_cb, NULL);
- ED_undo_push(C, "Delete Library");
- break;
- }
- case OL_LIB_RELOCATE:
- {
- /* rename */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, lib_relocate_cb, NULL);
- ED_undo_push(C, "Relocate Library");
- break;
- }
- case OL_LIB_RELOAD:
- {
- /* rename */
- outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, lib_reload_cb, NULL);
- break;
- }
- default:
- /* invalid - unhandled */
- break;
- }
-
- /* wrong notifier still... */
- WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
-
- /* XXX: this is just so that outliner is always up to date */
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutlinerLibOpTypes event;
+
+ /* check for invalid states */
+ if (soops == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ event = RNA_enum_get(op->ptr, "type");
+
+ switch (event) {
+ case OL_LIB_RENAME: {
+ /* rename */
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, item_rename_cb, NULL);
+
+ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
+ ED_undo_push(C, "Rename Library");
+ break;
+ }
+ case OL_LIB_DELETE: {
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, id_delete_cb, NULL);
+ ED_undo_push(C, "Delete Library");
+ break;
+ }
+ case OL_LIB_RELOCATE: {
+ /* rename */
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, lib_relocate_cb, NULL);
+ ED_undo_push(C, "Relocate Library");
+ break;
+ }
+ case OL_LIB_RELOAD: {
+ /* rename */
+ outliner_do_libdata_operation(
+ C, op->reports, scene, soops, &soops->tree, lib_reload_cb, NULL);
+ break;
+ }
+ default:
+ /* invalid - unhandled */
+ break;
+ }
+
+ /* wrong notifier still... */
+ WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
+
+ /* XXX: this is just so that outliner is always up to date */
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
+ return OPERATOR_FINISHED;
}
-
void OUTLINER_OT_lib_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner Library Operation";
- ot->idname = "OUTLINER_OT_lib_operation";
+ /* identifiers */
+ ot->name = "Outliner Library Operation";
+ ot->idname = "OUTLINER_OT_lib_operation";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_lib_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_lib_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->prop = RNA_def_enum(ot->srna, "type", outliner_lib_op_type_items, 0, "Library Operation", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", outliner_lib_op_type_items, 0, "Library Operation", "");
}
/* **************************************** */
-static void outliner_do_id_set_operation(SpaceOutliner *soops, int type, ListBase *lb, ID *newid,
- void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *, ID *))
-{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_SELECTED) {
- if (tselem->type == type) {
- TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
- operation_cb(te, tselem, tsep, newid);
- }
- }
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_do_id_set_operation(soops, type, &te->subtree, newid, operation_cb);
- }
- }
+static void outliner_do_id_set_operation(
+ SpaceOutliner *soops,
+ int type,
+ ListBase *lb,
+ ID *newid,
+ void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *, ID *))
+{
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & TSE_SELECTED) {
+ if (tselem->type == type) {
+ TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
+ operation_cb(te, tselem, tsep, newid);
+ }
+ }
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_do_id_set_operation(soops, type, &te->subtree, newid, operation_cb);
+ }
+ }
}
/* ------------------------------------------ */
-static void actionset_id_cb(TreeElement *UNUSED(te), TreeStoreElem *tselem, TreeStoreElem *tsep, ID *actId)
+static void actionset_id_cb(TreeElement *UNUSED(te),
+ TreeStoreElem *tselem,
+ TreeStoreElem *tsep,
+ ID *actId)
{
- bAction *act = (bAction *)actId;
+ bAction *act = (bAction *)actId;
- if (tselem->type == TSE_ANIM_DATA) {
- /* "animation" entries - action is child of this */
- BKE_animdata_set_action(NULL, tselem->id, act);
- }
- /* TODO: if any other "expander" channels which own actions need to support this menu,
- * add: tselem->type = ...
- */
- else if (tsep && (tsep->type == TSE_ANIM_DATA)) {
- /* "animation" entries case again */
- BKE_animdata_set_action(NULL, tsep->id, act);
- }
- // TODO: other cases not supported yet
+ if (tselem->type == TSE_ANIM_DATA) {
+ /* "animation" entries - action is child of this */
+ BKE_animdata_set_action(NULL, tselem->id, act);
+ }
+ /* TODO: if any other "expander" channels which own actions need to support this menu,
+ * add: tselem->type = ...
+ */
+ else if (tsep && (tsep->type == TSE_ANIM_DATA)) {
+ /* "animation" entries case again */
+ BKE_animdata_set_action(NULL, tsep->id, act);
+ }
+ // TODO: other cases not supported yet
}
static int outliner_action_set_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
-
- bAction *act;
-
- /* check for invalid states */
- if (soops == NULL) {
- return OPERATOR_CANCELLED;
- }
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- /* get action to use */
- act = BLI_findlink(&CTX_data_main(C)->actions, RNA_enum_get(op->ptr, "action"));
-
- if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No valid action to add");
- return OPERATOR_CANCELLED;
- }
- else if (act->idroot == 0) {
- /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */
- BKE_reportf(op->reports, RPT_WARNING,
- "Action '%s' does not specify what data-blocks it can be used on "
- "(try setting the 'ID Root Type' setting from the data-blocks editor "
- "for this action to avoid future problems)",
- act->id.name + 2);
- }
-
- /* perform action if valid channel */
- if (datalevel == TSE_ANIM_DATA) {
- outliner_do_id_set_operation(soops, datalevel, &soops->tree, (ID *)act, actionset_id_cb);
- }
- else if (idlevel == ID_AC) {
- outliner_do_id_set_operation(soops, idlevel, &soops->tree, (ID *)act, actionset_id_cb);
- }
- else {
- return OPERATOR_CANCELLED;
- }
-
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- ED_undo_push(C, "Set action");
-
- /* done */
- return OPERATOR_FINISHED;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+
+ bAction *act;
+
+ /* check for invalid states */
+ if (soops == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ /* get action to use */
+ act = BLI_findlink(&CTX_data_main(C)->actions, RNA_enum_get(op->ptr, "action"));
+
+ if (act == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No valid action to add");
+ return OPERATOR_CANCELLED;
+ }
+ else if (act->idroot == 0) {
+ /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Action '%s' does not specify what data-blocks it can be used on "
+ "(try setting the 'ID Root Type' setting from the data-blocks editor "
+ "for this action to avoid future problems)",
+ act->id.name + 2);
+ }
+
+ /* perform action if valid channel */
+ if (datalevel == TSE_ANIM_DATA) {
+ outliner_do_id_set_operation(soops, datalevel, &soops->tree, (ID *)act, actionset_id_cb);
+ }
+ else if (idlevel == ID_AC) {
+ outliner_do_id_set_operation(soops, idlevel, &soops->tree, (ID *)act, actionset_id_cb);
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ ED_undo_push(C, "Set action");
+
+ /* done */
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_action_set(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Outliner Set Action";
- ot->idname = "OUTLINER_OT_action_set";
- ot->description = "Change the active action used";
+ /* identifiers */
+ ot->name = "Outliner Set Action";
+ ot->idname = "OUTLINER_OT_action_set";
+ ot->description = "Change the active action used";
- /* api callbacks */
- ot->invoke = WM_enum_search_invoke;
- ot->exec = outliner_action_set_exec;
- ot->poll = ED_operator_outliner_active;
+ /* api callbacks */
+ ot->invoke = WM_enum_search_invoke;
+ ot->exec = outliner_action_set_exec;
+ ot->poll = ED_operator_outliner_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
- /* props */
- // TODO: this would be nicer as an ID-pointer...
- prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
- RNA_def_enum_funcs(prop, RNA_action_itemf);
- RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
- ot->prop = prop;
+ /* props */
+ // TODO: this would be nicer as an ID-pointer...
+ prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
+ RNA_def_enum_funcs(prop, RNA_action_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
}
/* **************************************** */
typedef enum eOutliner_AnimDataOps {
- OUTLINER_ANIMOP_INVALID = 0,
+ OUTLINER_ANIMOP_INVALID = 0,
- OUTLINER_ANIMOP_CLEAR_ADT,
+ OUTLINER_ANIMOP_CLEAR_ADT,
- OUTLINER_ANIMOP_SET_ACT,
- OUTLINER_ANIMOP_CLEAR_ACT,
+ OUTLINER_ANIMOP_SET_ACT,
+ OUTLINER_ANIMOP_CLEAR_ACT,
- OUTLINER_ANIMOP_REFRESH_DRV,
- OUTLINER_ANIMOP_CLEAR_DRV
+ OUTLINER_ANIMOP_REFRESH_DRV,
+ OUTLINER_ANIMOP_CLEAR_DRV
- //OUTLINER_ANIMOP_COPY_DRIVERS,
- //OUTLINER_ANIMOP_PASTE_DRIVERS
+ //OUTLINER_ANIMOP_COPY_DRIVERS,
+ //OUTLINER_ANIMOP_PASTE_DRIVERS
} eOutliner_AnimDataOps;
static const EnumPropertyItem prop_animdata_op_types[] = {
- {OUTLINER_ANIMOP_CLEAR_ADT, "CLEAR_ANIMDATA", 0, "Clear Animation Data", "Remove this animation data container"},
- {OUTLINER_ANIMOP_SET_ACT, "SET_ACT", 0, "Set Action", ""},
- {OUTLINER_ANIMOP_CLEAR_ACT, "CLEAR_ACT", 0, "Unlink Action", ""},
- {OUTLINER_ANIMOP_REFRESH_DRV, "REFRESH_DRIVERS", 0, "Refresh Drivers", ""},
- //{OUTLINER_ANIMOP_COPY_DRIVERS, "COPY_DRIVERS", 0, "Copy Drivers", ""},
- //{OUTLINER_ANIMOP_PASTE_DRIVERS, "PASTE_DRIVERS", 0, "Paste Drivers", ""},
- {OUTLINER_ANIMOP_CLEAR_DRV, "CLEAR_DRIVERS", 0, "Clear Drivers", ""},
- {0, NULL, 0, NULL, NULL},
+ {OUTLINER_ANIMOP_CLEAR_ADT,
+ "CLEAR_ANIMDATA",
+ 0,
+ "Clear Animation Data",
+ "Remove this animation data container"},
+ {OUTLINER_ANIMOP_SET_ACT, "SET_ACT", 0, "Set Action", ""},
+ {OUTLINER_ANIMOP_CLEAR_ACT, "CLEAR_ACT", 0, "Unlink Action", ""},
+ {OUTLINER_ANIMOP_REFRESH_DRV, "REFRESH_DRIVERS", 0, "Refresh Drivers", ""},
+ //{OUTLINER_ANIMOP_COPY_DRIVERS, "COPY_DRIVERS", 0, "Copy Drivers", ""},
+ //{OUTLINER_ANIMOP_PASTE_DRIVERS, "PASTE_DRIVERS", 0, "Paste Drivers", ""},
+ {OUTLINER_ANIMOP_CLEAR_DRV, "CLEAR_DRIVERS", 0, "Clear Drivers", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_AnimDataOps event;
- short updateDeps = 0;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutliner_AnimDataOps event;
+ short updateDeps = 0;
- /* check for invalid states */
- if (soops == NULL) {
- return OPERATOR_CANCELLED;
- }
+ /* check for invalid states */
+ if (soops == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ event = RNA_enum_get(op->ptr, "type");
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
- if (datalevel != TSE_ANIM_DATA) {
- return OPERATOR_CANCELLED;
- }
+ if (datalevel != TSE_ANIM_DATA) {
+ return OPERATOR_CANCELLED;
+ }
- /* perform the core operation */
- switch (event) {
- case OUTLINER_ANIMOP_CLEAR_ADT:
- /* Remove Animation Data - this may remove the active action, in some cases... */
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, clear_animdata_cb, NULL);
+ /* perform the core operation */
+ switch (event) {
+ case OUTLINER_ANIMOP_CLEAR_ADT:
+ /* Remove Animation Data - this may remove the active action, in some cases... */
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, clear_animdata_cb, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- ED_undo_push(C, "Clear Animation Data");
- break;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ ED_undo_push(C, "Clear Animation Data");
+ break;
- case OUTLINER_ANIMOP_SET_ACT:
- /* delegate once again... */
- WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL);
- break;
+ case OUTLINER_ANIMOP_SET_ACT:
+ /* delegate once again... */
+ WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL);
+ break;
- case OUTLINER_ANIMOP_CLEAR_ACT:
- /* clear active action - using standard rules */
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, unlinkact_animdata_cb, NULL);
+ case OUTLINER_ANIMOP_CLEAR_ACT:
+ /* clear active action - using standard rules */
+ outliner_do_data_operation(
+ soops, datalevel, event, &soops->tree, unlinkact_animdata_cb, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
- ED_undo_push(C, "Unlink action");
- break;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ ED_undo_push(C, "Unlink action");
+ break;
- case OUTLINER_ANIMOP_REFRESH_DRV:
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb, NULL);
+ case OUTLINER_ANIMOP_REFRESH_DRV:
+ outliner_do_data_operation(
+ soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
- //ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */
- updateDeps = 1;
- break;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
+ //ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */
+ updateDeps = 1;
+ break;
- case OUTLINER_ANIMOP_CLEAR_DRV:
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb, NULL);
+ case OUTLINER_ANIMOP_CLEAR_DRV:
+ outliner_do_data_operation(
+ soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
- ED_undo_push(C, "Clear Drivers");
- updateDeps = 1;
- break;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
+ ED_undo_push(C, "Clear Drivers");
+ updateDeps = 1;
+ break;
- default: // invalid
- break;
- }
+ default: // invalid
+ break;
+ }
- /* update dependencies */
- if (updateDeps) {
- /* rebuild depsgraph for the new deps */
- DEG_relations_tag_update(CTX_data_main(C));
- }
+ /* update dependencies */
+ if (updateDeps) {
+ /* rebuild depsgraph for the new deps */
+ DEG_relations_tag_update(CTX_data_main(C));
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
-
void OUTLINER_OT_animdata_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner Animation Data Operation";
- ot->idname = "OUTLINER_OT_animdata_operation";
+ /* identifiers */
+ ot->name = "Outliner Animation Data Operation";
+ ot->idname = "OUTLINER_OT_animdata_operation";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_animdata_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_animdata_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_animdata_op_types, 0, "Animation Operation", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_animdata_op_types, 0, "Animation Operation", "");
}
/* **************************************** */
static const EnumPropertyItem prop_constraint_op_types[] = {
- {OL_CONSTRAINTOP_ENABLE, "ENABLE", ICON_HIDE_OFF, "Enable", ""},
- {OL_CONSTRAINTOP_DISABLE, "DISABLE", ICON_HIDE_ON, "Disable", ""},
- {OL_CONSTRAINTOP_DELETE, "DELETE", ICON_X, "Delete", ""},
- {0, NULL, 0, NULL, NULL},
+ {OL_CONSTRAINTOP_ENABLE, "ENABLE", ICON_HIDE_OFF, "Enable", ""},
+ {OL_CONSTRAINTOP_DISABLE, "DISABLE", ICON_HIDE_ON, "Disable", ""},
+ {OL_CONSTRAINTOP_DELETE, "DELETE", ICON_X, "Delete", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int outliner_constraint_operation_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_PropConstraintOps event;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutliner_PropConstraintOps event;
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ event = RNA_enum_get(op->ptr, "type");
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, constraint_cb, C);
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, constraint_cb, C);
- if (event == OL_CONSTRAINTOP_DELETE) {
- outliner_cleanup_tree(soops);
- }
+ if (event == OL_CONSTRAINTOP_DELETE) {
+ outliner_cleanup_tree(soops);
+ }
- ED_undo_push(C, "Constraint operation");
+ ED_undo_push(C, "Constraint operation");
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_constraint_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner Constraint Operation";
- ot->idname = "OUTLINER_OT_constraint_operation";
+ /* identifiers */
+ ot->name = "Outliner Constraint Operation";
+ ot->idname = "OUTLINER_OT_constraint_operation";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_constraint_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_constraint_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_constraint_op_types, 0, "Constraint Operation", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", prop_constraint_op_types, 0, "Constraint Operation", "");
}
/* ******************** */
static const EnumPropertyItem prop_modifier_op_types[] = {
- {OL_MODIFIER_OP_TOGVIS, "TOGVIS", ICON_RESTRICT_VIEW_OFF, "Toggle viewport use", ""},
- {OL_MODIFIER_OP_TOGREN, "TOGREN", ICON_RESTRICT_RENDER_OFF, "Toggle render use", ""},
- {OL_MODIFIER_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
- {0, NULL, 0, NULL, NULL},
+ {OL_MODIFIER_OP_TOGVIS, "TOGVIS", ICON_RESTRICT_VIEW_OFF, "Toggle viewport use", ""},
+ {OL_MODIFIER_OP_TOGREN, "TOGREN", ICON_RESTRICT_RENDER_OFF, "Toggle render use", ""},
+ {OL_MODIFIER_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int outliner_modifier_operation_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_PropModifierOps event;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutliner_PropModifierOps event;
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+ event = RNA_enum_get(op->ptr, "type");
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, modifier_cb, C);
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, modifier_cb, C);
- if (event == OL_MODIFIER_OP_DELETE) {
- outliner_cleanup_tree(soops);
- }
+ if (event == OL_MODIFIER_OP_DELETE) {
+ outliner_cleanup_tree(soops);
+ }
- ED_undo_push(C, "Modifier operation");
+ ED_undo_push(C, "Modifier operation");
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner Modifier Operation";
- ot->idname = "OUTLINER_OT_modifier_operation";
+ /* identifiers */
+ ot->name = "Outliner Modifier Operation";
+ ot->idname = "OUTLINER_OT_modifier_operation";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_modifier_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_modifier_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_modifier_op_types, 0, "Modifier Operation", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_modifier_op_types, 0, "Modifier Operation", "");
}
/* ******************** */
// XXX: select linked is for RNA structs only
static const EnumPropertyItem prop_data_op_types[] = {
- {OL_DOP_SELECT, "SELECT", 0, "Select", ""},
- {OL_DOP_DESELECT, "DESELECT", 0, "Deselect", ""},
- {OL_DOP_HIDE, "HIDE", 0, "Hide", ""},
- {OL_DOP_UNHIDE, "UNHIDE", 0, "Unhide", ""},
- {OL_DOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
- {0, NULL, 0, NULL, NULL},
+ {OL_DOP_SELECT, "SELECT", 0, "Select", ""},
+ {OL_DOP_DESELECT, "DESELECT", 0, "Deselect", ""},
+ {OL_DOP_HIDE, "HIDE", 0, "Hide", ""},
+ {OL_DOP_UNHIDE, "UNHIDE", 0, "Unhide", ""},
+ {OL_DOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
+ {0, NULL, 0, NULL, NULL},
};
static int outliner_data_operation_exec(bContext *C, wmOperator *op)
{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- eOutliner_PropDataOps event;
-
- /* check for invalid states */
- if (soops == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- event = RNA_enum_get(op->ptr, "type");
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- switch (datalevel) {
- case TSE_POSE_CHANNEL:
- {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- ED_undo_push(C, "PoseChannel operation");
-
- break;
- }
- case TSE_BONE:
- {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- ED_undo_push(C, "Bone operation");
-
- break;
- }
- case TSE_EBONE:
- {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb, NULL);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- ED_undo_push(C, "EditBone operation");
-
- break;
- }
- case TSE_SEQUENCE:
- {
- Scene *scene = CTX_data_scene(C);
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene);
-
- break;
- }
- case TSE_GP_LAYER:
- {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, gp_layer_cb, NULL);
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
- ED_undo_push(C, "Grease Pencil Layer operation");
-
- break;
- }
- case TSE_RNA_STRUCT:
- if (event == OL_DOP_SELECT_LINKED) {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C);
- }
-
- break;
-
- default:
- BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
- break;
- }
-
- return OPERATOR_FINISHED;
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutliner_PropDataOps event;
+
+ /* check for invalid states */
+ if (soops == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ event = RNA_enum_get(op->ptr, "type");
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ switch (datalevel) {
+ case TSE_POSE_CHANNEL: {
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ ED_undo_push(C, "PoseChannel operation");
+
+ break;
+ }
+ case TSE_BONE: {
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ ED_undo_push(C, "Bone operation");
+
+ break;
+ }
+ case TSE_EBONE: {
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ ED_undo_push(C, "EditBone operation");
+
+ break;
+ }
+ case TSE_SEQUENCE: {
+ Scene *scene = CTX_data_scene(C);
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene);
+
+ break;
+ }
+ case TSE_GP_LAYER: {
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, gp_layer_cb, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
+ ED_undo_push(C, "Grease Pencil Layer operation");
+
+ break;
+ }
+ case TSE_RNA_STRUCT:
+ if (event == OL_DOP_SELECT_LINKED) {
+ outliner_do_data_operation(
+ soops, datalevel, event, &soops->tree, data_select_linked_cb, C);
+ }
+
+ break;
+
+ default:
+ BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
+ break;
+ }
+
+ return OPERATOR_FINISHED;
}
-
void OUTLINER_OT_data_operation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Outliner Data Operation";
- ot->idname = "OUTLINER_OT_data_operation";
+ /* identifiers */
+ ot->name = "Outliner Data Operation";
+ ot->idname = "OUTLINER_OT_data_operation";
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = outliner_data_operation_exec;
- ot->poll = ED_operator_outliner_active;
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_data_operation_exec;
+ ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", "");
}
-
/* ******************** */
static int outliner_operator_menu(bContext *C, const char *opname)
{
- wmOperatorType *ot = WM_operatortype_find(opname, false);
- uiPopupMenu *pup = UI_popup_menu_begin(C, RNA_struct_ui_name(ot->srna), ICON_NONE);
- uiLayout *layout = UI_popup_menu_layout(pup);
-
- /* set this so the default execution context is the same as submenus */
- uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
- uiItemsEnumO(layout, ot->idname, RNA_property_identifier(ot->prop));
-
- MenuType *mt = WM_menutype_find("OUTLINER_MT_context", false);
- if (mt) {
- uiItemS(layout);
- UI_menutype_draw(C, mt, layout);
- }
-
- UI_popup_menu_end(C, pup);
-
- return OPERATOR_INTERFACE;
-}
-
-static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOutliner *soops,
- TreeElement *te, const float mval[2])
-{
- ReportList *reports = CTX_wm_reports(C); // XXX...
-
- if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
- int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- TreeStoreElem *tselem = TREESTORE(te);
-
- /* select object that's clicked on and popup context menu */
- if (!(tselem->flag & TSE_SELECTED)) {
-
- if (outliner_flag_is_any_test(&soops->tree, TSE_SELECTED, 1)) {
- outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
- }
-
- tselem->flag |= TSE_SELECTED;
-
- /* Only redraw, don't rebuild here because TreeElement pointers will
- * become invalid and operations will crash. */
- ED_region_tag_redraw_no_rebuild(ar);
- }
-
- set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
- if (scenelevel) {
- if (objectlevel || datalevel || idlevel) {
- BKE_report(reports, RPT_WARNING, "Mixed selection");
- return OPERATOR_CANCELLED;
- }
- else {
- return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
- }
- }
- else if (objectlevel) {
- WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- }
- else if (idlevel) {
- if (idlevel == -1 || datalevel) {
- BKE_report(reports, RPT_WARNING, "Mixed selection");
- return OPERATOR_CANCELLED;
- }
- else {
- switch (idlevel) {
- case ID_GR:
- WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- break;
- case ID_LI:
- return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
- break;
- default:
- return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
- break;
- }
- }
- }
- else if (datalevel) {
- if (datalevel == -1) {
- BKE_report(reports, RPT_WARNING, "Mixed selection");
- return OPERATOR_CANCELLED;
- }
- else {
- if (datalevel == TSE_ANIM_DATA) {
- return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
- }
- else if (datalevel == TSE_DRIVER_BASE) {
- /* do nothing... no special ops needed yet */
- return OPERATOR_CANCELLED;
- }
- else if (datalevel == TSE_LAYER_COLLECTION) {
- WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- }
- else if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
- WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- }
- else if (datalevel == TSE_ID_BASE) {
- /* do nothing... there are no ops needed here yet */
- }
- else if (datalevel == TSE_CONSTRAINT) {
- return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
- }
- else if (datalevel == TSE_MODIFIER) {
- return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
- }
- else {
- return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
- }
- }
- }
-
- return 0;
- }
-
- for (te = te->subtree.first; te; te = te->next) {
- int retval = do_outliner_operation_event(C, ar, soops, te, mval);
- if (retval) {
- return retval;
- }
- }
-
- return 0;
+ wmOperatorType *ot = WM_operatortype_find(opname, false);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, RNA_struct_ui_name(ot->srna), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+
+ /* set this so the default execution context is the same as submenus */
+ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
+ uiItemsEnumO(layout, ot->idname, RNA_property_identifier(ot->prop));
+
+ MenuType *mt = WM_menutype_find("OUTLINER_MT_context", false);
+ if (mt) {
+ uiItemS(layout);
+ UI_menutype_draw(C, mt, layout);
+ }
+
+ UI_popup_menu_end(C, pup);
+
+ return OPERATOR_INTERFACE;
+}
+
+static int do_outliner_operation_event(
+ bContext *C, ARegion *ar, SpaceOutliner *soops, TreeElement *te, const float mval[2])
+{
+ ReportList *reports = CTX_wm_reports(C); // XXX...
+
+ if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ /* select object that's clicked on and popup context menu */
+ if (!(tselem->flag & TSE_SELECTED)) {
+
+ if (outliner_flag_is_any_test(&soops->tree, TSE_SELECTED, 1)) {
+ outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
+ }
+
+ tselem->flag |= TSE_SELECTED;
+
+ /* Only redraw, don't rebuild here because TreeElement pointers will
+ * become invalid and operations will crash. */
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ if (scenelevel) {
+ if (objectlevel || datalevel || idlevel) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
+ }
+ }
+ else if (objectlevel) {
+ WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ else if (idlevel) {
+ if (idlevel == -1 || datalevel) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ switch (idlevel) {
+ case ID_GR:
+ WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ break;
+ case ID_LI:
+ return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
+ break;
+ default:
+ return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
+ break;
+ }
+ }
+ }
+ else if (datalevel) {
+ if (datalevel == -1) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ if (datalevel == TSE_ANIM_DATA) {
+ return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
+ }
+ else if (datalevel == TSE_DRIVER_BASE) {
+ /* do nothing... no special ops needed yet */
+ return OPERATOR_CANCELLED;
+ }
+ else if (datalevel == TSE_LAYER_COLLECTION) {
+ WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ else if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
+ WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ else if (datalevel == TSE_ID_BASE) {
+ /* do nothing... there are no ops needed here yet */
+ }
+ else if (datalevel == TSE_CONSTRAINT) {
+ return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
+ }
+ else if (datalevel == TSE_MODIFIER) {
+ return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
+ }
+ else {
+ return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ for (te = te->subtree.first; te; te = te->next) {
+ int retval = do_outliner_operation_event(C, ar, soops, te, mval);
+ if (retval) {
+ return retval;
+ }
+ }
+
+ return 0;
}
-
static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- uiBut *but = UI_context_active_but_get(C);
- TreeElement *te;
- float fmval[2];
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ uiBut *but = UI_context_active_but_get(C);
+ TreeElement *te;
+ float fmval[2];
- if (but) {
- UI_but_tooltip_timer_remove(C, but);
- }
+ if (but) {
+ UI_but_tooltip_timer_remove(C, but);
+ }
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
- for (te = soops->tree.first; te; te = te->next) {
- int retval = do_outliner_operation_event(C, ar, soops, te, fmval);
- if (retval) {
- return retval;
- }
- }
+ for (te = soops->tree.first; te; te = te->next) {
+ int retval = do_outliner_operation_event(C, ar, soops, te, fmval);
+ if (retval) {
+ return retval;
+ }
+ }
- /* Menus for clicking in empty space. */
- if (soops->outlinevis == SO_VIEW_LAYER) {
- WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- }
+ /* Menus for clicking in empty space. */
+ if (soops->outlinevis == SO_VIEW_LAYER) {
+ WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
- WM_menu_name_call(C, "OUTLINER_MT_context", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
+ WM_menu_name_call(C, "OUTLINER_MT_context", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
}
/* Menu only! Calls other operators */
void OUTLINER_OT_operation(wmOperatorType *ot)
{
- ot->name = "Context Menu";
- ot->idname = "OUTLINER_OT_operation";
- ot->description = "Context menu for item operations";
+ ot->name = "Context Menu";
+ ot->idname = "OUTLINER_OT_operation";
+ ot->description = "Context menu for item operations";
- ot->invoke = outliner_operation;
+ ot->invoke = outliner_operation;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = ED_operator_outliner_active;
}
/* ****************************************************** */
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index a4e512d6846..a03d9b6fb6d 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -83,8 +83,9 @@
#endif
/* prototypes */
-static TreeElement *outliner_add_collection_recursive(
- SpaceOutliner *soops, Collection *collection, TreeElement *ten);
+static TreeElement *outliner_add_collection_recursive(SpaceOutliner *soops,
+ Collection *collection,
+ TreeElement *ten);
static void outliner_make_object_parent_hierarchy(ListBase *lb);
/* ********************************************************* */
@@ -92,98 +93,97 @@ static void outliner_make_object_parent_hierarchy(ListBase *lb);
static void outliner_storage_cleanup(SpaceOutliner *soops)
{
- BLI_mempool *ts = soops->treestore;
-
- if (ts) {
- TreeStoreElem *tselem;
- int unused = 0;
-
- /* each element used once, for ID blocks with more users to have each a treestore */
- BLI_mempool_iter iter;
-
- BLI_mempool_iternew(ts, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- tselem->used = 0;
- }
-
- /* cleanup only after reading file or undo step, and always for
- * RNA datablocks view in order to save memory */
- if (soops->storeflag & SO_TREESTORE_CLEANUP) {
- soops->storeflag &= ~SO_TREESTORE_CLEANUP;
-
- BLI_mempool_iternew(ts, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- if (tselem->id == NULL) {
- unused++;
- }
- }
-
- if (unused) {
- if (BLI_mempool_len(ts) == unused) {
- BLI_mempool_destroy(ts);
- soops->treestore = NULL;
- if (soops->treehash) {
- BKE_outliner_treehash_free(soops->treehash);
- soops->treehash = NULL;
- }
- }
- else {
- TreeStoreElem *tsenew;
- BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_len(ts) - unused,
- 512, BLI_MEMPOOL_ALLOW_ITER);
- BLI_mempool_iternew(ts, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- if (tselem->id) {
- tsenew = BLI_mempool_alloc(new_ts);
- *tsenew = *tselem;
- }
- }
- BLI_mempool_destroy(ts);
- soops->treestore = new_ts;
- if (soops->treehash) {
- /* update hash table to fix broken pointers */
- BKE_outliner_treehash_rebuild_from_treestore(soops->treehash, soops->treestore);
- }
- }
- }
- }
- else if (soops->treehash) {
- BKE_outliner_treehash_clear_used(soops->treehash);
- }
- }
+ BLI_mempool *ts = soops->treestore;
+
+ if (ts) {
+ TreeStoreElem *tselem;
+ int unused = 0;
+
+ /* each element used once, for ID blocks with more users to have each a treestore */
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(ts, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ tselem->used = 0;
+ }
+
+ /* cleanup only after reading file or undo step, and always for
+ * RNA datablocks view in order to save memory */
+ if (soops->storeflag & SO_TREESTORE_CLEANUP) {
+ soops->storeflag &= ~SO_TREESTORE_CLEANUP;
+
+ BLI_mempool_iternew(ts, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ if (tselem->id == NULL) {
+ unused++;
+ }
+ }
+
+ if (unused) {
+ if (BLI_mempool_len(ts) == unused) {
+ BLI_mempool_destroy(ts);
+ soops->treestore = NULL;
+ if (soops->treehash) {
+ BKE_outliner_treehash_free(soops->treehash);
+ soops->treehash = NULL;
+ }
+ }
+ else {
+ TreeStoreElem *tsenew;
+ BLI_mempool *new_ts = BLI_mempool_create(
+ sizeof(TreeStoreElem), BLI_mempool_len(ts) - unused, 512, BLI_MEMPOOL_ALLOW_ITER);
+ BLI_mempool_iternew(ts, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ if (tselem->id) {
+ tsenew = BLI_mempool_alloc(new_ts);
+ *tsenew = *tselem;
+ }
+ }
+ BLI_mempool_destroy(ts);
+ soops->treestore = new_ts;
+ if (soops->treehash) {
+ /* update hash table to fix broken pointers */
+ BKE_outliner_treehash_rebuild_from_treestore(soops->treehash, soops->treestore);
+ }
+ }
+ }
+ }
+ else if (soops->treehash) {
+ BKE_outliner_treehash_clear_used(soops->treehash);
+ }
+ }
}
static void check_persistent(SpaceOutliner *soops, TreeElement *te, ID *id, short type, short nr)
{
- TreeStoreElem *tselem;
-
- if (soops->treestore == NULL) {
- /* if treestore was not created in readfile.c, create it here */
- soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
-
- }
- if (soops->treehash == NULL) {
- soops->treehash = BKE_outliner_treehash_create_from_treestore(soops->treestore);
- }
-
- /* find any unused tree element in treestore and mark it as used
- * (note that there may be multiple unused elements in case of linked objects) */
- tselem = BKE_outliner_treehash_lookup_unused(soops->treehash, type, nr, id);
- if (tselem) {
- te->store_elem = tselem;
- tselem->used = 1;
- return;
- }
-
- /* add 1 element to treestore */
- tselem = BLI_mempool_alloc(soops->treestore);
- tselem->type = type;
- tselem->nr = type ? nr : 0;
- tselem->id = id;
- tselem->used = 0;
- tselem->flag = TSE_CLOSED;
- te->store_elem = tselem;
- BKE_outliner_treehash_add_element(soops->treehash, tselem);
+ TreeStoreElem *tselem;
+
+ if (soops->treestore == NULL) {
+ /* if treestore was not created in readfile.c, create it here */
+ soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
+ }
+ if (soops->treehash == NULL) {
+ soops->treehash = BKE_outliner_treehash_create_from_treestore(soops->treestore);
+ }
+
+ /* find any unused tree element in treestore and mark it as used
+ * (note that there may be multiple unused elements in case of linked objects) */
+ tselem = BKE_outliner_treehash_lookup_unused(soops->treehash, type, nr, id);
+ if (tselem) {
+ te->store_elem = tselem;
+ tselem->used = 1;
+ return;
+ }
+
+ /* add 1 element to treestore */
+ tselem = BLI_mempool_alloc(soops->treestore);
+ tselem->type = type;
+ tselem->nr = type ? nr : 0;
+ tselem->id = id;
+ tselem->used = 0;
+ tselem->flag = TSE_CLOSED;
+ te->store_elem = tselem;
+ BKE_outliner_treehash_add_element(soops->treehash, tselem);
}
/* ********************************************************* */
@@ -191,16 +191,16 @@ static void check_persistent(SpaceOutliner *soops, TreeElement *te, ID *id, shor
void outliner_free_tree(ListBase *tree)
{
- for (TreeElement *element = tree->first, *element_next; element; element = element_next) {
- element_next = element->next;
- outliner_free_tree_element(element, tree);
- }
+ for (TreeElement *element = tree->first, *element_next; element; element = element_next) {
+ element_next = element->next;
+ outliner_free_tree_element(element, tree);
+ }
}
void outliner_cleanup_tree(SpaceOutliner *soops)
{
- outliner_free_tree(&soops->tree);
- outliner_storage_cleanup(soops);
+ outliner_free_tree(&soops->tree);
+ outliner_storage_cleanup(soops);
}
/**
@@ -211,926 +211,924 @@ void outliner_cleanup_tree(SpaceOutliner *soops)
*/
void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree)
{
- BLI_assert(BLI_findindex(parent_subtree, element) > -1);
- BLI_remlink(parent_subtree, element);
+ BLI_assert(BLI_findindex(parent_subtree, element) > -1);
+ BLI_remlink(parent_subtree, element);
- outliner_free_tree(&element->subtree);
+ outliner_free_tree(&element->subtree);
- if (element->flag & TE_FREE_NAME) {
- MEM_freeN((void *)element->name);
- }
- MEM_freeN(element);
+ if (element->flag & TE_FREE_NAME) {
+ MEM_freeN((void *)element->name);
+ }
+ MEM_freeN(element);
}
-
/* ********************************************************* */
/* Prototype, see functions below */
-static TreeElement *outliner_add_element(SpaceOutliner *soops, ListBase *lb, void *idv,
- TreeElement *parent, short type, short index);
+static TreeElement *outliner_add_element(
+ SpaceOutliner *soops, ListBase *lb, void *idv, TreeElement *parent, short type, short index);
/* -------------------------------------------------------- */
/* special handling of hierarchical non-lib data */
-static void outliner_add_bone(SpaceOutliner *soops, ListBase *lb, ID *id, Bone *curBone,
- TreeElement *parent, int *a)
+static void outliner_add_bone(
+ SpaceOutliner *soops, ListBase *lb, ID *id, Bone *curBone, TreeElement *parent, int *a)
{
- TreeElement *te = outliner_add_element(soops, lb, id, parent, TSE_BONE, *a);
+ TreeElement *te = outliner_add_element(soops, lb, id, parent, TSE_BONE, *a);
- (*a)++;
- te->name = curBone->name;
- te->directdata = curBone;
+ (*a)++;
+ te->name = curBone->name;
+ te->directdata = curBone;
- for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(soops, &te->subtree, id, curBone, te, a);
- }
+ for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) {
+ outliner_add_bone(soops, &te->subtree, id, curBone, te, a);
+ }
}
static bool outliner_animdata_test(AnimData *adt)
{
- if (adt) {
- return (adt->action || adt->drivers.first || adt->nla_tracks.first);
- }
- return false;
+ if (adt) {
+ return (adt->action || adt->drivers.first || adt->nla_tracks.first);
+ }
+ return false;
}
#ifdef WITH_FREESTYLE
-static void outliner_add_line_styles(SpaceOutliner *soops, ListBase *lb, Scene *sce, TreeElement *te)
+static void outliner_add_line_styles(SpaceOutliner *soops,
+ ListBase *lb,
+ Scene *sce,
+ TreeElement *te)
{
- ViewLayer *view_layer;
- FreestyleLineSet *lineset;
-
- for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
- FreestyleLineStyle *linestyle = lineset->linestyle;
- if (linestyle) {
- linestyle->id.tag |= LIB_TAG_DOIT;
- }
- }
- }
- for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
- FreestyleLineStyle *linestyle = lineset->linestyle;
- if (linestyle) {
- if (!(linestyle->id.tag & LIB_TAG_DOIT)) {
- continue;
- }
- linestyle->id.tag &= ~LIB_TAG_DOIT;
- outliner_add_element(soops, lb, linestyle, te, 0, 0);
- }
- }
- }
+ ViewLayer *view_layer;
+ FreestyleLineSet *lineset;
+
+ for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
+ FreestyleLineStyle *linestyle = lineset->linestyle;
+ if (linestyle) {
+ linestyle->id.tag |= LIB_TAG_DOIT;
+ }
+ }
+ }
+ for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
+ FreestyleLineStyle *linestyle = lineset->linestyle;
+ if (linestyle) {
+ if (!(linestyle->id.tag & LIB_TAG_DOIT)) {
+ continue;
+ }
+ linestyle->id.tag &= ~LIB_TAG_DOIT;
+ outliner_add_element(soops, lb, linestyle, te, 0, 0);
+ }
+ }
+ }
}
#endif
-static void outliner_add_scene_contents(SpaceOutliner *soops, ListBase *lb, Scene *sce, TreeElement *te)
+static void outliner_add_scene_contents(SpaceOutliner *soops,
+ ListBase *lb,
+ Scene *sce,
+ TreeElement *te)
{
- /* View layers */
- TreeElement *ten = outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0);
- ten->name = IFACE_("View Layers");
-
- ViewLayer *view_layer;
- for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- TreeElement *tenlay = outliner_add_element(soops, &ten->subtree, sce, te, TSE_R_LAYER, 0);
- tenlay->name = view_layer->name;
- tenlay->directdata = view_layer;
- }
-
- /* Collections */
- ten = outliner_add_element(soops, lb, &sce->id, te, TSE_SCENE_COLLECTION_BASE, 0);
- ten->name = IFACE_("Scene Collection");
- outliner_add_collection_recursive(soops, sce->master_collection, ten);
-
- /* Objects */
- ten = outliner_add_element(soops, lb, sce, te, TSE_SCENE_OBJECTS_BASE, 0);
- ten->name = IFACE_("Objects");
- FOREACH_SCENE_OBJECT_BEGIN(sce, ob)
- {
- outliner_add_element(soops, &ten->subtree, ob, NULL, 0, 0);
- }
- FOREACH_SCENE_OBJECT_END;
- outliner_make_object_parent_hierarchy(&ten->subtree);
-
- /* Animation Data */
- if (outliner_animdata_test(sce->adt)) {
- outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0);
- }
-
+ /* View layers */
+ TreeElement *ten = outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0);
+ ten->name = IFACE_("View Layers");
+
+ ViewLayer *view_layer;
+ for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ TreeElement *tenlay = outliner_add_element(soops, &ten->subtree, sce, te, TSE_R_LAYER, 0);
+ tenlay->name = view_layer->name;
+ tenlay->directdata = view_layer;
+ }
+
+ /* Collections */
+ ten = outliner_add_element(soops, lb, &sce->id, te, TSE_SCENE_COLLECTION_BASE, 0);
+ ten->name = IFACE_("Scene Collection");
+ outliner_add_collection_recursive(soops, sce->master_collection, ten);
+
+ /* Objects */
+ ten = outliner_add_element(soops, lb, sce, te, TSE_SCENE_OBJECTS_BASE, 0);
+ ten->name = IFACE_("Objects");
+ FOREACH_SCENE_OBJECT_BEGIN (sce, ob) {
+ outliner_add_element(soops, &ten->subtree, ob, NULL, 0, 0);
+ }
+ FOREACH_SCENE_OBJECT_END;
+ outliner_make_object_parent_hierarchy(&ten->subtree);
+
+ /* Animation Data */
+ if (outliner_animdata_test(sce->adt)) {
+ outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0);
+ }
}
// can be inlined if necessary
-static void outliner_add_object_contents(SpaceOutliner *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob)
+static void outliner_add_object_contents(SpaceOutliner *soops,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ Object *ob)
{
- if (outliner_animdata_test(ob->adt)) {
- outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
- }
-
- outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
-
- if (ob->proxy && !ID_IS_LINKED(ob)) {
- outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
- }
-
- outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0);
-
- if (ob->pose) {
- bArmature *arm = ob->data;
- bPoseChannel *pchan;
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0);
-
- tenla->name = IFACE_("Pose");
-
- /* channels undefined in editmode, but we want the 'tenla' pose icon itself */
- if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
- TreeElement *ten;
- int a = 0, const_index = 1000; /* ensure unique id for bone constraints */
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, a++) {
- ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
- ten->name = pchan->name;
- ten->directdata = pchan;
- pchan->temp = (void *)ten;
-
- if (pchan->constraints.first) {
- //Object *target;
- bConstraint *con;
- TreeElement *ten1;
- TreeElement *tenla1 = outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
- //char *str;
-
- tenla1->name = IFACE_("Constraints");
- for (con = pchan->constraints.first; con; con = con->next, const_index++) {
- ten1 = outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
+ if (outliner_animdata_test(ob->adt)) {
+ outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
+ }
+
+ outliner_add_element(
+ soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
+
+ if (ob->proxy && !ID_IS_LINKED(ob)) {
+ outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
+ }
+
+ outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0);
+
+ if (ob->pose) {
+ bArmature *arm = ob->data;
+ bPoseChannel *pchan;
+ TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0);
+
+ tenla->name = IFACE_("Pose");
+
+ /* channels undefined in editmode, but we want the 'tenla' pose icon itself */
+ if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
+ TreeElement *ten;
+ int a = 0, const_index = 1000; /* ensure unique id for bone constraints */
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, a++) {
+ ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
+ ten->name = pchan->name;
+ ten->directdata = pchan;
+ pchan->temp = (void *)ten;
+
+ if (pchan->constraints.first) {
+ //Object *target;
+ bConstraint *con;
+ TreeElement *ten1;
+ TreeElement *tenla1 = outliner_add_element(
+ soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
+ //char *str;
+
+ tenla1->name = IFACE_("Constraints");
+ for (con = pchan->constraints.first; con; con = con->next, const_index++) {
+ ten1 = outliner_add_element(
+ soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
- target = get_constraint_target(con, &str);
- if (str && str[0]) ten1->name = str;
- else if (target) ten1->name = target->id.name + 2;
- else ten1->name = con->name;
+ target = get_constraint_target(con, &str);
+ if (str && str[0]) ten1->name = str;
+ else if (target) ten1->name = target->id.name + 2;
+ else ten1->name = con->name;
#endif
- ten1->name = con->name;
- ten1->directdata = con;
- /* possible add all other types links? */
- }
- }
- }
- /* make hierarchy */
- ten = tenla->subtree.first;
- while (ten) {
- TreeElement *nten = ten->next, *par;
- tselem = TREESTORE(ten);
- if (tselem->type == TSE_POSE_CHANNEL) {
- pchan = (bPoseChannel *)ten->directdata;
- if (pchan->parent) {
- BLI_remlink(&tenla->subtree, ten);
- par = (TreeElement *)pchan->parent->temp;
- BLI_addtail(&par->subtree, ten);
- ten->parent = par;
- }
- }
- ten = nten;
- }
- }
-
- /* Pose Groups */
- if (ob->pose->agroups.first) {
- bActionGroup *agrp;
- TreeElement *ten_bonegrp = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
- int a = 0;
-
- ten_bonegrp->name = IFACE_("Bone Groups");
- for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) {
- TreeElement *ten;
- ten = outliner_add_element(soops, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a);
- ten->name = agrp->name;
- ten->directdata = agrp;
- }
- }
- }
-
- for (int a = 0; a < ob->totcol; a++) {
- outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a);
- }
-
- if (ob->constraints.first) {
- //Object *target;
- bConstraint *con;
- TreeElement *ten;
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
- //char *str;
- int a;
-
- tenla->name = IFACE_("Constraints");
- for (con = ob->constraints.first, a = 0; con; con = con->next, a++) {
- ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
+ ten1->name = con->name;
+ ten1->directdata = con;
+ /* possible add all other types links? */
+ }
+ }
+ }
+ /* make hierarchy */
+ ten = tenla->subtree.first;
+ while (ten) {
+ TreeElement *nten = ten->next, *par;
+ tselem = TREESTORE(ten);
+ if (tselem->type == TSE_POSE_CHANNEL) {
+ pchan = (bPoseChannel *)ten->directdata;
+ if (pchan->parent) {
+ BLI_remlink(&tenla->subtree, ten);
+ par = (TreeElement *)pchan->parent->temp;
+ BLI_addtail(&par->subtree, ten);
+ ten->parent = par;
+ }
+ }
+ ten = nten;
+ }
+ }
+
+ /* Pose Groups */
+ if (ob->pose->agroups.first) {
+ bActionGroup *agrp;
+ TreeElement *ten_bonegrp = outliner_add_element(
+ soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
+ int a = 0;
+
+ ten_bonegrp->name = IFACE_("Bone Groups");
+ for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) {
+ TreeElement *ten;
+ ten = outliner_add_element(soops, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a);
+ ten->name = agrp->name;
+ ten->directdata = agrp;
+ }
+ }
+ }
+
+ for (int a = 0; a < ob->totcol; a++) {
+ outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a);
+ }
+
+ if (ob->constraints.first) {
+ //Object *target;
+ bConstraint *con;
+ TreeElement *ten;
+ TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
+ //char *str;
+ int a;
+
+ tenla->name = IFACE_("Constraints");
+ for (con = ob->constraints.first, a = 0; con; con = con->next, a++) {
+ ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
#if 0 /* disabled due to constraints system targets recode... code here needs review */
- target = get_constraint_target(con, &str);
- if (str && str[0]) ten->name = str;
- else if (target) ten->name = target->id.name + 2;
- else ten->name = con->name;
+ target = get_constraint_target(con, &str);
+ if (str && str[0]) ten->name = str;
+ else if (target) ten->name = target->id.name + 2;
+ else ten->name = con->name;
#endif
- ten->name = con->name;
- ten->directdata = con;
- /* possible add all other types links? */
- }
- }
-
- if (ob->modifiers.first) {
- ModifierData *md;
- TreeElement *ten_mod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
- int index;
-
- ten_mod->name = IFACE_("Modifiers");
- for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
- TreeElement *ten = outliner_add_element(soops, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
- ten->name = md->name;
- ten->directdata = md;
-
- if (md->type == eModifierType_Lattice) {
- outliner_add_element(soops, &ten->subtree, ((LatticeModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
- }
- else if (md->type == eModifierType_Curve) {
- outliner_add_element(soops, &ten->subtree, ((CurveModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
- }
- else if (md->type == eModifierType_Armature) {
- outliner_add_element(soops, &ten->subtree, ((ArmatureModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
- }
- else if (md->type == eModifierType_Hook) {
- outliner_add_element(soops, &ten->subtree, ((HookModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
- }
- else if (md->type == eModifierType_ParticleSystem) {
- ParticleSystem *psys = ((ParticleSystemModifierData *) md)->psys;
- TreeElement *ten_psys;
-
- ten_psys = outliner_add_element(soops, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0);
- ten_psys->directdata = psys;
- ten_psys->name = psys->part->id.name + 2;
- }
- }
- }
-
- /* vertex groups */
- if (ob->defbase.first) {
- bDeformGroup *defgroup;
- TreeElement *ten;
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
- int a;
-
- tenla->name = IFACE_("Vertex Groups");
- for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
- ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
- ten->name = defgroup->name;
- ten->directdata = defgroup;
- }
- }
-
- /* duplicated group */
- if (ob->instance_collection) {
- outliner_add_element(soops, &te->subtree, ob->instance_collection, te, 0, 0);
- }
+ ten->name = con->name;
+ ten->directdata = con;
+ /* possible add all other types links? */
+ }
+ }
+
+ if (ob->modifiers.first) {
+ ModifierData *md;
+ TreeElement *ten_mod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
+ int index;
+
+ ten_mod->name = IFACE_("Modifiers");
+ for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
+ TreeElement *ten = outliner_add_element(
+ soops, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
+ ten->name = md->name;
+ ten->directdata = md;
+
+ if (md->type == eModifierType_Lattice) {
+ outliner_add_element(
+ soops, &ten->subtree, ((LatticeModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
+ }
+ else if (md->type == eModifierType_Curve) {
+ outliner_add_element(
+ soops, &ten->subtree, ((CurveModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
+ }
+ else if (md->type == eModifierType_Armature) {
+ outliner_add_element(
+ soops, &ten->subtree, ((ArmatureModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
+ }
+ else if (md->type == eModifierType_Hook) {
+ outliner_add_element(
+ soops, &ten->subtree, ((HookModifierData *)md)->object, ten, TSE_LINKED_OB, 0);
+ }
+ else if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
+ TreeElement *ten_psys;
+
+ ten_psys = outliner_add_element(soops, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0);
+ ten_psys->directdata = psys;
+ ten_psys->name = psys->part->id.name + 2;
+ }
+ }
+ }
+
+ /* vertex groups */
+ if (ob->defbase.first) {
+ bDeformGroup *defgroup;
+ TreeElement *ten;
+ TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
+ int a;
+
+ tenla->name = IFACE_("Vertex Groups");
+ for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
+ ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
+ ten->name = defgroup->name;
+ ten->directdata = defgroup;
+ }
+ }
+
+ /* duplicated group */
+ if (ob->instance_collection) {
+ outliner_add_element(soops, &te->subtree, ob->instance_collection, te, 0, 0);
+ }
}
-
// can be inlined if necessary
-static void outliner_add_id_contents(SpaceOutliner *soops, TreeElement *te, TreeStoreElem *tselem, ID *id)
+static void outliner_add_id_contents(SpaceOutliner *soops,
+ TreeElement *te,
+ TreeStoreElem *tselem,
+ ID *id)
{
- /* tuck pointer back in object, to construct hierarchy */
- if (GS(id->name) == ID_OB) {
- id->newid = (ID *)te;
- }
-
- /* expand specific data always */
- switch (GS(id->name)) {
- case ID_LI:
- {
- te->name = ((Library *)id)->name;
- break;
- }
- case ID_SCE:
- {
- outliner_add_scene_contents(soops, &te->subtree, (Scene *)id, te);
- break;
- }
- case ID_OB:
- {
- outliner_add_object_contents(soops, te, tselem, (Object *)id);
- break;
- }
- case ID_ME:
- {
- Mesh *me = (Mesh *)id;
- int a;
-
- if (outliner_animdata_test(me->adt)) {
- outliner_add_element(soops, &te->subtree, me, te, TSE_ANIM_DATA, 0);
- }
-
- outliner_add_element(soops, &te->subtree, me->key, te, 0, 0);
- for (a = 0; a < me->totcol; a++) {
- outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a);
- }
- /* could do tfaces with image links, but the images are not grouped nicely.
- * would require going over all tfaces, sort images in use. etc... */
- break;
- }
- case ID_CU:
- {
- Curve *cu = (Curve *)id;
- int a;
-
- if (outliner_animdata_test(cu->adt)) {
- outliner_add_element(soops, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
- }
-
- for (a = 0; a < cu->totcol; a++) {
- outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a);
- }
- break;
- }
- case ID_MB:
- {
- MetaBall *mb = (MetaBall *)id;
- int a;
-
- if (outliner_animdata_test(mb->adt)) {
- outliner_add_element(soops, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
- }
-
- for (a = 0; a < mb->totcol; a++) {
- outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a);
- }
- break;
- }
- case ID_MA:
- {
- Material *ma = (Material *)id;
-
- if (outliner_animdata_test(ma->adt)) {
- outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
- }
- break;
- }
- case ID_TE:
- {
- Tex *tex = (Tex *)id;
-
- if (outliner_animdata_test(tex->adt)) {
- outliner_add_element(soops, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
- }
- outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0);
- break;
- }
- case ID_CA:
- {
- Camera *ca = (Camera *)id;
-
- if (outliner_animdata_test(ca->adt)) {
- outliner_add_element(soops, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
- }
- break;
- }
- case ID_CF:
- {
- CacheFile *cache_file = (CacheFile *)id;
-
- if (outliner_animdata_test(cache_file->adt)) {
- outliner_add_element(soops, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
- }
-
- break;
- }
- case ID_LA:
- {
- Light *la = (Light *)id;
-
- if (outliner_animdata_test(la->adt)) {
- outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0);
- }
- break;
- }
- case ID_SPK:
- {
- Speaker *spk = (Speaker *)id;
-
- if (outliner_animdata_test(spk->adt)) {
- outliner_add_element(soops, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
- }
- break;
- }
- case ID_LP:
- {
- LightProbe *prb = (LightProbe *)id;
-
- if (outliner_animdata_test(prb->adt)) {
- outliner_add_element(soops, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
- }
- break;
- }
- case ID_WO:
- {
- World *wrld = (World *)id;
-
- if (outliner_animdata_test(wrld->adt)) {
- outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
- }
- break;
- }
- case ID_KE:
- {
- Key *key = (Key *)id;
-
- if (outliner_animdata_test(key->adt)) {
- outliner_add_element(soops, &te->subtree, key, te, TSE_ANIM_DATA, 0);
- }
- break;
- }
- case ID_AC:
- {
- // XXX do we want to be exposing the F-Curves here?
- //bAction *act = (bAction *)id;
- break;
- }
- case ID_AR:
- {
- bArmature *arm = (bArmature *)id;
- int a = 0;
-
- if (outliner_animdata_test(arm->adt)) {
- outliner_add_element(soops, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
- }
-
- if (arm->edbo) {
- EditBone *ebone;
- TreeElement *ten;
-
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next, a++) {
- ten = outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a);
- ten->directdata = ebone;
- ten->name = ebone->name;
- ebone->temp.p = ten;
- }
- /* make hierarchy */
- ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
- while (ten) {
- TreeElement *nten = ten->next, *par;
- ebone = (EditBone *)ten->directdata;
- if (ebone->parent) {
- BLI_remlink(&te->subtree, ten);
- par = ebone->parent->temp.p;
- BLI_addtail(&par->subtree, ten);
- ten->parent = par;
- }
- ten = nten;
- }
- }
- else {
- /* do not extend Armature when we have posemode */
- tselem = TREESTORE(te->parent);
- if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) {
- /* pass */
- }
- else {
- Bone *curBone;
- for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
- outliner_add_bone(soops, &te->subtree, id, curBone, te, &a);
- }
- }
- }
- break;
- }
- case ID_LS:
- {
- FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
- int a;
-
- if (outliner_animdata_test(linestyle->adt)) {
- outliner_add_element(soops, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
- }
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (linestyle->mtex[a]) {
- outliner_add_element(soops, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
- }
- }
- break;
- }
- case ID_GD:
- {
- bGPdata *gpd = (bGPdata *)id;
- bGPDlayer *gpl;
- int a = 0;
-
- if (outliner_animdata_test(gpd->adt)) {
- outliner_add_element(soops, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
- }
-
- // TODO: base element for layers?
- for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
- outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a);
- a++;
- }
- break;
- }
- case ID_GR:
- {
- /* Don't expand for instances, creates too many elements. */
- if (!(te->parent && te->parent->idcode == ID_OB)) {
- Collection *collection = (Collection *)id;
- outliner_add_collection_recursive(soops, collection, te);
- }
- }
- default:
- break;
- }
+ /* tuck pointer back in object, to construct hierarchy */
+ if (GS(id->name) == ID_OB) {
+ id->newid = (ID *)te;
+ }
+
+ /* expand specific data always */
+ switch (GS(id->name)) {
+ case ID_LI: {
+ te->name = ((Library *)id)->name;
+ break;
+ }
+ case ID_SCE: {
+ outliner_add_scene_contents(soops, &te->subtree, (Scene *)id, te);
+ break;
+ }
+ case ID_OB: {
+ outliner_add_object_contents(soops, te, tselem, (Object *)id);
+ break;
+ }
+ case ID_ME: {
+ Mesh *me = (Mesh *)id;
+ int a;
+
+ if (outliner_animdata_test(me->adt)) {
+ outliner_add_element(soops, &te->subtree, me, te, TSE_ANIM_DATA, 0);
+ }
+
+ outliner_add_element(soops, &te->subtree, me->key, te, 0, 0);
+ for (a = 0; a < me->totcol; a++) {
+ outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a);
+ }
+ /* could do tfaces with image links, but the images are not grouped nicely.
+ * would require going over all tfaces, sort images in use. etc... */
+ break;
+ }
+ case ID_CU: {
+ Curve *cu = (Curve *)id;
+ int a;
+
+ if (outliner_animdata_test(cu->adt)) {
+ outliner_add_element(soops, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
+ }
+
+ for (a = 0; a < cu->totcol; a++) {
+ outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a);
+ }
+ break;
+ }
+ case ID_MB: {
+ MetaBall *mb = (MetaBall *)id;
+ int a;
+
+ if (outliner_animdata_test(mb->adt)) {
+ outliner_add_element(soops, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
+ }
+
+ for (a = 0; a < mb->totcol; a++) {
+ outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a);
+ }
+ break;
+ }
+ case ID_MA: {
+ Material *ma = (Material *)id;
+
+ if (outliner_animdata_test(ma->adt)) {
+ outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
+ }
+ break;
+ }
+ case ID_TE: {
+ Tex *tex = (Tex *)id;
+
+ if (outliner_animdata_test(tex->adt)) {
+ outliner_add_element(soops, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
+ }
+ outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0);
+ break;
+ }
+ case ID_CA: {
+ Camera *ca = (Camera *)id;
+
+ if (outliner_animdata_test(ca->adt)) {
+ outliner_add_element(soops, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
+ }
+ break;
+ }
+ case ID_CF: {
+ CacheFile *cache_file = (CacheFile *)id;
+
+ if (outliner_animdata_test(cache_file->adt)) {
+ outliner_add_element(soops, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
+ }
+
+ break;
+ }
+ case ID_LA: {
+ Light *la = (Light *)id;
+
+ if (outliner_animdata_test(la->adt)) {
+ outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0);
+ }
+ break;
+ }
+ case ID_SPK: {
+ Speaker *spk = (Speaker *)id;
+
+ if (outliner_animdata_test(spk->adt)) {
+ outliner_add_element(soops, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
+ }
+ break;
+ }
+ case ID_LP: {
+ LightProbe *prb = (LightProbe *)id;
+
+ if (outliner_animdata_test(prb->adt)) {
+ outliner_add_element(soops, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
+ }
+ break;
+ }
+ case ID_WO: {
+ World *wrld = (World *)id;
+
+ if (outliner_animdata_test(wrld->adt)) {
+ outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
+ }
+ break;
+ }
+ case ID_KE: {
+ Key *key = (Key *)id;
+
+ if (outliner_animdata_test(key->adt)) {
+ outliner_add_element(soops, &te->subtree, key, te, TSE_ANIM_DATA, 0);
+ }
+ break;
+ }
+ case ID_AC: {
+ // XXX do we want to be exposing the F-Curves here?
+ //bAction *act = (bAction *)id;
+ break;
+ }
+ case ID_AR: {
+ bArmature *arm = (bArmature *)id;
+ int a = 0;
+
+ if (outliner_animdata_test(arm->adt)) {
+ outliner_add_element(soops, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
+ }
+
+ if (arm->edbo) {
+ EditBone *ebone;
+ TreeElement *ten;
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next, a++) {
+ ten = outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a);
+ ten->directdata = ebone;
+ ten->name = ebone->name;
+ ebone->temp.p = ten;
+ }
+ /* make hierarchy */
+ ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
+ while (ten) {
+ TreeElement *nten = ten->next, *par;
+ ebone = (EditBone *)ten->directdata;
+ if (ebone->parent) {
+ BLI_remlink(&te->subtree, ten);
+ par = ebone->parent->temp.p;
+ BLI_addtail(&par->subtree, ten);
+ ten->parent = par;
+ }
+ ten = nten;
+ }
+ }
+ else {
+ /* do not extend Armature when we have posemode */
+ tselem = TREESTORE(te->parent);
+ if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) {
+ /* pass */
+ }
+ else {
+ Bone *curBone;
+ for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
+ outliner_add_bone(soops, &te->subtree, id, curBone, te, &a);
+ }
+ }
+ }
+ break;
+ }
+ case ID_LS: {
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
+ int a;
+
+ if (outliner_animdata_test(linestyle->adt)) {
+ outliner_add_element(soops, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
+ }
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (linestyle->mtex[a]) {
+ outliner_add_element(soops, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
+ }
+ }
+ break;
+ }
+ case ID_GD: {
+ bGPdata *gpd = (bGPdata *)id;
+ bGPDlayer *gpl;
+ int a = 0;
+
+ if (outliner_animdata_test(gpd->adt)) {
+ outliner_add_element(soops, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
+ }
+
+ // TODO: base element for layers?
+ for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
+ outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a);
+ a++;
+ }
+ break;
+ }
+ case ID_GR: {
+ /* Don't expand for instances, creates too many elements. */
+ if (!(te->parent && te->parent->idcode == ID_OB)) {
+ Collection *collection = (Collection *)id;
+ outliner_add_collection_recursive(soops, collection, te);
+ }
+ }
+ default:
+ break;
+ }
}
// TODO: this function needs to be split up! It's getting a bit too large...
// Note: "ID" is not always a real ID
-static TreeElement *outliner_add_element(SpaceOutliner *soops, ListBase *lb, void *idv,
- TreeElement *parent, short type, short index)
+static TreeElement *outliner_add_element(
+ SpaceOutliner *soops, ListBase *lb, void *idv, TreeElement *parent, short type, short index)
{
- TreeElement *te;
- TreeStoreElem *tselem;
- ID *id = idv;
-
- if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
- id = ((PointerRNA *)idv)->id.data;
- if (!id) {
- id = ((PointerRNA *)idv)->data;
- }
- }
- else if (type == TSE_GP_LAYER) {
- /* idv is the layer its self */
- id = TREESTORE(parent)->id;
- }
-
- /* exceptions */
- if (type == TSE_ID_BASE) {
- /* pass */
- }
- else if (id == NULL) {
- return NULL;
- }
-
- if (type == 0) {
- /* Zero type means real ID, ensure we do not get non-outliner ID types here... */
- BLI_assert(TREESTORE_ID_TYPE(id));
- }
-
- te = MEM_callocN(sizeof(TreeElement), "tree elem");
- /* add to the visual tree */
- BLI_addtail(lb, te);
- /* add to the storage */
- check_persistent(soops, te, id, type, index);
- tselem = TREESTORE(te);
-
- /* if we are searching for something expand to see child elements */
- if (SEARCHING_OUTLINER(soops)) {
- tselem->flag |= TSE_CHILDSEARCH;
- }
-
- te->parent = parent;
- te->index = index; // for data arrays
- if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
- /* pass */
- }
- else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
- /* pass */
- }
- else if (type == TSE_ANIM_DATA) {
- /* pass */
- }
- else if (type == TSE_GP_LAYER) {
- /* pass */
- }
- else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
- /* pass */
- }
- else if (type == TSE_ID_BASE) {
- /* pass */
- }
- else {
- /* do here too, for blend file viewer, own ID_LI then shows file name */
- if (GS(id->name) == ID_LI) {
- te->name = ((Library *)id)->name;
- }
- else {
- te->name = id->name + 2; // default, can be overridden by Library or non-ID data
- }
- te->idcode = GS(id->name);
- }
-
- if (type == 0) {
- TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
-
- /* ID datablock */
- if (tsepar == NULL || tsepar->type != TSE_ID_BASE || soops->filter_id_type) {
- outliner_add_id_contents(soops, te, tselem, id);
- }
- }
- else if (type == TSE_ANIM_DATA) {
- IdAdtTemplate *iat = (IdAdtTemplate *)idv;
- AnimData *adt = (AnimData *)iat->adt;
-
- /* this element's info */
- te->name = IFACE_("Animation");
- te->directdata = adt;
-
- /* Action */
- outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0);
-
- /* Drivers */
- if (adt->drivers.first) {
- TreeElement *ted = outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
- ID *lastadded = NULL;
- FCurve *fcu;
-
- ted->name = IFACE_("Drivers");
-
- for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
- if (fcu->driver && fcu->driver->variables.first) {
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* loop over all targets used here */
- DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
- {
- if (lastadded != dtar->id) {
- // XXX this lastadded check is rather lame, and also fails quite badly...
- outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
- lastadded = dtar->id;
- }
- }
- DRIVER_TARGETS_LOOPER_END;
- }
- }
- }
- }
-
- /* NLA Data */
- if (adt->nla_tracks.first) {
- TreeElement *tenla = outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0);
- NlaTrack *nlt;
- int a = 0;
-
- tenla->name = IFACE_("NLA Tracks");
-
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- TreeElement *tenlt = outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
- NlaStrip *strip;
- TreeElement *ten;
- int b = 0;
-
- tenlt->name = nlt->name;
-
- for (strip = nlt->strips.first; strip; strip = strip->next, b++) {
- ten = outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
- if (ten) {
- ten->directdata = strip;
- }
- }
- }
- }
- }
- else if (type == TSE_GP_LAYER) {
- bGPDlayer *gpl = (bGPDlayer *)idv;
-
- te->name = gpl->info;
- te->directdata = gpl;
- }
- else if (type == TSE_SEQUENCE) {
- Sequence *seq = (Sequence *) idv;
- Sequence *p;
-
- /*
- * The idcode is a little hack, but the outliner
- * only check te->idcode if te->type is equal to zero,
- * so this is "safe".
- */
- te->idcode = seq->type;
- te->directdata = seq;
- te->name = seq->name + 2;
-
- if (!(seq->type & SEQ_TYPE_EFFECT)) {
- /*
- * This work like the sequence.
- * If the sequence have a name (not default name)
- * show it, in other case put the filename.
- */
-
- if (seq->type == SEQ_TYPE_META) {
- p = seq->seqbase.first;
- while (p) {
- outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
- p = p->next;
- }
- }
- else {
- outliner_add_element(soops, &te->subtree, (void *)seq->strip, te, TSE_SEQ_STRIP, index);
- }
- }
- }
- else if (type == TSE_SEQ_STRIP) {
- Strip *strip = (Strip *)idv;
-
- if (strip->dir[0] != '\0') {
- te->name = strip->dir;
- }
- else {
- te->name = IFACE_("Strip None");
- }
- te->directdata = strip;
- }
- else if (type == TSE_SEQUENCE_DUP) {
- Sequence *seq = (Sequence *)idv;
-
- te->idcode = seq->type;
- te->directdata = seq;
- te->name = seq->strip->stripdata->name;
- }
- else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
- PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv;
- PropertyRNA *prop, *iterprop;
- PropertyType proptype;
-
- /* Don't display arrays larger, weak but index is stored as a short,
- * also the outliner isn't intended for editing such large data-sets. */
- BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!");
- const int tot_limit = SHRT_MAX;
-
- int a, tot;
-
- /* we do lazy build, for speed and to avoid infinite recursion */
-
- if (ptr->data == NULL) {
- te->name = IFACE_("(empty)");
- }
- else if (type == TSE_RNA_STRUCT) {
- /* struct */
- te->name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
-
- if (te->name) {
- te->flag |= TE_FREE_NAME;
- }
- else {
- te->name = RNA_struct_ui_name(ptr->type);
- }
-
- /* If searching don't expand RNA entries */
- if (SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA", te->name) == 0) {
- tselem->flag &= ~TSE_CHILDSEARCH;
- }
-
- iterprop = RNA_struct_iterator_property(ptr->type);
- tot = RNA_property_collection_length(ptr, iterprop);
- CLAMP_MAX(tot, tot_limit);
-
- /* auto open these cases */
- if (!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER) {
- if (!tselem->used) {
- tselem->flag &= ~TSE_CLOSED;
- }
- }
-
- if (TSELEM_OPEN(tselem, soops)) {
- for (a = 0; a < tot; a++) {
- RNA_property_collection_lookup_int(ptr, iterprop, a, &propptr);
- if (!(RNA_property_flag(propptr.data) & PROP_HIDDEN)) {
- outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_PROPERTY, a);
- }
- }
- }
- else if (tot) {
- te->flag |= TE_LAZY_CLOSED;
- }
-
- te->rnaptr = *ptr;
- }
- else if (type == TSE_RNA_PROPERTY) {
- /* property */
- iterprop = RNA_struct_iterator_property(ptr->type);
- RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr);
-
- prop = propptr.data;
- proptype = RNA_property_type(prop);
-
- te->name = RNA_property_ui_name(prop);
- te->directdata = prop;
- te->rnaptr = *ptr;
-
- /* If searching don't expand RNA entries */
- if (SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA", te->name) == 0) {
- tselem->flag &= ~TSE_CHILDSEARCH;
- }
-
- if (proptype == PROP_POINTER) {
- pptr = RNA_property_pointer_get(ptr, prop);
-
- if (pptr.data) {
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, -1);
- }
- else {
- te->flag |= TE_LAZY_CLOSED;
- }
- }
- }
- else if (proptype == PROP_COLLECTION) {
- tot = RNA_property_collection_length(ptr, prop);
- CLAMP_MAX(tot, tot_limit);
-
- if (TSELEM_OPEN(tselem, soops)) {
- for (a = 0; a < tot; a++) {
- RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
- outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a);
- }
- }
- else if (tot) {
- te->flag |= TE_LAZY_CLOSED;
- }
- }
- else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
- tot = RNA_property_array_length(ptr, prop);
- CLAMP_MAX(tot, tot_limit);
-
- if (TSELEM_OPEN(tselem, soops)) {
- for (a = 0; a < tot; a++) {
- outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a);
- }
- }
- else if (tot) {
- te->flag |= TE_LAZY_CLOSED;
- }
- }
- }
- else if (type == TSE_RNA_ARRAY_ELEM) {
- char c;
-
- prop = parent->directdata;
-
- te->directdata = prop;
- te->rnaptr = *ptr;
- te->index = index;
-
- c = RNA_property_array_item_char(prop, index);
-
- te->name = MEM_callocN(sizeof(char) * 20, "OutlinerRNAArrayName");
- if (c) {
- sprintf((char *)te->name, " %c", c);
- }
- else {
- sprintf((char *)te->name, " %d", index + 1);
- }
- te->flag |= TE_FREE_NAME;
- }
- }
- else if (type == TSE_KEYMAP) {
- wmKeyMap *km = (wmKeyMap *)idv;
- wmKeyMapItem *kmi;
- char opname[OP_MAX_TYPENAME];
-
- te->directdata = idv;
- te->name = km->idname;
-
- if (TSELEM_OPEN(tselem, soops)) {
- int a = 0;
-
- for (kmi = km->items.first; kmi; kmi = kmi->next, a++) {
- const char *key = WM_key_event_string(kmi->type, false);
-
- if (key[0]) {
- wmOperatorType *ot = NULL;
-
- if (kmi->propvalue) {
- /* pass */
- }
- else {
- ot = WM_operatortype_find(kmi->idname, 0);
- }
-
- if (ot || kmi->propvalue) {
- TreeElement *ten = outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
-
- ten->directdata = kmi;
-
- if (kmi->propvalue) {
- ten->name = IFACE_("Modal map, not yet");
- }
- else {
- WM_operator_py_idname(opname, ot->idname);
- ten->name = BLI_strdup(opname);
- ten->flag |= TE_FREE_NAME;
- }
- }
- }
- }
- }
- else {
- te->flag |= TE_LAZY_CLOSED;
- }
- }
-
- return te;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+ ID *id = idv;
+
+ if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
+ id = ((PointerRNA *)idv)->id.data;
+ if (!id) {
+ id = ((PointerRNA *)idv)->data;
+ }
+ }
+ else if (type == TSE_GP_LAYER) {
+ /* idv is the layer its self */
+ id = TREESTORE(parent)->id;
+ }
+
+ /* exceptions */
+ if (type == TSE_ID_BASE) {
+ /* pass */
+ }
+ else if (id == NULL) {
+ return NULL;
+ }
+
+ if (type == 0) {
+ /* Zero type means real ID, ensure we do not get non-outliner ID types here... */
+ BLI_assert(TREESTORE_ID_TYPE(id));
+ }
+
+ te = MEM_callocN(sizeof(TreeElement), "tree elem");
+ /* add to the visual tree */
+ BLI_addtail(lb, te);
+ /* add to the storage */
+ check_persistent(soops, te, id, type, index);
+ tselem = TREESTORE(te);
+
+ /* if we are searching for something expand to see child elements */
+ if (SEARCHING_OUTLINER(soops)) {
+ tselem->flag |= TSE_CHILDSEARCH;
+ }
+
+ te->parent = parent;
+ te->index = index; // for data arrays
+ if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
+ /* pass */
+ }
+ else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
+ /* pass */
+ }
+ else if (type == TSE_ANIM_DATA) {
+ /* pass */
+ }
+ else if (type == TSE_GP_LAYER) {
+ /* pass */
+ }
+ else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
+ /* pass */
+ }
+ else if (type == TSE_ID_BASE) {
+ /* pass */
+ }
+ else {
+ /* do here too, for blend file viewer, own ID_LI then shows file name */
+ if (GS(id->name) == ID_LI) {
+ te->name = ((Library *)id)->name;
+ }
+ else {
+ te->name = id->name + 2; // default, can be overridden by Library or non-ID data
+ }
+ te->idcode = GS(id->name);
+ }
+
+ if (type == 0) {
+ TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
+
+ /* ID datablock */
+ if (tsepar == NULL || tsepar->type != TSE_ID_BASE || soops->filter_id_type) {
+ outliner_add_id_contents(soops, te, tselem, id);
+ }
+ }
+ else if (type == TSE_ANIM_DATA) {
+ IdAdtTemplate *iat = (IdAdtTemplate *)idv;
+ AnimData *adt = (AnimData *)iat->adt;
+
+ /* this element's info */
+ te->name = IFACE_("Animation");
+ te->directdata = adt;
+
+ /* Action */
+ outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0);
+
+ /* Drivers */
+ if (adt->drivers.first) {
+ TreeElement *ted = outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
+ ID *lastadded = NULL;
+ FCurve *fcu;
+
+ ted->name = IFACE_("Drivers");
+
+ for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+ if (fcu->driver && fcu->driver->variables.first) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ /* loop over all targets used here */
+ DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
+ if (lastadded != dtar->id) {
+ // XXX this lastadded check is rather lame, and also fails quite badly...
+ outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
+ lastadded = dtar->id;
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END;
+ }
+ }
+ }
+ }
+
+ /* NLA Data */
+ if (adt->nla_tracks.first) {
+ TreeElement *tenla = outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0);
+ NlaTrack *nlt;
+ int a = 0;
+
+ tenla->name = IFACE_("NLA Tracks");
+
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ TreeElement *tenlt = outliner_add_element(
+ soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
+ NlaStrip *strip;
+ TreeElement *ten;
+ int b = 0;
+
+ tenlt->name = nlt->name;
+
+ for (strip = nlt->strips.first; strip; strip = strip->next, b++) {
+ ten = outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
+ if (ten) {
+ ten->directdata = strip;
+ }
+ }
+ }
+ }
+ }
+ else if (type == TSE_GP_LAYER) {
+ bGPDlayer *gpl = (bGPDlayer *)idv;
+
+ te->name = gpl->info;
+ te->directdata = gpl;
+ }
+ else if (type == TSE_SEQUENCE) {
+ Sequence *seq = (Sequence *)idv;
+ Sequence *p;
+
+ /*
+ * The idcode is a little hack, but the outliner
+ * only check te->idcode if te->type is equal to zero,
+ * so this is "safe".
+ */
+ te->idcode = seq->type;
+ te->directdata = seq;
+ te->name = seq->name + 2;
+
+ if (!(seq->type & SEQ_TYPE_EFFECT)) {
+ /*
+ * This work like the sequence.
+ * If the sequence have a name (not default name)
+ * show it, in other case put the filename.
+ */
+
+ if (seq->type == SEQ_TYPE_META) {
+ p = seq->seqbase.first;
+ while (p) {
+ outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
+ p = p->next;
+ }
+ }
+ else {
+ outliner_add_element(soops, &te->subtree, (void *)seq->strip, te, TSE_SEQ_STRIP, index);
+ }
+ }
+ }
+ else if (type == TSE_SEQ_STRIP) {
+ Strip *strip = (Strip *)idv;
+
+ if (strip->dir[0] != '\0') {
+ te->name = strip->dir;
+ }
+ else {
+ te->name = IFACE_("Strip None");
+ }
+ te->directdata = strip;
+ }
+ else if (type == TSE_SEQUENCE_DUP) {
+ Sequence *seq = (Sequence *)idv;
+
+ te->idcode = seq->type;
+ te->directdata = seq;
+ te->name = seq->strip->stripdata->name;
+ }
+ else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
+ PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv;
+ PropertyRNA *prop, *iterprop;
+ PropertyType proptype;
+
+ /* Don't display arrays larger, weak but index is stored as a short,
+ * also the outliner isn't intended for editing such large data-sets. */
+ BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!");
+ const int tot_limit = SHRT_MAX;
+
+ int a, tot;
+
+ /* we do lazy build, for speed and to avoid infinite recursion */
+
+ if (ptr->data == NULL) {
+ te->name = IFACE_("(empty)");
+ }
+ else if (type == TSE_RNA_STRUCT) {
+ /* struct */
+ te->name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
+
+ if (te->name) {
+ te->flag |= TE_FREE_NAME;
+ }
+ else {
+ te->name = RNA_struct_ui_name(ptr->type);
+ }
+
+ /* If searching don't expand RNA entries */
+ if (SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA", te->name) == 0) {
+ tselem->flag &= ~TSE_CHILDSEARCH;
+ }
+
+ iterprop = RNA_struct_iterator_property(ptr->type);
+ tot = RNA_property_collection_length(ptr, iterprop);
+ CLAMP_MAX(tot, tot_limit);
+
+ /* auto open these cases */
+ if (!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER) {
+ if (!tselem->used) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ for (a = 0; a < tot; a++) {
+ RNA_property_collection_lookup_int(ptr, iterprop, a, &propptr);
+ if (!(RNA_property_flag(propptr.data) & PROP_HIDDEN)) {
+ outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_PROPERTY, a);
+ }
+ }
+ }
+ else if (tot) {
+ te->flag |= TE_LAZY_CLOSED;
+ }
+
+ te->rnaptr = *ptr;
+ }
+ else if (type == TSE_RNA_PROPERTY) {
+ /* property */
+ iterprop = RNA_struct_iterator_property(ptr->type);
+ RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr);
+
+ prop = propptr.data;
+ proptype = RNA_property_type(prop);
+
+ te->name = RNA_property_ui_name(prop);
+ te->directdata = prop;
+ te->rnaptr = *ptr;
+
+ /* If searching don't expand RNA entries */
+ if (SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA", te->name) == 0) {
+ tselem->flag &= ~TSE_CHILDSEARCH;
+ }
+
+ if (proptype == PROP_POINTER) {
+ pptr = RNA_property_pointer_get(ptr, prop);
+
+ if (pptr.data) {
+ if (TSELEM_OPEN(tselem, soops)) {
+ outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, -1);
+ }
+ else {
+ te->flag |= TE_LAZY_CLOSED;
+ }
+ }
+ }
+ else if (proptype == PROP_COLLECTION) {
+ tot = RNA_property_collection_length(ptr, prop);
+ CLAMP_MAX(tot, tot_limit);
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ for (a = 0; a < tot; a++) {
+ RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
+ outliner_add_element(soops, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a);
+ }
+ }
+ else if (tot) {
+ te->flag |= TE_LAZY_CLOSED;
+ }
+ }
+ else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
+ tot = RNA_property_array_length(ptr, prop);
+ CLAMP_MAX(tot, tot_limit);
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ for (a = 0; a < tot; a++) {
+ outliner_add_element(soops, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a);
+ }
+ }
+ else if (tot) {
+ te->flag |= TE_LAZY_CLOSED;
+ }
+ }
+ }
+ else if (type == TSE_RNA_ARRAY_ELEM) {
+ char c;
+
+ prop = parent->directdata;
+
+ te->directdata = prop;
+ te->rnaptr = *ptr;
+ te->index = index;
+
+ c = RNA_property_array_item_char(prop, index);
+
+ te->name = MEM_callocN(sizeof(char) * 20, "OutlinerRNAArrayName");
+ if (c) {
+ sprintf((char *)te->name, " %c", c);
+ }
+ else {
+ sprintf((char *)te->name, " %d", index + 1);
+ }
+ te->flag |= TE_FREE_NAME;
+ }
+ }
+ else if (type == TSE_KEYMAP) {
+ wmKeyMap *km = (wmKeyMap *)idv;
+ wmKeyMapItem *kmi;
+ char opname[OP_MAX_TYPENAME];
+
+ te->directdata = idv;
+ te->name = km->idname;
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ int a = 0;
+
+ for (kmi = km->items.first; kmi; kmi = kmi->next, a++) {
+ const char *key = WM_key_event_string(kmi->type, false);
+
+ if (key[0]) {
+ wmOperatorType *ot = NULL;
+
+ if (kmi->propvalue) {
+ /* pass */
+ }
+ else {
+ ot = WM_operatortype_find(kmi->idname, 0);
+ }
+
+ if (ot || kmi->propvalue) {
+ TreeElement *ten = outliner_add_element(
+ soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
+
+ ten->directdata = kmi;
+
+ if (kmi->propvalue) {
+ ten->name = IFACE_("Modal map, not yet");
+ }
+ else {
+ WM_operator_py_idname(opname, ot->idname);
+ ten->name = BLI_strdup(opname);
+ ten->flag |= TE_FREE_NAME;
+ }
+ }
+ }
+ }
+ }
+ else {
+ te->flag |= TE_LAZY_CLOSED;
+ }
+ }
+
+ return te;
}
/* ======================================================= */
@@ -1139,297 +1137,307 @@ static TreeElement *outliner_add_element(SpaceOutliner *soops, ListBase *lb, voi
/* Helped function to put duplicate sequence in the same tree. */
static int need_add_seq_dup(Sequence *seq)
{
- Sequence *p;
-
- if ((!seq->strip) || (!seq->strip->stripdata)) {
- return 1;
- }
-
- /*
- * First check backward, if we found a duplicate
- * sequence before this, don't need it, just return.
- */
- p = seq->prev;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata)) {
- p = p->prev;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- return 2;
- }
- p = p->prev;
- }
-
- p = seq->next;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata)) {
- p = p->next;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- return 0;
- }
- p = p->next;
- }
- return(1);
+ Sequence *p;
+
+ if ((!seq->strip) || (!seq->strip->stripdata)) {
+ return 1;
+ }
+
+ /*
+ * First check backward, if we found a duplicate
+ * sequence before this, don't need it, just return.
+ */
+ p = seq->prev;
+ while (p) {
+ if ((!p->strip) || (!p->strip->stripdata)) {
+ p = p->prev;
+ continue;
+ }
+
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
+ return 2;
+ }
+ p = p->prev;
+ }
+
+ p = seq->next;
+ while (p) {
+ if ((!p->strip) || (!p->strip->stripdata)) {
+ p = p->next;
+ continue;
+ }
+
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
+ return 0;
+ }
+ p = p->next;
+ }
+ return (1);
}
static void outliner_add_seq_dup(SpaceOutliner *soops, Sequence *seq, TreeElement *te, short index)
{
- /* TreeElement *ch; */ /* UNUSED */
- Sequence *p;
-
- p = seq;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
- p = p->next;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- /* ch = */ /* UNUSED */ outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
- }
- p = p->next;
- }
+ /* TreeElement *ch; */ /* UNUSED */
+ Sequence *p;
+
+ p = seq;
+ while (p) {
+ if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
+ p = p->next;
+ continue;
+ }
+
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
+ /* ch = */ /* UNUSED */ outliner_add_element(
+ soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
+ }
+ p = p->next;
+ }
}
-
/* ----------------------------------------------- */
static const char *outliner_idcode_to_plural(short idcode)
{
- const char *propname = BKE_idcode_to_name_plural(idcode);
- PropertyRNA *prop = RNA_struct_type_find_property(&RNA_BlendData, propname);
- return (prop) ? RNA_property_ui_name(prop) : "UNKNOWN";
+ const char *propname = BKE_idcode_to_name_plural(idcode);
+ PropertyRNA *prop = RNA_struct_type_find_property(&RNA_BlendData, propname);
+ return (prop) ? RNA_property_ui_name(prop) : "UNKNOWN";
}
static bool outliner_library_id_show(Library *lib, ID *id, short filter_id_type)
{
- if (id->lib != lib) {
- return false;
- }
-
- if (filter_id_type == ID_GR) {
- /* Don't show child collections of non-scene master collection,
- * they are already shown as children. */
- Collection *collection = (Collection *)id;
- bool has_non_scene_parent = false;
-
- for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) {
- if (!(cparent->collection->flag & COLLECTION_IS_MASTER)) {
- has_non_scene_parent = true;
- }
- }
-
- if (has_non_scene_parent) {
- return false;
- }
- }
-
- return true;
+ if (id->lib != lib) {
+ return false;
+ }
+
+ if (filter_id_type == ID_GR) {
+ /* Don't show child collections of non-scene master collection,
+ * they are already shown as children. */
+ Collection *collection = (Collection *)id;
+ bool has_non_scene_parent = false;
+
+ for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) {
+ if (!(cparent->collection->flag & COLLECTION_IS_MASTER)) {
+ has_non_scene_parent = true;
+ }
+ }
+
+ if (has_non_scene_parent) {
+ return false;
+ }
+ }
+
+ return true;
}
-static TreeElement *outliner_add_library_contents(Main *mainvar, SpaceOutliner *soops, ListBase *lb, Library *lib)
+static TreeElement *outliner_add_library_contents(Main *mainvar,
+ SpaceOutliner *soops,
+ ListBase *lb,
+ Library *lib)
{
- TreeElement *ten, *tenlib = NULL;
- ListBase *lbarray[MAX_LIBARRAY];
- int a, tot;
- short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0;
-
- if (filter_id_type) {
- lbarray[0] = which_libbase(mainvar, soops->filter_id_type);
- tot = 1;
- }
- else {
- tot = set_listbasepointers(mainvar, lbarray);
- }
-
- for (a = 0; a < tot; a++) {
- if (lbarray[a] && lbarray[a]->first) {
- ID *id = lbarray[a]->first;
-
- /* check if there's data in current lib */
- for (; id; id = id->next) {
- if (id->lib == lib) {
- break;
- }
- }
-
- if (id) {
- if (!tenlib) {
- /* Create library tree element on demand, depending if there are any datablocks. */
- if (lib) {
- tenlib = outliner_add_element(soops, lb, lib, NULL, 0, 0);
- }
- else {
- tenlib = outliner_add_element(soops, lb, mainvar, NULL, TSE_ID_BASE, 0);
- tenlib->name = IFACE_("Current File");
- }
- }
-
- /* Create datablock list parent element on demand. */
- if (filter_id_type) {
- ten = tenlib;
- }
- else {
- ten = outliner_add_element(soops, &tenlib->subtree, lbarray[a], NULL, TSE_ID_BASE, 0);
- ten->directdata = lbarray[a];
- ten->name = outliner_idcode_to_plural(GS(id->name));
- }
-
- for (id = lbarray[a]->first; id; id = id->next) {
- if (outliner_library_id_show(lib, id, filter_id_type)) {
- outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
- }
- }
- }
- }
- }
-
- return tenlib;
+ TreeElement *ten, *tenlib = NULL;
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a, tot;
+ short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0;
+
+ if (filter_id_type) {
+ lbarray[0] = which_libbase(mainvar, soops->filter_id_type);
+ tot = 1;
+ }
+ else {
+ tot = set_listbasepointers(mainvar, lbarray);
+ }
+
+ for (a = 0; a < tot; a++) {
+ if (lbarray[a] && lbarray[a]->first) {
+ ID *id = lbarray[a]->first;
+
+ /* check if there's data in current lib */
+ for (; id; id = id->next) {
+ if (id->lib == lib) {
+ break;
+ }
+ }
+
+ if (id) {
+ if (!tenlib) {
+ /* Create library tree element on demand, depending if there are any datablocks. */
+ if (lib) {
+ tenlib = outliner_add_element(soops, lb, lib, NULL, 0, 0);
+ }
+ else {
+ tenlib = outliner_add_element(soops, lb, mainvar, NULL, TSE_ID_BASE, 0);
+ tenlib->name = IFACE_("Current File");
+ }
+ }
+
+ /* Create datablock list parent element on demand. */
+ if (filter_id_type) {
+ ten = tenlib;
+ }
+ else {
+ ten = outliner_add_element(soops, &tenlib->subtree, lbarray[a], NULL, TSE_ID_BASE, 0);
+ ten->directdata = lbarray[a];
+ ten->name = outliner_idcode_to_plural(GS(id->name));
+ }
+
+ for (id = lbarray[a]->first; id; id = id->next) {
+ if (outliner_library_id_show(lib, id, filter_id_type)) {
+ outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
+ }
+ }
+ }
+ }
+ }
+
+ return tenlib;
}
static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOutliner *soops)
{
- TreeElement *ten;
- ListBase *lbarray[MAX_LIBARRAY];
- int a, tot;
- short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0;
-
- if (filter_id_type) {
- lbarray[0] = which_libbase(mainvar, soops->filter_id_type);
- tot = 1;
- }
- else {
- tot = set_listbasepointers(mainvar, lbarray);
- }
-
- for (a = 0; a < tot; a++) {
- if (lbarray[a] && lbarray[a]->first) {
- ID *id = lbarray[a]->first;
-
- /* check if there are any datablocks of this type which are orphans */
- for (; id; id = id->next) {
- if (ID_REAL_USERS(id) <= 0) {
- break;
- }
- }
-
- if (id) {
- /* header for this type of datablock */
- if (filter_id_type) {
- ten = NULL;
- }
- else {
- ten = outliner_add_element(soops, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0);
- ten->directdata = lbarray[a];
- ten->name = outliner_idcode_to_plural(GS(id->name));
- }
-
- /* add the orphaned datablocks - these will not be added with any subtrees attached */
- for (id = lbarray[a]->first; id; id = id->next) {
- if (ID_REAL_USERS(id) <= 0) {
- outliner_add_element(soops, (ten) ? &ten->subtree : &soops->tree, id, ten, 0, 0);
- }
- }
- }
- }
- }
+ TreeElement *ten;
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a, tot;
+ short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0;
+
+ if (filter_id_type) {
+ lbarray[0] = which_libbase(mainvar, soops->filter_id_type);
+ tot = 1;
+ }
+ else {
+ tot = set_listbasepointers(mainvar, lbarray);
+ }
+
+ for (a = 0; a < tot; a++) {
+ if (lbarray[a] && lbarray[a]->first) {
+ ID *id = lbarray[a]->first;
+
+ /* check if there are any datablocks of this type which are orphans */
+ for (; id; id = id->next) {
+ if (ID_REAL_USERS(id) <= 0) {
+ break;
+ }
+ }
+
+ if (id) {
+ /* header for this type of datablock */
+ if (filter_id_type) {
+ ten = NULL;
+ }
+ else {
+ ten = outliner_add_element(soops, &soops->tree, lbarray[a], NULL, TSE_ID_BASE, 0);
+ ten->directdata = lbarray[a];
+ ten->name = outliner_idcode_to_plural(GS(id->name));
+ }
+
+ /* add the orphaned datablocks - these will not be added with any subtrees attached */
+ for (id = lbarray[a]->first; id; id = id->next) {
+ if (ID_REAL_USERS(id) <= 0) {
+ outliner_add_element(soops, (ten) ? &ten->subtree : &soops->tree, id, ten, 0, 0);
+ }
+ }
+ }
+ }
+ }
}
static void outliner_add_layer_collection_objects(
- SpaceOutliner *soops, ListBase *tree, ViewLayer *layer,
- LayerCollection *lc, TreeElement *ten)
+ SpaceOutliner *soops, ListBase *tree, ViewLayer *layer, LayerCollection *lc, TreeElement *ten)
{
- for (CollectionObject *cob = lc->collection->gobject.first; cob; cob = cob->next) {
- Base *base = BKE_view_layer_base_find(layer, cob->ob);
- TreeElement *te_object = outliner_add_element(soops, tree, base->object, ten, 0, 0);
- te_object->directdata = base;
-
- if (!(base->flag & BASE_VISIBLE)) {
- te_object->flag |= TE_DISABLED;
- }
- }
+ for (CollectionObject *cob = lc->collection->gobject.first; cob; cob = cob->next) {
+ Base *base = BKE_view_layer_base_find(layer, cob->ob);
+ TreeElement *te_object = outliner_add_element(soops, tree, base->object, ten, 0, 0);
+ te_object->directdata = base;
+
+ if (!(base->flag & BASE_VISIBLE)) {
+ te_object->flag |= TE_DISABLED;
+ }
+ }
}
-static void outliner_add_layer_collections_recursive(
- SpaceOutliner *soops, ListBase *tree, ViewLayer *layer,
- ListBase *layer_collections, TreeElement *parent_ten,
- const bool show_objects)
+static void outliner_add_layer_collections_recursive(SpaceOutliner *soops,
+ ListBase *tree,
+ ViewLayer *layer,
+ ListBase *layer_collections,
+ TreeElement *parent_ten,
+ const bool show_objects)
{
- for (LayerCollection *lc = layer_collections->first; lc; lc = lc->next) {
- ID *id = &lc->collection->id;
- TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
-
- ten->name = id->name + 2;
- ten->directdata = lc;
-
- /* Open by default. */
- TreeStoreElem *tselem = TREESTORE(ten);
- if (!tselem->used) {
- tselem->flag &= ~TSE_CLOSED;
- }
-
- const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
- if (exclude ||
- ((lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0))
- {
- ten->flag |= TE_DISABLED;
- }
-
- outliner_add_layer_collections_recursive(soops, &ten->subtree, layer, &lc->layer_collections, ten, show_objects);
- if (!exclude && show_objects) {
- outliner_add_layer_collection_objects(soops, &ten->subtree, layer, lc, ten);
- }
- }
+ for (LayerCollection *lc = layer_collections->first; lc; lc = lc->next) {
+ ID *id = &lc->collection->id;
+ TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
+
+ ten->name = id->name + 2;
+ ten->directdata = lc;
+
+ /* Open by default. */
+ TreeStoreElem *tselem = TREESTORE(ten);
+ if (!tselem->used) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+
+ const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
+ if (exclude || ((lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0)) {
+ ten->flag |= TE_DISABLED;
+ }
+
+ outliner_add_layer_collections_recursive(
+ soops, &ten->subtree, layer, &lc->layer_collections, ten, show_objects);
+ if (!exclude && show_objects) {
+ outliner_add_layer_collection_objects(soops, &ten->subtree, layer, lc, ten);
+ }
+ }
}
-static void outliner_add_view_layer(SpaceOutliner *soops, ListBase *tree, TreeElement *parent,
- ViewLayer *layer, const bool show_objects)
+static void outliner_add_view_layer(SpaceOutliner *soops,
+ ListBase *tree,
+ TreeElement *parent,
+ ViewLayer *layer,
+ const bool show_objects)
{
- /* First layer collection is for master collection, don't show it. */
- LayerCollection *lc = layer->layer_collections.first;
- if (lc == NULL) {
- return;
- }
-
- outliner_add_layer_collections_recursive(soops, tree, layer, &lc->layer_collections, parent, show_objects);
- if (show_objects) {
- outliner_add_layer_collection_objects(soops, tree, layer, lc, parent);
- }
+ /* First layer collection is for master collection, don't show it. */
+ LayerCollection *lc = layer->layer_collections.first;
+ if (lc == NULL) {
+ return;
+ }
+
+ outliner_add_layer_collections_recursive(
+ soops, tree, layer, &lc->layer_collections, parent, show_objects);
+ if (show_objects) {
+ outliner_add_layer_collection_objects(soops, tree, layer, lc, parent);
+ }
}
BLI_INLINE void outliner_add_collection_init(TreeElement *te, Collection *collection)
{
- te->name = BKE_collection_ui_name_get(collection);
- te->directdata = collection;
+ te->name = BKE_collection_ui_name_get(collection);
+ te->directdata = collection;
}
-BLI_INLINE void outliner_add_collection_objects(
- SpaceOutliner *soops, ListBase *tree, Collection *collection, TreeElement *parent)
+BLI_INLINE void outliner_add_collection_objects(SpaceOutliner *soops,
+ ListBase *tree,
+ Collection *collection,
+ TreeElement *parent)
{
- for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
- outliner_add_element(soops, tree, cob->ob, parent, 0, 0);
- }
+ for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
+ outliner_add_element(soops, tree, cob->ob, parent, 0, 0);
+ }
}
-static TreeElement *outliner_add_collection_recursive(
- SpaceOutliner *soops, Collection *collection, TreeElement *ten)
+static TreeElement *outliner_add_collection_recursive(SpaceOutliner *soops,
+ Collection *collection,
+ TreeElement *ten)
{
- outliner_add_collection_init(ten, collection);
+ outliner_add_collection_init(ten, collection);
- for (CollectionChild *child = collection->children.first; child; child = child->next) {
- outliner_add_element(soops, &ten->subtree, &child->collection->id, ten, 0, 0);
- }
+ for (CollectionChild *child = collection->children.first; child; child = child->next) {
+ outliner_add_element(soops, &ten->subtree, &child->collection->id, ten, 0, 0);
+ }
- if (soops->outlinevis != SO_SCENES) {
- outliner_add_collection_objects(soops, &ten->subtree, collection, ten);
- }
+ if (soops->outlinevis != SO_SCENES) {
+ outliner_add_collection_objects(soops, &ten->subtree, collection, ten);
+ }
- return ten;
+ return ten;
}
/* ======================================================= */
@@ -1440,267 +1448,270 @@ static TreeElement *outliner_add_collection_recursive(
/* make sure elements are correctly nested */
static void outliner_make_object_parent_hierarchy(ListBase *lb)
{
- TreeElement *te, *ten, *tep;
- TreeStoreElem *tselem;
-
- /* build hierarchy */
- // XXX also, set extents here...
- te = lb->first;
- while (te) {
- ten = te->next;
- tselem = TREESTORE(te);
-
- if (tselem->type == 0 && te->idcode == ID_OB) {
- Object *ob = (Object *)tselem->id;
- if (ob->parent && ob->parent->id.newid) {
- BLI_remlink(lb, te);
- tep = (TreeElement *)ob->parent->id.newid;
- BLI_addtail(&tep->subtree, te);
- // set correct parent pointers
- for (te = tep->subtree.first; te; te = te->next) {
- te->parent = tep;
- }
- }
- }
- te = ten;
- }
+ TreeElement *te, *ten, *tep;
+ TreeStoreElem *tselem;
+
+ /* build hierarchy */
+ // XXX also, set extents here...
+ te = lb->first;
+ while (te) {
+ ten = te->next;
+ tselem = TREESTORE(te);
+
+ if (tselem->type == 0 && te->idcode == ID_OB) {
+ Object *ob = (Object *)tselem->id;
+ if (ob->parent && ob->parent->id.newid) {
+ BLI_remlink(lb, te);
+ tep = (TreeElement *)ob->parent->id.newid;
+ BLI_addtail(&tep->subtree, te);
+ // set correct parent pointers
+ for (te = tep->subtree.first; te; te = te->next) {
+ te->parent = tep;
+ }
+ }
+ }
+ te = ten;
+ }
}
/* Sorting ------------------------------------------------------ */
typedef struct tTreeSort {
- TreeElement *te;
- ID *id;
- const char *name;
- short idcode;
+ TreeElement *te;
+ ID *id;
+ const char *name;
+ short idcode;
} tTreeSort;
/* alphabetical comparator, tryping to put objects first */
static int treesort_alpha_ob(const void *v1, const void *v2)
{
- const tTreeSort *x1 = v1, *x2 = v2;
- int comp;
-
- /* first put objects last (hierarchy) */
- comp = (x1->idcode == ID_OB);
- if (x2->idcode == ID_OB) {
- comp += 2;
- }
-
- if (comp == 1) {
- return 1;
- }
- else if (comp == 2) {
- return -1;
- }
- else if (comp == 3) {
- comp = strcmp(x1->name, x2->name);
-
- if (comp > 0) {
- return 1;
- }
- else if (comp < 0) {
- return -1;
- }
- return 0;
- }
- return 0;
+ const tTreeSort *x1 = v1, *x2 = v2;
+ int comp;
+
+ /* first put objects last (hierarchy) */
+ comp = (x1->idcode == ID_OB);
+ if (x2->idcode == ID_OB) {
+ comp += 2;
+ }
+
+ if (comp == 1) {
+ return 1;
+ }
+ else if (comp == 2) {
+ return -1;
+ }
+ else if (comp == 3) {
+ comp = strcmp(x1->name, x2->name);
+
+ if (comp > 0) {
+ return 1;
+ }
+ else if (comp < 0) {
+ return -1;
+ }
+ return 0;
+ }
+ return 0;
}
/* alphabetical comparator */
static int treesort_alpha(const void *v1, const void *v2)
{
- const tTreeSort *x1 = v1, *x2 = v2;
- int comp;
-
- comp = strcmp(x1->name, x2->name);
-
- if (comp > 0) {
- return 1;
- }
- else if (comp < 0) {
- return -1;
- }
- return 0;
+ const tTreeSort *x1 = v1, *x2 = v2;
+ int comp;
+
+ comp = strcmp(x1->name, x2->name);
+
+ if (comp > 0) {
+ return 1;
+ }
+ else if (comp < 0) {
+ return -1;
+ }
+ return 0;
}
-
/* this is nice option for later? doesn't look too useful... */
#if 0
static int treesort_obtype_alpha(const void *v1, const void *v2)
{
- const tTreeSort *x1 = v1, *x2 = v2;
-
- /* first put objects last (hierarchy) */
- if (x1->idcode == ID_OB && x2->idcode != ID_OB) {
- return 1;
- }
- else if (x2->idcode == ID_OB && x1->idcode != ID_OB) {
- return -1;
- }
- else {
- /* 2nd we check ob type */
- if (x1->idcode == ID_OB && x2->idcode == ID_OB) {
- if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1;
- else if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return -1;
- else return 0;
- }
- else {
- int comp = strcmp(x1->name, x2->name);
-
- if (comp > 0) return 1;
- else if (comp < 0) return -1;
- return 0;
- }
- }
+ const tTreeSort *x1 = v1, *x2 = v2;
+
+ /* first put objects last (hierarchy) */
+ if (x1->idcode == ID_OB && x2->idcode != ID_OB) {
+ return 1;
+ }
+ else if (x2->idcode == ID_OB && x1->idcode != ID_OB) {
+ return -1;
+ }
+ else {
+ /* 2nd we check ob type */
+ if (x1->idcode == ID_OB && x2->idcode == ID_OB) {
+ if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1;
+ else if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return -1;
+ else return 0;
+ }
+ else {
+ int comp = strcmp(x1->name, x2->name);
+
+ if (comp > 0) return 1;
+ else if (comp < 0) return -1;
+ return 0;
+ }
+ }
}
#endif
/* sort happens on each subtree individual */
static void outliner_sort(ListBase *lb)
{
- TreeElement *te;
- TreeStoreElem *tselem;
-
- te = lb->last;
- if (te == NULL) {
- return;
- }
- tselem = TREESTORE(te);
-
- /* sorting rules; only object lists, ID lists, or deformgroups */
- if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) {
- int totelem = BLI_listbase_count(lb);
-
- if (totelem > 1) {
- tTreeSort *tear = MEM_mallocN(totelem * sizeof(tTreeSort), "tree sort array");
- tTreeSort *tp = tear;
- int skip = 0;
-
- for (te = lb->first; te; te = te->next, tp++) {
- tselem = TREESTORE(te);
- tp->te = te;
- tp->name = te->name;
- tp->idcode = te->idcode;
-
- if (tselem->type && tselem->type != TSE_DEFGROUP) {
- tp->idcode = 0; // don't sort this
- }
- if (tselem->type == TSE_ID_BASE) {
- tp->idcode = 1; // do sort this
- }
-
- tp->id = tselem->id;
- }
-
- /* just sort alphabetically */
- if (tear->idcode == 1) {
- qsort(tear, totelem, sizeof(tTreeSort), treesort_alpha);
- }
- else {
- /* keep beginning of list */
- for (tp = tear, skip = 0; skip < totelem; skip++, tp++) {
- if (tp->idcode) {
- break;
- }
- }
-
- if (skip < totelem) {
- qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha_ob);
- }
- }
-
- BLI_listbase_clear(lb);
- tp = tear;
- while (totelem--) {
- BLI_addtail(lb, tp->te);
- tp++;
- }
- MEM_freeN(tear);
- }
- }
-
- for (te = lb->first; te; te = te->next) {
- outliner_sort(&te->subtree);
- }
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ te = lb->last;
+ if (te == NULL) {
+ return;
+ }
+ tselem = TREESTORE(te);
+
+ /* sorting rules; only object lists, ID lists, or deformgroups */
+ if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) ||
+ (tselem->type == 0 && te->idcode == ID_OB)) {
+ int totelem = BLI_listbase_count(lb);
+
+ if (totelem > 1) {
+ tTreeSort *tear = MEM_mallocN(totelem * sizeof(tTreeSort), "tree sort array");
+ tTreeSort *tp = tear;
+ int skip = 0;
+
+ for (te = lb->first; te; te = te->next, tp++) {
+ tselem = TREESTORE(te);
+ tp->te = te;
+ tp->name = te->name;
+ tp->idcode = te->idcode;
+
+ if (tselem->type && tselem->type != TSE_DEFGROUP) {
+ tp->idcode = 0; // don't sort this
+ }
+ if (tselem->type == TSE_ID_BASE) {
+ tp->idcode = 1; // do sort this
+ }
+
+ tp->id = tselem->id;
+ }
+
+ /* just sort alphabetically */
+ if (tear->idcode == 1) {
+ qsort(tear, totelem, sizeof(tTreeSort), treesort_alpha);
+ }
+ else {
+ /* keep beginning of list */
+ for (tp = tear, skip = 0; skip < totelem; skip++, tp++) {
+ if (tp->idcode) {
+ break;
+ }
+ }
+
+ if (skip < totelem) {
+ qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha_ob);
+ }
+ }
+
+ BLI_listbase_clear(lb);
+ tp = tear;
+ while (totelem--) {
+ BLI_addtail(lb, tp->te);
+ tp++;
+ }
+ MEM_freeN(tear);
+ }
+ }
+
+ for (te = lb->first; te; te = te->next) {
+ outliner_sort(&te->subtree);
+ }
}
/* Filtering ----------------------------------------------- */
typedef struct OutlinerTreeElementFocus {
- TreeStoreElem *tselem;
- int ys;
+ TreeStoreElem *tselem;
+ int ys;
} OutlinerTreeElementFocus;
/**
* Bring the outliner scrolling back to where it was in relation to the original focus element
* Caller is expected to handle redrawing of ARegion.
*/
-static void outliner_restore_scrolling_position(SpaceOutliner *soops, ARegion *ar, OutlinerTreeElementFocus *focus)
+static void outliner_restore_scrolling_position(SpaceOutliner *soops,
+ ARegion *ar,
+ OutlinerTreeElementFocus *focus)
{
- View2D *v2d = &ar->v2d;
- int ytop;
+ View2D *v2d = &ar->v2d;
+ int ytop;
- if (focus->tselem != NULL) {
- outliner_set_coordinates(ar, soops);
+ if (focus->tselem != NULL) {
+ outliner_set_coordinates(ar, soops);
- TreeElement *te_new = outliner_find_tree_element(&soops->tree, focus->tselem);
+ TreeElement *te_new = outliner_find_tree_element(&soops->tree, focus->tselem);
- if (te_new != NULL) {
- int ys_new, ys_old;
+ if (te_new != NULL) {
+ int ys_new, ys_old;
- ys_new = te_new->ys;
- ys_old = focus->ys;
+ ys_new = te_new->ys;
+ ys_old = focus->ys;
- ytop = v2d->cur.ymax + (ys_new - ys_old) -1;
- if (ytop > 0) {
- ytop = 0;
- }
+ ytop = v2d->cur.ymax + (ys_new - ys_old) - 1;
+ if (ytop > 0) {
+ ytop = 0;
+ }
- v2d->cur.ymax = (float)ytop;
- v2d->cur.ymin = (float)(ytop - BLI_rcti_size_y(&v2d->mask));
- }
- else {
- return;
- }
- }
+ v2d->cur.ymax = (float)ytop;
+ v2d->cur.ymin = (float)(ytop - BLI_rcti_size_y(&v2d->mask));
+ }
+ else {
+ return;
+ }
+ }
}
static bool test_collection_callback(TreeElement *te)
{
- return outliner_is_collection_tree_element(te);
+ return outliner_is_collection_tree_element(te);
}
static bool test_object_callback(TreeElement *te)
{
- TreeStoreElem *tselem = TREESTORE(te);
- return ((tselem->type == 0) && (te->idcode == ID_OB));
+ TreeStoreElem *tselem = TREESTORE(te);
+ return ((tselem->type == 0) && (te->idcode == ID_OB));
}
/**
* See if TreeElement or any of its children pass the callback_test.
*/
static TreeElement *outliner_find_first_desired_element_at_y_recursive(
- const SpaceOutliner *soops,
- TreeElement *te,
- const float limit,
- bool (*callback_test)(TreeElement *))
+ const SpaceOutliner *soops,
+ TreeElement *te,
+ const float limit,
+ bool (*callback_test)(TreeElement *))
{
- if (callback_test(te)) {
- return te;
- }
-
- if (TSELEM_OPEN(te->store_elem, soops)) {
- TreeElement *te_iter, *te_sub;
- for (te_iter = te->subtree.first; te_iter; te_iter = te_iter->next) {
- te_sub = outliner_find_first_desired_element_at_y_recursive(soops, te_iter, limit, callback_test);
- if (te_sub != NULL) {
- return te_sub;
- }
- }
- }
-
- return NULL;
+ if (callback_test(te)) {
+ return te;
+ }
+
+ if (TSELEM_OPEN(te->store_elem, soops)) {
+ TreeElement *te_iter, *te_sub;
+ for (te_iter = te->subtree.first; te_iter; te_iter = te_iter->next) {
+ te_sub = outliner_find_first_desired_element_at_y_recursive(
+ soops, te_iter, limit, callback_test);
+ if (te_sub != NULL) {
+ return te_sub;
+ }
+ }
+ }
+
+ return NULL;
}
/**
@@ -1713,55 +1724,53 @@ static TreeElement *outliner_find_first_desired_element_at_y_recursive(
* what we are looking for. If we are past the visible range and we can't find a valid element
* we return NULL.
*/
-static TreeElement *outliner_find_first_desired_element_at_y(
- const SpaceOutliner *soops,
- const float view_co,
- const float view_co_limit)
+static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner *soops,
+ const float view_co,
+ const float view_co_limit)
{
- TreeElement *te, *te_sub;
- te = outliner_find_item_at_y(soops, &soops->tree, view_co);
-
- bool (*callback_test)(TreeElement *);
- if ((soops->outlinevis == SO_VIEW_LAYER) &&
- (soops->filter & SO_FILTER_NO_COLLECTION))
- {
- callback_test = test_object_callback;
- }
- else {
- callback_test = test_collection_callback;
- }
-
- while (te != NULL) {
- te_sub = outliner_find_first_desired_element_at_y_recursive(soops, te, view_co_limit, callback_test);
- if (te_sub != NULL) {
- /* Skip the element if it was not visible to start with. */
- if (te->ys + UI_UNIT_Y > view_co_limit) {
- return te_sub;
- }
- else {
- return NULL;
- }
- }
-
- if (te->next) {
- te = te->next;
- continue;
- }
-
- if (te->parent == NULL) {
- break;
- }
-
- while (te->parent) {
- if (te->parent->next) {
- te = te->parent->next;
- break;
- }
- te = te->parent;
- }
- }
-
- return NULL;
+ TreeElement *te, *te_sub;
+ te = outliner_find_item_at_y(soops, &soops->tree, view_co);
+
+ bool (*callback_test)(TreeElement *);
+ if ((soops->outlinevis == SO_VIEW_LAYER) && (soops->filter & SO_FILTER_NO_COLLECTION)) {
+ callback_test = test_object_callback;
+ }
+ else {
+ callback_test = test_collection_callback;
+ }
+
+ while (te != NULL) {
+ te_sub = outliner_find_first_desired_element_at_y_recursive(
+ soops, te, view_co_limit, callback_test);
+ if (te_sub != NULL) {
+ /* Skip the element if it was not visible to start with. */
+ if (te->ys + UI_UNIT_Y > view_co_limit) {
+ return te_sub;
+ }
+ else {
+ return NULL;
+ }
+ }
+
+ if (te->next) {
+ te = te->next;
+ continue;
+ }
+
+ if (te->parent == NULL) {
+ break;
+ }
+
+ while (te->parent) {
+ if (te->parent->next) {
+ te = te->parent->next;
+ break;
+ }
+ te = te->parent;
+ }
+ }
+
+ return NULL;
}
/**
@@ -1770,240 +1779,244 @@ static TreeElement *outliner_find_first_desired_element_at_y(
* Finds the top-most collection visible in the outliner and populates the OutlinerTreeElementFocus
* struct to retrieve this element later to make sure it is in the same original position as before filtering
*/
-static void outliner_store_scrolling_position(SpaceOutliner *soops, ARegion *ar, OutlinerTreeElementFocus *focus)
+static void outliner_store_scrolling_position(SpaceOutliner *soops,
+ ARegion *ar,
+ OutlinerTreeElementFocus *focus)
{
- TreeElement *te;
- float limit = ar->v2d.cur.ymin;
+ TreeElement *te;
+ float limit = ar->v2d.cur.ymin;
- outliner_set_coordinates(ar, soops);
+ outliner_set_coordinates(ar, soops);
- te = outliner_find_first_desired_element_at_y(soops, ar->v2d.cur.ymax, limit);
+ te = outliner_find_first_desired_element_at_y(soops, ar->v2d.cur.ymax, limit);
- if (te != NULL) {
- focus->tselem = TREESTORE(te);
- focus->ys = te->ys;
- }
- else {
- focus->tselem = NULL;
- }
+ if (te != NULL) {
+ focus->tselem = TREESTORE(te);
+ focus->ys = te->ys;
+ }
+ else {
+ focus->tselem = NULL;
+ }
}
static int outliner_exclude_filter_get(SpaceOutliner *soops)
{
- int exclude_filter = soops->filter & ~SO_FILTER_OB_STATE;
-
- if (soops->search_string[0] != 0) {
- exclude_filter |= SO_FILTER_SEARCH;
- }
- else {
- exclude_filter &= ~SO_FILTER_SEARCH;
- }
-
- /* Let's have this for the collection options at first. */
- if (!SUPPORT_FILTER_OUTLINER(soops)) {
- return (exclude_filter & SO_FILTER_SEARCH);
- }
-
- if (soops->filter & SO_FILTER_NO_OBJECT) {
- exclude_filter |= SO_FILTER_OB_TYPE;
- }
-
- switch (soops->filter_state) {
- case SO_FILTER_OB_VISIBLE:
- exclude_filter |= SO_FILTER_OB_STATE_VISIBLE;
- break;
- case SO_FILTER_OB_SELECTED:
- exclude_filter |= SO_FILTER_OB_STATE_SELECTED;
- break;
- case SO_FILTER_OB_ACTIVE:
- exclude_filter |= SO_FILTER_OB_STATE_ACTIVE;
- break;
- }
-
- return exclude_filter;
+ int exclude_filter = soops->filter & ~SO_FILTER_OB_STATE;
+
+ if (soops->search_string[0] != 0) {
+ exclude_filter |= SO_FILTER_SEARCH;
+ }
+ else {
+ exclude_filter &= ~SO_FILTER_SEARCH;
+ }
+
+ /* Let's have this for the collection options at first. */
+ if (!SUPPORT_FILTER_OUTLINER(soops)) {
+ return (exclude_filter & SO_FILTER_SEARCH);
+ }
+
+ if (soops->filter & SO_FILTER_NO_OBJECT) {
+ exclude_filter |= SO_FILTER_OB_TYPE;
+ }
+
+ switch (soops->filter_state) {
+ case SO_FILTER_OB_VISIBLE:
+ exclude_filter |= SO_FILTER_OB_STATE_VISIBLE;
+ break;
+ case SO_FILTER_OB_SELECTED:
+ exclude_filter |= SO_FILTER_OB_STATE_SELECTED;
+ break;
+ case SO_FILTER_OB_ACTIVE:
+ exclude_filter |= SO_FILTER_OB_STATE_ACTIVE;
+ break;
+ }
+
+ return exclude_filter;
}
-static bool outliner_element_visible_get(ViewLayer *view_layer, TreeElement *te, const int exclude_filter)
+static bool outliner_element_visible_get(ViewLayer *view_layer,
+ TreeElement *te,
+ const int exclude_filter)
{
- if ((exclude_filter & SO_FILTER_ANY) == 0) {
- return true;
- }
-
- TreeStoreElem *tselem = TREESTORE(te);
- if ((tselem->type == 0) && (te->idcode == ID_OB)) {
- if ((exclude_filter & SO_FILTER_OB_TYPE) == SO_FILTER_OB_TYPE) {
- return false;
- }
-
- Object *ob = (Object *)tselem->id;
- Base *base = (Base *)te->directdata;
- BLI_assert((base == NULL) || (base->object == ob));
-
- if (exclude_filter & SO_FILTER_OB_TYPE) {
- switch (ob->type) {
- case OB_MESH:
- if (exclude_filter & SO_FILTER_NO_OB_MESH) {
- return false;
- }
- break;
- case OB_ARMATURE:
- if (exclude_filter & SO_FILTER_NO_OB_ARMATURE) {
- return false;
- }
- break;
- case OB_EMPTY:
- if (exclude_filter & SO_FILTER_NO_OB_EMPTY) {
- return false;
- }
- break;
- case OB_LAMP:
- if (exclude_filter & SO_FILTER_NO_OB_LAMP) {
- return false;
- }
- break;
- case OB_CAMERA:
- if (exclude_filter & SO_FILTER_NO_OB_CAMERA) {
- return false;
- }
- break;
- default:
- if (exclude_filter & SO_FILTER_NO_OB_OTHERS) {
- return false;
- }
- break;
- }
- }
-
- if (exclude_filter & SO_FILTER_OB_STATE) {
- if (base == NULL) {
- base = BKE_view_layer_base_find(view_layer, ob);
-
- if (base == NULL) {
- return false;
- }
- }
-
- if (exclude_filter & SO_FILTER_OB_STATE_VISIBLE) {
- if ((base->flag & BASE_VISIBLE) == 0) {
- return false;
- }
- }
- else if (exclude_filter & SO_FILTER_OB_STATE_SELECTED) {
- if ((base->flag & BASE_SELECTED) == 0) {
- return false;
- }
- }
- else {
- BLI_assert(exclude_filter & SO_FILTER_OB_STATE_ACTIVE);
- if (base != BASACT(view_layer)) {
- return false;
- }
- }
- }
-
- if ((te->parent != NULL) &&
- (TREESTORE(te->parent)->type == 0) && (te->parent->idcode == ID_OB))
- {
- if (exclude_filter & SO_FILTER_NO_CHILDREN) {
- return false;
- }
- }
- }
- else if (te->parent != NULL &&
- TREESTORE(te->parent)->type == 0 && te->parent->idcode == ID_OB)
- {
- if (exclude_filter & SO_FILTER_NO_OB_CONTENT) {
- return false;
- }
- }
-
- return true;
+ if ((exclude_filter & SO_FILTER_ANY) == 0) {
+ return true;
+ }
+
+ TreeStoreElem *tselem = TREESTORE(te);
+ if ((tselem->type == 0) && (te->idcode == ID_OB)) {
+ if ((exclude_filter & SO_FILTER_OB_TYPE) == SO_FILTER_OB_TYPE) {
+ return false;
+ }
+
+ Object *ob = (Object *)tselem->id;
+ Base *base = (Base *)te->directdata;
+ BLI_assert((base == NULL) || (base->object == ob));
+
+ if (exclude_filter & SO_FILTER_OB_TYPE) {
+ switch (ob->type) {
+ case OB_MESH:
+ if (exclude_filter & SO_FILTER_NO_OB_MESH) {
+ return false;
+ }
+ break;
+ case OB_ARMATURE:
+ if (exclude_filter & SO_FILTER_NO_OB_ARMATURE) {
+ return false;
+ }
+ break;
+ case OB_EMPTY:
+ if (exclude_filter & SO_FILTER_NO_OB_EMPTY) {
+ return false;
+ }
+ break;
+ case OB_LAMP:
+ if (exclude_filter & SO_FILTER_NO_OB_LAMP) {
+ return false;
+ }
+ break;
+ case OB_CAMERA:
+ if (exclude_filter & SO_FILTER_NO_OB_CAMERA) {
+ return false;
+ }
+ break;
+ default:
+ if (exclude_filter & SO_FILTER_NO_OB_OTHERS) {
+ return false;
+ }
+ break;
+ }
+ }
+
+ if (exclude_filter & SO_FILTER_OB_STATE) {
+ if (base == NULL) {
+ base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (base == NULL) {
+ return false;
+ }
+ }
+
+ if (exclude_filter & SO_FILTER_OB_STATE_VISIBLE) {
+ if ((base->flag & BASE_VISIBLE) == 0) {
+ return false;
+ }
+ }
+ else if (exclude_filter & SO_FILTER_OB_STATE_SELECTED) {
+ if ((base->flag & BASE_SELECTED) == 0) {
+ return false;
+ }
+ }
+ else {
+ BLI_assert(exclude_filter & SO_FILTER_OB_STATE_ACTIVE);
+ if (base != BASACT(view_layer)) {
+ return false;
+ }
+ }
+ }
+
+ if ((te->parent != NULL) && (TREESTORE(te->parent)->type == 0) &&
+ (te->parent->idcode == ID_OB)) {
+ if (exclude_filter & SO_FILTER_NO_CHILDREN) {
+ return false;
+ }
+ }
+ }
+ else if (te->parent != NULL && TREESTORE(te->parent)->type == 0 && te->parent->idcode == ID_OB) {
+ if (exclude_filter & SO_FILTER_NO_OB_CONTENT) {
+ return false;
+ }
+ }
+
+ return true;
}
static bool outliner_filter_has_name(TreeElement *te, const char *name, int flags)
{
- int fn_flag = 0;
+ int fn_flag = 0;
- if ((flags & SO_FIND_CASE_SENSITIVE) == 0) {
- fn_flag |= FNM_CASEFOLD;
- }
+ if ((flags & SO_FIND_CASE_SENSITIVE) == 0) {
+ fn_flag |= FNM_CASEFOLD;
+ }
- return fnmatch(name, te->name, fn_flag) == 0;
+ return fnmatch(name, te->name, fn_flag) == 0;
}
-static int outliner_filter_subtree(
- SpaceOutliner *soops, ViewLayer *view_layer, ListBase *lb, const char *search_string, const int exclude_filter)
+static int outliner_filter_subtree(SpaceOutliner *soops,
+ ViewLayer *view_layer,
+ ListBase *lb,
+ const char *search_string,
+ const int exclude_filter)
{
- TreeElement *te, *te_next;
- TreeStoreElem *tselem;
-
- for (te = lb->first; te; te = te_next) {
- te_next = te->next;
-
- if ((outliner_element_visible_get(view_layer, te, exclude_filter) == false)) {
- outliner_free_tree_element(te, lb);
- continue;
- }
- else if ((exclude_filter & SO_FILTER_SEARCH) == 0) {
- /* Filter subtree too. */
- outliner_filter_subtree(soops, view_layer, &te->subtree, search_string, exclude_filter);
- continue;
- }
-
- if (!outliner_filter_has_name(te, search_string, soops->search_flags)) {
- /* item isn't something we're looking for, but...
- * - if the subtree is expanded, check if there are any matches that can be easily found
- * so that searching for "cu" in the default scene will still match the Cube
- * - otherwise, we can't see within the subtree and the item doesn't match,
- * so these can be safely ignored (i.e. the subtree can get freed)
- */
- tselem = TREESTORE(te);
-
- /* flag as not a found item */
- tselem->flag &= ~TSE_SEARCHMATCH;
-
- if ((!TSELEM_OPEN(tselem, soops)) ||
- outliner_filter_subtree(soops, view_layer, &te->subtree, search_string, exclude_filter) == 0)
- {
- outliner_free_tree_element(te, lb);
- }
- }
- else {
- tselem = TREESTORE(te);
-
- /* flag as a found item - we can then highlight it */
- tselem->flag |= TSE_SEARCHMATCH;
-
- /* filter subtree too */
- outliner_filter_subtree(soops, view_layer, &te->subtree, search_string, exclude_filter);
- }
- }
-
- /* if there are still items in the list, that means that there were still some matches */
- return (BLI_listbase_is_empty(lb) == false);
+ TreeElement *te, *te_next;
+ TreeStoreElem *tselem;
+
+ for (te = lb->first; te; te = te_next) {
+ te_next = te->next;
+
+ if ((outliner_element_visible_get(view_layer, te, exclude_filter) == false)) {
+ outliner_free_tree_element(te, lb);
+ continue;
+ }
+ else if ((exclude_filter & SO_FILTER_SEARCH) == 0) {
+ /* Filter subtree too. */
+ outliner_filter_subtree(soops, view_layer, &te->subtree, search_string, exclude_filter);
+ continue;
+ }
+
+ if (!outliner_filter_has_name(te, search_string, soops->search_flags)) {
+ /* item isn't something we're looking for, but...
+ * - if the subtree is expanded, check if there are any matches that can be easily found
+ * so that searching for "cu" in the default scene will still match the Cube
+ * - otherwise, we can't see within the subtree and the item doesn't match,
+ * so these can be safely ignored (i.e. the subtree can get freed)
+ */
+ tselem = TREESTORE(te);
+
+ /* flag as not a found item */
+ tselem->flag &= ~TSE_SEARCHMATCH;
+
+ if ((!TSELEM_OPEN(tselem, soops)) ||
+ outliner_filter_subtree(
+ soops, view_layer, &te->subtree, search_string, exclude_filter) == 0) {
+ outliner_free_tree_element(te, lb);
+ }
+ }
+ else {
+ tselem = TREESTORE(te);
+
+ /* flag as a found item - we can then highlight it */
+ tselem->flag |= TSE_SEARCHMATCH;
+
+ /* filter subtree too */
+ outliner_filter_subtree(soops, view_layer, &te->subtree, search_string, exclude_filter);
+ }
+ }
+
+ /* if there are still items in the list, that means that there were still some matches */
+ return (BLI_listbase_is_empty(lb) == false);
}
static void outliner_filter_tree(SpaceOutliner *soops, ViewLayer *view_layer)
{
- char search_buff[sizeof(((struct SpaceOutliner *)NULL)->search_string) + 2];
- char *search_string;
+ char search_buff[sizeof(((struct SpaceOutliner *)NULL)->search_string) + 2];
+ char *search_string;
- const int exclude_filter = outliner_exclude_filter_get(soops);
+ const int exclude_filter = outliner_exclude_filter_get(soops);
- if (exclude_filter == 0) {
- return;
- }
+ if (exclude_filter == 0) {
+ return;
+ }
- if (soops->search_flags & SO_FIND_COMPLETE) {
- search_string = soops->search_string;
- }
- else {
- /* Implicitly add heading/trailing wildcards if needed. */
- BLI_strncpy_ensure_pad(search_buff, soops->search_string, '*', sizeof(search_buff));
- search_string = search_buff;
- }
+ if (soops->search_flags & SO_FIND_COMPLETE) {
+ search_string = soops->search_string;
+ }
+ else {
+ /* Implicitly add heading/trailing wildcards if needed. */
+ BLI_strncpy_ensure_pad(search_buff, soops->search_string, '*', sizeof(search_buff));
+ search_string = search_buff;
+ }
- outliner_filter_subtree(soops, view_layer, &soops->tree, search_string, exclude_filter);
+ outliner_filter_subtree(soops, view_layer, &soops->tree, search_string, exclude_filter);
}
/* ======================================================= */
@@ -2011,172 +2024,173 @@ static void outliner_filter_tree(SpaceOutliner *soops, ViewLayer *view_layer)
/* Main entry point for building the tree data-structure that the outliner represents */
// TODO: split each mode into its own function?
-void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops, ARegion *ar)
+void outliner_build_tree(
+ Main *mainvar, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops, ARegion *ar)
{
- TreeElement *te = NULL, *ten;
- TreeStoreElem *tselem;
- /* on first view, we open scenes */
- int show_opened = !soops->treestore || !BLI_mempool_len(soops->treestore);
-
- /* Are we looking for something - we want to tag parents to filter child matches
- * - NOT in datablocks view - searching all datablocks takes way too long to be useful
- * - this variable is only set once per tree build */
- if (soops->search_string[0] != 0 && soops->outlinevis != SO_DATA_API) {
- soops->search_flags |= SO_SEARCH_RECURSIVE;
- }
- else {
- soops->search_flags &= ~SO_SEARCH_RECURSIVE;
- }
-
- if (soops->treehash && (soops->storeflag & SO_TREESTORE_REBUILD) && soops->treestore) {
- soops->storeflag &= ~SO_TREESTORE_REBUILD;
- BKE_outliner_treehash_rebuild_from_treestore(soops->treehash, soops->treestore);
- }
-
- if (ar->do_draw & RGN_DRAW_NO_REBUILD) {
- return;
- }
-
- OutlinerTreeElementFocus focus;
- outliner_store_scrolling_position(soops, ar, &focus);
-
- outliner_free_tree(&soops->tree);
- outliner_storage_cleanup(soops);
-
- /* options */
- if (soops->outlinevis == SO_LIBRARIES) {
- Library *lib;
-
- /* current file first - mainvar provides tselem with unique pointer - not used */
- ten = outliner_add_library_contents(mainvar, soops, &soops->tree, NULL);
- if (ten) {
- tselem = TREESTORE(ten);
- if (!tselem->used) {
- tselem->flag &= ~TSE_CLOSED;
- }
- }
-
- for (lib = mainvar->libraries.first; lib; lib = lib->id.next) {
- ten = outliner_add_library_contents(mainvar, soops, &soops->tree, lib);
- if (ten) {
- lib->id.newid = (ID *)ten;
- }
-
- }
- /* make hierarchy */
- ten = soops->tree.first;
- if (ten != NULL) {
- ten = ten->next; /* first one is main */
- while (ten) {
- TreeElement *nten = ten->next, *par;
- tselem = TREESTORE(ten);
- lib = (Library *)tselem->id;
- if (lib && lib->parent) {
- par = (TreeElement *)lib->parent->id.newid;
- if (tselem->id->tag & LIB_TAG_INDIRECT) {
- /* Only remove from 'first level' if lib is not also directly used. */
- BLI_remlink(&soops->tree, ten);
- BLI_addtail(&par->subtree, ten);
- ten->parent = par;
- }
- else {
- /* Else, make a new copy of the libtree for our parent. */
- TreeElement *dupten = outliner_add_library_contents(mainvar, soops, &par->subtree, lib);
- if (dupten) {
- dupten->parent = par;
- }
- }
- }
- ten = nten;
- }
- }
- /* restore newid pointers */
- for (lib = mainvar->libraries.first; lib; lib = lib->id.next) {
- lib->id.newid = NULL;
- }
-
- }
- else if (soops->outlinevis == SO_SCENES) {
- Scene *sce;
- for (sce = mainvar->scenes.first; sce; sce = sce->id.next) {
- te = outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0);
- tselem = TREESTORE(te);
-
- if (sce == scene && show_opened) {
- tselem->flag &= ~TSE_CLOSED;
- }
-
- outliner_make_object_parent_hierarchy(&te->subtree);
- }
- }
- else if (soops->outlinevis == SO_SEQUENCE) {
- Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- int op;
-
- if (ed == NULL) {
- return;
- }
-
- seq = ed->seqbasep->first;
- if (!seq) {
- return;
- }
-
- while (seq) {
- op = need_add_seq_dup(seq);
- if (op == 1) {
- /* ten = */ outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE, 0);
- }
- else if (op == 0) {
- ten = outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0);
- outliner_add_seq_dup(soops, seq, ten, 0);
- }
- seq = seq->next;
- }
- }
- else if (soops->outlinevis == SO_DATA_API) {
- PointerRNA mainptr;
-
- RNA_main_pointer_create(mainvar, &mainptr);
-
- ten = outliner_add_element(soops, &soops->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1);
-
- if (show_opened) {
- tselem = TREESTORE(ten);
- tselem->flag &= ~TSE_CLOSED;
- }
- }
- else if (soops->outlinevis == SO_ID_ORPHANS) {
- outliner_add_orphaned_datablocks(mainvar, soops);
- }
- else if (soops->outlinevis == SO_VIEW_LAYER) {
- if (soops->filter & SO_FILTER_NO_COLLECTION) {
- /* Show objects in the view layer. */
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- TreeElement *te_object = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
- te_object->directdata = base;
- }
-
- outliner_make_object_parent_hierarchy(&soops->tree);
- }
- else {
- /* Show collections in the view layer. */
- ten = outliner_add_element(soops, &soops->tree, scene, NULL, TSE_VIEW_COLLECTION_BASE, 0);
- ten->name = IFACE_("Scene Collection");
- TREESTORE(ten)->flag &= ~TSE_CLOSED;
-
- bool show_objects = !(soops->filter & SO_FILTER_NO_OBJECT);
- outliner_add_view_layer(soops, &ten->subtree, ten, view_layer, show_objects);
- }
- }
-
- if ((soops->flag & SO_SKIP_SORT_ALPHA) == 0) {
- outliner_sort(&soops->tree);
- }
-
- outliner_filter_tree(soops, view_layer);
- outliner_restore_scrolling_position(soops, ar, &focus);
-
- BKE_main_id_clear_newpoins(mainvar);
+ TreeElement *te = NULL, *ten;
+ TreeStoreElem *tselem;
+ /* on first view, we open scenes */
+ int show_opened = !soops->treestore || !BLI_mempool_len(soops->treestore);
+
+ /* Are we looking for something - we want to tag parents to filter child matches
+ * - NOT in datablocks view - searching all datablocks takes way too long to be useful
+ * - this variable is only set once per tree build */
+ if (soops->search_string[0] != 0 && soops->outlinevis != SO_DATA_API) {
+ soops->search_flags |= SO_SEARCH_RECURSIVE;
+ }
+ else {
+ soops->search_flags &= ~SO_SEARCH_RECURSIVE;
+ }
+
+ if (soops->treehash && (soops->storeflag & SO_TREESTORE_REBUILD) && soops->treestore) {
+ soops->storeflag &= ~SO_TREESTORE_REBUILD;
+ BKE_outliner_treehash_rebuild_from_treestore(soops->treehash, soops->treestore);
+ }
+
+ if (ar->do_draw & RGN_DRAW_NO_REBUILD) {
+ return;
+ }
+
+ OutlinerTreeElementFocus focus;
+ outliner_store_scrolling_position(soops, ar, &focus);
+
+ outliner_free_tree(&soops->tree);
+ outliner_storage_cleanup(soops);
+
+ /* options */
+ if (soops->outlinevis == SO_LIBRARIES) {
+ Library *lib;
+
+ /* current file first - mainvar provides tselem with unique pointer - not used */
+ ten = outliner_add_library_contents(mainvar, soops, &soops->tree, NULL);
+ if (ten) {
+ tselem = TREESTORE(ten);
+ if (!tselem->used) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ }
+
+ for (lib = mainvar->libraries.first; lib; lib = lib->id.next) {
+ ten = outliner_add_library_contents(mainvar, soops, &soops->tree, lib);
+ if (ten) {
+ lib->id.newid = (ID *)ten;
+ }
+ }
+ /* make hierarchy */
+ ten = soops->tree.first;
+ if (ten != NULL) {
+ ten = ten->next; /* first one is main */
+ while (ten) {
+ TreeElement *nten = ten->next, *par;
+ tselem = TREESTORE(ten);
+ lib = (Library *)tselem->id;
+ if (lib && lib->parent) {
+ par = (TreeElement *)lib->parent->id.newid;
+ if (tselem->id->tag & LIB_TAG_INDIRECT) {
+ /* Only remove from 'first level' if lib is not also directly used. */
+ BLI_remlink(&soops->tree, ten);
+ BLI_addtail(&par->subtree, ten);
+ ten->parent = par;
+ }
+ else {
+ /* Else, make a new copy of the libtree for our parent. */
+ TreeElement *dupten = outliner_add_library_contents(
+ mainvar, soops, &par->subtree, lib);
+ if (dupten) {
+ dupten->parent = par;
+ }
+ }
+ }
+ ten = nten;
+ }
+ }
+ /* restore newid pointers */
+ for (lib = mainvar->libraries.first; lib; lib = lib->id.next) {
+ lib->id.newid = NULL;
+ }
+ }
+ else if (soops->outlinevis == SO_SCENES) {
+ Scene *sce;
+ for (sce = mainvar->scenes.first; sce; sce = sce->id.next) {
+ te = outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0);
+ tselem = TREESTORE(te);
+
+ if (sce == scene && show_opened) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+
+ outliner_make_object_parent_hierarchy(&te->subtree);
+ }
+ }
+ else if (soops->outlinevis == SO_SEQUENCE) {
+ Sequence *seq;
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ int op;
+
+ if (ed == NULL) {
+ return;
+ }
+
+ seq = ed->seqbasep->first;
+ if (!seq) {
+ return;
+ }
+
+ while (seq) {
+ op = need_add_seq_dup(seq);
+ if (op == 1) {
+ /* ten = */ outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE, 0);
+ }
+ else if (op == 0) {
+ ten = outliner_add_element(soops, &soops->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0);
+ outliner_add_seq_dup(soops, seq, ten, 0);
+ }
+ seq = seq->next;
+ }
+ }
+ else if (soops->outlinevis == SO_DATA_API) {
+ PointerRNA mainptr;
+
+ RNA_main_pointer_create(mainvar, &mainptr);
+
+ ten = outliner_add_element(soops, &soops->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1);
+
+ if (show_opened) {
+ tselem = TREESTORE(ten);
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ }
+ else if (soops->outlinevis == SO_ID_ORPHANS) {
+ outliner_add_orphaned_datablocks(mainvar, soops);
+ }
+ else if (soops->outlinevis == SO_VIEW_LAYER) {
+ if (soops->filter & SO_FILTER_NO_COLLECTION) {
+ /* Show objects in the view layer. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ TreeElement *te_object = outliner_add_element(
+ soops, &soops->tree, base->object, NULL, 0, 0);
+ te_object->directdata = base;
+ }
+
+ outliner_make_object_parent_hierarchy(&soops->tree);
+ }
+ else {
+ /* Show collections in the view layer. */
+ ten = outliner_add_element(soops, &soops->tree, scene, NULL, TSE_VIEW_COLLECTION_BASE, 0);
+ ten->name = IFACE_("Scene Collection");
+ TREESTORE(ten)->flag &= ~TSE_CLOSED;
+
+ bool show_objects = !(soops->filter & SO_FILTER_NO_OBJECT);
+ outliner_add_view_layer(soops, &ten->subtree, ten, view_layer, show_objects);
+ }
+ }
+
+ if ((soops->flag & SO_SKIP_SORT_ALPHA) == 0) {
+ outliner_sort(&soops->tree);
+ }
+
+ outliner_filter_tree(soops, view_layer);
+ outliner_restore_scrolling_position(soops, ar, &focus);
+
+ BKE_main_id_clear_newpoins(mainvar);
}
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index a44a6e605de..03d15088380 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -38,25 +38,27 @@
* Try to find an item under y-coordinate \a view_co_y (view-space).
* \note Recursive
*/
-TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops, const ListBase *tree, float view_co_y)
+TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops,
+ const ListBase *tree,
+ float view_co_y)
{
- for (TreeElement *te_iter = tree->first; te_iter; te_iter = te_iter->next) {
- if (view_co_y < (te_iter->ys + UI_UNIT_Y)) {
- if (view_co_y >= te_iter->ys) {
- /* co_y is inside this element */
- return te_iter;
- }
- else if (TSELEM_OPEN(te_iter->store_elem, soops)) {
- /* co_y is lower than current element, possibly inside children */
- TreeElement *te_sub = outliner_find_item_at_y(soops, &te_iter->subtree, view_co_y);
- if (te_sub) {
- return te_sub;
- }
- }
- }
- }
-
- return NULL;
+ for (TreeElement *te_iter = tree->first; te_iter; te_iter = te_iter->next) {
+ if (view_co_y < (te_iter->ys + UI_UNIT_Y)) {
+ if (view_co_y >= te_iter->ys) {
+ /* co_y is inside this element */
+ return te_iter;
+ }
+ else if (TSELEM_OPEN(te_iter->store_elem, soops)) {
+ /* co_y is lower than current element, possibly inside children */
+ TreeElement *te_sub = outliner_find_item_at_y(soops, &te_iter->subtree, view_co_y);
+ if (te_sub) {
+ return te_sub;
+ }
+ }
+ }
+ }
+
+ return NULL;
}
/**
@@ -65,146 +67,150 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops, const ListBase
*
* \return a hovered child item or \a parent_te (if no hovered child found).
*/
-TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops, const TreeElement *parent_te, float view_co_x)
+TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops,
+ const TreeElement *parent_te,
+ float view_co_x)
{
- /* if parent_te is opened, it doesn't show childs in row */
- if (!TSELEM_OPEN(TREESTORE(parent_te), soops)) {
- /* no recursion, items can only display their direct children in the row */
- for (TreeElement *child_te = parent_te->subtree.first;
- /* don't look further if co_x is smaller than child position*/
- child_te && view_co_x >= child_te->xs;
-
- child_te = child_te->next)
- {
- if ((child_te->flag & TE_ICONROW) && (view_co_x > child_te->xs) && (view_co_x < child_te->xend)) {
- return child_te;
- }
- }
- }
-
- /* return parent if no child is hovered */
- return (TreeElement *)parent_te;
+ /* if parent_te is opened, it doesn't show childs in row */
+ if (!TSELEM_OPEN(TREESTORE(parent_te), soops)) {
+ /* no recursion, items can only display their direct children in the row */
+ for (TreeElement *child_te = parent_te->subtree.first;
+ /* don't look further if co_x is smaller than child position*/
+ child_te && view_co_x >= child_te->xs;
+
+ child_te = child_te->next) {
+ if ((child_te->flag & TE_ICONROW) && (view_co_x > child_te->xs) &&
+ (view_co_x < child_te->xend)) {
+ return child_te;
+ }
+ }
+ }
+
+ /* return parent if no child is hovered */
+ return (TreeElement *)parent_te;
}
/* Find specific item from the treestore */
TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem)
{
- TreeElement *te, *tes;
- for (te = lb->first; te; te = te->next) {
- if (te->store_elem == store_elem) {
- return te;
- }
- tes = outliner_find_tree_element(&te->subtree, store_elem);
- if (tes) {
- return tes;
- }
- }
- return NULL;
+ TreeElement *te, *tes;
+ for (te = lb->first; te; te = te->next) {
+ if (te->store_elem == store_elem) {
+ return te;
+ }
+ tes = outliner_find_tree_element(&te->subtree, store_elem);
+ if (tes) {
+ return tes;
+ }
+ }
+ return NULL;
}
/* Find parent element of te */
-TreeElement *outliner_find_parent_element(ListBase *lb, TreeElement *parent_te, const TreeElement *child_te)
+TreeElement *outliner_find_parent_element(ListBase *lb,
+ TreeElement *parent_te,
+ const TreeElement *child_te)
{
- TreeElement *te;
- for (te = lb->first; te; te = te->next) {
- if (te == child_te) {
- return parent_te;
- }
-
- TreeElement *find_te = outliner_find_parent_element(&te->subtree, te, child_te);
- if (find_te) {
- return find_te;
- }
- }
- return NULL;
+ TreeElement *te;
+ for (te = lb->first; te; te = te->next) {
+ if (te == child_te) {
+ return parent_te;
+ }
+
+ TreeElement *find_te = outliner_find_parent_element(&te->subtree, te, child_te);
+ if (find_te) {
+ return find_te;
+ }
+ }
+ return NULL;
}
/* tse is not in the treestore, we use its contents to find a match */
TreeElement *outliner_find_tse(SpaceOutliner *soops, const TreeStoreElem *tse)
{
- TreeStoreElem *tselem;
+ TreeStoreElem *tselem;
- if (tse->id == NULL) {
- return NULL;
- }
+ if (tse->id == NULL) {
+ return NULL;
+ }
- /* check if 'tse' is in treestore */
- tselem = BKE_outliner_treehash_lookup_any(soops->treehash, tse->type, tse->nr, tse->id);
- if (tselem) {
- return outliner_find_tree_element(&soops->tree, tselem);
- }
+ /* check if 'tse' is in treestore */
+ tselem = BKE_outliner_treehash_lookup_any(soops->treehash, tse->type, tse->nr, tse->id);
+ if (tselem) {
+ return outliner_find_tree_element(&soops->tree, tselem);
+ }
- return NULL;
+ return NULL;
}
/* Find treestore that refers to given ID */
TreeElement *outliner_find_id(SpaceOutliner *soops, ListBase *lb, const ID *id)
{
- for (TreeElement *te = lb->first; te; te = te->next) {
- TreeStoreElem *tselem = TREESTORE(te);
- if (tselem->type == 0) {
- if (tselem->id == id) {
- return te;
- }
- }
-
- TreeElement *tes = outliner_find_id(soops, &te->subtree, id);
- if (tes) {
- return tes;
- }
- }
- return NULL;
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (tselem->type == 0) {
+ if (tselem->id == id) {
+ return te;
+ }
+ }
+
+ TreeElement *tes = outliner_find_id(soops, &te->subtree, id);
+ if (tes) {
+ return tes;
+ }
+ }
+ return NULL;
}
TreeElement *outliner_find_posechannel(ListBase *lb, const bPoseChannel *pchan)
{
- for (TreeElement *te = lb->first; te; te = te->next) {
- if (te->directdata == pchan) {
- return te;
- }
-
- TreeStoreElem *tselem = TREESTORE(te);
- if (ELEM(tselem->type, TSE_POSE_BASE, TSE_POSE_CHANNEL)) {
- TreeElement *tes = outliner_find_posechannel(&te->subtree, pchan);
- if (tes) {
- return tes;
- }
- }
- }
- return NULL;
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ if (te->directdata == pchan) {
+ return te;
+ }
+
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (ELEM(tselem->type, TSE_POSE_BASE, TSE_POSE_CHANNEL)) {
+ TreeElement *tes = outliner_find_posechannel(&te->subtree, pchan);
+ if (tes) {
+ return tes;
+ }
+ }
+ }
+ return NULL;
}
TreeElement *outliner_find_editbone(ListBase *lb, const EditBone *ebone)
{
- for (TreeElement *te = lb->first; te; te = te->next) {
- if (te->directdata == ebone) {
- return te;
- }
-
- TreeStoreElem *tselem = TREESTORE(te);
- if (ELEM(tselem->type, 0, TSE_EBONE)) {
- TreeElement *tes = outliner_find_editbone(&te->subtree, ebone);
- if (tes) {
- return tes;
- }
- }
- }
- return NULL;
+ for (TreeElement *te = lb->first; te; te = te->next) {
+ if (te->directdata == ebone) {
+ return te;
+ }
+
+ TreeStoreElem *tselem = TREESTORE(te);
+ if (ELEM(tselem->type, 0, TSE_EBONE)) {
+ TreeElement *tes = outliner_find_editbone(&te->subtree, ebone);
+ if (tes) {
+ return tes;
+ }
+ }
+ }
+ return NULL;
}
ID *outliner_search_back(SpaceOutliner *UNUSED(soops), TreeElement *te, short idcode)
{
- TreeStoreElem *tselem;
- te = te->parent;
-
- while (te) {
- tselem = TREESTORE(te);
- if (tselem->type == 0 && te->idcode == idcode) {
- return tselem->id;
- }
- te = te->parent;
- }
- return NULL;
+ TreeStoreElem *tselem;
+ te = te->parent;
+
+ while (te) {
+ tselem = TREESTORE(te);
+ if (tselem->type == 0 && te->idcode == idcode) {
+ return tselem->id;
+ }
+ te = te->parent;
+ }
+ return NULL;
}
/**
@@ -215,38 +221,43 @@ ID *outliner_search_back(SpaceOutliner *UNUSED(soops), TreeElement *te, short id
* \param filter_tselem_flag: Same as \a filter_te_flag, but for the TreeStoreElem.
* \param func: Custom callback to execute for each visited item.
*/
-bool outliner_tree_traverse(const SpaceOutliner *soops, ListBase *tree, int filter_te_flag, int filter_tselem_flag,
- TreeTraversalFunc func, void *customdata)
+bool outliner_tree_traverse(const SpaceOutliner *soops,
+ ListBase *tree,
+ int filter_te_flag,
+ int filter_tselem_flag,
+ TreeTraversalFunc func,
+ void *customdata)
{
- for (TreeElement *te = tree->first, *te_next; te; te = te_next) {
- TreeTraversalAction func_retval = TRAVERSE_CONTINUE;
- /* in case te is freed in callback */
- TreeStoreElem *tselem = TREESTORE(te);
- ListBase subtree = te->subtree;
- te_next = te->next;
-
- if (filter_te_flag && (te->flag & filter_te_flag) == 0) {
- /* skip */
- }
- else if (filter_tselem_flag && (tselem->flag & filter_tselem_flag) == 0) {
- /* skip */
- }
- else {
- func_retval = func(te, customdata);
- }
- /* Don't access te or tselem from now on! Might've been freed... */
-
- if (func_retval == TRAVERSE_BREAK) {
- return false;
- }
-
- if (func_retval == TRAVERSE_SKIP_CHILDS) {
- /* skip */
- }
- else if (!outliner_tree_traverse(soops, &subtree, filter_te_flag, filter_tselem_flag, func, customdata)) {
- return false;
- }
- }
-
- return true;
+ for (TreeElement *te = tree->first, *te_next; te; te = te_next) {
+ TreeTraversalAction func_retval = TRAVERSE_CONTINUE;
+ /* in case te is freed in callback */
+ TreeStoreElem *tselem = TREESTORE(te);
+ ListBase subtree = te->subtree;
+ te_next = te->next;
+
+ if (filter_te_flag && (te->flag & filter_te_flag) == 0) {
+ /* skip */
+ }
+ else if (filter_tselem_flag && (tselem->flag & filter_tselem_flag) == 0) {
+ /* skip */
+ }
+ else {
+ func_retval = func(te, customdata);
+ }
+ /* Don't access te or tselem from now on! Might've been freed... */
+
+ if (func_retval == TRAVERSE_BREAK) {
+ return false;
+ }
+
+ if (func_retval == TRAVERSE_SKIP_CHILDS) {
+ /* skip */
+ }
+ else if (!outliner_tree_traverse(
+ soops, &subtree, filter_te_flag, filter_tselem_flag, func, customdata)) {
+ return false;
+ }
+ }
+
+ return true;
}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index dc51d501b99..26b97a1cdd9 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -21,7 +21,6 @@
* \ingroup spoutliner
*/
-
#include <string.h>
#include <stdio.h>
@@ -52,380 +51,381 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-
#include "outliner_intern.h"
#include "GPU_framebuffer.h"
static void outliner_main_region_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *lb;
- wmKeyMap *keymap;
-
- /* make sure we keep the hide flags */
- ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
- ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP); /* prevent any noise of past */
- ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
-
- ar->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- ar->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
- ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
-
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
- /* own keymap */
- keymap = WM_keymap_ensure(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0);
- /* don't pass on view2d mask, it's always set with scrollbar space, hide fails */
- WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, &ar->winrct);
-
- /* Add dropboxes */
- lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
- WM_event_add_dropbox_handler(&ar->handlers, lb);
+ ListBase *lb;
+ wmKeyMap *keymap;
+
+ /* make sure we keep the hide flags */
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP); /* prevent any noise of past */
+ ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
+ ar->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ ar->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
+ ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
+
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
+
+ /* own keymap */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0);
+ /* don't pass on view2d mask, it's always set with scrollbar space, hide fails */
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, &ar->winrct);
+
+ /* Add dropboxes */
+ lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW);
+ WM_event_add_dropbox_handler(&ar->handlers, lb);
}
static void outliner_main_region_draw(const bContext *C, ARegion *ar)
{
- View2D *v2d = &ar->v2d;
- View2DScrollers *scrollers;
+ View2D *v2d = &ar->v2d;
+ View2DScrollers *scrollers;
- /* clear */
- UI_ThemeClearColor(TH_BACK);
- GPU_clear(GPU_COLOR_BIT);
+ /* clear */
+ UI_ThemeClearColor(TH_BACK);
+ GPU_clear(GPU_COLOR_BIT);
- draw_outliner(C);
+ draw_outliner(C);
- /* reset view matrix */
- UI_view2d_view_restore(C);
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
- /* scrollers */
- scrollers = UI_view2d_scrollers_calc(C, v2d, NULL, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
- UI_view2d_scrollers_draw(C, v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ /* scrollers */
+ scrollers = UI_view2d_scrollers_calc(
+ C, v2d, NULL, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+ UI_view2d_scrollers_draw(C, v2d, scrollers);
+ UI_view2d_scrollers_free(scrollers);
}
-
static void outliner_main_region_free(ARegion *UNUSED(ar))
{
-
}
-static void outliner_main_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void outliner_main_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_SCENE:
- switch (wmn->data) {
- case ND_OB_ACTIVE:
- case ND_OB_SELECT:
- case ND_OB_VISIBLE:
- case ND_OB_RENDER:
- case ND_MODE:
- case ND_KEYINGSET:
- case ND_FRAME:
- case ND_RENDER_OPTIONS:
- case ND_SEQUENCER:
- case ND_LAYER:
- case ND_LAYER_CONTENT:
- case ND_WORLD:
- case ND_SCENEBROWSE:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_TRANSFORM:
- /* transform doesn't change outliner data */
- break;
- case ND_BONE_ACTIVE:
- case ND_BONE_SELECT:
- case ND_DRAW:
- case ND_PARENT:
- case ND_OB_SHADING:
- ED_region_tag_redraw(ar);
- break;
- case ND_CONSTRAINT:
- switch (wmn->action) {
- case NA_ADDED:
- case NA_REMOVED:
- case NA_RENAME:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case ND_MODIFIER:
- /* all modifier actions now */
- ED_region_tag_redraw(ar);
- break;
- default:
- /* Trigger update for NC_OBJECT itself */
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_GROUP:
- /* all actions now, todo: check outliner view mode? */
- ED_region_tag_redraw(ar);
- break;
- case NC_LAMP:
- /* For updating light icons, when changing light type */
- if (wmn->data == ND_LIGHTING_DRAW) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_SPACE:
- if (wmn->data == ND_SPACE_OUTLINER) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_ID:
- if (wmn->action == NA_RENAME) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_MATERIAL:
- switch (wmn->data) {
- case ND_SHADING_LINKS:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_GEOM:
- switch (wmn->data) {
- case ND_VERTEX_GROUP:
- case ND_DATA:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_ANIMATION:
- switch (wmn->data) {
- case ND_NLA_ACTCHANGE:
- case ND_KEYFRAME:
- ED_region_tag_redraw(ar);
- break;
- case ND_ANIMCHAN:
- if (wmn->action == NA_SELECTED) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
- break;
- case NC_GPENCIL:
- if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_SCREEN:
- if (ELEM(wmn->data, ND_LAYER)) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_MASK:
- if (ELEM(wmn->action, NA_ADDED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_PAINTCURVE:
- if (ELEM(wmn->action, NA_ADDED)) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
-
+ /* context changes */
+ switch (wmn->category) {
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_OB_ACTIVE:
+ case ND_OB_SELECT:
+ case ND_OB_VISIBLE:
+ case ND_OB_RENDER:
+ case ND_MODE:
+ case ND_KEYINGSET:
+ case ND_FRAME:
+ case ND_RENDER_OPTIONS:
+ case ND_SEQUENCER:
+ case ND_LAYER:
+ case ND_LAYER_CONTENT:
+ case ND_WORLD:
+ case ND_SCENEBROWSE:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_TRANSFORM:
+ /* transform doesn't change outliner data */
+ break;
+ case ND_BONE_ACTIVE:
+ case ND_BONE_SELECT:
+ case ND_DRAW:
+ case ND_PARENT:
+ case ND_OB_SHADING:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_CONSTRAINT:
+ switch (wmn->action) {
+ case NA_ADDED:
+ case NA_REMOVED:
+ case NA_RENAME:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case ND_MODIFIER:
+ /* all modifier actions now */
+ ED_region_tag_redraw(ar);
+ break;
+ default:
+ /* Trigger update for NC_OBJECT itself */
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_GROUP:
+ /* all actions now, todo: check outliner view mode? */
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_LAMP:
+ /* For updating light icons, when changing light type */
+ if (wmn->data == ND_LIGHTING_DRAW) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_SPACE:
+ if (wmn->data == ND_SPACE_OUTLINER) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_ID:
+ if (wmn->action == NA_RENAME) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_MATERIAL:
+ switch (wmn->data) {
+ case ND_SHADING_LINKS:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_GEOM:
+ switch (wmn->data) {
+ case ND_VERTEX_GROUP:
+ case ND_DATA:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_ANIMATION:
+ switch (wmn->data) {
+ case ND_NLA_ACTCHANGE:
+ case ND_KEYFRAME:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_ANIMCHAN:
+ if (wmn->action == NA_SELECTED) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
+ break;
+ case NC_GPENCIL:
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_SCREEN:
+ if (ELEM(wmn->data, ND_LAYER)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_MASK:
+ if (ELEM(wmn->action, NA_ADDED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_PAINTCURVE:
+ if (ELEM(wmn->action, NA_ADDED)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
}
-static void outliner_main_region_message_subscribe(
- const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
- struct bScreen *UNUSED(screen), struct ScrArea *sa, struct ARegion *ar,
- struct wmMsgBus *mbus)
+static void outliner_main_region_message_subscribe(const struct bContext *UNUSED(C),
+ struct WorkSpace *UNUSED(workspace),
+ struct Scene *UNUSED(scene),
+ struct bScreen *UNUSED(screen),
+ struct ScrArea *sa,
+ struct ARegion *ar,
+ struct wmMsgBus *mbus)
{
- SpaceOutliner *soops = sa->spacedata.first;
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = ar,
- .user_data = ar,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
-
- if (ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_SCENES)) {
- WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
- }
+ SpaceOutliner *soops = sa->spacedata.first;
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ if (ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_SCENES)) {
+ WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
+ }
}
-
/* ************************ header outliner area region *********************** */
/* add handlers, stuff you only do once or on area/region changes */
static void outliner_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
{
- ED_region_header_init(ar);
+ ED_region_header_init(ar);
}
static void outliner_header_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_header(C, ar);
+ ED_region_header(C, ar);
}
static void outliner_header_region_free(ARegion *UNUSED(ar))
{
}
-static void outliner_header_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void outliner_header_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_SCENE:
- if (wmn->data == ND_KEYINGSET) {
- ED_region_tag_redraw(ar);
- }
- break;
- case NC_SPACE:
- if (wmn->data == ND_SPACE_OUTLINER) {
- ED_region_tag_redraw(ar);
- }
- break;
- }
+ /* context changes */
+ switch (wmn->category) {
+ case NC_SCENE:
+ if (wmn->data == ND_KEYINGSET) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ case NC_SPACE:
+ if (wmn->data == ND_SPACE_OUTLINER) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
}
/* ******************** default callbacks for outliner space ***************** */
static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
- ARegion *ar;
- SpaceOutliner *soutliner;
+ ARegion *ar;
+ SpaceOutliner *soutliner;
- soutliner = MEM_callocN(sizeof(SpaceOutliner), "initoutliner");
- soutliner->spacetype = SPACE_OUTLINER;
- soutliner->filter_id_type = ID_GR;
+ soutliner = MEM_callocN(sizeof(SpaceOutliner), "initoutliner");
+ soutliner->spacetype = SPACE_OUTLINER;
+ soutliner->filter_id_type = ID_GR;
- /* header */
- ar = MEM_callocN(sizeof(ARegion), "header for outliner");
+ /* header */
+ ar = MEM_callocN(sizeof(ARegion), "header for outliner");
- BLI_addtail(&soutliner->regionbase, ar);
- ar->regiontype = RGN_TYPE_HEADER;
- ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
+ BLI_addtail(&soutliner->regionbase, ar);
+ ar->regiontype = RGN_TYPE_HEADER;
+ ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
- /* main region */
- ar = MEM_callocN(sizeof(ARegion), "main region for outliner");
+ /* main region */
+ ar = MEM_callocN(sizeof(ARegion), "main region for outliner");
- BLI_addtail(&soutliner->regionbase, ar);
- ar->regiontype = RGN_TYPE_WINDOW;
+ BLI_addtail(&soutliner->regionbase, ar);
+ ar->regiontype = RGN_TYPE_WINDOW;
- return (SpaceLink *)soutliner;
+ return (SpaceLink *)soutliner;
}
/* not spacelink itself */
static void outliner_free(SpaceLink *sl)
{
- SpaceOutliner *soutliner = (SpaceOutliner *)sl;
-
- outliner_free_tree(&soutliner->tree);
- if (soutliner->treestore) {
- BLI_mempool_destroy(soutliner->treestore);
- }
- if (soutliner->treehash) {
- BKE_outliner_treehash_free(soutliner->treehash);
- }
+ SpaceOutliner *soutliner = (SpaceOutliner *)sl;
+
+ outliner_free_tree(&soutliner->tree);
+ if (soutliner->treestore) {
+ BLI_mempool_destroy(soutliner->treestore);
+ }
+ if (soutliner->treehash) {
+ BKE_outliner_treehash_free(soutliner->treehash);
+ }
}
/* spacetype; init callback */
static void outliner_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
{
-
}
static SpaceLink *outliner_duplicate(SpaceLink *sl)
{
- SpaceOutliner *soutliner = (SpaceOutliner *)sl;
- SpaceOutliner *soutlinern = MEM_dupallocN(soutliner);
+ SpaceOutliner *soutliner = (SpaceOutliner *)sl;
+ SpaceOutliner *soutlinern = MEM_dupallocN(soutliner);
- BLI_listbase_clear(&soutlinern->tree);
- soutlinern->treestore = NULL;
- soutlinern->treehash = NULL;
+ BLI_listbase_clear(&soutlinern->tree);
+ soutlinern->treestore = NULL;
+ soutlinern->treehash = NULL;
- return (SpaceLink *)soutlinern;
+ return (SpaceLink *)soutlinern;
}
static void outliner_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
{
- SpaceOutliner *so = (SpaceOutliner *)slink;
-
- /* Some early out checks. */
- if (!TREESTORE_ID_TYPE(old_id)) {
- return; /* ID type is not used by outilner... */
- }
-
- if (so->search_tse.id == old_id) {
- so->search_tse.id = new_id;
- }
-
- if (so->treestore) {
- TreeStoreElem *tselem;
- BLI_mempool_iter iter;
- bool changed = false;
-
- BLI_mempool_iternew(so->treestore, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- if (tselem->id == old_id) {
- tselem->id = new_id;
- changed = true;
- }
- }
- if (so->treehash && changed) {
- /* rebuild hash table, because it depends on ids too */
- /* postpone a full rebuild because this can be called many times on-free */
- so->storeflag |= SO_TREESTORE_REBUILD;
- }
- }
+ SpaceOutliner *so = (SpaceOutliner *)slink;
+
+ /* Some early out checks. */
+ if (!TREESTORE_ID_TYPE(old_id)) {
+ return; /* ID type is not used by outilner... */
+ }
+
+ if (so->search_tse.id == old_id) {
+ so->search_tse.id = new_id;
+ }
+
+ if (so->treestore) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+ bool changed = false;
+
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ if (tselem->id == old_id) {
+ tselem->id = new_id;
+ changed = true;
+ }
+ }
+ if (so->treehash && changed) {
+ /* rebuild hash table, because it depends on ids too */
+ /* postpone a full rebuild because this can be called many times on-free */
+ so->storeflag |= SO_TREESTORE_REBUILD;
+ }
+ }
}
/* only called once, from space_api/spacetypes.c */
void ED_spacetype_outliner(void)
{
- SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype time");
- ARegionType *art;
-
- st->spaceid = SPACE_OUTLINER;
- strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
-
- st->new = outliner_new;
- st->free = outliner_free;
- st->init = outliner_init;
- st->duplicate = outliner_duplicate;
- st->operatortypes = outliner_operatortypes;
- st->keymap = outliner_keymap;
- st->dropboxes = outliner_dropboxes;
- st->id_remap = outliner_id_remap;
-
- /* regions: main window */
- art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region");
- art->regionid = RGN_TYPE_WINDOW;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
-
- art->init = outliner_main_region_init;
- art->draw = outliner_main_region_draw;
- art->free = outliner_main_region_free;
- art->listener = outliner_main_region_listener;
- art->message_subscribe = outliner_main_region_message_subscribe;
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: header */
- art = MEM_callocN(sizeof(ARegionType), "spacetype outliner header region");
- art->regionid = RGN_TYPE_HEADER;
- art->prefsizey = HEADERY;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
-
- art->init = outliner_header_region_init;
- art->draw = outliner_header_region_draw;
- art->free = outliner_header_region_free;
- art->listener = outliner_header_region_listener;
- BLI_addhead(&st->regiontypes, art);
-
- BKE_spacetype_register(st);
+ SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype time");
+ ARegionType *art;
+
+ st->spaceid = SPACE_OUTLINER;
+ strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
+
+ st->new = outliner_new;
+ st->free = outliner_free;
+ st->init = outliner_init;
+ st->duplicate = outliner_duplicate;
+ st->operatortypes = outliner_operatortypes;
+ st->keymap = outliner_keymap;
+ st->dropboxes = outliner_dropboxes;
+ st->id_remap = outliner_id_remap;
+
+ /* regions: main window */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region");
+ art->regionid = RGN_TYPE_WINDOW;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
+
+ art->init = outliner_main_region_init;
+ art->draw = outliner_main_region_draw;
+ art->free = outliner_main_region_free;
+ art->listener = outliner_main_region_listener;
+ art->message_subscribe = outliner_main_region_message_subscribe;
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: header */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype outliner header region");
+ art->regionid = RGN_TYPE_HEADER;
+ art->prefsizey = HEADERY;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
+
+ art->init = outliner_header_region_init;
+ art->draw = outliner_header_region_draw;
+ art->free = outliner_header_region_free;
+ art->listener = outliner_header_region_listener;
+ BLI_addhead(&st->regiontypes, art);
+
+ BKE_spacetype_register(st);
}