WIP: Basic support for registering asset shelf as a type in BPY #104991

Closed
Julian Eisel wants to merge 73 commits from JulianEisel:temp-asset-shelf-type-bpy into asset-shelf

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 73 additions and 22 deletions
Showing only changes of commit 2cbf647d9c - Show all commits

View File

@ -409,7 +409,11 @@ typedef struct AssetShelfType {
int space_type;
/* Determine if the asset shelf should be visible or not. */
bool (*poll)(const struct bContext *C, struct AssetShelfType *shelf_type);
bool (*poll)(const struct bContext *C, const struct AssetShelfType *shelf_type);
/* Determine if an individual asset should be visible or not. May be a temporary design,
* visibility should be first and foremost controlled by asset traits. */
bool (*asset_poll)(const struct AssetShelfType *shelf_type, const struct AssetHandle *asset);
/* RNA integration */
ExtensionRNA rna_ext;

View File

@ -7,6 +7,7 @@
#include "AS_asset_library.hh"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@ -106,6 +107,29 @@ static std::optional<asset_system::AssetCatalogFilter> catalog_filter_from_shelf
return library->catalog_service->create_catalog_filter(active_catalog->catalog_id);
}
/* TODO calling a (.py defined) callback for every asset isn't exactly great. Should be a temporary
solution until there is proper filtering by asset traits. */
/**
* Returns true if the asset should be visible. That is, if any of the visible asset shelves has no
* poll function (all assets should be displayed), or its #AssetShelfType.asset_poll function
* returns true.
*/
static bool asset_shelf_asset_poll(const SpaceType &space_type,
const bContext &C,
const AssetHandle &asset)
{
LISTBASE_FOREACH (AssetShelfType *, shelf_type, &space_type.asset_shelf_types) {
if (!shelf_type->poll || !shelf_type->poll(&C, shelf_type)) {
continue;
}
if (!shelf_type->asset_poll || shelf_type->asset_poll(shelf_type, &asset)) {
return true;
}
}
return false;
}
void uiTemplateAssetShelf(uiLayout *layout,
const bContext *C,
const AssetFilterSettings *filter_settings)
@ -116,6 +140,8 @@ void uiTemplateAssetShelf(uiLayout *layout,
const AssetShelfSettings *shelf_settings = static_cast<AssetShelfSettings *>(
shelf_settings_ptr.data);
Vector<decltype(AssetShelfType::asset_poll)> asset_polls;
ED_assetlist_storage_fetch(library_ref, C);
ED_assetlist_ensure_previews_job(library_ref, C);
@ -139,8 +165,13 @@ void uiTemplateAssetShelf(uiLayout *layout,
uiLayout *box = uiLayoutBox(layout);
uiLayout *row = uiLayoutRow(box, false);
const SpaceLink *space_link = CTX_wm_space_data(C);
const SpaceType *space_type = BKE_spacetype_from_id(space_link->spacetype);
ED_assetlist_iterate(*library_ref, [&](AssetHandle asset) {
if (!asset_shelf_asset_poll(*space_type, *C, asset)) {
return true;
}
if (!ED_asset_filter_matches_asset(filter_settings, &asset)) {
/* Don't do anything else, but return true to continue iterating. */
return true;

View File

@ -1022,7 +1022,30 @@ static StructRNA *rna_Menu_refine(PointerRNA *mtr)
/* Asset Shelf */
static bool asset_shelf_poll(const bContext *C, AssetShelfType *shelf_type)
static bool asset_shelf_asset_poll(const AssetShelfType *shelf_type, const AssetHandle *asset)
{
extern FunctionRNA rna_AssetShelf_asset_poll___func;
PointerRNA ptr;
RNA_pointer_create(NULL, shelf_type->rna_ext.srna, NULL, &ptr); /* dummy */
FunctionRNA *func = &rna_AssetShelf_asset_poll___func;
ParameterList list;
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "asset_handle", &asset);
shelf_type->rna_ext.call(NULL, &ptr, func, &list);
void *ret;
RNA_parameter_get_lookup(&list, "visible", &ret);
/* Get the value before freeing. */
const bool is_visible = *(bool *)ret;
RNA_parameter_list_free(&list);
return is_visible;
}
static bool asset_shelf_poll(const bContext *C, const AssetShelfType *shelf_type)
{
extern FunctionRNA rna_AssetShelf_poll_func;
@ -1083,7 +1106,7 @@ static StructRNA *rna_AssetShelf_register(Main *bmain,
dummy_shelf.type = &dummy_shelf_type;
RNA_pointer_create(NULL, &RNA_AssetShelf, &dummy_shelf, &dummy_shelf_type_ptr);
int have_function[1];
int have_function[2];
/* validate the python class */
if (validate(&dummy_shelf_type_ptr, data, have_function) != 0) {
@ -1131,6 +1154,7 @@ static StructRNA *rna_AssetShelf_register(Main *bmain,
RNA_struct_blender_type_set(shelf_type->rna_ext.srna, shelf_type);
shelf_type->poll = have_function[0] ? asset_shelf_poll : NULL;
shelf_type->asset_poll = have_function[1] ? asset_shelf_asset_poll : NULL;
BLI_addtail(&space_type->asset_shelf_types, shelf_type);
@ -2000,6 +2024,17 @@ static void rna_def_asset_shelf(BlenderRNA *brna)
RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func = RNA_def_function(srna, "asset_poll__", NULL);
RNA_def_function_ui_description(
func,
"TEMPORARY DESIGN; Expect compatibility breakage. Determine if an asset should be visible "
"in the asset shelf. If this method returns a non-null output, then the asset shelf will be "
"visible");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
parm = RNA_def_pointer(func, "asset_handle", "AssetHandle", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
static void rna_def_asset_shelf_settings(BlenderRNA *brna)

View File

@ -714,15 +714,6 @@ static const EnumPropertyItem *rna_uiTemplateAssetView_filter_id_types_itemf(
return items;
}
static void rna_uiTemplateAssetShelf(uiLayout *layout, bContext *C, int filter_id_types)
{
AssetFilterSettings filter_settings = {
.id_types = filter_id_types ? filter_id_types : FILTER_ID_ALL,
};
uiTemplateAssetShelf(layout, C, &filter_settings);
}
static uiLayout *rna_uiLayoutRowWithHeading(
uiLayout *layout, bool align, const char *heading, const char *heading_ctxt, bool translate)
{
@ -1967,16 +1958,6 @@ void RNA_api_ui_layout(StructRNA *srna)
"Operator properties to fill in for the custom drag operator passed to the template");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_function_output(func, parm);
func = RNA_def_function(srna, "template_asset_shelf", "rna_uiTemplateAssetShelf");
RNA_def_function_ui_description(func,
"Item. A list of assets in a horizontally scrollable layout. "
"Meant to be placed in a 'ASSET_SHELF' region");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_property(func, "filter_id_types", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(parm, DummyRNA_NULL_items);
RNA_def_property_enum_funcs(parm, NULL, NULL, "rna_uiTemplateAssetView_filter_id_types_itemf");
RNA_def_property_flag(parm, PROP_ENUM_FLAG);
}
#endif