Assets: Allow specific data-block types to be enabled by default

Updates UI code so that we can enable the asset UI for specific data-block
types by default, i.e. irrespective of the "Extended Asset Browser"
experimental feature.
"Mark as Asset" and "Clear Asset" are always visible in the Outliner context
menu now, but are grayed out if not applicable and show a disabled hint in the
tooltip.

A known side-effect of this: The "Mark as Asset" and "Clear Asset" operators
are enabled for action data-blocks now, even though only pose actions created
through the Pose Libraries add-on are supported. If this is something worth
addressing is being discussed still.

Differential Revision: https://developer.blender.org/D12955

Reviewed by: Sybren Stüvel
This commit is contained in:
Julian Eisel 2021-10-21 20:42:41 +02:00
parent 9aab1a4626
commit a286148799
Notes: blender-bot 2023-02-14 02:30:11 +01:00
Referenced by issue #91752, Enable material and world support by default, disable the rest
10 changed files with 197 additions and 44 deletions

View File

@ -190,8 +190,7 @@ class FILEBROWSER_PT_filter(FileBrowserPanel, Panel):
sub = row.column(align=True)
if context.preferences.experimental.use_extended_asset_browser:
sub.prop(params, "use_filter_asset_only")
sub.prop(params, "use_filter_asset_only")
filter_id = params.filter_id
for identifier in dir(filter_id):

View File

@ -313,10 +313,6 @@ class OUTLINER_MT_object(Menu):
class OUTLINER_MT_asset(Menu):
bl_label = "Assets"
@classmethod
def poll(cls, context):
return context.preferences.experimental.use_extended_asset_browser
def draw(self, context):
layout = self.layout

View File

@ -40,6 +40,7 @@ set(SRC
intern/asset_mark_clear.cc
intern/asset_ops.cc
intern/asset_temp_id_consumer.cc
intern/asset_type.cc
ED_asset_catalog.h
ED_asset_catalog.hh
@ -50,6 +51,7 @@ set(SRC
ED_asset_list.hh
ED_asset_mark_clear.h
ED_asset_temp_id_consumer.h
ED_asset_type.h
intern/asset_library_reference.hh
)

View File

@ -0,0 +1,55 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/** \file
* \ingroup edasset
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct ID;
bool ED_asset_type_id_is_non_experimental(const struct ID *id);
/**
* Check if the asset type for \a id (which doesn't need to be an asset right now) can be an asset,
* respecting the "Extended Asset Browser" experimental feature flag.
*/
bool ED_asset_type_is_supported(const ID *id);
/**
* Get the filter flags (subset of #FILTER_ID_ALL) representing the asset ID types that may be
* turned into assets, respecting the "Extended Asset Browser" experimental feature flag.
* \note Does not check for #BKE_id_can_be_asset(), so may return filter flags for IDs that can
* never be assets.
*/
int64_t ED_asset_types_supported_as_filter_flags(void);
/**
* Utility: A string enumerating the non-experimental asset types. This is useful info to
* the user, it should be displayed in tooltips or messages. Macro to support concatenating static
* strings with this (not all UI code supports dynamic strings nicely).
* Should start with a consonant, so usages can prefix it with "a" (not "an").
*/
#define ED_ASSET_TYPE_IDS_NON_EXPERIMENTAL_UI_STRING "Pose Action"
#ifdef __cplusplus
}
#endif

View File

