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:
authorSybren A. Stüvel <sybren@blender.org>2021-09-28 16:04:55 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-09-28 16:04:55 +0300
commit3674347849311b3722c27c67a61b1fac5528bd6b (patch)
tree1aa54d5f4b2e36952e15120ea89ce60aa823b082
parent73b2ecb2975eb0438473e65c4c8f691e36524399 (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
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py5
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py3
-rw-r--r--source/blender/editors/asset/ED_asset_mark_clear.h15
-rw-r--r--source/blender/editors/asset/intern/asset_mark_clear.cc3
-rw-r--r--source/blender/editors/asset/intern/asset_ops.cc87
5 files changed, 103 insertions, 10 deletions
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index ee9a8cc3346..b47404fd727 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -786,9 +786,10 @@ class ASSETBROWSER_MT_context_menu(AssetBrowserMenu, Menu):
layout.separator()
- sub = layout.row()
+ sub = layout.column()
sub.operator_context = 'EXEC_DEFAULT'
- sub.operator("asset.clear", text="Clear Asset")
+ sub.operator("asset.clear", text="Clear Asset").set_fake_user = False
+ sub.operator("asset.clear", text="Clear Asset (Set Fake User)").set_fake_user = True
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index febd064147f..3d18160d90f 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -323,7 +323,8 @@ class OUTLINER_MT_asset(Menu):
space = context.space_data
layout.operator("asset.mark")
- layout.operator("asset.clear")
+ layout.operator("asset.clear", text="Clear Asset").set_fake_user = False
+ layout.operator("asset.clear", text="Clear Asset (Set Fake User)").set_fake_user = True
class OUTLINER_PT_filter(Panel):
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");
}
/* -------------------------------------------------------------------- */