This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/interface/interface_template_asset_view.cc
Sybren A. Stüvel 9cff9f9f5d Cleanup: rename FileList::asset_libraryasset_library_ref
In the `FileList` struct, rename the `AssetLibraryReference
*asset_library` field to `asset_library_ref` -- it's a description of
which asset library is used, and not the asset library itself.

This is to make space for a future `AssetLibrary *asset_library` field,
which will point to an actual asset library struct/class.

No functional changes.

Reviewed by: Severin

Differential Revision: https://developer.blender.org/D12151
2021-08-06 15:20:39 +02:00

278 lines
9.8 KiB
C++

/*
* 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 edinterface
*/
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "BKE_screen.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_string_ref.hh"
#include "BLO_readfile.h"
#include "ED_asset.h"
#include "ED_screen.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "UI_interface.h"
#include "WM_api.h"
#include "WM_types.h"
#include "interface_intern.h"
struct AssetViewListData {
AssetLibraryReference asset_library_ref;
bScreen *screen;
};
static void asset_view_item_but_drag_set(uiBut *but,
AssetViewListData *list_data,
AssetHandle *asset_handle)
{
ID *id = ED_asset_handle_get_local_id(asset_handle);
if (id != nullptr) {
UI_but_drag_set_id(but, id);
return;
}
char blend_path[FILE_MAX_LIBEXTRA];
/* Context can be null here, it's only needed for a File Browser specific hack that should go
* away before too long. */
ED_asset_handle_get_full_library_path(
nullptr, &list_data->asset_library_ref, asset_handle, blend_path);
if (blend_path[0]) {
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
UI_but_drag_set_asset(but,
asset_handle,
BLI_strdup(blend_path),
FILE_ASSET_IMPORT_APPEND,
ED_asset_handle_get_preview_icon_id(asset_handle),
imbuf,
1.0f);
}
}
static void asset_view_draw_item(uiList *ui_list,
bContext *UNUSED(C),
uiLayout *layout,
PointerRNA *UNUSED(dataptr),
PointerRNA *itemptr,
int UNUSED(icon),
PointerRNA *UNUSED(active_dataptr),
const char *UNUSED(active_propname),
int UNUSED(index),
int UNUSED(flt_flag))
{
AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
BLI_assert(RNA_struct_is_a(itemptr->type, &RNA_AssetHandle));
AssetHandle *asset_handle = (AssetHandle *)itemptr->data;
uiLayoutSetContextPointer(layout, "asset_handle", itemptr);
uiBlock *block = uiLayoutGetBlock(layout);
/* TODO ED_fileselect_init_layout(). Share somehow? */
const float size_x = (96.0f / 20.0f) * UI_UNIT_X;
const float size_y = (96.0f / 20.0f) * UI_UNIT_Y;
uiBut *but = uiDefIconTextBut(block,
UI_BTYPE_PREVIEW_TILE,
0,
ED_asset_handle_get_preview_icon_id(asset_handle),
ED_asset_handle_get_name(asset_handle),
0,
0,
size_x,
size_y,
nullptr,
0,
0,
0,
0,
"");
ui_def_but_icon(but,
ED_asset_handle_get_preview_icon_id(asset_handle),
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
if (!ui_list->dyn_data->custom_drag_optype) {
asset_view_item_but_drag_set(but, list_data, asset_handle);
}
}
static void asset_view_listener(uiList *ui_list, wmRegionListenerParams *params)
{
AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
const wmNotifier *notifier = params->notifier;
switch (notifier->category) {
case NC_ID: {
if (ELEM(notifier->action, NA_RENAME)) {
ED_assetlist_storage_tag_main_data_dirty();
}
break;
}
}
if (ED_assetlist_listen(&list_data->asset_library_ref, params->notifier)) {
ED_region_tag_redraw(params->region);
}
}
uiListType *UI_UL_asset_view()
{
uiListType *list_type = (uiListType *)MEM_callocN(sizeof(*list_type), __func__);
BLI_strncpy(list_type->idname, "UI_UL_asset_view", sizeof(list_type->idname));
list_type->draw_item = asset_view_draw_item;
list_type->listener = asset_view_listener;
return list_type;
}
static void asset_view_template_refresh_asset_collection(
const AssetLibraryReference &asset_library_ref,
const AssetFilterSettings &filter_settings,
PointerRNA &assets_dataptr,
const char *assets_propname)
{
PropertyRNA *assets_prop = RNA_struct_find_property(&assets_dataptr, assets_propname);
if (!assets_prop) {
RNA_warning("Asset collection not found");
return;
}
if (RNA_property_type(assets_prop) != PROP_COLLECTION) {
RNA_warning("Expected a collection property");
return;
}
if (!RNA_struct_is_a(RNA_property_pointer_type(&assets_dataptr, assets_prop),
&RNA_AssetHandle)) {
RNA_warning("Expected a collection property for AssetHandle items");
return;
}
RNA_property_collection_clear(&assets_dataptr, assets_prop);
ED_assetlist_iterate(&asset_library_ref, [&](AssetHandle asset) {
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
/* Don't do anything else, but return true to continue iterating. */
return true;
}
PointerRNA itemptr, fileptr;
RNA_property_collection_add(&assets_dataptr, assets_prop, &itemptr);
RNA_pointer_create(
nullptr, &RNA_FileSelectEntry, const_cast<FileDirEntry *>(asset.file_data), &fileptr);
RNA_pointer_set(&itemptr, "file_data", fileptr);
return true;
});
}
void uiTemplateAssetView(uiLayout *layout,
bContext *C,
const char *list_id,
PointerRNA *asset_library_dataptr,
const char *asset_library_propname,
PointerRNA *assets_dataptr,
const char *assets_propname,
PointerRNA *active_dataptr,
const char *active_propname,
const AssetFilterSettings *filter_settings,
const char *activate_opname,
PointerRNA *r_activate_op_properties,
const char *drag_opname,
PointerRNA *r_drag_op_properties)
{
if (!list_id || !list_id[0]) {
RNA_warning("Asset view needs a valid identifier");
return;
}
uiLayout *col = uiLayoutColumn(layout, false);
PropertyRNA *asset_library_prop = RNA_struct_find_property(asset_library_dataptr,
asset_library_propname);
AssetLibraryReference asset_library_ref = ED_asset_library_reference_from_enum_value(
RNA_property_enum_get(asset_library_dataptr, asset_library_prop));
uiLayout *row = uiLayoutRow(col, true);
uiItemFullR(row, asset_library_dataptr, asset_library_prop, RNA_NO_INDEX, 0, 0, "", 0);
if (asset_library_ref.type != ASSET_LIBRARY_LOCAL) {
uiItemO(row, "", ICON_FILE_REFRESH, "ASSET_OT_list_refresh");
}
ED_assetlist_storage_fetch(&asset_library_ref, C);
ED_assetlist_ensure_previews_job(&asset_library_ref, C);
const int tot_items = ED_assetlist_size(&asset_library_ref);
asset_view_template_refresh_asset_collection(
asset_library_ref, *filter_settings, *assets_dataptr, assets_propname);
AssetViewListData *list_data = (AssetViewListData *)MEM_mallocN(sizeof(*list_data),
"AssetViewListData");
list_data->asset_library_ref = asset_library_ref;
list_data->screen = CTX_wm_screen(C);
/* TODO can we have some kind of model-view API to handle referencing, filtering and lazy loading
* (of previews) of the items? */
uiList *list = uiTemplateList_ex(col,
C,
"UI_UL_asset_view",
list_id,
assets_dataptr,
assets_propname,
active_dataptr,
active_propname,
nullptr,
tot_items,
0,
UILST_LAYOUT_BIG_PREVIEW_GRID,
0,
UI_TEMPLATE_LIST_NO_GRIP,
list_data);
if (!list) {
/* List creation failed. */
MEM_freeN(list_data);
return;
}
if (activate_opname) {
PointerRNA *ptr = UI_list_custom_activate_operator_set(
list, activate_opname, r_activate_op_properties != nullptr);
if (r_activate_op_properties && ptr) {
*r_activate_op_properties = *ptr;
}
}
if (drag_opname) {
PointerRNA *ptr = UI_list_custom_drag_operator_set(
list, drag_opname, r_drag_op_properties != nullptr);
if (r_drag_op_properties && ptr) {
*r_drag_op_properties = *ptr;
}
}
}