Blender  V3.3
interface_template_list.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <cstdlib>
8 #include <cstring>
9 
10 #include "BLI_fnmatch.h"
11 #include "BLI_listbase.h"
12 #include "BLI_math_base.h"
13 #include "BLI_string.h"
14 #include "BLI_utildefines.h"
15 
16 #include "BKE_screen.h"
17 
18 #include "BLT_translation.h"
19 
20 #include "ED_asset.h"
21 #include "ED_screen.h"
22 
23 #include "MEM_guardedalloc.h"
24 
25 #include "RNA_access.h"
26 #include "RNA_prototypes.h"
27 
28 #include "UI_interface.h"
29 #include "UI_view2d.h"
30 
31 #include "WM_api.h"
32 
33 #include "interface_intern.h"
34 
44  const char *item_dyntip_propname;
45 
46  /* Index as stored in the input property. I.e. the index before sorting. */
48 };
49 
53 struct _uilist_item {
55  int org_idx;
56  int flt_flag;
57 };
58 
64  /* Index of the active item following visual order. I.e. unlike
65  * TemplateListInputData.active_item_idx, this is the index after sorting. */
67  int tot_items;
68 };
69 
73 
74  int rows;
75  int maxrows;
76  int columns;
77 };
78 
80  int visual_items; /* Visual number of items (i.e. number of items we have room to display). */
81  int start_idx; /* Index of first item to display. */
82  int end_idx; /* Index of last item to display + 1. */
83 };
84 
85 static void uilist_draw_item_default(struct uiList *ui_list,
86  struct bContext *UNUSED(C),
87  struct uiLayout *layout,
88  struct PointerRNA *UNUSED(dataptr),
89  struct PointerRNA *itemptr,
90  int icon,
91  struct PointerRNA *UNUSED(active_dataptr),
92  const char *UNUSED(active_propname),
93  int UNUSED(index),
94  int UNUSED(flt_flag))
95 {
96  PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type);
97 
98  /* Simplest one! */
99  switch (ui_list->layout_type) {
100  case UILST_LAYOUT_GRID:
101  uiItemL(layout, "", icon);
102  break;
105  default:
106  if (nameprop) {
107  uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon);
108  }
109  else {
110  uiItemL(layout, "", icon);
111  }
112  break;
113  }
114 }
115 
116 static void uilist_draw_filter_default(struct uiList *ui_list,
117  struct bContext *UNUSED(C),
118  struct uiLayout *layout)
119 {
120  PointerRNA listptr;
121  RNA_pointer_create(nullptr, &RNA_UIList, ui_list, &listptr);
122 
123  uiLayout *row = uiLayoutRow(layout, false);
124 
125  uiLayout *subrow = uiLayoutRow(row, true);
126  uiItemR(subrow, &listptr, "filter_name", 0, "", ICON_NONE);
127  uiItemR(subrow,
128  &listptr,
129  "use_filter_invert",
131  "",
132  ICON_ARROW_LEFTRIGHT);
133 
134  if ((ui_list->filter_sort_flag & UILST_FLT_SORT_LOCK) == 0) {
135  subrow = uiLayoutRow(row, true);
136  uiItemR(subrow,
137  &listptr,
138  "use_filter_sort_alpha",
140  "",
141  ICON_NONE);
142  uiItemR(subrow,
143  &listptr,
144  "use_filter_sort_reverse",
146  "",
147  (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC);
148  }
149 }
150 
151 struct StringCmp {
153  int org_idx;
154 };
155 
156 static int cmpstringp(const void *p1, const void *p2)
157 {
158  /* Case-insensitive comparison. */
159  return BLI_strcasecmp(((StringCmp *)p1)->name, ((StringCmp *)p2)->name);
160 }
161 
162 static void uilist_filter_items_default(struct uiList *ui_list,
163  struct bContext *UNUSED(C),
164  struct PointerRNA *dataptr,
165  const char *propname)
166 {
167  uiListDyn *dyn_data = ui_list->dyn_data;
168  PropertyRNA *prop = RNA_struct_find_property(dataptr, propname);
169 
170  const char *filter_raw = ui_list->filter_byname;
171  char *filter = (char *)filter_raw, filter_buff[32], *filter_dyn = nullptr;
172  const bool filter_exclude = (ui_list->filter_flag & UILST_FLT_EXCLUDE) != 0;
173  const bool order_by_name = (ui_list->filter_sort_flag & UILST_FLT_SORT_MASK) ==
175  const int len = RNA_property_collection_length(dataptr, prop);
176 
177  dyn_data->items_shown = dyn_data->items_len = len;
178 
179  if (len && (order_by_name || filter_raw[0])) {
180  StringCmp *names = nullptr;
181  int order_idx = 0, i = 0;
182 
183  if (order_by_name) {
184  names = static_cast<StringCmp *>(MEM_callocN(sizeof(StringCmp) * len, "StringCmp"));
185  }
186  if (filter_raw[0]) {
187  const size_t slen = strlen(filter_raw);
188 
189  dyn_data->items_filter_flags = static_cast<int *>(
190  MEM_callocN(sizeof(int) * len, "items_filter_flags"));
191  dyn_data->items_shown = 0;
192 
193  /* Implicitly add heading/trailing wildcards if needed. */
194  if (slen + 3 <= sizeof(filter_buff)) {
195  filter = filter_buff;
196  }
197  else {
198  filter = filter_dyn = static_cast<char *>(
199  MEM_mallocN((slen + 3) * sizeof(char), "filter_dyn"));
200  }
201  BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 3);
202  }
203 
204  RNA_PROP_BEGIN (dataptr, itemptr, prop) {
205  bool do_order = false;
206 
207  char *namebuf;
208  if (RNA_struct_is_a(itemptr.type, &RNA_AssetHandle)) {
209  /* XXX The AssetHandle design is hacky and meant to be temporary. It can't have a proper
210  * name property, so for now this hardcoded exception is needed. */
211  AssetHandle *asset_handle = (AssetHandle *)itemptr.data;
212  const char *asset_name = ED_asset_handle_get_name(asset_handle);
213  namebuf = BLI_strdup(asset_name);
214  }
215  else {
216  namebuf = RNA_struct_name_get_alloc(&itemptr, nullptr, 0, nullptr);
217  }
218 
219  const char *name = namebuf ? namebuf : "";
220 
221  if (filter[0]) {
222  /* Case-insensitive! */
223  if (fnmatch(filter, name, FNM_CASEFOLD) == 0) {
224  dyn_data->items_filter_flags[i] = UILST_FLT_ITEM;
225  if (!filter_exclude) {
226  dyn_data->items_shown++;
227  do_order = order_by_name;
228  }
229  // printf("%s: '%s' matches '%s'\n", __func__, name, filter);
230  }
231  else if (filter_exclude) {
232  dyn_data->items_shown++;
233  do_order = order_by_name;
234  }
235  }
236  else {
237  do_order = order_by_name;
238  }
239 
240  if (do_order) {
241  names[order_idx].org_idx = order_idx;
242  BLI_strncpy(names[order_idx++].name, name, MAX_IDPROP_NAME);
243  }
244 
245  /* free name */
246  if (namebuf) {
247  MEM_freeN(namebuf);
248  }
249  i++;
250  }
251  RNA_PROP_END;
252 
253  if (order_by_name) {
254  int new_idx;
255  /* NOTE: order_idx equals either to ui_list->items_len if no filtering done,
256  * or to ui_list->items_shown if filter is enabled,
257  * or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded.
258  * This way, we only sort items we actually intend to draw!
259  */
260  qsort(names, order_idx, sizeof(StringCmp), cmpstringp);
261 
262  dyn_data->items_filter_neworder = static_cast<int *>(
263  MEM_mallocN(sizeof(int) * order_idx, "items_filter_neworder"));
264  for (new_idx = 0; new_idx < order_idx; new_idx++) {
265  dyn_data->items_filter_neworder[names[new_idx].org_idx] = new_idx;
266  }
267  }
268 
269  if (filter_dyn) {
270  MEM_freeN(filter_dyn);
271  }
272  if (names) {
273  MEM_freeN(names);
274  }
275  }
276 }
277 
278 static void uilist_free_dyn_data(uiList *ui_list)
279 {
280  uiListDyn *dyn_data = ui_list->dyn_data;
281  if (!dyn_data) {
282  return;
283  }
284 
285  if (dyn_data->custom_activate_opptr) {
287  MEM_freeN(dyn_data->custom_activate_opptr);
288  }
289  if (dyn_data->custom_drag_opptr) {
291  MEM_freeN(dyn_data->custom_drag_opptr);
292  }
293 
296  MEM_SAFE_FREE(dyn_data->customdata);
297 }
298 
305 static bool ui_template_list_data_retrieve(const char *listtype_name,
306  const char *list_id,
307  PointerRNA *dataptr,
308  const char *propname,
309  PointerRNA *active_dataptr,
310  const char *active_propname,
311  const char *item_dyntip_propname,
312  TemplateListInputData *r_input_data,
313  uiListType **r_list_type)
314 {
315  memset(r_input_data, 0, sizeof(*r_input_data));
316 
317  /* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */
318  if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
319  RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
321  return false;
322  }
323 
324  if (!active_dataptr->data) {
325  RNA_warning("No active data");
326  return false;
327  }
328 
329  r_input_data->dataptr = *dataptr;
330  if (dataptr->data) {
331  r_input_data->prop = RNA_struct_find_property(dataptr, propname);
332  if (!r_input_data->prop) {
333  RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
334  return false;
335  }
336  }
337 
338  r_input_data->active_dataptr = *active_dataptr;
339  r_input_data->activeprop = RNA_struct_find_property(active_dataptr, active_propname);
340  if (!r_input_data->activeprop) {
341  RNA_warning(
342  "Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
343  return false;
344  }
345 
346  if (r_input_data->prop) {
347  const PropertyType type = RNA_property_type(r_input_data->prop);
348  if (type != PROP_COLLECTION) {
349  RNA_warning("Expected a collection data property");
350  return false;
351  }
352  }
353 
354  const PropertyType activetype = RNA_property_type(r_input_data->activeprop);
355  if (activetype != PROP_INT) {
356  RNA_warning("Expected an integer active data property");
357  return false;
358  }
359 
360  /* Find the uiList type. */
361  if (!(*r_list_type = WM_uilisttype_find(listtype_name, false))) {
362  RNA_warning("List type %s not found", listtype_name);
363  return false;
364  }
365 
366  r_input_data->active_item_idx = RNA_property_int_get(&r_input_data->active_dataptr,
367  r_input_data->activeprop);
368  r_input_data->item_dyntip_propname = item_dyntip_propname;
369 
370  return true;
371 }
372 
374  PropertyRNA *list_prop,
375  uiListDyn *dyn_data,
376  int filter_exclude,
377  bool order_reverse,
378  int activei,
379  TemplateListItems *r_items)
380 {
381  int i = 0;
382  int reorder_i = 0;
383  bool activei_mapping_pending = true;
384 
385  RNA_PROP_BEGIN (list_ptr, itemptr, list_prop) {
386  if (!dyn_data->items_filter_flags ||
387  ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)) {
388  int new_order_idx;
389  if (dyn_data->items_filter_neworder) {
390  new_order_idx = dyn_data->items_filter_neworder[reorder_i++];
391  new_order_idx = order_reverse ? dyn_data->items_shown - new_order_idx - 1 : new_order_idx;
392  }
393  else {
394  new_order_idx = order_reverse ? dyn_data->items_shown - ++reorder_i : reorder_i++;
395  }
396  // printf("%s: ii: %d\n", __func__, ii);
397  r_items->item_vec[new_order_idx].item = itemptr;
398  r_items->item_vec[new_order_idx].org_idx = i;
399  r_items->item_vec[new_order_idx].flt_flag = dyn_data->items_filter_flags ?
400  dyn_data->items_filter_flags[i] :
401  0;
402 
403  if (activei_mapping_pending && activei == i) {
404  activei = new_order_idx;
405  /* So that we do not map again activei! */
406  activei_mapping_pending = false;
407  }
408 #if 0 /* For now, do not alter active element, even if it will be hidden... */
409  else if (activei < i) {
410  /* We do not want an active but invisible item!
411  * Only exception is when all items are filtered out...
412  */
413  if (prev_order_idx >= 0) {
414  activei = prev_order_idx;
415  RNA_property_int_set(active_dataptr, activeprop, prev_i);
416  }
417  else {
418  activei = new_order_idx;
419  RNA_property_int_set(active_dataptr, activeprop, i);
420  }
421  }
422  prev_i = i;
423  prev_ii = new_order_idx;
424 #endif
425  }
426  i++;
427  }
428  RNA_PROP_END;
429 
430  /* If mapping is still pending, no active item was found. Mark as invalid (-1) */
431  r_items->active_item_idx = activei_mapping_pending ? -1 : activei;
432 }
433 
438  uiList *ui_list,
439  TemplateListInputData *input_data,
440  const uiListFilterItemsFunc filter_items_fn,
441  TemplateListItems *r_items)
442 {
443  uiListDyn *dyn_data = ui_list->dyn_data;
444  memset(r_items, 0, sizeof(*r_items));
445 
446  /* Filter list items! (not for compact layout, though) */
447  if (input_data->dataptr.data && input_data->prop) {
448  const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
449  const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0;
450  int items_shown;
451 #if 0
452  int prev_ii = -1, prev_i;
453 #endif
454 
455  if (ui_list->layout_type == UILST_LAYOUT_COMPACT) {
456  dyn_data->items_len = dyn_data->items_shown = RNA_property_collection_length(
457  &input_data->dataptr, input_data->prop);
458  }
459  else {
460  // printf("%s: filtering...\n", __func__);
461  filter_items_fn(ui_list, C, &input_data->dataptr, RNA_property_identifier(input_data->prop));
462  // printf("%s: filtering done.\n", __func__);
463  }
464 
465  items_shown = dyn_data->items_shown;
466  if (items_shown >= 0) {
467  r_items->item_vec = static_cast<_uilist_item *>(
468  MEM_mallocN(sizeof(*r_items->item_vec) * items_shown, __func__));
469  // printf("%s: items shown: %d.\n", __func__, items_shown);
470 
472  input_data->prop,
473  dyn_data,
474  filter_exclude,
475  order_reverse,
476  input_data->active_item_idx,
477  r_items);
478  }
479  if (dyn_data->items_shown >= 0) {
480  r_items->tot_items = dyn_data->items_shown;
481  }
482  else {
483  r_items->tot_items = dyn_data->items_len;
484  }
485  }
486 }
487 
489 {
490  if (items->item_vec) {
491  MEM_freeN(items->item_vec);
492  }
493 }
494 
495 static void uilist_prepare(uiList *ui_list,
496  const TemplateListItems *items,
497  const TemplateListLayoutDrawData *layout_data,
498  TemplateListVisualInfo *r_visual_info)
499 {
500  uiListDyn *dyn_data = ui_list->dyn_data;
501  const bool use_auto_size = (ui_list->list_grip <
502  (layout_data->rows - UI_LIST_AUTO_SIZE_THRESHOLD));
503 
504  int actual_rows = layout_data->rows;
505  int actual_maxrows = layout_data->maxrows;
506  int columns = layout_data->columns;
507 
508  /* default rows */
509  if (actual_rows <= 0) {
510  actual_rows = 5;
511  }
512  dyn_data->visual_height_min = actual_rows;
513  if (actual_maxrows < actual_rows) {
514  actual_maxrows = max_ii(actual_rows, 5);
515  }
516  if (columns <= 0) {
517  columns = 9;
518  }
519 
520  int activei_row;
521  if (columns > 1) {
522  dyn_data->height = (int)ceil((double)items->tot_items / (double)columns);
523  activei_row = (int)floor((double)items->active_item_idx / (double)columns);
524  }
525  else {
526  dyn_data->height = items->tot_items;
527  activei_row = items->active_item_idx;
528  }
529 
530  dyn_data->columns = columns;
531 
532  if (!use_auto_size) {
533  /* No auto-size, yet we clamp at min size! */
534  actual_rows = max_ii(ui_list->list_grip, actual_rows);
535  }
536  else if ((actual_rows != actual_maxrows) && (dyn_data->height > actual_rows)) {
537  /* Expand size if needed and possible. */
538  actual_rows = min_ii(dyn_data->height, actual_maxrows);
539  }
540 
541  /* If list length changes or list is tagged to check this,
542  * and active is out of view, scroll to it. */
543  if ((ui_list->list_last_len != items->tot_items) ||
544  (ui_list->flag & UILST_SCROLL_TO_ACTIVE_ITEM)) {
545  if (activei_row < ui_list->list_scroll) {
546  ui_list->list_scroll = activei_row;
547  }
548  else if (activei_row >= ui_list->list_scroll + actual_rows) {
549  ui_list->list_scroll = activei_row - actual_rows + 1;
550  }
551  ui_list->flag &= ~UILST_SCROLL_TO_ACTIVE_ITEM;
552  }
553 
554  const int max_scroll = max_ii(0, dyn_data->height - actual_rows);
555  CLAMP(ui_list->list_scroll, 0, max_scroll);
556  ui_list->list_last_len = items->tot_items;
557  dyn_data->visual_height = actual_rows;
558  r_visual_info->visual_items = actual_rows * columns;
559  r_visual_info->start_idx = ui_list->list_scroll * columns;
560  r_visual_info->end_idx = min_ii(r_visual_info->start_idx + actual_rows * columns,
561  items->tot_items);
562 }
563 
564 static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
565 {
566  uiList *ui_list = static_cast<uiList *>(arg1);
567  uiListDyn *dyn_data = ui_list->dyn_data;
568 
569  /* This way we get diff in number of additional items to show (positive) or hide (negative). */
570  const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) /
571  (float)UI_UNIT_Y);
572 
573  if (diff != 0) {
574  ui_list->list_grip += diff;
575  dyn_data->resize_prev += diff * UI_UNIT_Y;
576  ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
577  }
578 
579  /* In case uilist is in popup, we need special refreshing */
581 }
582 
583 static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname)
584 {
585  if (propname && propname[0] && itemptr && itemptr->data) {
586  PropertyRNA *prop = RNA_struct_find_property(itemptr, propname);
587 
588  if (prop && (RNA_property_type(prop) == PROP_STRING)) {
589  return RNA_property_string_get_alloc(itemptr, prop, nullptr, 0, nullptr);
590  }
591  }
592  return nullptr;
593 }
594 
595 static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
596 {
597  char *dyn_tooltip = static_cast<char *>(argN);
598  return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
599 }
600 
605  uiListType *ui_list_type,
606  const char *list_id,
607  int layout_type,
608  bool sort_reverse,
609  bool sort_lock)
610 {
611  /* Allows to work in popups. */
612  ARegion *region = CTX_wm_menu(C);
613  if (region == nullptr) {
614  region = CTX_wm_region(C);
615  }
616 
617  /* Find or add the uiList to the current Region. */
618 
619  char full_list_id[UI_MAX_NAME_STR];
620  WM_uilisttype_to_full_list_id(ui_list_type, list_id, full_list_id);
621 
622  uiList *ui_list = static_cast<uiList *>(
623  BLI_findstring(&region->ui_lists, full_list_id, offsetof(uiList, list_id)));
624 
625  if (!ui_list) {
626  ui_list = static_cast<uiList *>(MEM_callocN(sizeof(uiList), "uiList"));
627  BLI_strncpy(ui_list->list_id, full_list_id, sizeof(ui_list->list_id));
628  BLI_addtail(&region->ui_lists, ui_list);
629  ui_list->list_grip = -UI_LIST_AUTO_SIZE_THRESHOLD; /* Force auto size by default. */
630  if (sort_reverse) {
632  }
633  if (sort_lock) {
635  }
636  }
637 
638  if (!ui_list->dyn_data) {
639  ui_list->dyn_data = static_cast<uiListDyn *>(
640  MEM_callocN(sizeof(uiListDyn), "uiList.dyn_data"));
641  }
642  uiListDyn *dyn_data = ui_list->dyn_data;
643  /* Note that this isn't a `uiListType` callback, it's stored in the runtime list data. Otherwise
644  * the runtime data could leak when the type is unregistered (e.g. on "Reload Scripts"). */
646 
647  /* Because we can't actually pass type across save&load... */
648  ui_list->type = ui_list_type;
649  ui_list->layout_type = layout_type;
650 
651  /* Reset filtering data. */
654  dyn_data->items_len = dyn_data->items_shown = -1;
655 
656  return ui_list;
657 }
658 
660  uiList *ui_list,
661  uiLayout *layout,
662  TemplateListInputData *input_data,
663  TemplateListItems *items,
664  const TemplateListLayoutDrawData *layout_data,
665  const enum uiTemplateListFlags flags)
666 {
667  uiListDyn *dyn_data = ui_list->dyn_data;
668  const char *active_propname = RNA_property_identifier(input_data->activeprop);
669 
670  uiLayout *glob = nullptr, *box, *row, *col, *subrow, *sub, *overlap;
671  char numstr[32];
672  int rnaicon = ICON_NONE, icon = ICON_NONE;
673  uiBut *but;
674 
675  uiBlock *block = uiLayoutGetBlock(layout);
676 
677  /* get icon */
678  if (input_data->dataptr.data && input_data->prop) {
679  StructRNA *ptype = RNA_property_pointer_type(&input_data->dataptr, input_data->prop);
680  rnaicon = RNA_struct_ui_icon(ptype);
681  }
682 
683  TemplateListVisualInfo visual_info;
684  switch (ui_list->layout_type) {
685  case UILST_LAYOUT_DEFAULT: {
686  /* layout */
687  box = uiLayoutListBox(layout, ui_list, &input_data->active_dataptr, input_data->activeprop);
688  glob = uiLayoutColumn(box, true);
689  row = uiLayoutRow(glob, false);
690  col = uiLayoutColumn(row, true);
691 
692  TemplateListLayoutDrawData adjusted_layout_data = *layout_data;
693  adjusted_layout_data.columns = 1;
694  /* init numbers */
695  uilist_prepare(ui_list, items, &adjusted_layout_data, &visual_info);
696 
697  int i = 0;
698  if (input_data->dataptr.data && input_data->prop) {
699  /* create list items */
700  for (i = visual_info.start_idx; i < visual_info.end_idx; i++) {
701  PointerRNA *itemptr = &items->item_vec[i].item;
702  void *dyntip_data;
703  const int org_i = items->item_vec[i].org_idx;
704  const int flt_flag = items->item_vec[i].flt_flag;
705  uiBlock *subblock = uiLayoutGetBlock(col);
706 
707  overlap = uiLayoutOverlap(col);
708 
710 
711  /* list item behind label & other buttons */
712  uiLayoutRow(overlap, false);
713 
714  but = uiDefButR_prop(subblock,
716  0,
717  "",
718  0,
719  0,
720  UI_UNIT_X * 10,
721  UI_UNIT_Y,
722  &input_data->active_dataptr,
723  input_data->activeprop,
724  0,
725  0,
726  org_i,
727  0,
728  0,
729  TIP_("Double click to rename"));
730  if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr,
731  input_data->item_dyntip_propname))) {
733  }
734 
735  sub = uiLayoutRow(overlap, false);
736 
737  icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
738  if (icon == ICON_DOT) {
739  icon = ICON_NONE;
740  }
741  layout_data->draw_item(ui_list,
742  C,
743  sub,
744  &input_data->dataptr,
745  itemptr,
746  icon,
747  &input_data->active_dataptr,
748  active_propname,
749  org_i,
750  flt_flag);
751 
752  /* Items should be able to set context pointers for the layout. But the list-row button
753  * swallows events, so it needs the context storage too for handlers to see it. */
754  but->context = uiLayoutGetContextStore(sub);
755 
756  /* If we are "drawing" active item, set all labels as active. */
757  if (i == items->active_item_idx) {
759  }
760 
762  }
763  }
764 
765  /* add dummy buttons to fill space */
766  for (; i < visual_info.start_idx + visual_info.visual_items; i++) {
767  uiItemL(col, "", ICON_NONE);
768  }
769 
770  /* add scrollbar */
771  if (items->tot_items > visual_info.visual_items) {
772  uiLayoutColumn(row, false);
773  uiDefButI(block,
775  0,
776  "",
777  0,
778  0,
780  UI_UNIT_Y * dyn_data->visual_height,
781  &ui_list->list_scroll,
782  0,
783  dyn_data->height - dyn_data->visual_height,
784  dyn_data->visual_height,
785  0,
786  "");
787  }
788  } break;
790  row = uiLayoutRow(layout, true);
791 
792  if ((input_data->dataptr.data && input_data->prop) && (dyn_data->items_shown > 0) &&
793  (items->active_item_idx >= 0) && (items->active_item_idx < dyn_data->items_shown)) {
794  PointerRNA *itemptr = &items->item_vec[items->active_item_idx].item;
795  const int org_i = items->item_vec[items->active_item_idx].org_idx;
796 
797  icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
798  if (icon == ICON_DOT) {
799  icon = ICON_NONE;
800  }
801  layout_data->draw_item(ui_list,
802  C,
803  row,
804  &input_data->dataptr,
805  itemptr,
806  icon,
807  &input_data->active_dataptr,
808  active_propname,
809  org_i,
810  0);
811  }
812  /* if list is empty, add in dummy button */
813  else {
814  uiItemL(row, "", ICON_NONE);
815  }
816 
817  /* next/prev button */
818  BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown);
819  but = uiDefIconTextButR_prop(block,
820  UI_BTYPE_NUM,
821  0,
822  0,
823  numstr,
824  0,
825  0,
826  UI_UNIT_X * 5,
827  UI_UNIT_Y,
828  &input_data->active_dataptr,
829  input_data->activeprop,
830  0,
831  0,
832  0,
833  0,
834  0,
835  "");
836  if (dyn_data->items_shown == 0) {
838  }
839  break;
840  case UILST_LAYOUT_GRID: {
841  box = uiLayoutListBox(layout, ui_list, &input_data->active_dataptr, input_data->activeprop);
842  glob = uiLayoutColumn(box, true);
843  row = uiLayoutRow(glob, false);
844  col = uiLayoutColumn(row, true);
845  subrow = nullptr; /* Quite gcc warning! */
846 
847  uilist_prepare(ui_list, items, layout_data, &visual_info);
848 
849  int i = 0;
850  if (input_data->dataptr.data && input_data->prop) {
851  /* create list items */
852  for (i = visual_info.start_idx; i < visual_info.end_idx; i++) {
853  PointerRNA *itemptr = &items->item_vec[i].item;
854  const int org_i = items->item_vec[i].org_idx;
855  const int flt_flag = items->item_vec[i].flt_flag;
856 
857  /* create button */
858  if (!(i % layout_data->columns)) {
859  subrow = uiLayoutRow(col, false);
860  }
861 
862  uiBlock *subblock = uiLayoutGetBlock(subrow);
863  overlap = uiLayoutOverlap(subrow);
864 
866 
867  /* list item behind label & other buttons */
868  uiLayoutRow(overlap, false);
869 
870  but = uiDefButR_prop(subblock,
872  0,
873  "",
874  0,
875  0,
876  UI_UNIT_X * 10,
877  UI_UNIT_Y,
878  &input_data->active_dataptr,
879  input_data->activeprop,
880  0,
881  0,
882  org_i,
883  0,
884  0,
885  nullptr);
887 
888  sub = uiLayoutRow(overlap, false);
889 
890  icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
891  layout_data->draw_item(ui_list,
892  C,
893  sub,
894  &input_data->dataptr,
895  itemptr,
896  icon,
897  &input_data->active_dataptr,
898  active_propname,
899  org_i,
900  flt_flag);
901 
902  /* If we are "drawing" active item, set all labels as active. */
903  if (i == items->active_item_idx) {
905  }
906 
908  }
909  }
910 
911  /* add dummy buttons to fill space */
912  for (; i < visual_info.start_idx + visual_info.visual_items; i++) {
913  if (!(i % layout_data->columns)) {
914  subrow = uiLayoutRow(col, false);
915  }
916  uiItemL(subrow, "", ICON_NONE);
917  }
918 
919  /* add scrollbar */
920  if (items->tot_items > visual_info.visual_items) {
921  /* col = */ uiLayoutColumn(row, false);
922  uiDefButI(block,
924  0,
925  "",
926  0,
927  0,
929  UI_UNIT_Y * dyn_data->visual_height,
930  &ui_list->list_scroll,
931  0,
932  dyn_data->height - dyn_data->visual_height,
933  dyn_data->visual_height,
934  0,
935  "");
936  }
937  break;
938  }
940  box = uiLayoutListBox(layout, ui_list, &input_data->active_dataptr, input_data->activeprop);
941  /* For grip button. */
942  glob = uiLayoutColumn(box, true);
943  /* For scrollbar. */
944  row = uiLayoutRow(glob, false);
945 
946  const bool show_names = (flags & UI_TEMPLATE_LIST_NO_NAMES) == 0;
947 
948  const int size_x = UI_preview_tile_size_x();
949  const int size_y = show_names ? UI_preview_tile_size_y() : UI_preview_tile_size_y_no_label();
950 
951  const int cols_per_row = MAX2((uiLayoutGetWidth(box) - V2D_SCROLL_WIDTH) / size_x, 1);
952  uiLayout *grid = uiLayoutGridFlow(row, true, cols_per_row, true, true, true);
953 
954  TemplateListLayoutDrawData adjusted_layout_data = *layout_data;
955  adjusted_layout_data.columns = cols_per_row;
956  uilist_prepare(ui_list, items, &adjusted_layout_data, &visual_info);
957 
958  if (input_data->dataptr.data && input_data->prop) {
959  /* create list items */
960  for (int i = visual_info.start_idx; i < visual_info.end_idx; i++) {
961  PointerRNA *itemptr = &items->item_vec[i].item;
962  const int org_i = items->item_vec[i].org_idx;
963  const int flt_flag = items->item_vec[i].flt_flag;
964 
965  overlap = uiLayoutOverlap(grid);
966  col = uiLayoutColumn(overlap, false);
967 
968  uiBlock *subblock = uiLayoutGetBlock(col);
970 
971  but = uiDefButR_prop(subblock,
973  0,
974  "",
975  0,
976  0,
977  size_x,
978  size_y,
979  &input_data->active_dataptr,
980  input_data->activeprop,
981  0,
982  0,
983  org_i,
984  0,
985  0,
986  nullptr);
988 
989  col = uiLayoutColumn(overlap, false);
990 
991  icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
992  layout_data->draw_item(ui_list,
993  C,
994  col,
995  &input_data->dataptr,
996  itemptr,
997  icon,
998  &input_data->active_dataptr,
999  active_propname,
1000  org_i,
1001  flt_flag);
1002 
1003  /* Items should be able to set context pointers for the layout. But the list-row button
1004  * swallows events, so it needs the context storage too for handlers to see it. */
1006 
1007  /* If we are "drawing" active item, set all labels as active. */
1008  if (i == items->active_item_idx) {
1010  }
1011 
1013  }
1014  }
1015 
1016  if (items->tot_items > visual_info.visual_items) {
1017  /* col = */ uiLayoutColumn(row, false);
1018  uiDefButI(block,
1020  0,
1021  "",
1022  0,
1023  0,
1025  size_y * dyn_data->visual_height,
1026  &ui_list->list_scroll,
1027  0,
1028  dyn_data->height - dyn_data->visual_height,
1029  dyn_data->visual_height,
1030  0,
1031  "");
1032  }
1033  break;
1034  }
1035 
1036  const bool add_filters_but = (flags & UI_TEMPLATE_LIST_NO_FILTER_OPTIONS) == 0;
1037  if (glob && add_filters_but) {
1038  const bool add_grip_but = (flags & UI_TEMPLATE_LIST_NO_GRIP) == 0;
1039 
1040  /* About #UI_BTYPE_GRIP drag-resize:
1041  * We can't directly use results from a grip button, since we have a
1042  * rather complex behavior here (sizing by discrete steps and, overall, auto-size feature).
1043  * Since we *never* know whether we are grip-resizing or not
1044  * (because there is no callback for when a button enters/leaves its "edit mode"),
1045  * we use the fact that grip-controlled value (dyn_data->resize) is completely handled
1046  * by the grip during the grab resize, so settings its value here has no effect at all.
1047  *
1048  * It is only meaningful when we are not resizing,
1049  * in which case this gives us the correct "init drag" value.
1050  * Note we cannot affect `dyn_data->resize_prev here`,
1051  * since this value is not controlled by the grip!
1052  */
1053  dyn_data->resize = dyn_data->resize_prev +
1054  (dyn_data->visual_height - ui_list->list_grip) * UI_UNIT_Y;
1055 
1056  row = uiLayoutRow(glob, true);
1057  uiBlock *subblock = uiLayoutGetBlock(row);
1059 
1060  if (ui_list->filter_flag & UILST_FLT_SHOW) {
1061  but = uiDefIconButBitI(subblock,
1064  0,
1065  ICON_DISCLOSURE_TRI_DOWN,
1066  0,
1067  0,
1068  UI_UNIT_X,
1069  UI_UNIT_Y * 0.5f,
1070  &(ui_list->filter_flag),
1071  0,
1072  0,
1073  0,
1074  0,
1075  TIP_("Hide filtering options"));
1076  UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
1077 
1078  if (add_grip_but) {
1079  but = uiDefIconButI(subblock,
1080  UI_BTYPE_GRIP,
1081  0,
1082  ICON_GRIP,
1083  0,
1084  0,
1085  UI_UNIT_X * 10.0f,
1086  UI_UNIT_Y * 0.5f,
1087  &dyn_data->resize,
1088  0.0,
1089  0.0,
1090  0,
1091  0,
1092  "");
1093  UI_but_func_set(but, uilist_resize_update_cb, ui_list, nullptr);
1094  }
1095 
1096  UI_block_emboss_set(subblock, UI_EMBOSS);
1097 
1098  col = uiLayoutColumn(glob, false);
1099  subblock = uiLayoutGetBlock(col);
1100  uiDefBut(subblock,
1101  UI_BTYPE_SEPR,
1102  0,
1103  "",
1104  0,
1105  0,
1106  UI_UNIT_X,
1107  UI_UNIT_Y * 0.05f,
1108  nullptr,
1109  0.0,
1110  0.0,
1111  0,
1112  0,
1113  "");
1114 
1115  layout_data->draw_filter(ui_list, C, col);
1116  }
1117  else {
1118  but = uiDefIconButBitI(subblock,
1121  0,
1122  ICON_DISCLOSURE_TRI_RIGHT,
1123  0,
1124  0,
1125  UI_UNIT_X,
1126  UI_UNIT_Y * 0.5f,
1127  &(ui_list->filter_flag),
1128  0,
1129  0,
1130  0,
1131  0,
1132  TIP_("Show filtering options"));
1133  UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
1134 
1135  if (add_grip_but) {
1136  but = uiDefIconButI(subblock,
1137  UI_BTYPE_GRIP,
1138  0,
1139  ICON_GRIP,
1140  0,
1141  0,
1142  UI_UNIT_X * 10.0f,
1143  UI_UNIT_Y * 0.5f,
1144  &dyn_data->resize,
1145  0.0,
1146  0.0,
1147  0,
1148  0,
1149  "");
1150  UI_but_func_set(but, uilist_resize_update_cb, ui_list, nullptr);
1151  }
1152 
1153  UI_block_emboss_set(subblock, UI_EMBOSS);
1154  }
1155  }
1156 }
1157 
1159  bContext *C,
1160  const char *listtype_name,
1161  const char *list_id,
1162  PointerRNA *dataptr,
1163  const char *propname,
1164  PointerRNA *active_dataptr,
1165  const char *active_propname,
1166  const char *item_dyntip_propname,
1167  int rows,
1168  int maxrows,
1169  int layout_type,
1170  int columns,
1171  enum uiTemplateListFlags flags,
1172  void *customdata)
1173 {
1174  TemplateListInputData input_data = {{nullptr}};
1175  uiListType *ui_list_type;
1176  if (!ui_template_list_data_retrieve(listtype_name,
1177  list_id,
1178  dataptr,
1179  propname,
1180  active_dataptr,
1181  active_propname,
1182  item_dyntip_propname,
1183  &input_data,
1184  &ui_list_type)) {
1185  return nullptr;
1186  }
1187 
1188  uiListDrawItemFunc draw_item = ui_list_type->draw_item ? ui_list_type->draw_item :
1190  uiListDrawFilterFunc draw_filter = ui_list_type->draw_filter ? ui_list_type->draw_filter :
1192  uiListFilterItemsFunc filter_items = ui_list_type->filter_items ? ui_list_type->filter_items :
1194 
1195  uiList *ui_list = ui_list_ensure(C,
1196  ui_list_type,
1197  list_id,
1198  layout_type,
1200  flags & UI_TEMPLATE_LIST_SORT_LOCK);
1201  uiListDyn *dyn_data = ui_list->dyn_data;
1202 
1203  MEM_SAFE_FREE(dyn_data->customdata);
1204  dyn_data->customdata = customdata;
1205 
1206  /* When active item changed since last draw, scroll to it. */
1207  if (input_data.active_item_idx != ui_list->list_last_activei) {
1208  ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
1209  ui_list->list_last_activei = input_data.active_item_idx;
1210  }
1211 
1212  TemplateListItems items;
1213  ui_template_list_collect_display_items(C, ui_list, &input_data, filter_items, &items);
1214 
1215  TemplateListLayoutDrawData layout_data;
1216  layout_data.draw_item = draw_item;
1217  layout_data.draw_filter = draw_filter;
1218  layout_data.rows = rows;
1219  layout_data.maxrows = maxrows;
1220  layout_data.columns = columns;
1221 
1222  ui_template_list_layout_draw(C, ui_list, layout, &input_data, &items, &layout_data, flags);
1223 
1225 
1226  return ui_list;
1227 }
1228 
1230  bContext *C,
1231  const char *listtype_name,
1232  const char *list_id,
1233  PointerRNA *dataptr,
1234  const char *propname,
1235  PointerRNA *active_dataptr,
1236  const char *active_propname,
1237  const char *item_dyntip_propname,
1238  int rows,
1239  int maxrows,
1240  int layout_type,
1241  int columns,
1242  enum uiTemplateListFlags flags)
1243 {
1244  uiTemplateList_ex(layout,
1245  C,
1246  listtype_name,
1247  list_id,
1248  dataptr,
1249  propname,
1250  active_dataptr,
1251  active_propname,
1252  item_dyntip_propname,
1253  rows,
1254  maxrows,
1255  layout_type,
1256  columns,
1257  flags,
1258  nullptr);
1259 }
1260 
1262  const char *opname,
1263  bool create_properties)
1264 {
1265  uiListDyn *dyn_data = ui_list->dyn_data;
1266  dyn_data->custom_activate_optype = WM_operatortype_find(opname, false);
1267  if (!dyn_data->custom_activate_optype) {
1268  return nullptr;
1269  }
1270 
1271  if (create_properties) {
1272  PointerRNA *opptr = dyn_data->custom_activate_opptr;
1274  &dyn_data->custom_activate_opptr, opptr ? (IDProperty **)&opptr->data : nullptr, opname);
1275  }
1276 
1277  return dyn_data->custom_activate_opptr;
1278 }
1279 
1281  const char *opname,
1282  bool create_properties)
1283 {
1284  uiListDyn *dyn_data = ui_list->dyn_data;
1285  dyn_data->custom_drag_optype = WM_operatortype_find(opname, false);
1286  if (!dyn_data->custom_drag_optype) {
1287  return nullptr;
1288  }
1289 
1290  if (create_properties) {
1291  PointerRNA *opptr = dyn_data->custom_drag_opptr;
1293  &dyn_data->custom_drag_opptr, opptr ? (IDProperty **)&opptr->data : nullptr, opname);
1294  }
1295 
1296  return dyn_data->custom_drag_opptr;
1297 }
1298 
1299 /* -------------------------------------------------------------------- */
1300 
1305 {
1308 }
1309 
struct ARegion * CTX_wm_menu(const bContext *C)
Definition: context.c:760
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
void(* uiListDrawItemFunc)(struct uiList *ui_list, struct bContext *C, struct uiLayout *layout, struct PointerRNA *dataptr, struct PointerRNA *itemptr, int icon, struct PointerRNA *active_dataptr, const char *active_propname, int index, int flt_flag)
Definition: BKE_screen.h:293
void(* uiListFilterItemsFunc)(struct uiList *ui_list, struct bContext *C, struct PointerRNA *, const char *propname)
Definition: BKE_screen.h:310
void(* uiListDrawFilterFunc)(struct uiList *ui_list, struct bContext *C, struct uiLayout *layout)
Definition: BKE_screen.h:305
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:623
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, char pad, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:78
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED(x)
#define MAX2(a, b)
#define STREQ(a, b)
#define TIP_(msgid)
typedef double(DMatrix)[4][4]
#define MAX_IDPROP_NAME
Definition: DNA_ID.h:131
@ UILST_FLT_ITEM
#define UI_LIST_AUTO_SIZE_THRESHOLD
@ UILST_SCROLL_TO_ACTIVE_ITEM
@ UILST_LAYOUT_COMPACT
@ UILST_LAYOUT_DEFAULT
@ UILST_LAYOUT_BIG_PREVIEW_GRID
@ UILST_LAYOUT_GRID
@ UILST_FLT_SORT_LOCK
@ UILST_FLT_SORT_ALPHA
@ UILST_FLT_SORT_REVERSE
@ UILST_FLT_EXCLUDE
@ UILST_FLT_SHOW
#define UILST_FLT_SORT_MASK
const char * ED_asset_handle_get_name(const struct AssetHandle *asset)
void ED_region_tag_refresh_ui(struct ARegion *region)
Definition: area.c:683
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define RNA_PROP_END
Definition: RNA_access.h:563
#define RNA_PROP_BEGIN(sptr, itemptr, prop)
Definition: RNA_access.h:556
#define RNA_warning(format,...)
Definition: RNA_access.h:756
PropertyType
Definition: RNA_types.h:58
@ PROP_INT
Definition: RNA_types.h:60
@ PROP_STRING
Definition: RNA_types.h:62
@ PROP_COLLECTION
Definition: RNA_types.h:65
#define C
Definition: RandGen.cpp:25
@ UI_BUT_NO_TOOLTIP
Definition: UI_interface.h:263
void UI_but_flag_disable(uiBut *but, int flag)
Definition: interface.cc:5863
#define UI_UNIT_Y
uiBut * uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5733
struct bContextStore * uiLayoutGetContextStore(uiLayout *layout)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_BUT_UNDO
Definition: UI_interface.h:205
@ UI_BUT_DISABLED
Definition: UI_interface.h:196
@ UI_EMBOSS_NONE
Definition: UI_interface.h:109
@ UI_EMBOSS
Definition: UI_interface.h:108
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
uiLayout * uiLayoutGridFlow(uiLayout *layout, bool row_major, int columns_len, bool even_columns, bool even_rows, bool align)
uiLayout * uiLayoutOverlap(uiLayout *layout)
uiBut * uiDefBut(uiBlock *block, int type, int retval, 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:4806
uiBut * uiDefIconButI(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5392
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg)
Definition: interface.cc:6029
void uiItemL(uiLayout *layout, const char *name, int icon)
void UI_block_flag_disable(uiBlock *block, int flag)
Definition: interface.cc:5853
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.cc:5873
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
#define UI_UL_DEFAULT_CLASS_NAME
uiLayout * uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, struct PointerRNA *actptr, struct PropertyRNA *actprop)
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_NO_BG
@ UI_ITEM_R_ICON_ONLY
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
Definition: interface.cc:3629
int UI_preview_tile_size_x(void)
Definition: interface.cc:4973
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.cc:6000
uiBut * uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5280
int uiLayoutGetWidth(uiLayout *layout)
uiBut * uiDefButI(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5072
int UI_preview_tile_size_y(void)
Definition: interface.cc:4979
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
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.cc:5848
uiBut * uiDefIconButBitI(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5422
@ UI_BTYPE_TOGGLE
Definition: UI_interface.h:340
@ UI_BTYPE_LISTROW
Definition: UI_interface.h:367
@ UI_BTYPE_SEPR
Definition: UI_interface.h:385
@ UI_BTYPE_NUM
Definition: UI_interface.h:337
@ UI_BTYPE_GRIP
Definition: UI_interface.h:390
@ UI_BTYPE_SCROLL
Definition: UI_interface.h:352
#define UI_MAX_NAME_STR
Definition: UI_interface.h:92
int UI_preview_tile_size_y_no_label(void)
Definition: interface.cc:4990
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.cc:5858
uiTemplateListFlags
@ UI_TEMPLATE_LIST_SORT_LOCK
@ UI_TEMPLATE_LIST_SORT_REVERSE
@ UI_TEMPLATE_LIST_NO_NAMES
@ UI_TEMPLATE_LIST_NO_FILTER_OPTIONS
@ UI_TEMPLATE_LIST_NO_GRIP
@ UI_BLOCK_LIST_ITEM
Definition: UI_interface.h:155
int UI_icon_from_rnaptr(const struct bContext *C, struct PointerRNA *ptr, int rnaicon, bool big)
#define V2D_SCROLL_WIDTH
Definition: UI_view2d.h:55
int len
Definition: draw_manager.c:108
uint col
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
#define RNA_NO_INDEX
struct uiListType * UI_UL_cache_file_layers(void)
void ui_layout_list_set_labels_active(uiLayout *layout)
struct uiListType * UI_UL_asset_view(void)
static int cmpstringp(const void *p1, const void *p2)
static bool ui_template_list_data_retrieve(const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, TemplateListInputData *r_input_data, uiListType **r_list_type)
void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, enum uiTemplateListFlags flags)
PointerRNA * UI_list_custom_drag_operator_set(uiList *ui_list, const char *opname, bool create_properties)
static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
uiList * uiTemplateList_ex(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, 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)
static void ui_template_list_free_items(TemplateListItems *items)
static void uilist_free_dyn_data(uiList *ui_list)
static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout)
static void ui_template_list_layout_draw(bContext *C, uiList *ui_list, uiLayout *layout, TemplateListInputData *input_data, TemplateListItems *items, const TemplateListLayoutDrawData *layout_data, const enum uiTemplateListFlags flags)
static uiList * ui_list_ensure(bContext *C, uiListType *ui_list_type, const char *list_id, int layout_type, bool sort_reverse, bool sort_lock)
PointerRNA * UI_list_custom_activate_operator_set(uiList *ui_list, const char *opname, bool create_properties)
static void ui_template_list_collect_items(PointerRNA *list_ptr, PropertyRNA *list_prop, uiListDyn *dyn_data, int filter_exclude, bool order_reverse, int activei, TemplateListItems *r_items)
static void * uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname)
static char * uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
static void uilist_filter_items_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct PointerRNA *dataptr, const char *propname)
void ED_uilisttypes_ui()
static void uilist_prepare(uiList *ui_list, const TemplateListItems *items, const TemplateListLayoutDrawData *layout_data, TemplateListVisualInfo *r_visual_info)
static void ui_template_list_collect_display_items(bContext *C, uiList *ui_list, TemplateListInputData *input_data, const uiListFilterItemsFunc filter_items_fn, TemplateListItems *r_items)
static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout, struct PointerRNA *UNUSED(dataptr), struct PointerRNA *itemptr, int icon, struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname), int UNUSED(index), int UNUSED(flt_flag))
static char ** names
Definition: makesdna.c:65
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
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
T floor(const T &a)
const char * RNA_struct_identifier(const StructRNA *type)
Definition: rna_access.c:586
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:2449
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
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
char * RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:907
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
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:3178
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2429
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1405
int RNA_struct_ui_icon(const StructRNA *type)
Definition: rna_access.c:601
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
Definition: rna_access.c:624
int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3762
ListBase ui_lists
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
char name[MAX_IDPROP_NAME]
struct bContextStore * context
struct wmOperatorType * custom_activate_optype
struct PointerRNA * custom_drag_opptr
uiListFreeRuntimeDataFunc free_runtime_data_fn
int * items_filter_neworder
void * customdata
struct wmOperatorType * custom_drag_optype
int * items_filter_flags
struct PointerRNA * custom_activate_opptr
uiListFilterItemsFunc filter_items
Definition: BKE_screen.h:325
uiListDrawFilterFunc draw_filter
Definition: BKE_screen.h:324
uiListDrawItemFunc draw_item
Definition: BKE_screen.h:323
char list_id[64]
int list_last_len
int filter_sort_flag
uiListDyn * dyn_data
int list_last_activei
struct uiListType * type
char filter_byname[64]
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *opstring)
Definition: wm_operators.c:680
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:783
bool WM_uilisttype_add(uiListType *ult)
void WM_uilisttype_to_full_list_id(const uiListType *ult, const char *list_id, char r_full_list_id[])
uiListType * WM_uilisttype_find(const char *idname, bool quiet)