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.
14 changed files with 168 additions and 20 deletions
Showing only changes of commit 8ddf492e7c - Show all commits

View File

@ -3926,10 +3926,18 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
if (new_asset_shelf != nullptr) {
new_asset_shelf->alignment = RGN_ALIGN_BOTTOM;
new_asset_shelf->flag |= RGN_FLAG_HIDDEN;
new_asset_shelf->flag = RGN_FLAG_HIDDEN | RGN_FLAG_DYNAMIC_SIZE;
}
}
}
}
}
/* Should we really use the "All" library by default? Consider loading time and memory usage.
*/
LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
workspace->asset_library_ref.type = ASSET_LIBRARY_ALL;
workspace->asset_library_ref.custom_library_index = -1;
}
}
}

View File

@ -260,6 +260,9 @@ void BLO_update_defaults_workspace(WorkSpace *workspace, const char *app_templat
BKE_workspace_tool_remove(workspace, static_cast<bToolRef *>(workspace->tools.first));
}
workspace->asset_library_ref.type = ASSET_LIBRARY_ALL;
workspace->asset_library_ref.custom_library_index = -1;
/* For 2D animation template. */
if (STREQ(workspace->id.name + 2, "Drawing")) {
workspace->object_mode = OB_MODE_PAINT_GPENCIL;

View File

@ -55,8 +55,7 @@ struct ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle);
/**
* \return True if the region needs a UI redraw.
*/
bool ED_assetlist_listen(const struct AssetLibraryReference *library_reference,
const struct wmNotifier *notifier);
bool ED_assetlist_listen(const struct wmNotifier *notifier);
/**
* \return The number of assets stored in the asset list for \a library_reference, or -1 if there
* is no list fetched for it.

View File

@ -116,7 +116,7 @@ class AssetList : NonCopyable {
bool isLoaded() const;
asset_system::AssetLibrary *asset_library() const;
void iterate(AssetListIterFn fn) const;
bool listen(const wmNotifier &notifier) const;
static bool listen(const wmNotifier &notifier);
int size() const;
void tagMainDataDirty() const;
void remapID(ID *id_old, ID *id_new) const;
@ -249,7 +249,7 @@ void AssetList::clear(bContext *C)
/**
* \return True if the asset-list needs a UI redraw.
*/
bool AssetList::listen(const wmNotifier &notifier) const
bool AssetList::listen(const wmNotifier &notifier)
{
switch (notifier.category) {
case NC_ID: {
@ -481,14 +481,9 @@ ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
return filelist_geticon_image_ex(asset_handle->file_data);
}
bool ED_assetlist_listen(const AssetLibraryReference *library_reference,
const wmNotifier *notifier)
bool ED_assetlist_listen(const wmNotifier *notifier)
{
AssetList *list = AssetListStorage::lookup_list(*library_reference);
if (list) {
return list->listen(*notifier);
}
return false;
return AssetList::listen(*notifier);
}
int ED_assetlist_size(const AssetLibraryReference *library_reference)

View File

@ -122,6 +122,8 @@ void ED_region_header(const struct bContext *C, struct ARegion *region);
void ED_region_header_layout(const struct bContext *C, struct ARegion *region);
void ED_region_header_draw(const struct bContext *C, struct ARegion *region);
void ED_region_asset_shelf_listen(const struct wmRegionListenerParams *params);
void ED_region_cursor_set(struct wmWindow *win, struct ScrArea *area, struct ARegion *region);
/**
* Exported to all editors, uses fading default.

View File

@ -2161,6 +2161,7 @@ int uiLayoutGetAlignment(uiLayout *layout);
bool uiLayoutGetFixedSize(uiLayout *layout);
bool uiLayoutGetKeepAspect(uiLayout *layout);
int uiLayoutGetWidth(uiLayout *layout);
int uiLayoutGetRootHeight(uiLayout *layout);
float uiLayoutGetScaleX(uiLayout *layout);
float uiLayoutGetScaleY(uiLayout *layout);
float uiLayoutGetUnitsX(uiLayout *layout);
@ -2598,6 +2599,9 @@ void uiTemplateAssetView(struct uiLayout *layout,
struct PointerRNA *r_activate_op_properties,
const char *drag_opname,
struct PointerRNA *r_drag_op_properties);
void uiTemplateAssetShelf(uiLayout *layout,
const struct bContext *C,
const struct AssetFilterSettings *filter_settings);
/**
* \return: A RNA pointer for the operator properties.

View File

@ -60,6 +60,7 @@ set(SRC
interface_region_tooltip.cc
interface_regions.cc
interface_style.cc
interface_template_asset_shelf.cc
interface_template_asset_view.cc
interface_template_attribute_search.cc
interface_template_list.cc

View File

@ -4088,7 +4088,7 @@ static void ui_litem_layout_box(uiLayout *litem)
const uiStyle *style = litem->root->style;
int boxspace = style->boxspace;
if (litem->root->type == UI_LAYOUT_HEADER) {
if (litem->root->type == UI_LAYOUT_HEADER && false) {
boxspace = 0;
}
@ -5117,6 +5117,11 @@ int uiLayoutGetWidth(uiLayout *layout)
return layout->w;
}
int uiLayoutGetRootHeight(uiLayout *layout)
{
return layout->root->layout->h;
}
float uiLayoutGetScaleX(uiLayout *layout)
{
return layout->scale[0];

View File

@ -0,0 +1,101 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edinterface
*/
#include "BKE_context.h"
#include "DNA_space_types.h"
#include "ED_asset.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "interface_intern.hh"
/* TODO copy of #asset_view_item_but_drag_set(). */
static void asset_tile_but_drag_set(uiBut &but, 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(&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_tile_draw(uiLayout &layout,
AssetHandle &asset_handle,
const int width,
const int height,
const bool show_names)
{
uiBlock *block = uiLayoutGetBlock(&layout);
uiBut *but = uiDefIconTextBut(block,
UI_BTYPE_PREVIEW_TILE,
0,
ED_asset_handle_get_preview_icon_id(&asset_handle),
show_names ? ED_asset_handle_get_name(&asset_handle) : "",
0,
0,
width,
height,
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);
asset_tile_but_drag_set(*but, asset_handle);
}
void uiTemplateAssetShelf(uiLayout *layout,
const bContext *C,
const AssetFilterSettings *filter_settings)
{
const AssetLibraryReference *library_ref = CTX_wm_asset_library_ref(C);
ED_assetlist_storage_fetch(library_ref, C);
ED_assetlist_ensure_previews_job(library_ref, C);
uiLayoutSetScaleX(layout, 1.0f);
uiLayoutSetScaleY(layout, 1.0f);
const bool show_names = true;
const int height = uiLayoutGetRootHeight(layout) - UI_style_get_dpi()->boxspace * 2;
/* Width is derived from the height. It's the height without the space for the name (if there is
* any). */
const int width = height - (show_names ? 0 : UI_UNIT_Y);
uiLayout *box = uiLayoutBox(layout);
uiLayout *row = uiLayoutRow(box, false);
ED_assetlist_iterate(*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;
}
asset_tile_draw(*row, asset, width, height, show_names);
return true;
});
}

View File

@ -108,9 +108,8 @@ static void asset_view_draw_item(uiList *ui_list,
}
}
static void asset_view_listener(uiList *ui_list, wmRegionListenerParams *params)
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) {
@ -122,7 +121,7 @@ static void asset_view_listener(uiList *ui_list, wmRegionListenerParams *params)
}
}
if (ED_assetlist_listen(&list_data->asset_library_ref, params->notifier)) {
if (ED_assetlist_listen(params->notifier)) {
ED_region_tag_redraw(params->region);
}
}

