UI/Assets: Initial Asset View UI template

The asset view UI template is a mini-version of the Asset Browser that
can be placed in regular layouts, regions or popups. At this point it's
made specifically for placement in vertical layouts, it can be made more
flexible in the future.
Generally the way this is implemented will likely change a lot still as
the asset system evolves.

The Pose Library add-on will use the asset view to display pose
libraries in the 3D View sidebar.

References:
* https://developer.blender.org/T86139
* https://code.blender.org/2021/06/asset-browser-project-update/#what-are-we-building
* https://code.blender.org/2021/05/pose-library-v2-0/#use-from-3d-viewport

Notes:
* Important limitation: Due to the early & WIP implementation of the
  asset list, all asset views showing the same library will show the
  same assets. That is despite the ID type filter option the template
  provides. The first asset view created will determine what's visible.
  Of course this should be made to work eventually.
* The template supports passing an activate and a drag operator name.
  The former is called when an asset is clicked on (e.g. to apply the
  asset) the latter when dragging (e.g. to .blend a pose asset). If no
  drag operator is set, regular asset drag & drop will be executed.
* The template returns the properties for both operators (see example
  below).
* The argument list for using the template is quite long, but we can't
  avoid that currently. The UI list design requires that we pass a
  number of RNA or custom properties to work with, that for the Pose
  Libraries should be registered at the Pose Library add-on level, not
  in core Blender.
* Idea is that Python scripts or add-ons that want to use the asset view
  can register custom properties, to hold data like the list of assets,
  and the active asset index. Maybe that will change in future and we
  can manage these internally.

As an example, the pose library add-on uses it like this:
```
activate_op_props, drag_op_props = layout.template_asset_view(
    "pose_assets",
    workspace,
    "active_asset_library",
    wm,
    "pose_assets",
    workspace,
    "active_pose_asset_index",
    filter_id_types={"filter_action"},
    activate_operator="poselib.apply_pose_asset",
    drag_operator="poselib.blend_pose_asset",
)
drag_op_props.release_confirm = True
drag_op_props.flipped = wm.poselib_flipped
activate_op_props.flipped = wm.poselib_flipped
```
This commit is contained in:
Julian Eisel 2021-07-13 18:07:57 +02:00 committed by Sybren A. Stüvel
parent 6bd42baaeb
commit 8925d3b7bf
Notes: blender-bot 2023-02-14 09:02:41 +01:00
Referenced by issue #102856, Clickable area of Current File Assets in 'template_asset_view' is reduced when no 'drag_operator' is used
11 changed files with 612 additions and 143 deletions

View File

