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
This commit is contained in:
parent
73b2ecb297
commit
3674347849
|
@ -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()
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
Loading…
Reference in New Issue