@ -39,6 +39,7 @@
#include "ED_asset_list.h"
#include "ED_asset_mark_clear.h"
#include "ED_asset_type.h"
bool ED_asset_mark_id(ID *id)
{
@ -81,5 +82,9 @@ bool ED_asset_clear_id(ID *id)
bool ED_asset_can_mark_single_from_context(const bContext *C)
{
/* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */
return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != nullptr;
const ID *id = static_cast<ID *>(CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data);
if (!id) {
return false;
}
return ED_asset_type_is_supported(id);
}

View File

@ -18,6 +18,7 @@
* \ingroup edasset
*/
#include "BKE_asset.h"
#include "BKE_asset_catalog.hh"
#include "BKE_asset_library.hh"
#include "BKE_context.h"
@ -45,30 +46,6 @@ using namespace blender;
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_experimental_feature_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_experimental_feature_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).
@ -94,26 +71,51 @@ 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)
/**
* Information about what's contained in a #PointerRNAVec, returned by
* #asset_operation_get_id_vec_stats_from_context().
*/
struct IDVecStats {
bool has_asset = false;
bool has_supported_type = false;
bool is_single = false;
};
/**
* Helper to report stats about the IDs in context. Operator polls use this, also to report a
* helpful disabled hint to the user.
*/
static IDVecStats asset_operation_get_id_vec_stats_from_context(const bContext *C)
{
PointerRNAVec nonexperimental;
PointerRNAVec pointers = asset_operation_get_ids_from_context(C);
IDVecStats stats;
stats.is_single = pointers.size() == 1;
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);
if (ED_asset_type_is_supported(id)) {
stats.has_supported_type = true;
}
if (ID_IS_ASSET(id)) {
stats.has_asset = true;
}
}
return nonexperimental;
return stats;
}
static bool asset_type_is_nonexperimental(const ID_Type id_type)
static const char *asset_operation_unsupported_type_msg(const bool is_single)
{
/* 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);
const char *msg_single =
"Data-block does not support asset operations - must be "
"a " ED_ASSET_TYPE_IDS_NON_EXPERIMENTAL_UI_STRING;
const char *msg_multiple =
"No data-block selected that supports asset operations - select at least "
"one " ED_ASSET_TYPE_IDS_NON_EXPERIMENTAL_UI_STRING;
return is_single ? msg_single : msg_multiple;
}
/* -------------------------------------------------------------------- */
@ -203,6 +205,18 @@ static int asset_mark_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static bool asset_mark_poll(bContext *C)
{
IDVecStats ctx_stats = asset_operation_get_id_vec_stats_from_context(C);
if (!ctx_stats.has_supported_type) {
CTX_wm_operator_poll_msg_set(C, asset_operation_unsupported_type_msg(ctx_stats.is_single));
return false;
}
return true;
}
static void ASSET_OT_mark(wmOperatorType *ot)
{
ot->name = "Mark as Asset";
@ -212,7 +226,7 @@ static void ASSET_OT_mark(wmOperatorType *ot)
ot->idname = "ASSET_OT_mark";
ot->exec = asset_mark_exec;
ot->poll = asset_operation_experimental_feature_poll;
ot->poll = asset_mark_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@ -315,6 +329,24 @@ static int asset_clear_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static bool asset_clear_poll(bContext *C)
{
IDVecStats ctx_stats = asset_operation_get_id_vec_stats_from_context(C);
if (!ctx_stats.has_asset) {
const char *msg_single = "Data-block is not marked as asset";
const char *msg_multiple = "No data-block selected that is marked as asset";
CTX_wm_operator_poll_msg_set(C, ctx_stats.is_single ? msg_single : msg_multiple);
return false;
}
if (!ctx_stats.has_supported_type) {
CTX_wm_operator_poll_msg_set(C, asset_operation_unsupported_type_msg(ctx_stats.is_single));
return false;
}
return true;
}
static char *asset_clear_get_description(struct bContext *UNUSED(C),
struct wmOperatorType *UNUSED(op),
struct PointerRNA *values)

View File

@ -0,0 +1,62 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/** \file
* \ingroup edasset
*/
#include "BLI_utildefines.h"
#include "DNA_userdef_types.h"
#include "BKE_lib_id.h"
#include "ED_asset_type.h"
bool ED_asset_type_id_is_non_experimental(const ID *id)
{
/* Remember to update #ED_ASSET_TYPE_IDS_NON_EXPERIMENTAL_UI_STRING and
* #asset_type_ids_non_experimental_as_filter_flags() with this! */
return ELEM(GS(id->name), ID_AC);
}
static int64_t asset_type_ids_non_experimental_as_filter_flags()
{
return FILTER_ID_AC;
}
bool ED_asset_type_is_supported(const ID *id)
{
if (!BKE_id_can_be_asset(id)) {
return false;
}
if (U.experimental.use_extended_asset_browser) {
/* The "Extended Asset Browser" experimental feature flag enables all asset types that can
* technically be assets. */
return true;
}
return ED_asset_type_id_is_non_experimental(id);
}
int64_t ED_asset_types_supported_as_filter_flags()
{
if (U.experimental.use_extended_asset_browser) {
return FILTER_ID_ALL;
}
return asset_type_ids_non_experimental_as_filter_flags();
}

View File

@ -43,6 +43,7 @@ void ED_operatortypes_asset(void);
#include "../asset/ED_asset_list.h"
#include "../asset/ED_asset_mark_clear.h"
#include "../asset/ED_asset_temp_id_consumer.h"
#include "../asset/ED_asset_type.h"
/* C++ only headers. */
#ifdef __cplusplus

View File

@ -937,7 +937,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
}
/* If the button represents an id, it can set the "id" context pointer. */
if (U.experimental.use_extended_asset_browser && ED_asset_can_mark_single_from_context(C)) {
if (ED_asset_can_mark_single_from_context(C)) {
ID *id = CTX_data_pointer_get_type(C, "id", &RNA_ID).data;
/* Gray out items depending on if data-block is an asset. Preferably this could be done via

View File

@ -43,6 +43,7 @@
#include "WM_message.h"
#include "WM_types.h"
#include "ED_asset.h"
#include "ED_fileselect.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@ -327,8 +328,8 @@ static void file_refresh(const bContext *C, ScrArea *area)
}
if (ED_fileselect_is_asset_browser(sfile)) {
/* Only poses supported as non-experimental right now. */
params->filter_id = U.experimental.use_extended_asset_browser ? FILTER_ID_ALL : FILTER_ID_AC;
/* Ask the asset code for appropriate ID filter flags for the supported assets. */
params->filter_id = ED_asset_types_supported_as_filter_flags();
}
filelist_settype(sfile->files, params->type);