@ -332,6 +332,9 @@ typedef void (*uiListFilterItemsFunc)(struct uiList *ui_list,
struct PointerRNA *,
const char *propname);
/* Listen to notifiers. Only for lists defined in C. */
typedef void (*uiListListener)(struct uiList *ui_list, wmRegionListenerParams *params);
typedef struct uiListType {
struct uiListType *next, *prev;
@ -341,6 +344,9 @@ typedef struct uiListType {
uiListDrawFilterFunc draw_filter;
uiListFilterItemsFunc filter_items;
/* For lists defined in C only. */
uiListListener listener;
/* RNA integration */
ExtensionRNA rna_ext;
} uiListType;

View File

@ -35,6 +35,7 @@ extern "C" {
/* Struct Declarations */
struct ARegion;
struct AssetFilterSettings;
struct AutoComplete;
struct EnumPropertyItem;
struct FileSelectParams;
@ -2287,6 +2288,20 @@ int uiTemplateRecentFiles(struct uiLayout *layout, int rows);
void uiTemplateFileSelectPath(uiLayout *layout,
struct bContext *C,
struct FileSelectParams *params);
void uiTemplateAssetView(struct uiLayout *layout,
struct bContext *C,
const char *list_id,
struct PointerRNA *asset_library_dataptr,
const char *asset_library_propname,
struct PointerRNA *assets_dataptr,
const char *assets_propname,
struct PointerRNA *active_dataptr,
const char *active_propname,
const struct AssetFilterSettings *filter_settings,
const char *activate_opname,
struct PointerRNA *r_activate_op_properties,
const char *drag_opname,
struct PointerRNA *r_drag_op_properties);
struct PointerRNA *UI_list_custom_activate_operator_set(struct uiList *ui_list,
const char *opname,

View File

@ -66,6 +66,7 @@ set(SRC
interface_region_tooltip.c
interface_regions.c
interface_style.c
interface_template_asset_view.cc
interface_template_list.cc
interface_template_search_menu.c
interface_template_search_operator.c

View File

@ -1241,6 +1241,9 @@ void UI_OT_eyedropper_driver(struct wmOperatorType *ot);
/* interface_eyedropper_gpencil_color.c */
void UI_OT_eyedropper_gpencil_color(struct wmOperatorType *ot);
/* interface_template_asset_view.cc */
struct uiListType *UI_UL_asset_view(void);
/**
* For use with #ui_rna_collection_search_update_fn.
*/

View File

@ -0,0 +1,272 @@
/*
* 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;
bScreen *screen;
};
static void asset_view_item_but_drag_set(uiBut *but,
AssetViewListData *list_data,
AssetHandle *asset_handle)
{
ID *id = asset_handle->file_data->id;
if (id != NULL) {
UI_but_drag_set_id(but, id);
return;
}
const blender::StringRef asset_list_path = ED_assetlist_library_path(&list_data->asset_library);
char blend_path[FILE_MAX_LIBEXTRA];
char path[FILE_MAX_LIBEXTRA];
BLI_join_dirfile(path, sizeof(path), asset_list_path.data(), asset_handle->file_data->relpath);
if (BLO_library_path_explode(path, blend_path, nullptr, nullptr)) {
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
UI_but_drag_set_asset(but,
asset_handle->file_data->name,
BLI_strdup(blend_path),
asset_handle->file_data->blentype,
FILE_ASSET_IMPORT_APPEND,
asset_handle->file_data->preview_icon_id,
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,
asset_handle->file_data->preview_icon_id,
asset_handle->file_data->name,
0,
0,
size_x,
size_y,
nullptr,
0,
0,
0,
0,
"");
ui_def_but_icon(but,
asset_handle->file_data->preview_icon_id,
/* 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, 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,
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_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, [&](FileDirEntry &file) {
PointerRNA itemptr, fileptr;
RNA_property_collection_add(&assets_dataptr, assets_prop, &itemptr);
RNA_pointer_create(nullptr, &RNA_FileSelectEntry, &file, &fileptr);
RNA_pointer_set(&itemptr, "file_data", fileptr);
/* Copy name from file to asset-handle name ID-property. */
char name[MAX_NAME];
PropertyRNA *file_name_prop = RNA_struct_name_property(fileptr.type);
RNA_property_string_get(&fileptr, file_name_prop, name);
PropertyRNA *asset_name_prop = RNA_struct_name_property(&RNA_AssetHandle);
RNA_property_string_set(&itemptr, asset_name_prop, name);
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 = 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.type != ASSET_LIBRARY_LOCAL) {
uiItemO(row, "", ICON_FILE_REFRESH, "ASSET_OT_list_refresh");
}
ED_assetlist_storage_fetch(&asset_library, filter_settings, C);
ED_assetlist_ensure_previews_job(&asset_library, C);
const int tot_items = ED_assetlist_size(&asset_library);
asset_view_template_refresh_asset_collection(asset_library, *assets_dataptr, assets_propname);
AssetViewListData *list_data = (AssetViewListData *)MEM_mallocN(sizeof(*list_data),
"AssetViewListData");
list_data->asset_library = asset_library;
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 != NULL);
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 != NULL);
if (r_drag_op_properties && ptr) {
*r_drag_op_properties = *ptr;
}
}
}

View File

@ -20,8 +20,13 @@
* TODO: The UI list template implementation should be moved here.
*/
#include "WM_api.h"
#include "UI_interface.h"
#include "interface_intern.h"
void ED_uilisttypes_ui(void)
{
WM_uilisttype_add(UI_UL_asset_view());
}

View File

@ -161,6 +161,12 @@ void ED_region_do_listen(wmRegionListenerParams *params)
if (region->type && region->type->listener) {
region->type->listener(params);
}
LISTBASE_FOREACH (uiList *, list, &region->ui_lists) {
if (list->type && list->type->listener) {
list->type->listener(list, params);
}
}
}
/* only exported for WM */

View File

