Blender  V3.3
interface_template_asset_view.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "DNA_space_types.h"
8 #include "DNA_userdef_types.h"
9 
10 #include "BKE_screen.h"
11 
12 #include "BLI_path_util.h"
13 #include "BLI_string.h"
14 #include "BLI_string_ref.hh"
15 
16 #include "BLO_readfile.h"
17 
18 #include "ED_asset.h"
19 #include "ED_screen.h"
20 
21 #include "MEM_guardedalloc.h"
22 
23 #include "RNA_access.h"
24 #include "RNA_prototypes.h"
25 
26 #include "UI_interface.h"
27 
28 #include "WM_api.h"
29 #include "WM_types.h"
30 
31 #include "interface_intern.h"
32 
36  bool show_names;
37 };
38 
40  AssetViewListData *list_data,
41  AssetHandle *asset_handle)
42 {
43  ID *id = ED_asset_handle_get_local_id(asset_handle);
44  if (id != nullptr) {
45  UI_but_drag_set_id(but, id);
46  return;
47  }
48 
49  char blend_path[FILE_MAX_LIBEXTRA];
50  /* Context can be null here, it's only needed for a File Browser specific hack that should go
51  * away before too long. */
53  nullptr, &list_data->asset_library_ref, asset_handle, blend_path);
54 
55  if (blend_path[0]) {
56  ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
58  asset_handle,
59  BLI_strdup(blend_path),
60  ED_asset_handle_get_metadata(asset_handle),
63  imbuf,
64  1.0f);
65  }
66 }
67 
68 static void asset_view_draw_item(uiList *ui_list,
69  bContext *UNUSED(C),
70  uiLayout *layout,
71  PointerRNA *UNUSED(dataptr),
72  PointerRNA *itemptr,
73  int UNUSED(icon),
74  PointerRNA *UNUSED(active_dataptr),
75  const char *UNUSED(active_propname),
76  int UNUSED(index),
77  int UNUSED(flt_flag))
78 {
79  AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
80 
81  BLI_assert(RNA_struct_is_a(itemptr->type, &RNA_AssetHandle));
82  AssetHandle *asset_handle = (AssetHandle *)itemptr->data;
83 
84  uiLayoutSetContextPointer(layout, "asset_handle", itemptr);
85 
86  uiBlock *block = uiLayoutGetBlock(layout);
87  const bool show_names = list_data->show_names;
88  /* TODO ED_fileselect_init_layout(). Share somehow? */
89  const float size_x = (96.0f / 20.0f) * UI_UNIT_X;
90  const float size_y = (96.0f / 20.0f) * UI_UNIT_Y - (show_names ? 0 : UI_UNIT_Y);
91  uiBut *but = uiDefIconTextBut(block,
93  0,
95  show_names ? ED_asset_handle_get_name(asset_handle) : "",
96  0,
97  0,
98  size_x,
99  size_y,
100  nullptr,
101  0,
102  0,
103  0,
104  0,
105  "");
106  ui_def_but_icon(but,
108  /* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
110  if (!ui_list->dyn_data->custom_drag_optype) {
111  asset_view_item_but_drag_set(but, list_data, asset_handle);
112  }
113 }
114 
116 {
117  AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
118  const wmNotifier *notifier = params->notifier;
119 
120  switch (notifier->category) {
121  case NC_ID: {
122  if (ELEM(notifier->action, NA_RENAME)) {
124  }
125  break;
126  }
127  }
128 
129  if (ED_assetlist_listen(&list_data->asset_library_ref, params->notifier)) {
130  ED_region_tag_redraw(params->region);
131  }
132 }
133 
135 {
136  uiListType *list_type = (uiListType *)MEM_callocN(sizeof(*list_type), __func__);
137 
138  BLI_strncpy(list_type->idname, "UI_UL_asset_view", sizeof(list_type->idname));
139  list_type->draw_item = asset_view_draw_item;
140  list_type->listener = asset_view_listener;
141 
142  return list_type;
143 }
144 
146  const AssetLibraryReference &asset_library_ref,
147  const AssetFilterSettings &filter_settings,
148  PointerRNA &assets_dataptr,
149  const char *assets_propname)
150 {
151  PropertyRNA *assets_prop = RNA_struct_find_property(&assets_dataptr, assets_propname);
152  if (!assets_prop) {
153  RNA_warning("Asset collection not found");
154  return;
155  }
156  if (RNA_property_type(assets_prop) != PROP_COLLECTION) {
157  RNA_warning("Expected a collection property");
158  return;
159  }
160  if (!RNA_struct_is_a(RNA_property_pointer_type(&assets_dataptr, assets_prop),
161  &RNA_AssetHandle)) {
162  RNA_warning("Expected a collection property for AssetHandle items");
163  return;
164  }
165 
166  RNA_property_collection_clear(&assets_dataptr, assets_prop);
167 
168  ED_assetlist_iterate(asset_library_ref, [&](AssetHandle asset) {
169  if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
170  /* Don't do anything else, but return true to continue iterating. */
171  return true;
172  }
173 
174  PointerRNA itemptr, fileptr;
175  RNA_property_collection_add(&assets_dataptr, assets_prop, &itemptr);
176 
178  nullptr, &RNA_FileSelectEntry, const_cast<FileDirEntry *>(asset.file_data), &fileptr);
179  RNA_pointer_set(&itemptr, "file_data", fileptr);
180 
181  return true;
182  });
183 }
184 
186  bContext *C,
187  const char *list_id,
188  PointerRNA *asset_library_dataptr,
189  const char *asset_library_propname,
190  PointerRNA *assets_dataptr,
191  const char *assets_propname,
192  PointerRNA *active_dataptr,
193  const char *active_propname,
194  const AssetFilterSettings *filter_settings,
195  const int display_flags,
196  const char *activate_opname,
197  PointerRNA *r_activate_op_properties,
198  const char *drag_opname,
199  PointerRNA *r_drag_op_properties)
200 {
201  if (!list_id || !list_id[0]) {
202  RNA_warning("Asset view needs a valid identifier");
203  return;
204  }
205 
206  uiLayout *col = uiLayoutColumn(layout, false);
207 
208  PropertyRNA *asset_library_prop = RNA_struct_find_property(asset_library_dataptr,
209  asset_library_propname);
211  RNA_property_enum_get(asset_library_dataptr, asset_library_prop));
212 
213  uiLayout *row = uiLayoutRow(col, true);
214  if ((display_flags & UI_TEMPLATE_ASSET_DRAW_NO_LIBRARY) == 0) {
215  uiItemFullR(row, asset_library_dataptr, asset_library_prop, RNA_NO_INDEX, 0, 0, "", 0);
216  if (asset_library_ref.type != ASSET_LIBRARY_LOCAL) {
217  uiItemO(row, "", ICON_FILE_REFRESH, "ASSET_OT_library_refresh");
218  }
219  }
220 
221  ED_assetlist_storage_fetch(&asset_library_ref, C);
222  ED_assetlist_ensure_previews_job(&asset_library_ref, C);
223  const int tot_items = ED_assetlist_size(&asset_library_ref);
224 
226  asset_library_ref, *filter_settings, *assets_dataptr, assets_propname);
227 
228  AssetViewListData *list_data = (AssetViewListData *)MEM_mallocN(sizeof(*list_data),
229  "AssetViewListData");
230  list_data->asset_library_ref = asset_library_ref;
231  list_data->screen = CTX_wm_screen(C);
232  list_data->show_names = (display_flags & UI_TEMPLATE_ASSET_DRAW_NO_NAMES) == 0;
233 
234  uiTemplateListFlags template_list_flags = UI_TEMPLATE_LIST_NO_GRIP;
235  if ((display_flags & UI_TEMPLATE_ASSET_DRAW_NO_NAMES) != 0) {
236  template_list_flags |= UI_TEMPLATE_LIST_NO_NAMES;
237  }
238  if ((display_flags & UI_TEMPLATE_ASSET_DRAW_NO_FILTER) != 0) {
239  template_list_flags |= UI_TEMPLATE_LIST_NO_FILTER_OPTIONS;
240  }
241 
242  /* TODO can we have some kind of model-view API to handle referencing, filtering and lazy loading
243  * (of previews) of the items? */
244  uiList *list = uiTemplateList_ex(col,
245  C,
246  "UI_UL_asset_view",
247  list_id,
248  assets_dataptr,
249  assets_propname,
250  active_dataptr,
251  active_propname,
252  nullptr,
253  tot_items,
254  0,
256  0,
257  template_list_flags,
258  list_data);
259  if (!list) {
260  /* List creation failed. */
261  MEM_freeN(list_data);
262  return;
263  }
264 
265  if (activate_opname) {
267  list, activate_opname, r_activate_op_properties != nullptr);
268  if (r_activate_op_properties && ptr) {
269  *r_activate_op_properties = *ptr;
270  }
271  }
272  if (drag_opname) {
274  list, drag_opname, r_drag_op_properties != nullptr);
275  if (r_drag_op_properties && ptr) {
276  *r_drag_op_properties = *ptr;
277  }
278  }
279 }
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:733
#define BLI_assert(a)
Definition: BLI_assert.h:46
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED(x)
#define ELEM(...)
external readfile function prototypes.
@ ASSET_LIBRARY_LOCAL
@ UILST_LAYOUT_BIG_PREVIEW_GRID
@ FILE_ASSET_IMPORT_APPEND
#define FILE_MAX_LIBEXTRA
bool ED_asset_filter_matches_asset(const struct AssetFilterSettings *filter, const struct AssetHandle *asset)
struct ID * ED_asset_handle_get_local_id(const struct AssetHandle *asset)
const char * ED_asset_handle_get_name(const struct AssetHandle *asset)
struct AssetMetaData * ED_asset_handle_get_metadata(const struct AssetHandle *asset)
void ED_asset_handle_get_full_library_path(const struct bContext *C, const struct AssetLibraryReference *asset_library_ref, const struct AssetHandle *asset, char r_full_lib_path[])
int ED_asset_handle_get_preview_icon_id(const struct AssetHandle *asset)
AssetLibraryReference ED_asset_library_reference_from_enum_value(int value)
struct ImBuf * ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
Definition: asset_list.cc:495
int ED_assetlist_size(const struct AssetLibraryReference *library_reference)
void ED_assetlist_storage_fetch(const struct AssetLibraryReference *library_reference, const struct bContext *C)
bool ED_assetlist_listen(const struct AssetLibraryReference *library_reference, const struct wmNotifier *notifier)
void ED_assetlist_ensure_previews_job(const struct AssetLibraryReference *library_reference, struct bContext *C)
void ED_assetlist_storage_tag_main_data_dirty(void)
Definition: asset_list.cc:533
void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetListIterFn fn)
Definition: asset_list.cc:447
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
Read Guarded memory(de)allocation.
#define RNA_warning(format,...)
Definition: RNA_access.h:756
@ PROP_COLLECTION
Definition: RNA_types.h:65
#define C
Definition: RandGen.cpp:25
uiBut * uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5623
#define UI_UNIT_Y
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_BUT_ICON_PREVIEW
Definition: UI_interface.h:190
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void UI_but_drag_set_id(uiBut *but, struct ID *id)
@ UI_TEMPLATE_ASSET_DRAW_NO_NAMES
@ UI_TEMPLATE_ASSET_DRAW_NO_LIBRARY
@ UI_TEMPLATE_ASSET_DRAW_NO_FILTER
struct uiList * uiTemplateList_ex(uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id, struct PointerRNA *dataptr, const char *propname, struct PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, enum uiTemplateListFlags flags, void *customdata)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr)
struct PointerRNA * UI_list_custom_drag_operator_set(struct uiList *ui_list, const char *opname, bool create_properties)
void UI_but_drag_set_asset(uiBut *but, const struct AssetHandle *asset, const char *path, struct AssetMetaData *metadata, int import_type, int icon, struct ImBuf *imb, float scale)
void uiItemFullR(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int flag, const char *name, int icon)
#define UI_UNIT_X
@ UI_BTYPE_PREVIEW_TILE
Definition: UI_interface.h:376
struct PointerRNA * UI_list_custom_activate_operator_set(struct uiList *ui_list, const char *opname, bool create_properties)
uiTemplateListFlags
@ UI_TEMPLATE_LIST_NO_NAMES
@ UI_TEMPLATE_LIST_NO_FILTER_OPTIONS
@ UI_TEMPLATE_LIST_NO_GRIP
#define NC_ID
Definition: WM_types.h:345
#define NA_RENAME
Definition: WM_types.h:527
uint col
void ui_def_but_icon(uiBut *but, const int icon, const int flag)
Definition: interface.cc:4244
#define RNA_NO_INDEX
@ UI_HAS_ICON
static void asset_view_item_but_drag_set(uiBut *but, AssetViewListData *list_data, AssetHandle *asset_handle)
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 int display_flags, const char *activate_opname, PointerRNA *r_activate_op_properties, const char *drag_opname, PointerRNA *r_drag_op_properties)
static void asset_view_template_refresh_asset_collection(const AssetLibraryReference &asset_library_ref, const AssetFilterSettings &filter_settings, PointerRNA &assets_dataptr, const char *assets_propname)
static void asset_view_listener(uiList *ui_list, wmRegionListenerParams *params)
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))
uiListType * UI_UL_asset_view()
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:695
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
Definition: rna_access.c:5179
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1405
void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
Definition: rna_access.c:3835
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:4026
const struct FileDirEntry * file_data
AssetLibraryReference asset_library_ref
Definition: DNA_ID.h:368
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
void * customdata
struct wmOperatorType * custom_drag_optype
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:321
uiListDrawItemFunc draw_item
Definition: BKE_screen.h:323
uiListListener listener
Definition: BKE_screen.h:328
uiListDyn * dyn_data
PointerRNA * ptr
Definition: wm_files.c:3480