diff options
33 files changed, 1143 insertions, 432 deletions
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index d64dfbfdfdf..f0f6776805d 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -47,7 +47,7 @@ class OUTLINER_HT_header(Header): layout.separator_spacer() row = layout.row(align=True) - if display_mode in {'VIEW_LAYER'}: + if display_mode in {'SCENES', 'VIEW_LAYER'}: row.popover( panel="OUTLINER_PT_filter", text="", @@ -303,10 +303,29 @@ class OUTLINER_PT_filter(Panel): space = context.space_data display_mode = space.display_mode + if display_mode == 'VIEW_LAYER': + layout.label(text="Restriction Toggles:") + row = layout.row(align=True) + row.prop(space, "show_restrict_column_enable", text="") + row.prop(space, "show_restrict_column_selectable", text="") + row.prop(space, "show_restrict_column_instance", text="") + row.prop(space, "show_restrict_column_viewport", text="") + row.prop(space, "show_restrict_column_render", text="") + row.prop(space, "show_restrict_column_holdout", text="") + row.prop(space, "show_restrict_column_indirect_only", text="") + layout.separator() + elif display_mode == 'SCENES': + layout.label(text="Restriction Toggles:") + row = layout.row(align=True) + row.prop(space, "show_restrict_column_selectable", text="") + row.prop(space, "show_restrict_column_instance", text="") + row.prop(space, "show_restrict_column_viewport", text="") + row.prop(space, "show_restrict_column_render", text="") + layout.separator() + if display_mode != 'DATA_API': col = layout.column(align=True) col.prop(space, "use_sort_alpha") - col.prop(space, "show_restrict_columns") layout.separator() col = layout.column(align=True) @@ -314,6 +333,9 @@ class OUTLINER_PT_filter(Panel): col.prop(space, "use_filter_complete", text="Exact Match") col.prop(space, "use_filter_case_sensitive", text="Case Sensitive") + if display_mode != 'VIEW_LAYER': + return + layout.separator() layout.label(text="Filter:") diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc index 8b8ed6c5c4b..1ec23b9dfd0 100644 --- a/source/blender/alembic/intern/abc_transform.cc +++ b/source/blender/alembic/intern/abc_transform.cc @@ -86,7 +86,7 @@ void AbcTransformWriter::do_write() m_xform, m_xform.getSchema().getTimeSampling()); } - m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEW)); + m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_INSTANCE)); if (!m_first_frame && !m_is_animated) { return; diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index e01f6a6b751..b03686ca241 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ * \note Use #STRINGIFY() rather than defining with quotes. */ #define BLENDER_VERSION 280 -#define BLENDER_SUBVERSION 60 +#define BLENDER_SUBVERSION 61 /** Several breakages with 280, e.g. collections vs layers. */ #define BLENDER_MINVERSION 280 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index 47786629aed..0e093bb086b 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -161,6 +161,8 @@ bool BKE_collection_move(struct Main *bmain, bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collection *collection); +bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection); + /* Iteration callbacks. */ typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data); diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index d33d4e344b5..a7d23eff726 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -434,8 +434,8 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i int object_restrict = base->object->restrictflag; - if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) && - ((object_restrict & OB_RESTRICT_VIEW) == 0)) { + if (((child_restrict & COLLECTION_RESTRICT_INSTANCE) == 0) && + ((object_restrict & OB_RESTRICT_INSTANCE) == 0)) { base->flag |= BASE_ENABLED_VIEWPORT; } @@ -966,6 +966,11 @@ static bool collection_find_child_recursive(Collection *parent, Collection *coll return false; } +bool BKE_collection_has_collection(Collection *parent, Collection *collection) +{ + return collection_find_child_recursive(parent, collection); +} + static CollectionParent *collection_find_parent(Collection *child, Collection *collection) { return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection)); diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index fc349e62809..0eb2252cbfb 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -693,7 +693,7 @@ static short layer_collection_sync(ViewLayer *view_layer, lc->runtime_flag = child_runtime_flag; } - if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) && + if (((child_restrict & COLLECTION_RESTRICT_INSTANCE) == 0) && ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0)) { lc->runtime_flag |= LAYER_COLLECTION_VISIBLE; } @@ -723,7 +723,7 @@ static short layer_collection_sync(ViewLayer *view_layer, BLI_addtail(new_object_bases, base); } - if ((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) { + if ((child_restrict & COLLECTION_RESTRICT_INSTANCE) == 0) { base->flag_from_collection |= BASE_ENABLED_VIEWPORT; if ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) { base->flag_from_collection |= BASE_VISIBLE; @@ -1014,8 +1014,8 @@ bool BKE_layer_collection_isolate(Scene *scene, bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE); if ((!ID_IS_LINKED(lc->collection) && !hide_it)) { - if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) { - lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW; + if (lc->collection->flag & COLLECTION_RESTRICT_INSTANCE) { + lc->collection->flag &= ~COLLECTION_RESTRICT_INSTANCE; depsgraph_need_update = true; } } @@ -1044,8 +1044,8 @@ bool BKE_layer_collection_isolate(Scene *scene, while (lc_parent != lc) { if (!ID_IS_LINKED(lc_parent->collection)) { - if (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEW) { - lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEW; + if (lc_parent->collection->flag & COLLECTION_RESTRICT_INSTANCE) { + lc_parent->collection->flag &= ~COLLECTION_RESTRICT_INSTANCE; depsgraph_need_update = true; } } @@ -1109,8 +1109,8 @@ bool BKE_layer_collection_set_visible(ViewLayer *view_layer, bool depsgraph_changed = false; if (visible && (!ID_IS_LINKED(lc->collection)) && - ((lc->collection->flag & COLLECTION_RESTRICT_VIEW) != 0)) { - lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW; + ((lc->collection->flag & COLLECTION_RESTRICT_INSTANCE) != 0)) { + lc->collection->flag &= ~COLLECTION_RESTRICT_INSTANCE; depsgraph_changed = true; } @@ -1491,7 +1491,7 @@ void BKE_base_eval_flags(Base *base) /* Apply object restrictions. */ const int object_restrict = base->object->restrictflag; - if (object_restrict & OB_RESTRICT_VIEW) { + if (object_restrict & OB_RESTRICT_INSTANCE) { base->flag &= ~BASE_ENABLED_VIEWPORT; } if (object_restrict & OB_RESTRICT_RENDER) { diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 8080834a53a..044d6da9466 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -1082,7 +1082,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx) /* Should the dupli's be generated for this object? - Respect restrict flags */ if (DEG_get_mode(ctx->depsgraph) == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) : - (restrictflag & OB_RESTRICT_VIEW)) { + (restrictflag & OB_RESTRICT_INSTANCE)) { return NULL; } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index b958d7532bf..66c186d4561 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -427,7 +427,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) collections[layer] = collection; if (!(scene->lay & (1 << layer))) { - collection->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER; + collection->flag |= COLLECTION_RESTRICT_INSTANCE | COLLECTION_RESTRICT_RENDER; } } @@ -728,7 +728,7 @@ void do_versions_after_linking_280(Main *bmain) /* Add fake user for all existing groups. */ id_fake_user_set(&collection->id); - if (collection->flag & (COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER)) { + if (collection->flag & (COLLECTION_RESTRICT_INSTANCE | COLLECTION_RESTRICT_RENDER)) { continue; } @@ -754,7 +754,8 @@ void do_versions_after_linking_280(Main *bmain) char name[MAX_ID_NAME]; BLI_snprintf(name, sizeof(name), DATA_("Hidden %d"), coll_idx + 1); *collection_hidden = BKE_collection_add(bmain, collection, name); - (*collection_hidden)->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER; + (*collection_hidden)->flag |= COLLECTION_RESTRICT_INSTANCE | + COLLECTION_RESTRICT_RENDER; } BKE_collection_object_add(bmain, *collection_hidden, ob); @@ -3360,7 +3361,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - { + if (!MAIN_VERSION_ATLEAST(bmain, 280, 61)) { /* Added a power option to Copy Scale. */ if (!DNA_struct_elem_find(fd->filesdna, "bSizeLikeConstraint", "float", "power")) { LISTBASE_FOREACH (Object *, ob, &bmain->objects) { @@ -3398,6 +3399,22 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + for (ScrArea *area = screen->areabase.first; area; area = area->next) { + for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype != SPACE_OUTLINER) { + continue; + } + SpaceOutliner *so = (SpaceOutliner *)sl; + so->filter &= ~SO_FLAG_UNUSED_1; + so->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_SELECTABLE | + SO_RESTRICT_VIEWPORT; + } + } + } + } + + { /* Versioning code until next subversion bump goes here. */ LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) { arm->flag &= ~(ARM_FLAG_UNUSED_7 | ARM_FLAG_UNUSED_9); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 37712296bdf..fa40d794559 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -463,7 +463,7 @@ void DepsgraphNodeBuilder::build_id(ID *id) void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collection, Collection *collection) { - const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW : + const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_INSTANCE : COLLECTION_RESTRICT_RENDER; const bool is_collection_restricted = (collection->flag & restrict_flag); const bool is_collection_visible = !is_collection_restricted && is_parent_collection_visible_; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index b36213d6890..418818f047a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -60,7 +60,7 @@ namespace DEG { void DepsgraphNodeBuilder::build_layer_collections(ListBase *lb) { - const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW : + const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_INSTANCE : COLLECTION_RESTRICT_RENDER; for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc index a325544e046..642ab4a91fc 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc @@ -61,7 +61,7 @@ namespace DEG { void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb) { - const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_VIEW : + const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_RESTRICT_INSTANCE : COLLECTION_RESTRICT_RENDER; for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) { diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index b94d0e3ada7..7e3c85268db 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1823,7 +1823,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, } /* outliner restrict-flag */ - if (ob->restrictflag & OB_RESTRICT_VIEW) { + if (ob->restrictflag & OB_RESTRICT_INSTANCE) { continue; } } @@ -3022,7 +3022,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m } /* outliner restrict-flag */ - if (ob->restrictflag & OB_RESTRICT_VIEW) { + if (ob->restrictflag & OB_RESTRICT_INSTANCE) { return false; } } diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 18960853011..918883ea0b1 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -641,6 +641,7 @@ enum { UI_BLOCK_THEME_STYLE_POPUP = 1, }; void UI_block_theme_style_set(uiBlock *block, char theme_style); +char UI_block_emboss_get(uiBlock *block); void UI_block_emboss_set(uiBlock *block, char dt); void UI_block_free(const struct bContext *C, uiBlock *block); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 42f4b4495c3..7c60ac75df8 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3235,6 +3235,11 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh return block; } +char UI_block_emboss_get(uiBlock *block) +{ + return block->dt; +} + void UI_block_emboss_set(uiBlock *block, char dt) { block->dt = dt; diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index c0f3b1f8338..6f6dd12c3ec 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1992,9 +1992,9 @@ static int mask_hide_view_clear_exec(bContext *C, wmOperator *op) for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { - if (masklay->restrictflag & OB_RESTRICT_VIEW) { + if (masklay->restrictflag & OB_RESTRICT_INSTANCE) { ED_mask_layer_select_set(masklay, select); - masklay->restrictflag &= ~OB_RESTRICT_VIEW; + masklay->restrictflag &= ~OB_RESTRICT_INSTANCE; changed = true; } } @@ -2045,7 +2045,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op) if (ED_mask_layer_select_check(masklay)) { ED_mask_layer_select_set(masklay, false); - masklay->restrictflag |= OB_RESTRICT_VIEW; + masklay->restrictflag |= OB_RESTRICT_INSTANCE; changed = true; if (masklay == BKE_mask_layer_active(mask)) { BKE_mask_layer_active_set(mask, NULL); @@ -2054,7 +2054,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op) } else { if (!ED_mask_layer_select_check(masklay)) { - masklay->restrictflag |= OB_RESTRICT_VIEW; + masklay->restrictflag |= OB_RESTRICT_INSTANCE; changed = true; if (masklay == BKE_mask_layer_active(mask)) { BKE_mask_layer_active_set(mask, NULL); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 0185b664fba..e52eee0693d 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -2481,7 +2481,7 @@ static int add_named_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - basen->object->restrictflag &= ~OB_RESTRICT_VIEW; + basen->object->restrictflag &= ~OB_RESTRICT_INSTANCE; if (event) { ARegion *ar = CTX_wm_region(C); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 795e1dd66a5..279eadbe810 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -314,7 +314,7 @@ void ED_collection_hide_menu_draw(const bContext *C, uiLayout *layout) continue; } - if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) { + if (lc->collection->flag & COLLECTION_RESTRICT_INSTANCE) { continue; } @@ -722,7 +722,7 @@ static bool editmode_toggle_poll(bContext *C) } /* if hidden but in edit mode, we still display */ - if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)) { + if ((ob->restrictflag & OB_RESTRICT_INSTANCE) && !(ob->mode & OB_MODE_EDIT)) { return 0; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index bebab6b3a36..68347a762ea 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -342,7 +342,7 @@ bool ED_operator_console_active(bContext *C) static bool ed_object_hidden(Object *ob) { /* if hidden but in edit mode, we still display, can happen with animation */ - return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)); + return ((ob->restrictflag & OB_RESTRICT_INSTANCE) && !(ob->mode & OB_MODE_EDIT)); } bool ED_operator_object_active(bContext *C) diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index 6da42ecb3c0..99c98f7af8c 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -1163,12 +1163,12 @@ static bool collection_flag_poll(bContext *C, bool clear, int flag) static bool collection_enable_poll(bContext *C) { - return collection_flag_poll(C, true, COLLECTION_RESTRICT_VIEW); + return collection_flag_poll(C, true, COLLECTION_RESTRICT_INSTANCE); } static bool collection_disable_poll(bContext *C) { - return collection_flag_poll(C, false, COLLECTION_RESTRICT_VIEW); + return collection_flag_poll(C, false, COLLECTION_RESTRICT_INSTANCE); } static bool collection_enable_render_poll(bContext *C) @@ -1188,7 +1188,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op) 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; + int flag = is_render ? COLLECTION_RESTRICT_RENDER : COLLECTION_RESTRICT_INSTANCE; struct CollectionEditData data = { .scene = scene, .soops = soops, diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 10b248de21d..94f768b609c 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -270,16 +270,7 @@ static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void } } -static int base_pushed_state_cb(bContext *UNUSED(C), void *poin) -{ - 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; -} - +#if 0 static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2) { wmWindow *win = CTX_wm_window(C); @@ -296,12 +287,12 @@ static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2) if (do_disable) { if (!is_linked) { - ob->restrictflag |= OB_RESTRICT_VIEW; + ob->restrictflag |= OB_RESTRICT_INSTANCE; depsgraph_changed = true; } } else if (do_isolate) { - depsgraph_changed = (!is_linked) && ((ob->restrictflag & OB_RESTRICT_VIEW) != 0); + depsgraph_changed = (!is_linked) && ((ob->restrictflag & OB_RESTRICT_INSTANCE) != 0); if (!extend) { /* Make only one base visible. */ @@ -317,12 +308,12 @@ static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2) } if (!is_linked) { - ob->restrictflag &= ~OB_RESTRICT_VIEW; + ob->restrictflag &= ~OB_RESTRICT_INSTANCE; } } - else if (ob->restrictflag & OB_RESTRICT_VIEW) { + else if (ob->restrictflag & OB_RESTRICT_INSTANCE) { if (!is_linked) { - ob->restrictflag &= ~OB_RESTRICT_VIEW; + ob->restrictflag &= ~OB_RESTRICT_INSTANCE; base->flag &= ~BASE_HIDDEN; } depsgraph_changed = true; @@ -344,53 +335,341 @@ static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2) WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } } +#endif + +/** Create either a RNA_LayerCollection or a RNA_Collection pointer. */ +static void outliner_layer_or_collection_pointer_create(Scene *scene, + LayerCollection *layer_collection, + Collection *collection, + PointerRNA *ptr) +{ + if (collection) { + RNA_id_pointer_create(&collection->id, ptr); + } + else { + RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, ptr); + } +} + +/** Create either a RNA_ObjectBase or a RNA_Object pointer. */ +static void outliner_base_or_object_pointer_create(ViewLayer *view_layer, + Collection *collection, + Object *ob, + PointerRNA *ptr) +{ + if (collection) { + RNA_id_pointer_create(&ob->id, ptr); + } + else { + Base *base = BKE_view_layer_base_find(view_layer, ob); + RNA_pointer_create(&base->object->id, &RNA_ObjectBase, base, ptr); + } +} + +/* Note: Collection is only valid when we want to change the collection data, otherwise we get it + * from layer collection. Layer collection is valid whenever we are looking at a view layer. */ +static void outliner_collection_set_flag_recursive(Scene *scene, + ViewLayer *view_layer, + LayerCollection *layer_collection, + Collection *collection, + PropertyRNA *layer_or_collection_prop, + PropertyRNA *base_or_object_prop, + const bool value) +{ + if (layer_collection && layer_collection->flag & LAYER_COLLECTION_EXCLUDE) { + return; + } + PointerRNA ptr; + outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr); + RNA_property_boolean_set(&ptr, layer_or_collection_prop, value); + + /* Set the same flag for the nested objects as well. */ + if (base_or_object_prop) { + /* Note: We can't use BKE_collection_object_cache_get() + * otherwise we would not take collection exclusion into account. */ + for (CollectionObject *cob = layer_collection->collection->gobject.first; cob; + cob = cob->next) { + + outliner_base_or_object_pointer_create(view_layer, collection, cob->ob, &ptr); + RNA_property_boolean_set(&ptr, base_or_object_prop, value); + + if (collection) { + DEG_id_tag_update(&cob->ob->id, ID_RECALC_COPY_ON_WRITE); + } + } + } + + /* Keep going recursively. */ + ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children); + for (Link *link = lb->first; link; link = link->next) { + LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL; + Collection *collection_iter = layer_collection ? + (collection ? layer_collection_iter->collection : NULL) : + ((CollectionChild *)link)->collection; + outliner_collection_set_flag_recursive(scene, + view_layer, + layer_collection_iter, + collection_iter, + layer_or_collection_prop, + base_or_object_prop, + value); + } + + if (collection) { + DEG_id_tag_update(&collection->id, ID_RECALC_COPY_ON_WRITE); + } +} + +/** Check if collection is already isolated. + * + * A collection is isolated if all its parents and children are "visible". + * All the other collections must be "invisible". + * + * Note: We could/should boost performance by iterating over the tree twice. + * First tagging all the children/parent collections, then getting their values and comparing. + * To run BKE_collection_has_collection() so many times is silly and slow. + */ +static bool outliner_collection_is_isolated(Scene *scene, + const LayerCollection *layer_collection_cmp, + const Collection *collection_cmp, + const bool value_cmp, + const PropertyRNA *layer_or_collection_prop, + LayerCollection *layer_collection, + Collection *collection) +{ + PointerRNA ptr; + outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr); + const bool value = RNA_property_boolean_get(&ptr, (PropertyRNA *)layer_or_collection_prop); + Collection *collection_ensure = collection ? collection : layer_collection->collection; + const Collection *collection_ensure_cmp = collection_cmp ? collection_cmp : + layer_collection_cmp->collection; + + if (collection_ensure->flag & COLLECTION_IS_MASTER) { + } + else if (collection_ensure == collection_ensure_cmp) { + } + else if (BKE_collection_has_collection(collection_ensure, (Collection *)collection_ensure_cmp) || + BKE_collection_has_collection((Collection *)collection_ensure_cmp, collection_ensure)) { + /* This collection is either a parent or a child of the collection. + * We expect it to be set "visble" already. */ + if (value != value_cmp) { + return false; + } + } + else { + /* This collection is neither a parent nor a child of the collection. + * We expect it to be "invisble". */ + if (value == value_cmp) { + return false; + } + } + + /* Keep going recursively. */ + ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children); + for (Link *link = lb->first; link; link = link->next) { + LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL; + Collection *collection_iter = layer_collection ? + (collection ? layer_collection_iter->collection : NULL) : + ((CollectionChild *)link)->collection; + if (layer_collection_iter && layer_collection_iter->flag & LAYER_COLLECTION_EXCLUDE) { + continue; + } + if (!outliner_collection_is_isolated(scene, + layer_collection_cmp, + collection_cmp, + value_cmp, + layer_or_collection_prop, + layer_collection_iter, + collection_iter)) { + return false; + } + } + + return true; +} -static int layer_collection_pushed_state_cb(bContext *UNUSED(C), void *poin) +static void outliner_collection_isolate_flag(Scene *scene, + ViewLayer *view_layer, + LayerCollection *layer_collection, + Collection *collection, + PropertyRNA *layer_or_collection_prop, + const char *propname, + const bool value) { - LayerCollection *lc = poin; - Collection *collection = lc->collection; + PointerRNA ptr; + const bool is_hide = strstr(propname, "hide_") != NULL; + + LayerCollection *top_layer_collection = layer_collection ? view_layer->layer_collections.first : + NULL; + Collection *top_collection = collection ? scene->master_collection : NULL; + + bool was_isolated = (value == is_hide); + was_isolated &= outliner_collection_is_isolated(scene, + layer_collection, + collection, + !is_hide, + layer_or_collection_prop, + top_layer_collection, + top_collection); + + if (was_isolated) { + const bool default_value = RNA_property_boolean_get_default(NULL, layer_or_collection_prop); + /* Make every collection go back to its default "visibility" state. */ + outliner_collection_set_flag_recursive(scene, + view_layer, + top_layer_collection, + top_collection, + layer_or_collection_prop, + NULL, + default_value); + return; + } - const bool is_visible = ((lc->flag & LAYER_COLLECTION_RESTRICT_VIEW) == 0) && - ((collection->flag & COLLECTION_RESTRICT_VIEW) == 0); - return !is_visible; + /* Make every collection "invisible". */ + outliner_collection_set_flag_recursive(scene, + view_layer, + top_layer_collection, + top_collection, + layer_or_collection_prop, + NULL, + is_hide); + + /* Make this collection and its children collections the only "visible". */ + outliner_collection_set_flag_recursive( + scene, view_layer, layer_collection, collection, layer_or_collection_prop, NULL, !is_hide); + + /* Make this collection direct parents also "visible". */ + if (layer_collection) { + LayerCollection *lc_parent = layer_collection; + for (LayerCollection *lc_iter = top_layer_collection->layer_collections.first; lc_iter; + lc_iter = lc_iter->next) { + if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) { + lc_parent = lc_iter; + break; + } + } + + while (lc_parent != layer_collection) { + outliner_layer_or_collection_pointer_create( + scene, lc_parent, collection ? lc_parent->collection : NULL, &ptr); + RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide); + + for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter; + lc_iter = lc_iter->next) { + if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) { + lc_parent = lc_iter; + break; + } + } + } + } + else { + CollectionParent *parent; + Collection *child = collection; + while ((parent = child->parents.first)) { + if (parent->collection->flag & COLLECTION_IS_MASTER) { + break; + } + RNA_id_pointer_create(&parent->collection->id, &ptr); + RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide); + child = parent->collection; + } + } } -static void hidebutton_layer_collection_flag_cb(bContext *C, void *poin, void *poin2) +static void outliner_collection_set_flag_recursive_cb(bContext *C, + LayerCollection *layer_collection, + Collection *collection, + const char *propname) { 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; + ViewLayer *view_layer = CTX_data_view_layer(C); + PointerRNA ptr; + + bool do_isolate = (win->eventstate->ctrl != 0); 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; - } + if (!ELEM(true, do_isolate, extend)) { + return; } - else if (do_isolate) { - depsgraph_changed |= BKE_layer_collection_isolate(scene, view_layer, lc, extend); + + /* Create PointerRNA and PropertyRNA for either Collection or LayerCollection. */ + ID *id = collection ? &collection->id : &scene->id; + StructRNA *struct_rna = collection ? &RNA_Collection : &RNA_LayerCollection; + void *data = collection ? (void *)collection : (void *)layer_collection; + + RNA_pointer_create(id, struct_rna, data, &ptr); + PropertyRNA *layer_or_collection_prop = RNA_struct_type_find_property(struct_rna, propname); + const bool value = RNA_property_boolean_get(&ptr, layer_or_collection_prop); + + PropertyRNA *base_or_object_prop = NULL; + if (layer_collection != NULL) { + /* If we are toggling Layer collections we still want to change the properties of the base + * or the objects. If we have a matching property, toggle it as well, it can be NULL. */ + struct_rna = collection ? &RNA_Object : &RNA_ObjectBase; + base_or_object_prop = RNA_struct_type_find_property(struct_rna, propname); } - 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); + + if (extend) { + outliner_collection_set_flag_recursive(scene, + view_layer, + layer_collection, + collection, + layer_or_collection_prop, + base_or_object_prop, + value); } + else { + outliner_collection_isolate_flag(scene, + view_layer, + layer_collection, + collection, + layer_or_collection_prop, + propname, + value); + } + + /* We don't call RNA_property_update() due to performance, so we batch update them. */ + BKE_main_collection_sync_remap(bmain); + DEG_relations_tag_update(bmain); +} - BKE_layer_collection_sync(scene, view_layer); - DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS); +/** + * Layer collection properties called from the ViewLayer mode. + * Change the (non-excluded) collection children, and the objects nested to them all. + */ +static void view_layer__layer_collection_set_flag_recursive_cb(bContext *C, + void *poin, + void *poin2) +{ + LayerCollection *layer_collection = poin; + char *propname = poin2; + outliner_collection_set_flag_recursive_cb(C, layer_collection, NULL, propname); +} - if (depsgraph_changed) { - BKE_main_collection_sync_remap(bmain); - DEG_relations_tag_update(bmain); - } - WM_main_add_notifier(NC_SCENE | ND_LAYER_CONTENT, NULL); +/** + * Collection properties called from the ViewLayer mode. + * Change the (non-excluded) collection children, and the objects nested to them all. + */ +static void view_layer__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2) +{ + LayerCollection *layer_collection = poin; + char *propname = poin2; + outliner_collection_set_flag_recursive_cb( + C, layer_collection, layer_collection->collection, propname); +} + +/** + * Collection properties called from the Scenes mode. + * Change the collection children but no objects. + */ +static void scenes__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2) +{ + Collection *collection = poin; + char *propname = poin2; + outliner_collection_set_flag_recursive_cb(C, NULL, collection, propname); } static void namebutton_cb(bContext *C, void *tsep, char *oldname) @@ -579,25 +858,69 @@ static void outliner_draw_restrictbuts(uiBlock *block, 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 *object_hide_instance, *object_hide_select, *object_hide_render; + PropertyRNA *base_hide_viewport; + PropertyRNA *collection_hide_instance, *collection_hide_select, *collection_hide_render; + PropertyRNA *layer_collection_holdout, *layer_collection_indirect_only, + *layer_collection_hide_viewport; 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_instance = RNA_struct_type_find_property(&RNA_Object, "hide_instance"); 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.base_hide_viewport = RNA_struct_type_find_property(&RNA_ObjectBase, "hide_viewport"); + props.collection_hide_instance = RNA_struct_type_find_property(&RNA_Collection, + "hide_instance"); 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.layer_collection_holdout = RNA_struct_type_find_property(&RNA_LayerCollection, + "holdout"); + props.layer_collection_indirect_only = RNA_struct_type_find_property(&RNA_LayerCollection, + "indirect_only"); + props.layer_collection_hide_viewport = RNA_struct_type_find_property(&RNA_LayerCollection, + "hide_viewport"); 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; } + struct { + int select; + int viewport; + int instance; + int render; + int indirect_only; + int holdout; + } restrict_offsets = {0}; + int restrict_column_offset = 0; + + /* This will determine the order of drawing from RIGHT to LEFT. */ + if (soops->outlinevis == SO_VIEW_LAYER) { + if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) { + restrict_offsets.indirect_only = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; + } + if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) { + restrict_offsets.holdout = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; + } + } + if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { + restrict_offsets.render = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; + } + if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) { + restrict_offsets.instance = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; + } + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + restrict_offsets.viewport = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; + } + if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) { + restrict_offsets.select = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; + } + BLI_assert((restrict_column_offset * UI_UNIT_X + V2D_SCROLL_WIDTH) == + outliner_restrict_columns_width(soops)); + /* Create buttons. */ uiBut *bt; @@ -605,27 +928,29 @@ static void outliner_draw_restrictbuts(uiBlock *block, 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; + if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { + /* 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); + bt = uiDefIconButBitS(block, + UI_BTYPE_ICON_TOGGLE_N, + VIEW_LAYER_RENDER, + 0, + ICON_RESTRICT_RENDER_OFF, + (int)(ar->v2d.cur.xmax - restrict_offsets.render), + 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) && (te->flag & TE_CHILD_NOT_IN_COLLECTION)) { @@ -634,45 +959,84 @@ static void outliner_draw_restrictbuts(uiBlock *block, 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; + RNA_id_pointer_create(&ob->id, &ptr); + + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + Base *base = (te->directdata) ? (Base *)te->directdata : + BKE_view_layer_base_find(view_layer, ob); + if (base) { + PointerRNA base_ptr; + RNA_pointer_create(&ob->id, &RNA_ObjectBase, base, &base_ptr); + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.viewport), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &base_ptr, + props.base_hide_viewport, + -1, + 0, + 0, + 0, + 0, + NULL); + 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 - restrict_offsets.viewport), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &ptr, + props.object_hide_instance, + -1, + 0, + 0, + 0, + 0, + NULL); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); } - 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); + } + + if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.select), + 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); } - else { + + if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) { bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, 0, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), + (int)(ar->v2d.cur.xmax - restrict_offsets.instance), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, - props.object_hide_viewport, + props.object_hide_instance, -1, 0, 0, @@ -682,301 +1046,404 @@ static void outliner_draw_restrictbuts(uiBlock *block, UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); } - bt = uiDefIconButR_prop(block, + if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.render), + 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); + + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.viewport), + 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); + } + + if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.render), + 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; + + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, + BONE_HIDDEN_P, 0, - 0, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), + ICON_HIDE_OFF, + (int)(ar->v2d.cur.xmax - restrict_offsets.viewport), te->ys, UI_UNIT_X, UI_UNIT_Y, - &ptr, - props.object_hide_select, - -1, + &(bone->flag), + 0, 0, 0, - -1, - -1, - NULL); - UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + 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 = uiDefIconButR_prop(block, + if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) { + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, + BONE_UNSELECTABLE, 0, - 0, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), + ICON_RESTRICT_SELECT_OFF, + (int)(ar->v2d.cur.xmax - restrict_offsets.select), te->ys, UI_UNIT_X, UI_UNIT_Y, - &ptr, - props.object_hide_render, - -1, + &(bone->flag), + 0, + 0, 0, 0, - -1, - -1, - NULL); - UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + 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_MODIFIER) { - ModifierData *md = (ModifierData *)te->directdata; - - PointerRNA ptr; - RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr); + else if (tselem->type == TSE_EBONE) { + EditBone *ebone = (EditBone *)te->directdata; - bt = uiDefIconButR_prop(block, + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, + BONE_HIDDEN_A, 0, - 0, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), + ICON_RESTRICT_VIEW_OFF, + (int)(ar->v2d.cur.xmax - restrict_offsets.viewport), te->ys, UI_UNIT_X, UI_UNIT_Y, - &ptr, - props.modifier_show_viewport, - -1, + &(ebone->flag), + 0, 0, 0, - -1, - -1, - NULL); - UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + 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 = uiDefIconButR_prop(block, + if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) { + bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, + BONE_UNSELECTABLE, 0, - 0, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), + ICON_RESTRICT_SELECT_OFF, + (int)(ar->v2d.cur.xmax - restrict_offsets.select), te->ys, UI_UNIT_X, UI_UNIT_Y, - &ptr, - props.modifier_show_render, - -1, + &(ebone->flag), 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); + 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); + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + bt = uiDefIconButBitS(block, + UI_BTYPE_ICON_TOGGLE, + GP_LAYER_HIDE, + 0, + ICON_HIDE_OFF, + (int)(ar->v2d.cur.xmax - restrict_offsets.viewport), + 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); + } + + if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) { + bt = uiDefIconButBitS( + block, + UI_BTYPE_ICON_TOGGLE, + GP_LAYER_LOCKED, + 0, + ICON_UNLOCKED, + (int)(ar->v2d.cur.xmax - restrict_offsets.select), + 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; + LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ? + te->directdata : + NULL; Collection *collection = outliner_collection_from_tree_element(te); - if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) && + if ((!layer_collection || !(layer_collection->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; + if (layer_collection != NULL) { + PointerRNA layer_collection_ptr; + RNA_pointer_create( + &scene->id, &RNA_LayerCollection, layer_collection, &layer_collection_ptr); + + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.viewport), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &layer_collection_ptr, + props.layer_collection_hide_viewport, + -1, + 0, + 0, + 0, + 0, + TIP_("Hide/Show collection in viewport\n" + "* Ctrl to isolate collection\n" + "* Shift to set/unset inside collections and objects")); + UI_but_func_set(bt, + view_layer__layer_collection_set_flag_recursive_cb, + layer_collection, + (char *)"hide_viewport"); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + } + + if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.holdout), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &layer_collection_ptr, + props.layer_collection_holdout, + -1, + 0, + 0, + 0, + 0, + TIP_("Mask out/in objects in collection from view layer\n" + "* Ctrl to isolate collection\n" + "* Shift to set/unset inside collections")); + UI_but_func_set(bt, + view_layer__layer_collection_set_flag_recursive_cb, + layer_collection, + (char *)"holdout"); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + } + + if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) { + bt = uiDefIconButR_prop( + block, + UI_BTYPE_ICON_TOGGLE, + 0, + (layer_collection->flag & LAYER_COLLECTION_INDIRECT_ONLY) != 0 ? 0 : ICON_REMOVE, + (int)(ar->v2d.cur.xmax - restrict_offsets.indirect_only), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &layer_collection_ptr, + props.layer_collection_indirect_only, + -1, + 0, + 0, + 0, + 0, + TIP_("Objects in collection only contribute indirectly (through shadows and " + "reflections) in the view layer\n" + "* Ctrl to isolate collection\n" + "* Shift to set/unset inside collections")); + UI_but_func_set(bt, + view_layer__layer_collection_set_flag_recursive_cb, + layer_collection, + (char *)"indirect_only"); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); } - 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 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 { + + if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) { bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, 0, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), + (int)(ar->v2d.cur.xmax - restrict_offsets.instance), te->ys, UI_UNIT_X, UI_UNIT_Y, &collection_ptr, - props.collection_hide_viewport, + props.collection_hide_instance, -1, 0, 0, 0, 0, - NULL); + TIP_("Disable/Enable collection in viewport\n" + "* Ctrl to isolate collection\n" + "* Shift to set/unset inside collections and objects")); + if (layer_collection != NULL) { + UI_but_func_set(bt, + view_layer__collection_set_flag_recursive_cb, + layer_collection, + (char *)"hide_instance"); + } + else { + UI_but_func_set(bt, + scenes__collection_set_flag_recursive_cb, + collection, + (char *)"hide_instance"); + } 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); + if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.render), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &collection_ptr, + props.collection_hide_render, + -1, + 0, + 0, + 0, + 0, + TIP_("Disable/Enable collection in renders\n" + "* Ctrl to isolate collection\n" + "* Shift to set/unset inside collections and objects")); + if (layer_collection != NULL) { + UI_but_func_set(bt, + view_layer__collection_set_flag_recursive_cb, + layer_collection, + (char *)"hide_render"); + } + else { + UI_but_func_set( + bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_render"); + } + 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 (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) { + bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + (int)(ar->v2d.cur.xmax - restrict_offsets.select), + te->ys, + UI_UNIT_X, + UI_UNIT_Y, + &collection_ptr, + props.collection_hide_select, + -1, + 0, + 0, + 0, + 0, + TIP_("Disable/Enable collection for viewport selection\n" + "* Ctrl to isolate collection\n" + "* Shift to set/unset inside collections and objects")); + if (layer_collection != NULL) { + UI_but_func_set(bt, + view_layer__collection_set_flag_recursive_cb, + layer_collection, + (char *)"hide_select"); + } + else { + UI_but_func_set( + bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_select"); + } + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + } } } } @@ -1005,6 +1472,23 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s but_flag |= UI_BUT_DISABLED; } + BLI_str_format_int_grouped(buf, id->us); + bt = uiDefBut(block, + UI_BTYPE_BUT, + 1, + buf, + (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS), + 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); + if (id->flag & LIB_FAKEUSER) { icon = ICON_FILE_TICK; tip = TIP_("Data-block will be retained using a fake user"); @@ -1018,7 +1502,7 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s LIB_FAKEUSER, 1, icon, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), + (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS), te->ys, UI_UNIT_X, UI_UNIT_Y, @@ -1031,29 +1515,12 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOutliner *s 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_ICON_TOGGLE, LIB_FAKEUSER, 1, (id->flag & LIB_FAKEUSER) ? "F" : " ", - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), + (int)(ar->v2d.cur.xmax - OL_TOG_USER_BUTS_FAKEUSER), te->ys, UI_UNIT_X, UI_UNIT_Y, @@ -1778,6 +2245,60 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) return data; } +static void tselem_draw_layer_collection_enable_icon( + Scene *scene, uiBlock *block, int xmax, float x, float y, TreeElement *te, float alpha) +{ + /* Get RNA property (once for speed). */ + static PropertyRNA *exclude_prop = NULL; + if (exclude_prop == NULL) { + exclude_prop = RNA_struct_type_find_property(&RNA_LayerCollection, "exclude"); + } + + if (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 */ + char color[4]; + int icon = RNA_property_ui_icon(exclude_prop); + if (UI_icon_get_theme_color(icon, (uchar *)color)) { + UI_icon_draw_ex(x, y, icon, U.inv_dpi_fac, alpha, 0.0f, color, true); + } + else { + UI_icon_draw_ex(x, y, icon, U.inv_dpi_fac, alpha, 0.0f, NULL, false); + } + } + else { + LayerCollection *layer_collection = te->directdata; + PointerRNA layer_collection_ptr; + RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, &layer_collection_ptr); + + char emboss = UI_block_emboss_get(block); + UI_block_emboss_set(block, UI_EMBOSS_NONE); + uiBut *bt = uiDefIconButR_prop(block, + UI_BTYPE_ICON_TOGGLE, + 0, + 0, + x, + y, + UI_UNIT_X, + UI_UNIT_Y, + &layer_collection_ptr, + exclude_prop, + -1, + 0, + 0, + 0, + 0, + NULL); + UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); + UI_block_emboss_set(block, emboss); + } +} + static void tselem_draw_icon(uiBlock *block, int xmax, float x, @@ -2074,6 +2595,7 @@ static void outliner_draw_tree_element(bContext *C, bool draw_grayed_out, int startx, int *starty, + const float restrict_column_width, TreeElement **te_edit) { TreeStoreElem *tselem; @@ -2096,8 +2618,8 @@ static void outliner_draw_tree_element(bContext *C, } /* 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; + if (restrict_column_width > 0) { + xmax -= restrict_column_width + UI_UNIT_X; } GPU_blend(true); @@ -2156,13 +2678,21 @@ static void outliner_draw_tree_element(bContext *C, rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha); } + /* Checkbox to enable collections. */ + if ((tselem->type == TSE_LAYER_COLLECTION) && + (soops->show_restrict_flags & SO_RESTRICT_ENABLE)) { + tselem_draw_layer_collection_enable_icon( + scene, block, xmax, (float)startx + offsx + UI_UNIT_X, (float)*starty, te, 0.8f); + offsx += UI_UNIT_X; + } + /* 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)startx + offsx + UI_UNIT_X + 1.0f * ufac, (float)*starty + 1.0f * ufac, - (float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac, + (float)startx + offsx + 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); @@ -2196,7 +2726,6 @@ static void outliner_draw_tree_element(bContext *C, 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); @@ -2312,6 +2841,7 @@ static void outliner_draw_tree_element(bContext *C, draw_childs_grayed_out, startx + UI_UNIT_X, starty, + restrict_column_width, te_edit); } } @@ -2591,7 +3121,7 @@ static void outliner_draw_tree(bContext *C, ViewLayer *view_layer, ARegion *ar, SpaceOutliner *soops, - const bool has_restrict_icons, + const float restrict_column_width, TreeElement **te_edit) { const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; @@ -2613,8 +3143,8 @@ static void outliner_draw_tree(bContext *C, /* 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; + if (restrict_column_width > 0.0f) { + int mask_x = BLI_rcti_size_x(&ar->v2d.mask) - (int)restrict_column_width + 1; CLAMP_MIN(mask_x, 0); GPU_scissor_get_f(scissor); @@ -2642,10 +3172,11 @@ static void outliner_draw_tree(bContext *C, (te->flag & TE_DRAGGING) != 0, startx, &starty, + restrict_column_width, te_edit); } - if (has_restrict_icons) { + if (restrict_column_width > 0.0f) { /* reset scissor */ GPU_scissor(UNPACK4(scissor)); } @@ -2700,7 +3231,6 @@ void draw_outliner(const bContext *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 @@ -2710,6 +3240,7 @@ void draw_outliner(const bContext *C) /* extend size to allow for horizontal scrollbar */ sizey += V2D_SCROLL_HEIGHT; + const float restrict_column_width = outliner_restrict_columns_width(soops); if (soops->outlinevis == SO_DATA_API) { /* RNA has two columns: * - column 1 is (max_width + OL_RNA_COL_SPACEX) or @@ -2725,7 +3256,6 @@ void draw_outliner(const bContext *C) /* 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) @@ -2734,13 +3264,8 @@ void draw_outliner(const bContext *C) // 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); + /* Constant offset for restriction columns */ + sizex += restrict_column_width; } /* adds vertical offset */ @@ -2758,7 +3283,7 @@ void draw_outliner(const bContext *C) 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); + (bContext *)C, block, scene, view_layer, ar, soops, restrict_column_width, &te_edit); /* Default to no emboss for outliner UI. */ UI_block_emboss_set(block, UI_EMBOSS_NONE); @@ -2771,11 +3296,11 @@ void draw_outliner(const bContext *C) 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) { + else if (soops->outlinevis == SO_ID_ORPHANS) { /* draw user toggle columns */ outliner_draw_userbuts(block, ar, soops, &soops->tree); } - else if (has_restrict_icons) { + else if (restrict_column_width > 0.0f) { /* draw restriction columns */ outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &soops->tree); } diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index a943e972cf5..80b717aeb43 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1025,8 +1025,8 @@ int common_restrict_check(bContext *C, Object *ob) 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; + if (ob->restrictflag & OB_RESTRICT_INSTANCE) { + ob->restrictflag &= ~OB_RESTRICT_INSTANCE; } /* found object is unselectable, reset */ if (ob->restrictflag & OB_RESTRICT_SELECT) { diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 8211e3005c7..15489c61230 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -156,11 +156,9 @@ typedef enum { /* size constants */ #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_RENDERX (UI_UNIT_X + V2D_SCROLL_WIDTH) - -#define OL_TOGW OL_TOG_RESTRICT_SELECTX +#define OL_TOG_USER_BUTS_USERS (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH) +#define OL_TOG_USER_BUTS_STATUS (UI_UNIT_X * 3.0f + V2D_SCROLL_WIDTH) +#define OL_TOG_USER_BUTS_FAKEUSER (UI_UNIT_X + V2D_SCROLL_WIDTH) #define OL_RNA_COLX (UI_UNIT_X * 15) #define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f) @@ -449,5 +447,6 @@ bool outliner_tree_traverse(const SpaceOutliner *soops, int filter_tselem_flag, TreeTraversalFunc func, void *customdata); +float outliner_restrict_columns_width(const struct SpaceOutliner *soops); #endif /* __OUTLINER_INTERN_H__ */ diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 995f41382cd..c6fcf1d8cf7 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -1271,8 +1271,7 @@ 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 (view_co_x > ar->v2d.cur.xmax - outliner_restrict_columns_width(soops)); } /** diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 4e3fd6037bb..7e804e10559 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -1370,6 +1370,12 @@ static void outliner_add_layer_collections_recursive(SpaceOutliner *soops, const bool show_objects) { for (LayerCollection *lc = layer_collections->first; lc; lc = lc->next) { + const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0; + + if (exclude && ((soops->show_restrict_flags & SO_RESTRICT_ENABLE) == 0)) { + continue; + } + ID *id = &lc->collection->id; TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0); @@ -1382,8 +1388,7 @@ static void outliner_add_layer_collections_recursive(SpaceOutliner *soops, tselem->flag &= ~TSE_CLOSED; } - const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0; - if (exclude || ((lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0)) { + if (exclude || (lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0) { ten->flag |= TE_DISABLED; } diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c index 03d15088380..4d3272eab20 100644 --- a/source/blender/editors/space_outliner/outliner_utils.c +++ b/source/blender/editors/space_outliner/outliner_utils.c @@ -31,6 +31,7 @@ #include "ED_armature.h" #include "UI_interface.h" +#include "UI_view2d.h" #include "outliner_intern.h" @@ -261,3 +262,42 @@ bool outliner_tree_traverse(const SpaceOutliner *soops, return true; } + +float outliner_restrict_columns_width(const SpaceOutliner *soops) +{ + int num_columns = 0; + + switch (soops->outlinevis) { + case SO_DATA_API: + case SO_SEQUENCE: + return 0.0f; + case SO_ID_ORPHANS: + num_columns = 3; + break; + case SO_VIEW_LAYER: + if (soops->show_restrict_flags & SO_RESTRICT_HOLDOUT) { + num_columns++; + } + if (soops->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) { + num_columns++; + } + ATTR_FALLTHROUGH; + case SO_SCENES: + if (soops->show_restrict_flags & SO_RESTRICT_SELECTABLE) { + num_columns++; + } + if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) { + num_columns++; + } + if (soops->show_restrict_flags & SO_RESTRICT_INSTANCE) { + num_columns++; + } + if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { + num_columns++; + } + break; + case SO_LIBRARIES: + return 0.0f; + } + return (num_columns * UI_UNIT_X + V2D_SCROLL_WIDTH); +} diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index a8e3129b5b4..71290fc9fe0 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -302,6 +302,8 @@ static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED( soutliner = MEM_callocN(sizeof(SpaceOutliner), "initoutliner"); soutliner->spacetype = SPACE_OUTLINER; soutliner->filter_id_type = ID_GR; + soutliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_SELECTABLE | + SO_RESTRICT_VIEWPORT; /* header */ ar = MEM_callocN(sizeof(ARegion), "header for outliner"); diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h index b935acd5a24..9183537e2f0 100644 --- a/source/blender/makesdna/DNA_collection_types.h +++ b/source/blender/makesdna/DNA_collection_types.h @@ -76,7 +76,7 @@ typedef struct Collection { /* Collection->flag */ enum { - COLLECTION_RESTRICT_VIEW = (1 << 0), /* Hidden in viewport. */ + COLLECTION_RESTRICT_INSTANCE = (1 << 0), /* Hidden in viewport. */ COLLECTION_RESTRICT_SELECT = (1 << 1), /* Not selectable in viewport. */ COLLECTION_DISABLED_DEPRECATED = (1 << 2), /* Not used anymore */ COLLECTION_RESTRICT_RENDER = (1 << 3), /* Hidden in renders. */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index ae781ac4e9e..3a2d749b321 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -602,7 +602,7 @@ enum { /* ob->restrictflag */ enum { - OB_RESTRICT_VIEW = 1 << 0, + OB_RESTRICT_INSTANCE = 1 << 0, OB_RESTRICT_SELECT = 1 << 1, OB_RESTRICT_RENDER = 1 << 2, }; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 9e8ece0c6e8..bca2df27560 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -247,7 +247,7 @@ typedef struct SpaceOutliner { short flag, outlinevis, storeflag, search_flags; int filter; char filter_state; - char _pad; + char show_restrict_flags; short filter_id_type; /** @@ -260,7 +260,7 @@ typedef struct SpaceOutliner { typedef enum eSpaceOutliner_Flag { SO_TESTBLOCKS = (1 << 0), SO_NEWSELECTED = (1 << 1), - SO_HIDE_RESTRICTCOLS = (1 << 2), + SO_FLAG_UNUSED_1 = (1 << 2), /* cleared */ SO_HIDE_KEYINGSETINFO = (1 << 3), SO_SKIP_SORT_ALPHA = (1 << 4), } eSpaceOutliner_Flag; @@ -309,6 +309,17 @@ typedef enum eSpaceOutliner_StateFilter { SO_FILTER_OB_ACTIVE = 3, } eSpaceOutliner_StateFilter; +/* SpaceOutliner.show_restrict_flags */ +typedef enum eSpaceOutliner_ShowRestrictFlag { + SO_RESTRICT_ENABLE = (1 << 0), + SO_RESTRICT_SELECTABLE = (1 << 1), + SO_RESTRICT_INSTANCE = (1 << 2), + SO_RESTRICT_VIEWPORT = (1 << 3), + SO_RESTRICT_RENDER = (1 << 4), + SO_RESTRICT_HOLDOUT = (1 << 5), + SO_RESTRICT_INDIRECT_ONLY = (1 << 6), +} eSpaceOutliner_Restrict; + /* SpaceOutliner.outlinevis */ typedef enum eSpaceOutliner_Mode { SO_SCENES = 0, diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c index 501895eefc8..e2ffddc8e07 100644 --- a/source/blender/makesrna/intern/rna_collection.c +++ b/source/blender/makesrna/intern/rna_collection.c @@ -408,12 +408,12 @@ void RNA_def_collections(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Disable Select", "Disable collection for viewport selection"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update"); - prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_VIEW); + prop = RNA_def_property(srna, "hide_instance", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_INSTANCE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1); - RNA_def_property_ui_text(prop, "Disable Viewport", "Disable collection in viewport"); + RNA_def_property_ui_icon(prop, ICON_LINKED, -1); + RNA_def_property_ui_text(prop, "Hide Instance", "Disable collection in viewport"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update"); prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c index 03c507cabd1..21b189c7494 100644 --- a/source/blender/makesrna/intern/rna_layer.c +++ b/source/blender/makesrna/intern/rna_layer.c @@ -187,6 +187,15 @@ static void rna_ObjectBase_select_update(Main *UNUSED(bmain), ED_object_base_select(base, mode); } +static void rna_ObjectBase_hide_viewport_update(bContext *C, PointerRNA *UNUSED(ptr)) +{ + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + 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 void rna_LayerCollection_name_get(struct PointerRNA *ptr, char *value) { ID *id = (ID *)((LayerCollection *)ptr->data)->collection; @@ -199,12 +208,29 @@ int rna_LayerCollection_name_length(PointerRNA *ptr) return strlen(id->name + 2); } +static void rna_LayerCollection_exclude_update_recursive(ListBase *lb, const bool exclude) +{ + for (LayerCollection *lc = lb->first; lc; lc = lc->next) { + if (exclude) { + lc->flag |= LAYER_COLLECTION_EXCLUDE; + } + else { + lc->flag &= ~LAYER_COLLECTION_EXCLUDE; + } + rna_LayerCollection_exclude_update_recursive(&lc->layer_collections, exclude); + } +} + static void rna_LayerCollection_exclude_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { Scene *scene = (Scene *)ptr->id.data; LayerCollection *lc = (LayerCollection *)ptr->data; ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc); + /* Set/Unset it recursively to match the behaviour of excluding via the menu or shortcuts. */ + rna_LayerCollection_exclude_update_recursive(&lc->layer_collections, + (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0); + BKE_layer_collection_sync(scene, view_layer); DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS); @@ -266,21 +292,26 @@ static void rna_def_layer_collection(BlenderRNA *brna) RNA_def_property_struct_type(prop, "LayerCollection"); RNA_def_property_ui_text(prop, "Children", "Child layer collections"); + /* Restriction flags. */ prop = RNA_def_property(srna, "exclude", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_EXCLUDE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Exclude", "Exclude collection from view layer"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, -1); RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_exclude_update"); prop = RNA_def_property(srna, "holdout", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_HOLDOUT); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_icon(prop, ICON_CLIPUV_HLT, -1); RNA_def_property_ui_text(prop, "Holdout", "Mask out objects in collection from view layer"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_update"); prop = RNA_def_property(srna, "indirect_only", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_INDIRECT_ONLY); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_icon(prop, ICON_MOD_PHYSICS, 0); RNA_def_property_ui_text( prop, "Indirect Only", @@ -291,12 +322,12 @@ static void rna_def_layer_collection(BlenderRNA *brna) prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_RESTRICT_VIEW); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1); RNA_def_property_ui_text( prop, "Disable Viewport", "Disable collection in viewport for this view layer"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_update"); + /* Run-time flags. */ prop = RNA_def_property(srna, "is_visible", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "runtime_flag", LAYER_COLLECTION_VISIBLE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -374,6 +405,15 @@ static void rna_def_object_base(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_SELECTED); RNA_def_property_ui_text(prop, "Select", "Object base selection state"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_select_update"); + + prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_HIDDEN); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1); + RNA_def_property_ui_text( + prop, "Disable Viewport", "Disable object base in viewport for this view layer"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_hide_viewport_update"); } void RNA_def_view_layer(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 219445f629f..1e90fba0eb6 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2800,11 +2800,11 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Rigid Body Constraint", "Constraint constraining rigid bodies"); /* restrict */ - prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_VIEW); + prop = RNA_def_property(srna, "hide_instance", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_INSTANCE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_ui_text(prop, "Disable View", "Disable object in the viewport"); - RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1); + RNA_def_property_ui_icon(prop, ICON_LINKED, -1); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_hide_update"); prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ba14329d267..0eb5b52baf0 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2763,9 +2763,47 @@ static void rna_def_space_outliner(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sort Alphabetically", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); - prop = RNA_def_property(srna, "show_restrict_columns", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SO_HIDE_RESTRICTCOLS); - RNA_def_property_ui_text(prop, "Show Restriction Columns", "Show column"); + /* Granular restriction column option. */ + prop = RNA_def_property(srna, "show_restrict_column_enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_ENABLE); + RNA_def_property_ui_text(prop, "Enabled/Disabled", "Enable/ddisable"); + RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + + prop = RNA_def_property(srna, "show_restrict_column_selectable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_SELECTABLE); + RNA_def_property_ui_text(prop, "Selectable", "Selectable"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + + prop = RNA_def_property(srna, "show_restrict_column_instance", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_INSTANCE); + RNA_def_property_ui_text(prop, "Instance Visibility", "Instance visibility"); + RNA_def_property_ui_icon(prop, ICON_LINKED, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + + prop = RNA_def_property(srna, "show_restrict_column_viewport", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_VIEWPORT); + RNA_def_property_ui_text(prop, "Viewport Visibility", "Viewport visibility"); + RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + + prop = RNA_def_property(srna, "show_restrict_column_render", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_RENDER); + RNA_def_property_ui_text(prop, "Render Visibility", "Render visibility"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + + prop = RNA_def_property(srna, "show_restrict_column_holdout", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_HOLDOUT); + RNA_def_property_ui_text(prop, "Holdout", "Holdout"); + RNA_def_property_ui_icon(prop, ICON_CLIPUV_DEHLT, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); + + prop = RNA_def_property(srna, "show_restrict_column_indirect_only", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "show_restrict_flags", SO_RESTRICT_INDIRECT_ONLY); + RNA_def_property_ui_text(prop, "Indirect Only", "Indirect only"); + RNA_def_property_ui_icon(prop, ICON_MOD_PHYSICS, 0); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL); /* Filters. */ |