@ -245,6 +245,22 @@ extern const EnumPropertyItem *rna_enum_attribute_domain_itemf(struct ID *id, bo
extern const EnumPropertyItem rna_enum_collection_color_items[];
/**
* For ID filters (#FILTER_ID_AC, #FILTER_ID_AR, ...) an int isn't enough. This version allows 64
* bit integers. So can't use the regular #EnumPropertyItem. Would be nice if RNA supported this
* itself.
*
* Meant to be used with #RNA_def_property_boolean_sdna() which supports 64 bit flags as well.
*/
struct IDFilterEnumPropertyItem {
const uint64_t flag;
const char *identifier;
const int icon;
const char *name;
const char *description;
};
extern const struct IDFilterEnumPropertyItem rna_enum_id_type_filter_items[];
/* API calls */
int rna_node_tree_type_to_enum(struct bNodeTreeType *typeinfo);
int rna_node_tree_idname_to_enum(const char *idname);

View File

@ -126,6 +126,97 @@ static const EnumPropertyItem rna_enum_override_library_property_operation_items
{0, NULL, 0, NULL, NULL},
};
/**
* \note Uses #IDFilterEnumPropertyItem, not EnumPropertyItem, to support 64 bit items.
*/
const struct IDFilterEnumPropertyItem rna_enum_id_type_filter_items[] = {
/* Datablocks */
{FILTER_ID_AC, "filter_action", ICON_ANIM_DATA, "Actions", "Show Action data-blocks"},
{FILTER_ID_AR,
"filter_armature",
ICON_ARMATURE_DATA,
"Armatures",
"Show Armature data-blocks"},
{FILTER_ID_BR, "filter_brush", ICON_BRUSH_DATA, "Brushes", "Show Brushes data-blocks"},
{FILTER_ID_CA, "filter_camera", ICON_CAMERA_DATA, "Cameras", "Show Camera data-blocks"},
{FILTER_ID_CF, "filter_cachefile", ICON_FILE, "Cache Files", "Show Cache File data-blocks"},
{FILTER_ID_CU, "filter_curve", ICON_CURVE_DATA, "Curves", "Show Curve data-blocks"},
{FILTER_ID_GD,
"filter_grease_pencil",
ICON_GREASEPENCIL,
"Grease Pencil",
"Show Grease pencil data-blocks"},
{FILTER_ID_GR,
"filter_group",
ICON_OUTLINER_COLLECTION,
"Collections",
"Show Collection data-blocks"},
{FILTER_ID_HA, "filter_hair", ICON_HAIR_DATA, "Hairs", "Show/hide Hair data-blocks"},
{FILTER_ID_IM, "filter_image", ICON_IMAGE_DATA, "Images", "Show Image data-blocks"},
{FILTER_ID_LA, "filter_light", ICON_LIGHT_DATA, "Lights", "Show Light data-blocks"},
{FILTER_ID_LP,
"filter_light_probe",
ICON_OUTLINER_DATA_LIGHTPROBE,
"Light Probes",
"Show Light Probe data-blocks"},
{FILTER_ID_LS,
"filter_linestyle",
ICON_LINE_DATA,
"Freestyle Linestyles",
"Show Freestyle's Line Style data-blocks"},
{FILTER_ID_LT, "filter_lattice", ICON_LATTICE_DATA, "Lattices", "Show Lattice data-blocks"},
{FILTER_ID_MA,
"filter_material",
ICON_MATERIAL_DATA,
"Materials",
"Show Material data-blocks"},
{FILTER_ID_MB, "filter_metaball", ICON_META_DATA, "Metaballs", "Show Metaball data-blocks"},
{FILTER_ID_MC,
"filter_movie_clip",
ICON_TRACKER_DATA,
"Movie Clips",
"Show Movie Clip data-blocks"},
{FILTER_ID_ME, "filter_mesh", ICON_MESH_DATA, "Meshes", "Show Mesh data-blocks"},
{FILTER_ID_MSK, "filter_mask", ICON_MOD_MASK, "Masks", "Show Mask data-blocks"},
{FILTER_ID_NT, "filter_node_tree", ICON_NODETREE, "Node Trees", "Show Node Tree data-blocks"},
{FILTER_ID_OB, "filter_object", ICON_OBJECT_DATA, "Objects", "Show Object data-blocks"},
{FILTER_ID_PA,
"filter_particle_settings",
ICON_PARTICLE_DATA,
"Particles Settings",
"Show Particle Settings data-blocks"},
{FILTER_ID_PAL, "filter_palette", ICON_COLOR, "Palettes", "Show Palette data-blocks"},
{FILTER_ID_PC,
"filter_paint_curve",
ICON_CURVE_BEZCURVE,
"Paint Curves",
"Show Paint Curve data-blocks"},
{FILTER_ID_PT,
"filter_pointcloud",
ICON_POINTCLOUD_DATA,
"Point Clouds",
"Show/hide Point Cloud data-blocks"},
{FILTER_ID_SCE, "filter_scene", ICON_SCENE_DATA, "Scenes", "Show Scene data-blocks"},
{FILTER_ID_SIM,
"filter_simulation",
ICON_PHYSICS,
"Simulations",
"Show Simulation data-blocks"}, /* TODO: Use correct icon. */
{FILTER_ID_SPK, "filter_speaker", ICON_SPEAKER, "Speakers", "Show Speaker data-blocks"},
{FILTER_ID_SO, "filter_sound", ICON_SOUND, "Sounds", "Show Sound data-blocks"},
{FILTER_ID_TE, "filter_texture", ICON_TEXTURE_DATA, "Textures", "Show Texture data-blocks"},
{FILTER_ID_TXT, "filter_text", ICON_TEXT, "Texts", "Show Text data-blocks"},
{FILTER_ID_VF, "filter_font", ICON_FONT_DATA, "Fonts", "Show Font data-blocks"},
{FILTER_ID_VO, "filter_volume", ICON_VOLUME_DATA, "Volumes", "Show/hide Volume data-blocks"},
{FILTER_ID_WO, "filter_world", ICON_WORLD_DATA, "Worlds", "Show World data-blocks"},
{FILTER_ID_WS,
"filter_work_space",
ICON_WORKSPACE,
"Workspaces",
"Show workspace data-blocks"},
{0, NULL, 0, NULL, NULL},
};
#ifdef RNA_RUNTIME
# include "DNA_anim_types.h"

