Assets: Show all assets indirectly nested inside the active catalog

The asset catalog design was always that the active catalog would also
display all assets of its child catalogs (or grand-childs, etc.). This
is one of the main characteristics that differentiates catalogs from
usual directories.

Sybren prepared this on the asset catalog backend side with
56ce51d1f7. This integrates it into the Asset Browser backend and the
UI.
This commit is contained in:
Julian Eisel 2021-10-04 19:46:15 +02:00
parent ffa20de050
commit 3391a2ef1d
3 changed files with 148 additions and 31 deletions

View File

@ -358,6 +358,97 @@ bool AssetCatalogTreeViewUnassignedItem::on_drop(const wmDrag &drag)
} // namespace blender::ed::asset_browser
namespace blender::ed::asset_browser {
class AssetCatalogFilterSettings {
public:
eFileSel_Params_AssetCatalogVisibility asset_catalog_visibility;
bUUID asset_catalog_id;
std::unique_ptr<AssetCatalogFilter> catalog_filter;
};
} // namespace blender::ed::asset_browser
using namespace blender::ed::asset_browser;
FileAssetCatalogFilterSettingsHandle *file_create_asset_catalog_filter_settings()
{
AssetCatalogFilterSettings *filter_settings = OBJECT_GUARDED_NEW(AssetCatalogFilterSettings);
return reinterpret_cast<FileAssetCatalogFilterSettingsHandle *>(filter_settings);
}
void file_delete_asset_catalog_filter_settings(
FileAssetCatalogFilterSettingsHandle **filter_settings_handle)
{
AssetCatalogFilterSettings **filter_settings = reinterpret_cast<AssetCatalogFilterSettings **>(
filter_settings_handle);
OBJECT_GUARDED_SAFE_DELETE(*filter_settings, AssetCatalogFilterSettings);
}
/**
* \return True if the file list should update its filtered results (e.g. because filtering
* parameters changed).
*/
bool file_set_asset_catalog_filter_settings(
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
::bUUID catalog_id)
{
AssetCatalogFilterSettings *filter_settings = reinterpret_cast<AssetCatalogFilterSettings *>(
filter_settings_handle);
bool needs_update = false;
if (filter_settings->asset_catalog_visibility != catalog_visibility) {
filter_settings->asset_catalog_visibility = catalog_visibility;
needs_update = true;
}
if (filter_settings->asset_catalog_visibility == FILE_SHOW_ASSETS_FROM_CATALOG &&
!BLI_uuid_equal(filter_settings->asset_catalog_id, catalog_id)) {
filter_settings->asset_catalog_id = catalog_id;
needs_update = true;
}
return needs_update;
}
void file_ensure_updated_catalog_filter_data(
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
const ::AssetLibrary *asset_library)
{
AssetCatalogFilterSettings *filter_settings = reinterpret_cast<AssetCatalogFilterSettings *>(
filter_settings_handle);
const AssetCatalogService *catalog_service = BKE_asset_library_get_catalog_service(
asset_library);
if (filter_settings->asset_catalog_visibility == FILE_SHOW_ASSETS_FROM_CATALOG) {
filter_settings->catalog_filter = std::make_unique<AssetCatalogFilter>(
catalog_service->create_catalog_filter(filter_settings->asset_catalog_id));
}
}
bool file_is_asset_visible_in_catalog_filter_settings(
const FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
const AssetMetaData *asset_data)
{
const AssetCatalogFilterSettings *filter_settings =
reinterpret_cast<const AssetCatalogFilterSettings *>(filter_settings_handle);
switch (filter_settings->asset_catalog_visibility) {
case FILE_SHOW_ASSETS_WITHOUT_CATALOG:
return BLI_uuid_is_nil(asset_data->catalog_id);
case FILE_SHOW_ASSETS_FROM_CATALOG:
return filter_settings->catalog_filter->contains(asset_data->catalog_id);
case FILE_SHOW_ASSETS_ALL_CATALOGS:
/* All asset files should be visible. */
return true;
}
BLI_assert_unreachable();
return false;
}
/* ---------------------------------------------------------------------- */
void file_create_asset_catalog_tree_view_in_layout(::AssetLibrary *asset_library,

View File

@ -23,6 +23,8 @@
#pragma once
#include "DNA_space_types.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -163,6 +165,26 @@ void file_path_to_ui_path(const char *path, char *r_pathi, int max_size);
/* asset_catalog_tree_view.cc */
/* C-handle for #ed::asset_browser::AssetCatalogFilterSettings. */
typedef struct FileAssetCatalogFilterSettingsHandle FileAssetCatalogFilterSettingsHandle;
FileAssetCatalogFilterSettingsHandle *file_create_asset_catalog_filter_settings(void);
void file_delete_asset_catalog_filter_settings(
FileAssetCatalogFilterSettingsHandle **filter_settings_handle);
/**
* \return True if the stored filter settings were modified.
*/
bool file_set_asset_catalog_filter_settings(
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
bUUID catalog_id);
void file_ensure_updated_catalog_filter_data(
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
const struct AssetLibrary *asset_library);
bool file_is_asset_visible_in_catalog_filter_settings(
const FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
const AssetMetaData *asset_data);
void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library,
struct uiLayout *layout,
struct SpaceFile *space_file,

View File

@ -89,6 +89,7 @@
#include "atomic_ops.h"
#include "file_intern.h"
#include "filelist.h"
#define FILEDIR_NBR_ENTRIES_UNSET -1
@ -371,8 +372,7 @@ typedef struct FileListFilter {
char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */
short flags;
eFileSel_Params_AssetCatalogVisibility asset_catalog_visibility;
bUUID asset_catalog_id;
FileAssetCatalogFilterSettingsHandle *asset_catalog_filter;
} FileListFilter;
/* FileListFilter.flags */
@ -426,6 +426,8 @@ typedef struct FileList {
/* Filter an entry of current filelist. */
bool (*filter_fn)(struct FileListInternEntry *, const char *, FileListFilter *);
/* Executed before filtering individual items, to set up additional filter data. */
void (*prepare_filter_fn)(const struct FileList *, FileListFilter *);
short tags; /* FileListTags */
} FileList;
@ -906,27 +908,26 @@ static AssetMetaData *filelist_file_internal_get_asset_data(const FileListIntern
return local_id ? local_id->asset_data : file->imported_asset_data;
}
static bool is_filtered_asset(FileListInternEntry *file, FileListFilter *filter)
static void prepare_filter_asset_library(const FileList *filelist, FileListFilter *filter)
{
const AssetMetaData *asset_data = filelist_file_internal_get_asset_data(file);
bool is_visible = false;
switch (filter->asset_catalog_visibility) {
case FILE_SHOW_ASSETS_WITHOUT_CATALOG:
is_visible = BLI_uuid_is_nil(asset_data->catalog_id);
break;
case FILE_SHOW_ASSETS_FROM_CATALOG:
/* TODO show all assets that are in child catalogs of the selected catalog. */
is_visible = !BLI_uuid_is_nil(filter->asset_catalog_id) &&
BLI_uuid_equal(filter->asset_catalog_id, asset_data->catalog_id);
break;
case FILE_SHOW_ASSETS_ALL_CATALOGS:
/* All asset files should be visible. */
is_visible = true;
break;
/* Not used yet for the asset view template. */
if (!filter->asset_catalog_filter) {
return;
}
return is_visible;
file_ensure_updated_catalog_filter_data(filter->asset_catalog_filter, filelist->asset_library);
}
static bool is_filtered_asset(FileListInternEntry *file, FileListFilter *filter)
{
/* Not used yet for the asset view template. */
if (!filter->asset_catalog_filter) {
return true;
}
const AssetMetaData *asset_data = filelist_file_internal_get_asset_data(file);
return file_is_asset_visible_in_catalog_filter_settings(filter->asset_catalog_filter,
asset_data);
}
static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileListFilter *filter)
@ -999,6 +1000,10 @@ void filelist_filter(FileList *filelist)
}
}
if (filelist->prepare_filter_fn) {
filelist->prepare_filter_fn(filelist, &filelist->filter_data);
}
filtered_tmp = MEM_mallocN(sizeof(*filtered_tmp) * (size_t)num_files, __func__);
/* Filter remap & count how many files are left after filter in a single loop. */
@ -1090,20 +1095,15 @@ void filelist_set_asset_catalog_filter_options(
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
const bUUID *catalog_id)
{
bool update = false;
if (filelist->filter_data.asset_catalog_visibility != catalog_visibility) {
filelist->filter_data.asset_catalog_visibility = catalog_visibility;
update = true;
if (!filelist->filter_data.asset_catalog_filter) {
/* There's no filter data yet. */
filelist->filter_data.asset_catalog_filter = file_create_asset_catalog_filter_settings();
}
if (filelist->filter_data.asset_catalog_visibility == FILE_SHOW_ASSETS_FROM_CATALOG &&
catalog_id && !BLI_uuid_equal(filelist->filter_data.asset_catalog_id, *catalog_id)) {
filelist->filter_data.asset_catalog_id = *catalog_id;
update = true;
}
const bool needs_update = file_set_asset_catalog_filter_settings(
filelist->filter_data.asset_catalog_filter, catalog_visibility, *catalog_id);
if (update) {
if (needs_update) {
filelist_tag_needs_filtering(filelist);
}
}
@ -1803,11 +1803,13 @@ void filelist_settype(FileList *filelist, short type)
case FILE_ASSET_LIBRARY:
filelist->check_dir_fn = filelist_checkdir_lib;
filelist->read_job_fn = filelist_readjob_asset_library;
filelist->prepare_filter_fn = prepare_filter_asset_library;
filelist->filter_fn = is_filtered_asset_library;
break;
case FILE_MAIN_ASSET:
filelist->check_dir_fn = filelist_checkdir_main_assets;
filelist->read_job_fn = filelist_readjob_main_assets;
filelist->prepare_filter_fn = prepare_filter_asset_library;
filelist->filter_fn = is_filtered_main_assets;
filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA | FILELIST_TAGS_NO_THREADS;
break;
@ -1873,6 +1875,7 @@ void filelist_free(struct FileList *filelist)
filelist->selection_state = NULL;
}
file_delete_asset_catalog_filter_settings(&filelist->filter_data.asset_catalog_filter);
MEM_SAFE_FREE(filelist->asset_library_ref);
memset(&filelist->filter_data, 0, sizeof(filelist->filter_data));
@ -3612,6 +3615,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update
memset(&flrj->tmp_filelist->filelist_cache, 0, sizeof(flrj->tmp_filelist->filelist_cache));
flrj->tmp_filelist->selection_state = NULL;
flrj->tmp_filelist->asset_library_ref = NULL;
flrj->tmp_filelist->filter_data.asset_catalog_filter = NULL;
BLI_mutex_unlock(&flrj->lock);