Basic asset shelf prototype

Adds the necessary bits to be able to show an asset shelf template via
the pose library add-on.
This commit is contained in:
Julian Eisel 2023-01-17 15:18:17 +01:00
parent 0e3f5c6673
commit 8ddf492e7c
14 changed files with 168 additions and 20 deletions

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