View File

@ -33,6 +33,7 @@
#include "WM_toolsystem.h"
#include "WM_types.h"
#include "ED_asset.h"
#include "ED_buttons.h"
#include "ED_screen.h"
#include "ED_screen_types.h"
@ -3311,12 +3312,15 @@ void ED_region_header_layout(const bContext *C, ARegion *region)
bool region_layout_based = region->flag & RGN_FLAG_DYNAMIC_SIZE;
/* Height of buttons and scaling needed to achieve it. */
const int buttony = min_ii(UI_UNIT_Y, region->winy - 2 * UI_DPI_FAC);
const bool is_fixed_header_height = region->type->prefsizey == HEADERY;
const int buttony = is_fixed_header_height ? UI_UNIT_Y :
region->winy - 2 * UI_DPI_FAC - UI_HEADER_OFFSET;
const float buttony_scale = buttony / (float)UI_UNIT_Y;
/* Vertically center buttons. */
int xco = UI_HEADER_OFFSET;
int yco = buttony + (region->winy - buttony) / 2;
int yco = is_fixed_header_height ? buttony + (region->winy - buttony) / 2 :
buttony + UI_HEADER_OFFSET / 2;
int maxco = xco;
/* XXX workaround for 1 px alignment issue. Not sure what causes it...
@ -3422,6 +3426,13 @@ void ED_region_header_init(ARegion *region)
UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_HEADER, region->winx, region->winy);
}
void ED_region_asset_shelf_listen(const wmRegionListenerParams *params)
{
if (ED_assetlist_listen(params->notifier)) {
ED_region_tag_redraw_no_rebuild(params->region);
}
}
int ED_area_headersize(void)
{
/* Accommodate widget and padding. */

View File

@ -2148,10 +2148,11 @@ void ED_spacetype_view3d()
/* regions: asset shelf */
art = MEM_cnew<ARegionType>("spacetype view3d asset shelf region");
art->regionid = RGN_TYPE_ASSET_SHELF;
art->prefsizey = HEADERY * 4;
art->prefsizey = HEADERY * 3.5f;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
art->listener = ED_region_asset_shelf_listen;
art->init = view3d_header_region_init;
art->draw = view3d_header_region_draw;
art->draw = ED_region_header;
BLI_addhead(&st->regiontypes, art);
/* regions: hud */

View File

@ -20,7 +20,7 @@
#define _DNA_DEFAULT_AssetLibraryReference \
{ \
.type = ASSET_LIBRARY_LOCAL, \
.type = ASSET_LIBRARY_ALL, \
/* Not needed really (should be ignored for anything but #ASSET_LIBRARY_CUSTOM), but helps debugging. */ \
.custom_library_index = -1, \
}

View File

@ -714,6 +714,15 @@ 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)
{
@ -1958,6 +1967,16 @@ 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