diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2021-09-28 16:04:55 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2021-09-28 16:04:55 +0300 |
commit | 3674347849311b3722c27c67a61b1fac5528bd6b (patch) | |
tree | 1aa54d5f4b2e36952e15120ea89ce60aa823b082 /source | |
parent | 73b2ecb2975eb0438473e65c4c8f691e36524399 (diff) |
Assets: Clear Asset operator variants for clearing/setting Fake User
The Clear Asset operator (`ASSET_OT_clear`) now clears the Fake User.
This makes it symmetrical with the Mark Asset (`ASSET_OT_mark`)
operator, which sets Fake User to ensure assets are always saved to
disk.
Clear Asset now also has a `set_fake_user` boolean option, which allows
users to Clear Asset and set Fake User in one go.
The asset browser now shows these options in the context menu:
- Clear Asset: also clears Fake User. This makes it possible to actually
remove assets from the blend file without leaving the Asset Browser.
- Clear Asset (Set Fake User): keeps the Fake User bit set. This makes
it possible to "hide" the asset from the asset browser, without
loosing the actual data.
Internally, the `ED_asset_clear_id(id)` function now always clears the
Fake User bit. If it was intended that this bit was kept set, it's up to
the caller to explicitly call `id_fake_user_set(id)` afterwards.
Manifest Task: T90844
Reviewed By: Severin
Differential Revision: https://developer.blender.org/D12663
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/asset/ED_asset_mark_clear.h | 15 | ||||
-rw-r--r-- | source/blender/editors/asset/intern/asset_mark_clear.cc | 3 | ||||
-rw-r--r-- | source/blender/editors/asset/intern/asset_ops.cc | 87 |
3 files changed, 98 insertions, 7 deletions
diff --git a/source/blender/editors/asset/ED_asset_mark_clear.h b/source/blender/editors/asset/ED_asset_mark_clear.h index 7524ec6b02a..d8b8f15a109 100644 --- a/source/blender/editors/asset/ED_asset_mark_clear.h +++ b/source/blender/editors/asset/ED_asset_mark_clear.h @@ -27,7 +27,22 @@ extern "C" { struct ID; struct bContext; +/** + * Mark the datablock as asset. + * + * To ensure the datablock is saved, this sets Fake User. + * + * \return whether the datablock was marked as asset; false when it is not capable of becoming an + * asset, or when it already was an asset. */ bool ED_asset_mark_id(const struct bContext *C, struct ID *id); + +/** + * Remove the asset metadata, turning the ID into a "normal" ID. + * + * This clears the Fake User. If for some reason the datablock is meant to be saved anyway, the + * caller is responsible for explicitly setting the Fake User. + * + * \return whether the asset metadata was actually removed; false when the ID was not an asset. */ bool ED_asset_clear_id(struct ID *id); bool ED_asset_can_mark_single_from_context(const struct bContext *C); diff --git a/source/blender/editors/asset/intern/asset_mark_clear.cc b/source/blender/editors/asset/intern/asset_mark_clear.cc index ba348e38823..8290124c209 100644 --- a/source/blender/editors/asset/intern/asset_mark_clear.cc +++ b/source/blender/editors/asset/intern/asset_mark_clear.cc @@ -67,8 +67,7 @@ bool ED_asset_clear_id(ID *id) return false; } BKE_asset_metadata_free(&id->asset_data); - /* Don't clear fake user here, there's no guarantee that it was actually set by - * #ED_asset_mark_id(), it might have been something/someone else. */ + id_fake_user_clear(id); /* Important for asset storage to update properly! */ ED_assetlist_storage_tag_main_data_dirty(); diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc index d69a2cae94d..a18b7649060 100644 --- a/source/blender/editors/asset/intern/asset_ops.cc +++ b/source/blender/editors/asset/intern/asset_ops.cc @@ -19,6 +19,7 @@ */ #include "BKE_context.h" +#include "BKE_lib_id.h" #include "BKE_report.h" #include "BLI_vector.hh" @@ -26,6 +27,7 @@ #include "ED_asset.h" #include "RNA_access.h" +#include "RNA_define.h" #include "WM_api.h" #include "WM_types.h" @@ -34,11 +36,30 @@ using PointerRNAVec = blender::Vector<PointerRNA>; +static PointerRNAVec asset_operation_get_ids_from_context(const bContext *C); +static PointerRNAVec asset_operation_get_nonexperimental_ids_from_context(const bContext *C); +static bool asset_type_is_nonexperimental(const ID_Type id_type); + static bool asset_operation_poll(bContext * /*C*/) { + /* At this moment only the pose library is non-experimental. Still, directly marking arbitrary + * Actions as asset is not part of the stable functionality; instead, the pose library "Create + * Pose Asset" operator should be used. Actions can still be marked as asset via + * `the_action.asset_mark()` (so a function call instead of this operator), which is what the + * pose library uses internally. */ return U.experimental.use_extended_asset_browser; } +static bool asset_clear_poll(bContext *C) +{ + if (asset_operation_poll(C)) { + return true; + } + + PointerRNAVec pointers = asset_operation_get_nonexperimental_ids_from_context(C); + return !pointers.is_empty(); +} + /** * Return the IDs to operate on as PointerRNA vector. Either a single one ("id" context member) or * multiple ones ("selected_ids" context member). @@ -64,6 +85,28 @@ static PointerRNAVec asset_operation_get_ids_from_context(const bContext *C) return ids; } +static PointerRNAVec asset_operation_get_nonexperimental_ids_from_context(const bContext *C) +{ + PointerRNAVec nonexperimental; + PointerRNAVec pointers = asset_operation_get_ids_from_context(C); + for (PointerRNA &ptr : pointers) { + BLI_assert(RNA_struct_is_ID(ptr.type)); + + ID *id = static_cast<ID *>(ptr.data); + if (asset_type_is_nonexperimental(GS(id->name))) { + nonexperimental.append(ptr); + } + } + return nonexperimental; +} + +static bool asset_type_is_nonexperimental(const ID_Type id_type) +{ + /* At this moment only the pose library is non-experimental. For simplicity, allow asset + * operations on all Action datablocks (even though pose assets are limited to single frames). */ + return ELEM(id_type, ID_AC); +} + /* -------------------------------------------------------------------- */ class AssetMarkHelper { @@ -166,7 +209,13 @@ static void ASSET_OT_mark(wmOperatorType *ot) /* -------------------------------------------------------------------- */ class AssetClearHelper { + const bool set_fake_user_; + public: + AssetClearHelper(const bool set_fake_user) : set_fake_user_(set_fake_user) + { + } + void operator()(PointerRNAVec &ids); void reportResults(const bContext *C, ReportList &reports) const; @@ -191,10 +240,16 @@ void AssetClearHelper::operator()(PointerRNAVec &ids) continue; } - if (ED_asset_clear_id(id)) { - stats.tot_cleared++; - stats.last_id = id; + if (!ED_asset_clear_id(id)) { + continue; + } + + if (set_fake_user_) { + id_fake_user_set(id); } + + stats.tot_cleared++; + stats.last_id = id; } } @@ -234,7 +289,8 @@ static int asset_clear_exec(bContext *C, wmOperator *op) { PointerRNAVec ids = asset_operation_get_ids_from_context(C); - AssetClearHelper clear_helper; + const bool set_fake_user = RNA_boolean_get(op->ptr, "set_fake_user"); + AssetClearHelper clear_helper(set_fake_user); clear_helper(ids); clear_helper.reportResults(C, *op->reports); @@ -248,18 +304,39 @@ static int asset_clear_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static char *asset_clear_get_description(struct bContext *UNUSED(C), + struct wmOperatorType *UNUSED(op), + struct PointerRNA *values) +{ + const bool set_fake_user = RNA_boolean_get(values, "set_fake_user"); + if (!set_fake_user) { + return nullptr; + } + + return BLI_strdup( + "Delete all asset metadata, turning the selected asset data-blocks back into normal " + "data-blocks, and set Fake User to ensure the data-blocks will still be saved"); +} + static void ASSET_OT_clear(wmOperatorType *ot) { ot->name = "Clear Asset"; ot->description = "Delete all asset metadata and turn the selected asset data-blocks back into normal " "data-blocks"; + ot->get_description = asset_clear_get_description; ot->idname = "ASSET_OT_clear"; ot->exec = asset_clear_exec; - ot->poll = asset_operation_poll; + ot->poll = asset_clear_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, + "set_fake_user", + false, + "Set Fake User", + "Ensure the data-block is saved, even when it is no longer marked as asset"); } /* -------------------------------------------------------------------- */ |