View File

@ -3217,6 +3217,45 @@ static const EnumPropertyItem dt_uv_items[] = {
{0, NULL, 0, NULL, NULL},
};
static struct IDFilterEnumPropertyItem rna_enum_space_file_id_filter_categories[] = {
/* Categories */
{FILTER_ID_SCE, "category_scene", ICON_SCENE_DATA, "Scenes", "Show scenes"},
{FILTER_ID_AC, "category_animation", ICON_ANIM_DATA, "Animations", "Show animation data"},
{FILTER_ID_OB | FILTER_ID_GR,
"category_object",
ICON_OUTLINER_COLLECTION,
"Objects & Collections",
"Show objects and collections"},
{FILTER_ID_AR | FILTER_ID_CU | FILTER_ID_LT | FILTER_ID_MB | FILTER_ID_ME | FILTER_ID_HA |
FILTER_ID_PT | FILTER_ID_VO,
"category_geometry",
ICON_NODETREE,
"Geometry",
"Show meshes, curves, lattice, armatures and metaballs data"},
{FILTER_ID_LS | FILTER_ID_MA | FILTER_ID_NT | FILTER_ID_TE,
"category_shading",
ICON_MATERIAL_DATA,
"Shading",
"Show materials, nodetrees, textures and Freestyle's linestyles"},
{FILTER_ID_IM | FILTER_ID_MC | FILTER_ID_MSK | FILTER_ID_SO,
"category_image",
ICON_IMAGE_DATA,
"Images & Sounds",
"Show images, movie clips, sounds and masks"},
{FILTER_ID_CA | FILTER_ID_LA | FILTER_ID_LP | FILTER_ID_SPK | FILTER_ID_WO,
"category_environment",
ICON_WORLD_DATA,
"Environment",
"Show worlds, lights, cameras and speakers"},
{FILTER_ID_BR | FILTER_ID_GD | FILTER_ID_PA | FILTER_ID_PAL | FILTER_ID_PC | FILTER_ID_TXT |
FILTER_ID_VF | FILTER_ID_CF | FILTER_ID_WS,
"category_misc",
ICON_GREASEPENCIL,
"Miscellaneous",
"Show other data types"},
{0, NULL, 0, NULL, NULL},
};
static void rna_def_space_generic_show_region_toggles(StructRNA *srna, int region_type_mask)
{
PropertyRNA *prop;
@ -6164,142 +6203,6 @@ static void rna_def_space_console(BlenderRNA *brna)
/* Filter for datablock types in link/append. */
static void rna_def_fileselect_idfilter(BlenderRNA *brna)
{
struct IDFilterBoolean {
/* 64 bit, so we can't use bitflag enum. */
const uint64_t flag;
const char *identifier;
const int icon;
const char *name;
const char *description;
};
static const struct IDFilterBoolean booleans[] = {
/* Datablocks */
{FILTER_ID_AC, "filter_action", ICON_ANIM_DATA, "Actions", "Show Action data-blocks"},
{FILTER_ID_AR,
"filter_armature",
ICON_ARMATURE_DATA,
"Armatures",
"Show Armature data-blocks"},
{FILTER_ID_BR, "filter_brush", ICON_BRUSH_DATA, "Brushes", "Show Brushes data-blocks"},
{FILTER_ID_CA, "filter_camera", ICON_CAMERA_DATA, "Cameras", "Show Camera data-blocks"},
{FILTER_ID_CF, "filter_cachefile", ICON_FILE, "Cache Files", "Show Cache File data-blocks"},
{FILTER_ID_CU, "filter_curve", ICON_CURVE_DATA, "Curves", "Show Curve data-blocks"},
{FILTER_ID_GD,
"filter_grease_pencil",
ICON_GREASEPENCIL,
"Grease Pencil",
"Show Grease pencil data-blocks"},
{FILTER_ID_GR,
"filter_group",
ICON_OUTLINER_COLLECTION,
"Collections",
"Show Collection data-blocks"},
{FILTER_ID_HA, "filter_hair", ICON_HAIR_DATA, "Hairs", "Show/hide Hair data-blocks"},
{FILTER_ID_IM, "filter_image", ICON_IMAGE_DATA, "Images", "Show Image data-blocks"},
{FILTER_ID_LA, "filter_light", ICON_LIGHT_DATA, "Lights", "Show Light data-blocks"},
{FILTER_ID_LP,
"filter_light_probe",
ICON_OUTLINER_DATA_LIGHTPROBE,
"Light Probes",
"Show Light Probe data-blocks"},
{FILTER_ID_LS,
"filter_linestyle",
ICON_LINE_DATA,
"Freestyle Linestyles",
"Show Freestyle's Line Style data-blocks"},
{FILTER_ID_LT, "filter_lattice", ICON_LATTICE_DATA, "Lattices", "Show Lattice data-blocks"},
{FILTER_ID_MA,
"filter_material",
ICON_MATERIAL_DATA,
"Materials",
"Show Material data-blocks"},
{FILTER_ID_MB, "filter_metaball", ICON_META_DATA, "Metaballs", "Show Metaball data-blocks"},
{FILTER_ID_MC,
"filter_movie_clip",
ICON_TRACKER_DATA,
"Movie Clips",
"Show Movie Clip data-blocks"},
{FILTER_ID_ME, "filter_mesh", ICON_MESH_DATA, "Meshes", "Show Mesh data-blocks"},
{FILTER_ID_MSK, "filter_mask", ICON_MOD_MASK, "Masks", "Show Mask data-blocks"},
{FILTER_ID_NT,
"filter_node_tree",
ICON_NODETREE,
"Node Trees",
"Show Node Tree data-blocks"},
{FILTER_ID_OB, "filter_object", ICON_OBJECT_DATA, "Objects", "Show Object data-blocks"},
{FILTER_ID_PA,
"filter_particle_settings",
ICON_PARTICLE_DATA,
"Particles Settings",
"Show Particle Settings data-blocks"},
{FILTER_ID_PAL, "filter_palette", ICON_COLOR, "Palettes", "Show Palette data-blocks"},
{FILTER_ID_PC,
"filter_paint_curve",
ICON_CURVE_BEZCURVE,
"Paint Curves",
"Show Paint Curve data-blocks"},
{FILTER_ID_PT,
"filter_pointcloud",
ICON_POINTCLOUD_DATA,
"Point Clouds",
"Show/hide Point Cloud data-blocks"},
{FILTER_ID_SCE, "filter_scene", ICON_SCENE_DATA, "Scenes", "Show Scene data-blocks"},
{FILTER_ID_SIM,
"filter_simulation",
ICON_PHYSICS,
"Simulations",
"Show Simulation data-blocks"}, /* TODO: Use correct icon. */
{FILTER_ID_SPK, "filter_speaker", ICON_SPEAKER, "Speakers", "Show Speaker data-blocks"},
{FILTER_ID_SO, "filter_sound", ICON_SOUND, "Sounds", "Show Sound data-blocks"},
{FILTER_ID_TE, "filter_texture", ICON_TEXTURE_DATA, "Textures", "Show Texture data-blocks"},
{FILTER_ID_TXT, "filter_text", ICON_TEXT, "Texts", "Show Text data-blocks"},
{FILTER_ID_VF, "filter_font", ICON_FONT_DATA, "Fonts", "Show Font data-blocks"},
{FILTER_ID_VO, "filter_volume", ICON_VOLUME_DATA, "Volumes", "Show/hide Volume data-blocks"},
{FILTER_ID_WO, "filter_world", ICON_WORLD_DATA, "Worlds", "Show World data-blocks"},
{FILTER_ID_WS,
"filter_work_space",
ICON_WORKSPACE,
"Workspaces",
"Show workspace data-blocks"},
/* Categories */
{FILTER_ID_SCE, "category_scene", ICON_SCENE_DATA, "Scenes", "Show scenes"},
{FILTER_ID_AC, "category_animation", ICON_ANIM_DATA, "Animations", "Show animation data"},
{FILTER_ID_OB | FILTER_ID_GR,
"category_object",
ICON_OUTLINER_COLLECTION,
"Objects & Collections",
"Show objects and collections"},
{FILTER_ID_AR | FILTER_ID_CU | FILTER_ID_LT | FILTER_ID_MB | FILTER_ID_ME | FILTER_ID_HA |
FILTER_ID_PT | FILTER_ID_VO,
"category_geometry",
ICON_NODETREE,
"Geometry",
"Show meshes, curves, lattice, armatures and metaballs data"},
{FILTER_ID_LS | FILTER_ID_MA | FILTER_ID_NT | FILTER_ID_TE,
"category_shading",
ICON_MATERIAL_DATA,
"Shading",
"Show materials, nodetrees, textures and Freestyle's linestyles"},
{FILTER_ID_IM | FILTER_ID_MC | FILTER_ID_MSK | FILTER_ID_SO,
"category_image",
ICON_IMAGE_DATA,
"Images & Sounds",
"Show images, movie clips, sounds and masks"},
{FILTER_ID_CA | FILTER_ID_LA | FILTER_ID_LP | FILTER_ID_SPK | FILTER_ID_WO,
"category_environment",
ICON_WORLD_DATA,
"Environment",
"Show worlds, lights, cameras and speakers"},
{FILTER_ID_BR | FILTER_ID_GD | FILTER_ID_PA | FILTER_ID_PAL | FILTER_ID_PC | FILTER_ID_TXT |
FILTER_ID_VF | FILTER_ID_CF | FILTER_ID_WS,
"category_misc",
ICON_GREASEPENCIL,
"Miscellaneous",
"Show other data types"},
{0, NULL, 0, NULL, NULL}};
StructRNA *srna = RNA_def_struct(brna, "FileSelectIDFilter", NULL);
RNA_def_struct_sdna(srna, "FileSelectParams");
@ -6307,12 +6210,23 @@ static void rna_def_fileselect_idfilter(BlenderRNA *brna)
RNA_def_struct_ui_text(
srna, "File Select ID Filter", "Which ID types to show/hide, when browsing a library");
for (int i = 0; booleans[i].identifier; i++) {
PropertyRNA *prop = RNA_def_property(srna, booleans[i].identifier, PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filter_id", booleans[i].flag);
RNA_def_property_ui_text(prop, booleans[i].name, booleans[i].description);
RNA_def_property_ui_icon(prop, booleans[i].icon, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
const struct IDFilterEnumPropertyItem *individual_ids_and_categories[] = {
rna_enum_id_type_filter_items,
rna_enum_space_file_id_filter_categories,
NULL,
};
for (uint i = 0; individual_ids_and_categories[i]; i++) {
for (int j = 0; individual_ids_and_categories[i][j].identifier; j++) {
PropertyRNA *prop = RNA_def_property(
srna, individual_ids_and_categories[i][j].identifier, PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "filter_id", individual_ids_and_categories[i][j].flag);
RNA_def_property_ui_text(prop,
individual_ids_and_categories[i][j].name,
individual_ids_and_categories[i][j].description);
RNA_def_property_ui_icon(prop, individual_ids_and_categories[i][j].icon, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
}
}
@ -6590,7 +6504,7 @@ static void rna_def_fileselect_asset_params(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
/* XXX copied from rna_def_fileselect_idfilter. */
/* XXX copied from rna_enum_id_type_filter_items. */
static const EnumPropertyItem asset_category_items[] = {
{FILTER_ID_SCE, "SCENES", ICON_SCENE_DATA, "Scenes", "Show scenes"},
{FILTER_ID_AC, "ANIMATIONS", ICON_ANIM_DATA, "Animations", "Show animation data"},

View File

@ -50,6 +50,8 @@ const EnumPropertyItem rna_enum_icon_items[] = {
#ifdef RNA_RUNTIME
# include "DNA_asset_types.h"
const char *rna_translate_ui_text(
const char *text, const char *text_ctxt, StructRNA *type, PropertyRNA *prop, bool translate)
{
@ -610,6 +612,69 @@ static void rna_uiTemplateEventFromKeymapItem(
uiTemplateEventFromKeymapItem(layout, name, kmi, true);
}
static void rna_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,
int filter_id_types,
const char *activate_opname,
PointerRNA *r_activate_op_properties,
const char *drag_opname,
PointerRNA *r_drag_op_properties)
{
AssetFilterSettings filter_settings = {
.id_types = filter_id_types ? filter_id_types : FILTER_ID_ALL,
};
uiTemplateAssetView(layout,
C,
list_id,
asset_library_dataptr,
asset_library_propname,
assets_dataptr,
assets_propname,
active_dataptr,
active_propname,
&filter_settings,
activate_opname,
r_activate_op_properties,
drag_opname,
r_drag_op_properties);
}
/**
* XXX Remove filter items that require more than 32 bits for storage. RNA enums don't support
* that currently.
*/
static const EnumPropertyItem *rna_uiTemplateAssetView_filter_id_types_itemf(
bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
for (int i = 0; rna_enum_id_type_filter_items[i].identifier; i++) {
if (rna_enum_id_type_filter_items[i].flag > (1ULL << 31)) {
continue;
}
EnumPropertyItem tmp = {0, "", 0, "", ""};
tmp.value = rna_enum_id_type_filter_items[i].flag;
tmp.identifier = rna_enum_id_type_filter_items[i].identifier;
tmp.icon = rna_enum_id_type_filter_items[i].icon;
tmp.name = rna_enum_id_type_filter_items[i].name;
tmp.description = rna_enum_id_type_filter_items[i].description;
RNA_enum_item_add(&items, &totitem, &tmp);
}
RNA_enum_item_end(&items, &totitem);
*r_free = true;
return items;
}
static uiLayout *rna_uiLayoutRowWithHeading(
uiLayout *layout, bool align, const char *heading, const char *heading_ctxt, bool translate)
{
@ -1729,6 +1794,81 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_property_ui_text(parm, "Item", "");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
api_ui_item_common_text(func);
func = RNA_def_function(srna, "template_asset_view", "rna_uiTemplateAssetView");
RNA_def_function_ui_description(func, "Item. A scrollable list of assets in a grid view");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_string(func,
"list_id",
NULL,
0,
"",
"Identifier of this asset view. Necessary to tell apart different asset "
"views and to idenify an asset view read from a .blend");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func,
"asset_library_dataptr",
"AnyType",
"",
"Data from which to take the active asset library property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "asset_library_propname", NULL, 0, "", "Identifier of the asset library property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(
func, "assets_dataptr", "AnyType", "", "Data from which to take the asset list property");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func, "assets_propname", NULL, 0, "", "Identifier of the asset list property");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func,
"active_dataptr",
"AnyType",
"",
"Data from which to take the integer property, index of the active item");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_string(
func,
"active_propname",
NULL,
0,
"",
"Identifier of the integer property in active_data, index of the active item");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
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);
RNA_def_string(func,
"activate_operator",
NULL,
0,
"",
"Name of a custom operator to invoke when activating an item");
parm = RNA_def_pointer(
func,
"activate_operator_properties",
"OperatorProperties",
"",
"Operator properties to fill in for the custom activate operator passed to the template");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_function_output(func, parm);
RNA_def_string(func,
"drag_operator",
NULL,
0,
"",
"Name of a custom operator to invoke when starting to drag an item. Never "
"invoked together with the `active_operator` (if set), it's either the drag or "
"the activate one");
parm = RNA_def_pointer(
func,
"drag_operator_properties",
"OperatorProperties",
"",
"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);
}
#endif