diff options
-rw-r--r-- | source/blender/blenkernel/BKE_screen.h | 6 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 15 | ||||
-rw-r--r-- | source/blender/editors/interface/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_template_asset_view.cc | 272 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_template_list.cc | 5 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 6 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_enum_types.h | 16 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ID.c | 91 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 200 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui_api.c | 140 |
11 files changed, 612 insertions, 143 deletions
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index fed155626ed..0b08bbfeff5 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -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; diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 020ca1f8f55..a25aac5803c 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -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, diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index 29f868eebb0..39dd6143eb9 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -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 diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index f3085c6b79b..a07f924e65b 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -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. */ diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc new file mode 100644 index 00000000000..2860abb32a1 --- /dev/null +++ b/source/blender/editors/interface/interface_template_asset_view.cc @@ -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; + } + } +} diff --git a/source/blender/editors/interface/interface_template_list.cc b/source/blender/editors/interface/interface_template_list.cc index 90980b3c963..334fc7ff057 100644 --- a/source/blender/editors/interface/interface_template_list.cc +++ b/source/blender/editors/interface/interface_template_list.cc @@ -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()); } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index cb81857eb83..c351ade9954 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -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, ®ion->ui_lists) { + if (list->type && list->type->listener) { + list->type->listener(list, params); + } + } } /* only exported for WM */ diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index c8010a0e1ae..d544083a749 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -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); diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 38b00afdc8f..6df03d19538 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -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" diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index f934b1400ee..0019f315bbe 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -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"}, diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 4b8938053ba..e06cc39a88b 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -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 |