Blender  V2.93
interface_templates.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include <ctype.h>
22 #include <stddef.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include "DNA_brush_types.h"
29 #include "DNA_cachefile_types.h"
30 #include "DNA_constraint_types.h"
31 #include "DNA_curveprofile_types.h"
33 #include "DNA_node_types.h"
34 #include "DNA_object_force_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_shader_fx_types.h"
38 #include "DNA_texture_types.h"
39 
40 #include "BLI_alloca.h"
41 #include "BLI_fnmatch.h"
42 #include "BLI_listbase.h"
43 #include "BLI_math.h"
44 #include "BLI_path_util.h"
45 #include "BLI_rect.h"
46 #include "BLI_string.h"
47 #include "BLI_string_search.h"
48 #include "BLI_timecode.h"
49 #include "BLI_utildefines.h"
50 
51 #include "BLF_api.h"
52 #include "BLT_translation.h"
53 
54 #include "BKE_action.h"
55 #include "BKE_colorband.h"
56 #include "BKE_colortools.h"
57 #include "BKE_constraint.h"
58 #include "BKE_context.h"
59 #include "BKE_curveprofile.h"
60 #include "BKE_global.h"
61 #include "BKE_gpencil_modifier.h"
62 #include "BKE_idprop.h"
63 #include "BKE_idtype.h"
64 #include "BKE_layer.h"
65 #include "BKE_lib_id.h"
66 #include "BKE_lib_override.h"
67 #include "BKE_linestyle.h"
68 #include "BKE_main.h"
69 #include "BKE_modifier.h"
70 #include "BKE_object.h"
71 #include "BKE_packedFile.h"
72 #include "BKE_particle.h"
73 #include "BKE_report.h"
74 #include "BKE_scene.h"
75 #include "BKE_screen.h"
76 #include "BKE_shader_fx.h"
77 
78 #include "DEG_depsgraph.h"
79 #include "DEG_depsgraph_build.h"
80 
81 #include "ED_fileselect.h"
82 #include "ED_object.h"
83 #include "ED_render.h"
84 #include "ED_screen.h"
85 #include "ED_undo.h"
86 
87 #include "RNA_access.h"
88 
89 #include "WM_api.h"
90 #include "WM_types.h"
91 
92 #include "BLO_readfile.h"
93 
94 #include "UI_interface.h"
95 #include "UI_interface_icons.h"
96 #include "UI_view2d.h"
97 #include "interface_intern.h"
98 
99 #include "PIL_time.h"
100 
101 /* we may want to make this optional, disable for now. */
102 // #define USE_OP_RESET_BUT
103 
104 /* defines for templateID/TemplateSearch */
105 #define TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH (UI_UNIT_X * 6)
106 #define TEMPLATE_SEARCH_TEXTBUT_HEIGHT UI_UNIT_Y
107 
109 {
110 }
111 
112 /* -------------------------------------------------------------------- */
117 {
118  uiBlock *block = uiLayoutAbsoluteBlock(layout);
119  ED_area_header_switchbutton(C, block, 0);
120 }
121 
124 /* -------------------------------------------------------------------- */
129 {
130  char str[UI_MAX_DRAW_STR];
131  int buf_len = 0;
132 
134 
135  const char *name = RNA_property_string_get_alloc(ptr, name_prop, str, sizeof(str), &buf_len);
136 
137  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
138  const int margin = UI_UNIT_X * 0.75f;
139  const int estimated_width = UI_fontstyle_string_width(fstyle, name) + margin;
140 
141  if (name != str) {
142  MEM_freeN((void *)name);
143  }
144 
145  /* Clamp to some min/max width. */
146  return CLAMPIS(
148 }
149 
151 {
153 }
154 
159  uiLayout *layout,
160  uiBlock *block,
161  PointerRNA *ptr,
162  PropertyRNA *prop,
163  uiBlockCreateFunc block_func,
164  void *block_argN,
165  const char *const tip,
166  const bool use_previews,
167  const bool editable,
168  const bool live_icon)
169 {
170  const PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
171  ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
172  const ID *idfrom = ptr->owner_id;
173  const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
174  uiBut *but;
175 
176  if (use_previews) {
177  ARegion *region = CTX_wm_region(C);
178  /* Ugly tool header exception. */
179  const bool use_big_size = (region->regiontype != RGN_TYPE_TOOL_HEADER);
180  /* Ugly exception for screens here,
181  * drawing their preview in icon size looks ugly/useless */
182  const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
183  const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
184  const short height = UI_UNIT_Y * (use_big_size ? 6 : 1);
185  uiLayout *col = NULL;
186 
187  if (use_big_size) {
188  /* Assume column layout here. To be more correct, we should check if the layout passed to
189  * template_id is a column one, but this should work well in practice. */
190  col = uiLayoutColumn(layout, true);
191  }
192 
193  but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
194  if (use_preview_icon) {
195  const int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
197  }
198  else {
201  }
202 
203  if ((idfrom && idfrom->lib) || !editable) {
205  }
206  if (use_big_size) {
207  uiLayoutRow(col ? col : layout, true);
208  }
209  }
210  else {
211  but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
212 
213  if (live_icon) {
214  const int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type);
216  }
217  else {
219  }
220  if (id) {
221  /* default dragging of icon for id browse buttons */
222  UI_but_drag_set_id(but, id);
223  }
225 
226  if ((idfrom && idfrom->lib) || !editable) {
228  }
229  }
230 }
231 
233  ARegion *region,
234  uiButSearchUpdateFn search_update_fn,
235  void *search_arg,
236  uiButHandleFunc search_exec_fn,
237  void *active_item,
238  uiButSearchTooltipFn item_tooltip_fn,
239  const int preview_rows,
240  const int preview_cols,
241  float scale)
242 {
243  static char search[256];
244  wmWindow *win = CTX_wm_window(C);
245  uiBut *but;
246 
247  /* clear initial search string, then all items show */
248  search[0] = 0;
249 
250  uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
253 
254  /* preview thumbnails */
255  if (preview_rows > 0 && preview_cols > 0) {
256  const int w = 4 * U.widget_unit * preview_cols * scale;
257  const int h = 5 * U.widget_unit * preview_rows * scale;
258 
259  /* fake button, it holds space for search items */
260  uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
261 
262  but = uiDefSearchBut(block,
263  search,
264  0,
265  ICON_VIEWZOOM,
266  sizeof(search),
267  10,
268  0,
269  w,
270  UI_UNIT_Y,
271  preview_rows,
272  preview_cols,
273  "");
274  }
275  /* list view */
276  else {
277  const int searchbox_width = UI_searchbox_size_x();
278  const int searchbox_height = UI_searchbox_size_y();
279 
280  /* fake button, it holds space for search items */
281  uiDefBut(block,
283  0,
284  "",
285  10,
286  15,
287  searchbox_width,
288  searchbox_height,
289  NULL,
290  0,
291  0,
292  0,
293  0,
294  NULL);
295  but = uiDefSearchBut(block,
296  search,
297  0,
298  ICON_VIEWZOOM,
299  sizeof(search),
300  10,
301  0,
302  searchbox_width,
303  UI_UNIT_Y - 1,
304  0,
305  0,
306  "");
307  }
310  search_update_fn,
311  search_arg,
312  false,
313  NULL,
314  search_exec_fn,
315  active_item);
316  UI_but_func_search_set_tooltip(but, item_tooltip_fn);
317 
318  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
320 
321  /* give search-field focus */
322  UI_but_focus_on_enter_event(win, but);
323  /* this type of search menu requires undo */
324  but->flag |= UI_BUT_UNDO;
325 
326  return block;
327 }
328 
331 /* -------------------------------------------------------------------- */
335 typedef struct TemplateID {
338 
340  short idcode;
341  short filter;
343  bool preview;
344  float scale;
346 
347 /* Search browse menu, assign */
348 static void template_ID_set_property_exec_fn(bContext *C, void *arg_template, void *item)
349 {
350  TemplateID *template_ui = (TemplateID *)arg_template;
351 
352  /* ID */
353  if (item) {
354  PointerRNA idptr;
355 
356  RNA_id_pointer_create(item, &idptr);
357  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
358  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
359  }
360 }
361 
362 static bool id_search_allows_id(TemplateID *template_ui, const int flag, ID *id, const char *query)
363 {
364  ID *id_from = template_ui->ptr.owner_id;
365 
366  /* Do self check. */
367  if ((flag & PROP_ID_SELF_CHECK) && id == id_from) {
368  return false;
369  }
370 
371  /* Use filter. */
372  if (RNA_property_type(template_ui->prop) == PROP_POINTER) {
373  PointerRNA ptr;
375  if (RNA_property_pointer_poll(&template_ui->ptr, template_ui->prop, &ptr) == 0) {
376  return false;
377  }
378  }
379 
380  /* Hide dot prefixed data-blocks, but only if filter does not force them visible. */
381  if (U.uiflag & USER_HIDE_DOT) {
382  if ((id->name[2] == '.') && (query[0] != '.')) {
383  return false;
384  }
385  }
386 
387  return true;
388 }
389 
390 static bool id_search_add(const bContext *C, TemplateID *template_ui, uiSearchItems *items, ID *id)
391 {
392  /* +1 is needed because BKE_id_ui_prefix used 3 letter prefix
393  * followed by ID_NAME-2 characters from id->name
394  */
395  char name_ui[MAX_ID_FULL_NAME_UI];
396  int iconid = ui_id_icon_get(C, id, template_ui->preview);
397  const bool use_lib_prefix = template_ui->preview || iconid;
398  const bool has_sep_char = (id->lib != NULL);
399 
400  /* When using previews, the library hint (linked, overridden, missing) is added with a
401  * character prefix, otherwise we can use a icon. */
402  int name_prefix_offset;
403  BKE_id_full_name_ui_prefix_get(name_ui, id, use_lib_prefix, UI_SEP_CHAR, &name_prefix_offset);
404  if (!use_lib_prefix) {
405  iconid = UI_icon_from_library(id);
406  }
407 
408  if (!UI_search_item_add(items,
409  name_ui,
410  id,
411  iconid,
412  has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0,
413  name_prefix_offset)) {
414  return false;
415  }
416 
417  return true;
418 }
419 
420 /* ID Search browse menu, do the search */
421 static void id_search_cb(const bContext *C,
422  void *arg_template,
423  const char *str,
424  uiSearchItems *items,
425  const bool UNUSED(is_first))
426 {
427  TemplateID *template_ui = (TemplateID *)arg_template;
428  ListBase *lb = template_ui->idlb;
429  const int flag = RNA_property_flag(template_ui->prop);
430 
432 
433  /* ID listbase */
434  LISTBASE_FOREACH (ID *, id, lb) {
435  if (id_search_allows_id(template_ui, flag, id, str)) {
436  BLI_string_search_add(search, id->name + 2, id);
437  }
438  }
439 
440  ID **filtered_ids;
441  const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids);
442 
443  for (int i = 0; i < filtered_amount; i++) {
444  if (!id_search_add(C, template_ui, items, filtered_ids[i])) {
445  break;
446  }
447  }
448 
449  MEM_freeN(filtered_ids);
450  BLI_string_search_free(search);
451 }
452 
456 static void id_search_cb_tagged(const bContext *C,
457  void *arg_template,
458  const char *str,
459  uiSearchItems *items)
460 {
461  TemplateID *template_ui = (TemplateID *)arg_template;
462  ListBase *lb = template_ui->idlb;
463  const int flag = RNA_property_flag(template_ui->prop);
464 
466 
467  /* ID listbase */
468  LISTBASE_FOREACH (ID *, id, lb) {
469  if (id->tag & LIB_TAG_DOIT) {
470  if (id_search_allows_id(template_ui, flag, id, str)) {
471  BLI_string_search_add(search, id->name + 2, id);
472  }
473  id->tag &= ~LIB_TAG_DOIT;
474  }
475  }
476 
477  ID **filtered_ids;
478  const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids);
479 
480  for (int i = 0; i < filtered_amount; i++) {
481  if (!id_search_add(C, template_ui, items, filtered_ids[i])) {
482  break;
483  }
484  }
485 
486  MEM_freeN(filtered_ids);
487  BLI_string_search_free(search);
488 }
489 
494  void *arg_template,
495  const char *str,
496  uiSearchItems *items,
497  const bool UNUSED(is_first))
498 {
499  TemplateID *template_ui = (TemplateID *)arg_template;
500  ListBase *lb = template_ui->idlb;
501  Scene *scene = NULL;
502  ID *id_from = template_ui->ptr.owner_id;
503 
504  if (id_from && GS(id_from->name) == ID_SCE) {
505  scene = (Scene *)id_from;
506  }
507  else {
509  }
510 
512 
513  FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
514  ob_iter->id.tag |= LIB_TAG_DOIT;
515  }
517  id_search_cb_tagged(C, arg_template, str, items);
518 }
519 
521  bContext *C, ARegion *region, const rcti *item_rect, void *arg, void *active)
522 {
523  TemplateID *template_ui = arg;
524  ID *active_id = active;
525  StructRNA *type = RNA_property_pointer_type(&template_ui->ptr, template_ui->prop);
526 
527  uiSearchItemTooltipData tooltip_data = {0};
528 
529  tooltip_data.name = active_id->name + 2;
530  BLI_snprintf(tooltip_data.description,
531  sizeof(tooltip_data.description),
532  TIP_("Choose %s data-block to be assigned to this user"),
534  if (ID_IS_LINKED(active_id)) {
535  BLI_snprintf(tooltip_data.hint,
536  sizeof(tooltip_data.hint),
537  TIP_("Source library: %s\n%s"),
538  active_id->lib->id.name + 2,
539  active_id->lib->filepath);
540  }
541 
542  return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data);
543 }
544 
545 /* ID Search browse menu, open */
546 static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem)
547 {
548  static TemplateID template_ui;
549  PointerRNA active_item_ptr;
550  void (*id_search_update_fn)(
551  const bContext *, void *, const char *, uiSearchItems *, const bool) = id_search_cb;
552 
553  /* arg_litem is malloced, can be freed by parent button */
554  template_ui = *((TemplateID *)arg_litem);
555  active_item_ptr = RNA_property_pointer_get(&template_ui.ptr, template_ui.prop);
556 
557  if (template_ui.filter) {
558  /* Currently only used for objects. */
559  if (template_ui.idcode == ID_OB) {
560  if (template_ui.filter == UI_TEMPLATE_ID_FILTER_AVAILABLE) {
561  id_search_update_fn = id_search_cb_objects_from_scene;
562  }
563  }
564  }
565 
567  region,
568  id_search_update_fn,
569  &template_ui,
571  active_item_ptr.data,
573  template_ui.prv_rows,
574  template_ui.prv_cols,
575  template_ui.scale);
576 }
577 
580 /* -------------------------------------------------------------------- */
584 /* This is for browsing and editing the ID-blocks used */
585 
586 /* for new/open operators */
588  PointerRNA *r_ptr,
589  PropertyRNA **r_prop)
590 {
592 
593  memset(r_ptr, 0, sizeof(*r_ptr));
594  *r_prop = NULL;
595 
596  if (but && but->func_argN) {
597  TemplateID *template_ui = but->func_argN;
598  *r_ptr = template_ui->ptr;
599  *r_prop = template_ui->prop;
600  }
601 }
602 
603 static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
604 {
605  TemplateID *template_ui = (TemplateID *)arg_litem;
606  PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
607  ID *id = idptr.data;
608  const int event = POINTER_AS_INT(arg_event);
609  const char *undo_push_label = NULL;
610 
611  switch (event) {
612  case UI_ID_BROWSE:
613  case UI_ID_PIN:
614  RNA_warning("warning, id event %d shouldn't come here", event);
615  break;
616  case UI_ID_OPEN:
617  case UI_ID_ADD_NEW:
618  /* these call UI_context_active_but_prop_get_templateID */
619  break;
620  case UI_ID_DELETE:
621  memset(&idptr, 0, sizeof(idptr));
622  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
623  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
624 
625  if (id && CTX_wm_window(C)->eventstate->shift) {
626  /* only way to force-remove data (on save) */
627  id_us_clear_real(id);
628  id_fake_user_clear(id);
629  id->us = 0;
630  undo_push_label = "Delete Data-Block";
631  }
632 
633  break;
634  case UI_ID_FAKE_USER:
635  if (id) {
636  if (id->flag & LIB_FAKEUSER) {
637  id_us_plus(id);
638  }
639  else {
640  id_us_min(id);
641  }
642  undo_push_label = "Fake User";
643  }
644  else {
645  return;
646  }
647  break;
648  case UI_ID_LOCAL:
649  if (id) {
650  Main *bmain = CTX_data_main(C);
651  if (CTX_wm_window(C)->eventstate->shift) {
652  if (ID_IS_OVERRIDABLE_LIBRARY(id)) {
653  /* Only remap that specific ID usage to overriding local data-block. */
654  ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false);
655  if (override_id != NULL) {
657 
658  if (GS(override_id->name) == ID_OB) {
661  (Object *)override_id)) {
663  bmain, scene, (Object *)id, (Object *)override_id);
664  }
665  }
666 
667  /* Assign new pointer, takes care of updates/notifiers */
668  RNA_id_pointer_create(override_id, &idptr);
669  }
670  undo_push_label = "Make Library Override";
671  }
672  }
673  else {
674  if (BKE_lib_id_make_local(bmain, id, false, 0)) {
676 
677  /* reassign to get get proper updates/notifiers */
678  idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
679  undo_push_label = "Make Local";
680  }
681  }
682  if (undo_push_label != NULL) {
683  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
684  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
685  }
686  }
687  break;
688  case UI_ID_OVERRIDE:
689  if (id && ID_IS_OVERRIDE_LIBRARY(id)) {
691  /* reassign to get get proper updates/notifiers */
692  idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
693  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
694  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
695  undo_push_label = "Override Data-Block";
696  }
697  break;
698  case UI_ID_ALONE:
699  if (id) {
700  const bool do_scene_obj = ((GS(id->name) == ID_OB) &&
701  (template_ui->ptr.type == &RNA_LayerObjects));
702 
703  /* make copy */
704  if (do_scene_obj) {
705  Main *bmain = CTX_data_main(C);
707  ED_object_single_user(bmain, scene, (struct Object *)id);
710  }
711  else {
712  Main *bmain = CTX_data_main(C);
713  id_single_user(C, id, &template_ui->ptr, template_ui->prop);
715  }
716  undo_push_label = "Make Single User";
717  }
718  break;
719 #if 0
720  case UI_ID_AUTO_NAME:
721  break;
722 #endif
723  }
724 
725  if (undo_push_label != NULL) {
726  ED_undo_push(C, undo_push_label);
727  }
728 }
729 
730 static const char *template_id_browse_tip(const StructRNA *type)
731 {
732  if (type) {
733  switch ((ID_Type)RNA_type_to_ID_code(type)) {
734  case ID_SCE:
735  return N_("Browse Scene to be linked");
736  case ID_OB:
737  return N_("Browse Object to be linked");
738  case ID_ME:
739  return N_("Browse Mesh Data to be linked");
740  case ID_CU:
741  return N_("Browse Curve Data to be linked");
742  case ID_MB:
743  return N_("Browse Metaball Data to be linked");
744  case ID_MA:
745  return N_("Browse Material to be linked");
746  case ID_TE:
747  return N_("Browse Texture to be linked");
748  case ID_IM:
749  return N_("Browse Image to be linked");
750  case ID_LS:
751  return N_("Browse Line Style Data to be linked");
752  case ID_LT:
753  return N_("Browse Lattice Data to be linked");
754  case ID_LA:
755  return N_("Browse Light Data to be linked");
756  case ID_CA:
757  return N_("Browse Camera Data to be linked");
758  case ID_WO:
759  return N_("Browse World Settings to be linked");
760  case ID_SCR:
761  return N_("Choose Screen layout");
762  case ID_TXT:
763  return N_("Browse Text to be linked");
764  case ID_SPK:
765  return N_("Browse Speaker Data to be linked");
766  case ID_SO:
767  return N_("Browse Sound to be linked");
768  case ID_AR:
769  return N_("Browse Armature data to be linked");
770  case ID_AC:
771  return N_("Browse Action to be linked");
772  case ID_NT:
773  return N_("Browse Node Tree to be linked");
774  case ID_BR:
775  return N_("Browse Brush to be linked");
776  case ID_PA:
777  return N_("Browse Particle Settings to be linked");
778  case ID_GD:
779  return N_("Browse Grease Pencil Data to be linked");
780  case ID_MC:
781  return N_("Browse Movie Clip to be linked");
782  case ID_MSK:
783  return N_("Browse Mask to be linked");
784  case ID_PAL:
785  return N_("Browse Palette Data to be linked");
786  case ID_PC:
787  return N_("Browse Paint Curve Data to be linked");
788  case ID_CF:
789  return N_("Browse Cache Files to be linked");
790  case ID_WS:
791  return N_("Browse Workspace to be linked");
792  case ID_LP:
793  return N_("Browse LightProbe to be linked");
794  case ID_HA:
795  return N_("Browse Hair Data to be linked");
796  case ID_PT:
797  return N_("Browse Point Cloud Data to be linked");
798  case ID_VO:
799  return N_("Browse Volume Data to be linked");
800  case ID_SIM:
801  return N_("Browse Simulation to be linked");
802 
803  /* Use generic text. */
804  case ID_LI:
805  case ID_IP:
806  case ID_KE:
807  case ID_VF:
808  case ID_GR:
809  case ID_WM:
810  break;
811  }
812  }
813  return N_("Browse ID data to be linked");
814 }
815 
820 #ifdef WITH_INTERNATIONAL
821 static const char *template_id_context(StructRNA *type)
822 {
823  if (type) {
825  }
827 }
828 #else
829 # define template_id_context(type) 0
830 #endif
831 
833  const ID *id,
834  const TemplateID *template_ui,
835  StructRNA *type,
836  const char *const newop,
837  const bool editable,
838  const bool id_open,
839  const bool use_tab_but,
840  int but_height)
841 {
842  ID *idfrom = template_ui->ptr.owner_id;
843  uiBut *but;
844  const int w = id ? UI_UNIT_X : id_open ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
845  const int but_type = use_tab_but ? UI_BTYPE_TAB : UI_BTYPE_BUT;
846 
847  /* i18n markup, does nothing! */
880  /* Note: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters,
881  * check the definition to see if a new call must be added when the limit
882  * is exceeded. */
883 
884  if (newop) {
885  but = uiDefIconTextButO(block,
886  but_type,
887  newop,
889  (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
890  (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
891  0,
892  0,
893  w,
894  but_height,
895  NULL);
898  }
899  else {
900  but = uiDefIconTextBut(block,
901  but_type,
902  0,
903  (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
904  (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
905  0,
906  0,
907  w,
908  but_height,
909  NULL,
910  0,
911  0,
912  0,
913  0,
914  NULL);
917  }
918 
919  if ((idfrom && idfrom->lib) || !editable) {
921  }
922 
923 #ifndef WITH_INTERNATIONAL
924  UNUSED_VARS(type);
925 #endif
926 
927  return but;
928 }
929 
930 static void template_ID(const bContext *C,
931  uiLayout *layout,
932  TemplateID *template_ui,
933  StructRNA *type,
934  int flag,
935  const char *newop,
936  const char *openop,
937  const char *unlinkop,
938  const char *text,
939  const bool live_icon,
940  const bool hide_buttons)
941 {
942  uiBut *but;
943  const bool editable = RNA_property_editable(&template_ui->ptr, template_ui->prop);
944  const bool use_previews = template_ui->preview = (flag & UI_ID_PREVIEWS) != 0;
945 
946  PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
947  ID *id = idptr.data;
948  ID *idfrom = template_ui->ptr.owner_id;
949  // lb = template_ui->idlb;
950 
951  /* Allow operators to take the ID from context. */
952  uiLayoutSetContextPointer(layout, "id", &idptr);
953 
954  uiBlock *block = uiLayoutGetBlock(layout);
955  UI_block_align_begin(block);
956 
957  if (idptr.type) {
958  type = idptr.type;
959  }
960 
961  if (text) {
962  /* Add label respecting the separated layout property split state. */
963  uiItemL_respect_property_split(layout, text, ICON_NONE);
964  }
965 
966  if (flag & UI_ID_BROWSE) {
968  layout,
969  block,
970  &template_ui->ptr,
971  template_ui->prop,
973  MEM_dupallocN(template_ui),
975  use_previews,
976  editable,
977  live_icon);
978  }
979 
980  /* text button with name */
981  if (id) {
982  char name[UI_MAX_NAME_STR];
983  const bool user_alert = (id->us <= 0);
984 
985  const int width = template_search_textbut_width(&idptr,
986  RNA_struct_find_property(&idptr, "name"));
988 
989  // text_idbutton(id, name);
990  name[0] = '\0';
991  but = uiDefButR(block,
993  0,
994  name,
995  0,
996  0,
997  width,
998  height,
999  &idptr,
1000  "name",
1001  -1,
1002  0,
1003  0,
1004  -1,
1005  -1,
1009  if (user_alert) {
1011  }
1012 
1013  if (id->lib) {
1014  if (id->tag & LIB_TAG_INDIRECT) {
1015  but = uiDefIconBut(block,
1016  UI_BTYPE_BUT,
1017  0,
1018  ICON_LIBRARY_DATA_INDIRECT,
1019  0,
1020  0,
1021  UI_UNIT_X,
1022  UI_UNIT_Y,
1023  NULL,
1024  0,
1025  0,
1026  0,
1027  0,
1028  TIP_("Indirect library data-block, cannot change"));
1030  }
1031  else {
1032  const bool disabled = (!BKE_lib_id_make_local(CTX_data_main(C), id, true /* test */, 0) ||
1033  (idfrom && idfrom->lib));
1034  but = uiDefIconBut(block,
1035  UI_BTYPE_BUT,
1036  0,
1037  ICON_LIBRARY_DATA_DIRECT,
1038  0,
1039  0,
1040  UI_UNIT_X,
1041  UI_UNIT_Y,
1042  NULL,
1043  0,
1044  0,
1045  0,
1046  0,
1047  TIP_("Direct linked library data-block, click to make local, "
1048  "Shift + Click to create a library override"));
1049  if (disabled) {
1051  }
1052  else {
1055  }
1056  }
1057  }
1058  else if (ID_IS_OVERRIDE_LIBRARY(id)) {
1059  but = uiDefIconBut(block,
1060  UI_BTYPE_BUT,
1061  0,
1062  ICON_LIBRARY_DATA_OVERRIDE,
1063  0,
1064  0,
1065  UI_UNIT_X,
1066  UI_UNIT_Y,
1067  NULL,
1068  0,
1069  0,
1070  0,
1071  0,
1072  TIP_("Library override of linked data-block, click to make fully local"));
1075  }
1076 
1077  if ((ID_REAL_USERS(id) > 1) && (hide_buttons == false)) {
1078  char numstr[32];
1079  short numstr_len;
1080 
1081  numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id));
1082 
1083  but = uiDefBut(
1084  block,
1085  UI_BTYPE_BUT,
1086  0,
1087  numstr,
1088  0,
1089  0,
1090  numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X,
1091  UI_UNIT_Y,
1092  NULL,
1093  0,
1094  0,
1095  0,
1096  0,
1097  TIP_("Display number of users of this data (click to make a single-user copy)"));
1098  but->flag |= UI_BUT_UNDO;
1099 
1102  if ((!BKE_id_copy_is_allowed(id)) || (idfrom && idfrom->lib) || (!editable) ||
1103  /* object in editmode - don't change data */
1104  (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) {
1106  }
1107  }
1108 
1109  if (user_alert) {
1111  }
1112 
1113  if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_OB, ID_WS)) &&
1114  (hide_buttons == false)) {
1115  uiDefIconButR(block,
1117  0,
1118  ICON_FAKE_USER_OFF,
1119  0,
1120  0,
1121  UI_UNIT_X,
1122  UI_UNIT_Y,
1123  &idptr,
1124  "use_fake_user",
1125  -1,
1126  0,
1127  0,
1128  -1,
1129  -1,
1130  NULL);
1131  }
1132  }
1133 
1134  if ((flag & UI_ID_ADD_NEW) && (hide_buttons == false)) {
1136  block, id, template_ui, type, newop, editable, flag & UI_ID_OPEN, false, UI_UNIT_X);
1137  }
1138 
1139  /* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
1140  * Only for images, sound and fonts */
1141  if (id && BKE_packedfile_id_check(id)) {
1142  but = uiDefIconButO(block,
1143  UI_BTYPE_BUT,
1144  "FILE_OT_unpack_item",
1146  ICON_PACKAGE,
1147  0,
1148  0,
1149  UI_UNIT_X,
1150  UI_UNIT_Y,
1151  TIP_("Packed File, click to unpack"));
1153 
1154  RNA_string_set(but->opptr, "id_name", id->name + 2);
1155  RNA_int_set(but->opptr, "id_type", GS(id->name));
1156  }
1157  else if (flag & UI_ID_OPEN) {
1158  const int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
1159 
1160  if (openop) {
1161  but = uiDefIconTextButO(block,
1162  UI_BTYPE_BUT,
1163  openop,
1165  ICON_FILEBROWSER,
1166  (id) ? "" : IFACE_("Open"),
1167  0,
1168  0,
1169  w,
1170  UI_UNIT_Y,
1171  NULL);
1174  }
1175  else {
1176  but = uiDefIconTextBut(block,
1177  UI_BTYPE_BUT,
1178  0,
1179  ICON_FILEBROWSER,
1180  (id) ? "" : IFACE_("Open"),
1181  0,
1182  0,
1183  w,
1184  UI_UNIT_Y,
1185  NULL,
1186  0,
1187  0,
1188  0,
1189  0,
1190  NULL);
1193  }
1194 
1195  if ((idfrom && idfrom->lib) || !editable) {
1197  }
1198  }
1199 
1200  /* delete button */
1201  /* don't use RNA_property_is_unlink here */
1202  if (id && (flag & UI_ID_DELETE) && (hide_buttons == false)) {
1203  /* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */
1204  but = NULL;
1205 
1206  if (unlinkop) {
1207  but = uiDefIconButO(block,
1208  UI_BTYPE_BUT,
1209  unlinkop,
1211  ICON_X,
1212  0,
1213  0,
1214  UI_UNIT_X,
1215  UI_UNIT_Y,
1216  NULL);
1217  /* so we can access the template from operators, font unlinking needs this */
1218  UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL);
1219  }
1220  else {
1221  if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) {
1222  but = uiDefIconBut(
1223  block,
1224  UI_BTYPE_BUT,
1225  0,
1226  ICON_X,
1227  0,
1228  0,
1229  UI_UNIT_X,
1230  UI_UNIT_Y,
1231  NULL,
1232  0,
1233  0,
1234  0,
1235  0,
1236  TIP_("Unlink data-block "
1237  "(Shift + Click to set users to zero, data will then not be saved)"));
1240 
1241  if (RNA_property_flag(template_ui->prop) & PROP_NEVER_NULL) {
1243  }
1244  }
1245  }
1246 
1247  if (but) {
1248  if ((idfrom && idfrom->lib) || !editable) {
1250  }
1251  }
1252  }
1253 
1254  if (template_ui->idcode == ID_TE) {
1255  uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop);
1256  }
1257  UI_block_align_end(block);
1258 }
1259 
1261 {
1263 
1264  if (but && but->type == UI_BTYPE_TAB) {
1265  return but->custom_data;
1266  }
1267  return NULL;
1268 }
1269 
1270 static void template_ID_tabs(const bContext *C,
1271  uiLayout *layout,
1272  TemplateID *template,
1273  StructRNA *type,
1274  int flag,
1275  const char *newop,
1276  const char *menu)
1277 {
1278  const ARegion *region = CTX_wm_region(C);
1279  const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, template->prop);
1280  MenuType *mt = menu ? WM_menutype_find(menu, false) : NULL;
1281 
1282  const int but_align = ui_but_align_opposite_to_area_align_get(region);
1283  const int but_height = UI_UNIT_Y * 1.1;
1284 
1285  uiBlock *block = uiLayoutGetBlock(layout);
1286  const uiStyle *style = UI_style_get_dpi();
1287 
1288  ListBase ordered;
1289  BKE_id_ordered_list(&ordered, template->idlb);
1290 
1291  LISTBASE_FOREACH (LinkData *, link, &ordered) {
1292  ID *id = link->data;
1293  const int name_width = UI_fontstyle_string_width(&style->widget, id->name + 2);
1294  const int but_width = name_width + UI_UNIT_X;
1295 
1296  uiButTab *tab = (uiButTab *)uiDefButR_prop(block,
1297  UI_BTYPE_TAB,
1298  0,
1299  id->name + 2,
1300  0,
1301  0,
1302  but_width,
1303  but_height,
1304  &template->ptr,
1305  template->prop,
1306  0,
1307  0.0f,
1308  sizeof(id->name) - 2,
1309  0.0f,
1310  0.0f,
1311  "");
1313  tab->but.custom_data = (void *)id;
1314  tab->but.dragpoin = id;
1315  tab->menu = mt;
1316 
1317  UI_but_drawflag_enable(&tab->but, but_align);
1318  }
1319 
1320  BLI_freelistN(&ordered);
1321 
1322  if (flag & UI_ID_ADD_NEW) {
1323  const bool editable = RNA_property_editable(&template->ptr, template->prop);
1324  uiBut *but;
1325 
1326  if (active_ptr.type) {
1327  type = active_ptr.type;
1328  }
1329 
1330  but = template_id_def_new_but(block,
1331  active_ptr.data,
1332  template,
1333  type,
1334  newop,
1335  editable,
1336  flag & UI_ID_OPEN,
1337  true,
1338  but_height);
1339  UI_but_drawflag_enable(but, but_align);
1340  }
1341 }
1342 
1343 static void ui_template_id(uiLayout *layout,
1344  const bContext *C,
1345  PointerRNA *ptr,
1346  const char *propname,
1347  const char *newop,
1348  const char *openop,
1349  const char *unlinkop,
1350  /* Only respected by tabs (use_tabs). */
1351  const char *menu,
1352  const char *text,
1353  int flag,
1354  int prv_rows,
1355  int prv_cols,
1356  int filter,
1357  bool use_tabs,
1358  float scale,
1359  const bool live_icon,
1360  const bool hide_buttons)
1361 {
1362  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
1363 
1364  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
1365  RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
1366  return;
1367  }
1368 
1369  TemplateID *template_ui = MEM_callocN(sizeof(TemplateID), "TemplateID");
1370  template_ui->ptr = *ptr;
1371  template_ui->prop = prop;
1372  template_ui->prv_rows = prv_rows;
1373  template_ui->prv_cols = prv_cols;
1374  template_ui->scale = scale;
1375 
1376  if ((flag & UI_ID_PIN) == 0) {
1377  template_ui->filter = filter;
1378  }
1379  else {
1380  template_ui->filter = 0;
1381  }
1382 
1383  if (newop) {
1384  flag |= UI_ID_ADD_NEW;
1385  }
1386  if (openop) {
1387  flag |= UI_ID_OPEN;
1388  }
1389 
1391  short idcode = RNA_type_to_ID_code(type);
1392  template_ui->idcode = idcode;
1393  template_ui->idlb = which_libbase(CTX_data_main(C), idcode);
1394 
1395  /* create UI elements for this template
1396  * - template_ID makes a copy of the template data and assigns it to the relevant buttons
1397  */
1398  if (template_ui->idlb) {
1399  if (use_tabs) {
1400  layout = uiLayoutRow(layout, true);
1401  template_ID_tabs(C, layout, template_ui, type, flag, newop, menu);
1402  }
1403  else {
1404  layout = uiLayoutRow(layout, true);
1405  template_ID(C,
1406  layout,
1407  template_ui,
1408  type,
1409  flag,
1410  newop,
1411  openop,
1412  unlinkop,
1413  text,
1414  live_icon,
1415  hide_buttons);
1416  }
1417  }
1418 
1419  MEM_freeN(template_ui);
1420 }
1421 
1422 void uiTemplateID(uiLayout *layout,
1423  const bContext *C,
1424  PointerRNA *ptr,
1425  const char *propname,
1426  const char *newop,
1427  const char *openop,
1428  const char *unlinkop,
1429  int filter,
1430  const bool live_icon,
1431  const char *text)
1432 {
1433  ui_template_id(layout,
1434  C,
1435  ptr,
1436  propname,
1437  newop,
1438  openop,
1439  unlinkop,
1440  NULL,
1441  text,
1443  0,
1444  0,
1445  filter,
1446  false,
1447  1.0f,
1448  live_icon,
1449  false);
1450 }
1451 
1453  bContext *C,
1454  PointerRNA *ptr,
1455  const char *propname,
1456  const char *newop,
1457  const char *openop,
1458  const char *unlinkop,
1459  int filter,
1460  const char *text)
1461 {
1462  ui_template_id(layout,
1463  C,
1464  ptr,
1465  propname,
1466  newop,
1467  openop,
1468  unlinkop,
1469  NULL,
1470  text,
1472  0,
1473  0,
1474  filter,
1475  false,
1476  1.0f,
1477  false,
1478  false);
1479 }
1480 
1482  bContext *C,
1483  PointerRNA *ptr,
1484  const char *propname,
1485  const char *newop,
1486  const char *openop,
1487  const char *unlinkop,
1488  int rows,
1489  int cols,
1490  int filter,
1491  const bool hide_buttons)
1492 {
1493  ui_template_id(layout,
1494  C,
1495  ptr,
1496  propname,
1497  newop,
1498  openop,
1499  unlinkop,
1500  NULL,
1501  NULL,
1503  rows,
1504  cols,
1505  filter,
1506  false,
1507  1.0f,
1508  false,
1509  hide_buttons);
1510 }
1511 
1513  bContext *C,
1514  PointerRNA *ptr,
1515  const char *propname,
1516  int rows,
1517  int cols,
1518  float scale,
1519  int filter)
1520 {
1521  ui_template_id(layout,
1522  C,
1523  ptr,
1524  propname,
1525  NULL,
1526  NULL,
1527  NULL,
1528  NULL,
1529  NULL,
1531  rows,
1532  cols,
1533  filter,
1534  false,
1535  scale < 0.5f ? 0.5f : scale,
1536  false,
1537  false);
1538 }
1539 
1544  bContext *C,
1545  PointerRNA *ptr,
1546  const char *propname,
1547  const char *newop,
1548  const char *menu,
1549  int filter)
1550 {
1551  ui_template_id(layout,
1552  C,
1553  ptr,
1554  propname,
1555  newop,
1556  NULL,
1557  NULL,
1558  menu,
1559  NULL,
1561  0,
1562  0,
1563  filter,
1564  true,
1565  1.0f,
1566  false,
1567  false);
1568 }
1569 
1572 /* -------------------------------------------------------------------- */
1585  PointerRNA *ptr,
1586  const char *propname,
1587  const char *proptypename,
1588  const char *text)
1589 {
1590  /* get properties... */
1591  PropertyRNA *propID = RNA_struct_find_property(ptr, propname);
1592  PropertyRNA *propType = RNA_struct_find_property(ptr, proptypename);
1593 
1594  if (!propID || RNA_property_type(propID) != PROP_POINTER) {
1595  RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
1596  return;
1597  }
1598  if (!propType || RNA_property_type(propType) != PROP_ENUM) {
1599  RNA_warning(
1600  "pointer-type property not found: %s.%s", RNA_struct_identifier(ptr->type), proptypename);
1601  return;
1602  }
1603 
1604  /* Start drawing UI Elements using standard defines */
1605 
1606  /* NOTE: split amount here needs to be synced with normal labels */
1607  uiLayout *split = uiLayoutSplit(layout, 0.33f, false);
1608 
1609  /* FIRST PART ................................................ */
1610  uiLayout *row = uiLayoutRow(split, false);
1611 
1612  /* Label - either use the provided text, or will become "ID-Block:" */
1613  if (text) {
1614  if (text[0]) {
1615  uiItemL(row, text, ICON_NONE);
1616  }
1617  }
1618  else {
1619  uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
1620  }
1621 
1622  /* SECOND PART ................................................ */
1623  row = uiLayoutRow(split, true);
1624 
1625  /* ID-Type Selector - just have a menu of icons */
1626 
1627  /* HACK: special group just for the enum,
1628  * otherwise we get ugly layout with text included too... */
1629  uiLayout *sub = uiLayoutRow(row, true);
1631 
1632  uiItemFullR(sub, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
1633 
1634  /* ID-Block Selector - just use pointer widget... */
1635 
1636  /* HACK: special group to counteract the effects of the previous enum,
1637  * which now pushes everything too far right. */
1638  sub = uiLayoutRow(row, true);
1640 
1641  uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
1642 }
1643 
1646 /* -------------------------------------------------------------------- */
1650 typedef struct TemplateSearch {
1652 
1656 
1657 static void template_search_exec_fn(bContext *C, void *arg_template, void *item)
1658 {
1659  TemplateSearch *template_search = arg_template;
1660  uiRNACollectionSearch *coll_search = &template_search->search_data;
1661  StructRNA *type = RNA_property_pointer_type(&coll_search->target_ptr, coll_search->target_prop);
1662  PointerRNA item_ptr;
1663 
1664  RNA_pointer_create(NULL, type, item, &item_ptr);
1665  RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr, NULL);
1666  RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
1667 }
1668 
1669 static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_template)
1670 {
1671  static TemplateSearch template_search;
1672 
1673  /* arg_template is malloced, can be freed by parent button */
1674  template_search = *((TemplateSearch *)arg_template);
1675  PointerRNA active_ptr = RNA_property_pointer_get(&template_search.search_data.target_ptr,
1676  template_search.search_data.target_prop);
1677 
1679  region,
1681  &template_search,
1683  active_ptr.data,
1684  NULL,
1685  template_search.preview_rows,
1686  template_search.preview_cols,
1687  1.0f);
1688 }
1689 
1691  uiLayout *layout,
1692  uiBlock *block,
1693  TemplateSearch *template_search,
1694  const bool editable,
1695  const bool live_icon)
1696 {
1697  const char *ui_description = RNA_property_ui_description(
1698  template_search->search_data.target_prop);
1699 
1701  layout,
1702  block,
1703  &template_search->search_data.target_ptr,
1704  template_search->search_data.target_prop,
1706  MEM_dupallocN(template_search),
1707  ui_description,
1708  template_search->use_previews,
1709  editable,
1710  live_icon);
1711 }
1712 
1714  PointerRNA *active_ptr,
1715  const StructRNA *type)
1716 {
1718  const int width = template_search_textbut_width(active_ptr, name_prop);
1719  const int height = template_search_textbut_height();
1720  uiDefAutoButR(block, active_ptr, name_prop, 0, "", ICON_NONE, 0, 0, width, height);
1721 }
1722 
1724  const char *const operator_name,
1725  const int opcontext,
1726  const int icon,
1727  const bool editable)
1728 {
1729  if (!operator_name) {
1730  return;
1731  }
1732 
1733  uiBut *but = uiDefIconButO(
1734  block, UI_BTYPE_BUT, operator_name, opcontext, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
1735 
1736  if (!editable) {
1738  }
1739 }
1740 
1742  uiLayout *layout,
1743  TemplateSearch *template_search,
1744  const char *newop,
1745  const char *unlinkop)
1746 {
1747  uiBlock *block = uiLayoutGetBlock(layout);
1748  uiRNACollectionSearch *search_data = &template_search->search_data;
1749  StructRNA *type = RNA_property_pointer_type(&search_data->target_ptr, search_data->target_prop);
1750  const bool editable = RNA_property_editable(&search_data->target_ptr, search_data->target_prop);
1751  PointerRNA active_ptr = RNA_property_pointer_get(&search_data->target_ptr,
1752  search_data->target_prop);
1753 
1754  if (active_ptr.type) {
1755  /* can only get correct type when there is an active item */
1756  type = active_ptr.type;
1757  }
1758 
1759  uiLayoutRow(layout, true);
1760  UI_block_align_begin(block);
1761 
1762  template_search_add_button_searchmenu(C, layout, block, template_search, editable, false);
1763  template_search_add_button_name(block, &active_ptr, type);
1765  block, newop, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE, editable);
1766  template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
1767 
1768  UI_block_align_end(block);
1769 }
1770 
1772  PropertyRNA *targetprop,
1773  PointerRNA *searchptr,
1774  const char *const searchpropname)
1775 {
1776  PropertyRNA *searchprop;
1777 
1778  if (searchptr && !searchptr->data) {
1779  searchptr = NULL;
1780  }
1781 
1782  if (!searchptr && !searchpropname) {
1783  /* both NULL means we don't use a custom rna collection to search in */
1784  }
1785  else if (!searchptr && searchpropname) {
1786  RNA_warning("searchpropname defined (%s) but searchptr is missing", searchpropname);
1787  }
1788  else if (searchptr && !searchpropname) {
1789  RNA_warning("searchptr defined (%s) but searchpropname is missing",
1790  RNA_struct_identifier(searchptr->type));
1791  }
1792  else if (!(searchprop = RNA_struct_find_property(searchptr, searchpropname))) {
1793  RNA_warning("search collection property not found: %s.%s",
1794  RNA_struct_identifier(searchptr->type),
1795  searchpropname);
1796  }
1797  else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
1798  RNA_warning("search collection property is not a collection type: %s.%s",
1799  RNA_struct_identifier(searchptr->type),
1800  searchpropname);
1801  }
1802  /* check if searchprop has same type as targetprop */
1803  else if (RNA_property_pointer_type(searchptr, searchprop) !=
1804  RNA_property_pointer_type(targetptr, targetprop)) {
1805  RNA_warning("search collection items from %s.%s are not of type %s",
1806  RNA_struct_identifier(searchptr->type),
1807  searchpropname,
1808  RNA_struct_identifier(RNA_property_pointer_type(targetptr, targetprop)));
1809  }
1810  else {
1811  return searchprop;
1812  }
1813 
1814  return NULL;
1815 }
1816 
1818  const char *const propname,
1819  PointerRNA *searchptr,
1820  const char *const searchpropname)
1821 {
1822  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
1823 
1824  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
1825  RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
1826  return NULL;
1827  }
1828  PropertyRNA *searchprop = template_search_get_searchprop(ptr, prop, searchptr, searchpropname);
1829 
1830  TemplateSearch *template_search = MEM_callocN(sizeof(*template_search), __func__);
1831  template_search->search_data.target_ptr = *ptr;
1832  template_search->search_data.target_prop = prop;
1833  template_search->search_data.search_ptr = *searchptr;
1834  template_search->search_data.search_prop = searchprop;
1835 
1836  return template_search;
1837 }
1838 
1844  bContext *C,
1845  PointerRNA *ptr,
1846  const char *propname,
1847  PointerRNA *searchptr,
1848  const char *searchpropname,
1849  const char *newop,
1850  const char *unlinkop)
1851 {
1852  TemplateSearch *template_search = template_search_setup(
1853  ptr, propname, searchptr, searchpropname);
1854  if (template_search != NULL) {
1855  template_search_buttons(C, layout, template_search, newop, unlinkop);
1856  MEM_freeN(template_search);
1857  }
1858 }
1859 
1861  bContext *C,
1862  PointerRNA *ptr,
1863  const char *propname,
1864  PointerRNA *searchptr,
1865  const char *searchpropname,
1866  const char *newop,
1867  const char *unlinkop,
1868  const int rows,
1869  const int cols)
1870 {
1871  TemplateSearch *template_search = template_search_setup(
1872  ptr, propname, searchptr, searchpropname);
1873 
1874  if (template_search != NULL) {
1875  template_search->use_previews = true;
1876  template_search->preview_rows = rows;
1877  template_search->preview_cols = cols;
1878 
1879  template_search_buttons(C, layout, template_search, newop, unlinkop);
1880 
1881  MEM_freeN(template_search);
1882  }
1883 }
1884 
1887 /* -------------------------------------------------------------------- */
1891 /* ---------- */
1892 
1901  PointerRNA *ptr,
1902  const char *propname,
1903  PointerRNA *UNUSED(root_ptr),
1904  const char *text)
1905 {
1906  /* check that properties are valid */
1907  PropertyRNA *propPath = RNA_struct_find_property(ptr, propname);
1908  if (!propPath || RNA_property_type(propPath) != PROP_STRING) {
1909  RNA_warning("path property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
1910  return;
1911  }
1912 
1913  /* Start drawing UI Elements using standard defines */
1914  uiLayout *row = uiLayoutRow(layout, true);
1915 
1916  /* Path (existing string) Widget */
1917  uiItemR(row, ptr, propname, 0, text, ICON_RNA);
1918 
1919  /* TODO: attach something to this to make allow
1920  * searching of nested properties to 'build' the path */
1921 }
1922 
1925 /* -------------------------------------------------------------------- */
1931 static void modifier_panel_id(void *md_link, char *r_name)
1932 {
1933  ModifierData *md = (ModifierData *)md_link;
1934  BKE_modifier_type_panel_id(md->type, r_name);
1935 }
1936 
1938 {
1939  ARegion *region = CTX_wm_region(C);
1940 
1942  ListBase *modifiers = &ob->modifiers;
1943 
1944  const bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id);
1945 
1946  if (!panels_match) {
1947  UI_panels_free_instanced(C, region);
1948  ModifierData *md = modifiers->first;
1949  for (int i = 0; md; i++, md = md->next) {
1950  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
1951  if (mti->panelRegister == NULL) {
1952  continue;
1953  }
1954 
1955  char panel_idname[MAX_NAME];
1956  modifier_panel_id(md, panel_idname);
1957 
1958  /* Create custom data RNA pointer. */
1959  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
1960  RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
1961 
1962  UI_panel_add_instanced(C, region, &region->panels, panel_idname, md_ptr);
1963  }
1964  }
1965  else {
1966  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
1967  Panel *panel = region->panels.first;
1968  LISTBASE_FOREACH (ModifierData *, md, modifiers) {
1969  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
1970  if (mti->panelRegister == NULL) {
1971  continue;
1972  }
1973 
1974  /* Move to the next instanced panel corresponding to the next modifier. */
1975  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
1976  panel = panel->next;
1977  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
1978  }
1979 
1980  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
1981  RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
1982  UI_panel_custom_data_set(panel, md_ptr);
1983 
1984  panel = panel->next;
1985  }
1986  }
1987 }
1988 
1991 /* -------------------------------------------------------------------- */
1998 #define CONSTRAINT_TYPE_PANEL_PREFIX "OBJECT_PT_"
1999 #define CONSTRAINT_BONE_TYPE_PANEL_PREFIX "BONE_PT_"
2000 
2004 static bool constraint_panel_is_bone(Panel *panel)
2005 {
2006  return (panel->panelname[0] == 'B') && (panel->panelname[1] == 'O') &&
2007  (panel->panelname[2] == 'N') && (panel->panelname[3] == 'E');
2008 }
2009 
2013 static void constraint_reorder(bContext *C, Panel *panel, int new_index)
2014 {
2015  const bool constraint_from_bone = constraint_panel_is_bone(panel);
2016 
2017  PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
2018  bConstraint *con = (bConstraint *)con_ptr->data;
2019 
2020  PointerRNA props_ptr;
2021  wmOperatorType *ot = WM_operatortype_find("CONSTRAINT_OT_move_to_index", false);
2023  RNA_string_set(&props_ptr, "constraint", con->name);
2024  RNA_int_set(&props_ptr, "index", new_index);
2025  /* Set owner to #EDIT_CONSTRAINT_OWNER_OBJECT or #EDIT_CONSTRAINT_OWNER_BONE. */
2026  RNA_enum_set(&props_ptr, "owner", constraint_from_bone ? 1 : 0);
2028  WM_operator_properties_free(&props_ptr);
2029 }
2030 
2034 static short get_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel)
2035 {
2036  PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
2037  bConstraint *con = (bConstraint *)con_ptr->data;
2038 
2039  return con->ui_expand_flag;
2040 }
2041 
2045 static void set_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
2046 {
2047  PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
2048  bConstraint *con = (bConstraint *)con_ptr->data;
2049  con->ui_expand_flag = expand_flag;
2050 }
2051 
2058 static void object_constraint_panel_id(void *md_link, char *r_name)
2059 {
2060  bConstraint *con = (bConstraint *)md_link;
2062 
2063  /* Cannot get TypeInfo for invalid/legacy constraints. */
2064  if (cti == NULL) {
2065  return;
2066  }
2067 
2068  strcpy(r_name, CONSTRAINT_TYPE_PANEL_PREFIX);
2069  strcat(r_name, cti->structName);
2070 }
2071 
2072 static void bone_constraint_panel_id(void *md_link, char *r_name)
2073 {
2074  bConstraint *con = (bConstraint *)md_link;
2076 
2077  /* Cannot get TypeInfo for invalid/legacy constraints. */
2078  if (cti == NULL) {
2079  return;
2080  }
2081 
2082  strcpy(r_name, CONSTRAINT_BONE_TYPE_PANEL_PREFIX);
2083  strcat(r_name, cti->structName);
2084 }
2085 
2089 void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_constraints)
2090 {
2091  ARegion *region = CTX_wm_region(C);
2092 
2094  ListBase *constraints = {NULL};
2095  if (use_bone_constraints) {
2097  }
2098  else if (ob != NULL) {
2099  constraints = &ob->constraints;
2100  }
2101 
2102  /* Switch between the bone panel ID function and the object panel ID function. */
2103  uiListPanelIDFromDataFunc panel_id_func = use_bone_constraints ? bone_constraint_panel_id :
2105 
2106  const bool panels_match = UI_panel_list_matches_data(region, constraints, panel_id_func);
2107 
2108  if (!panels_match) {
2109  UI_panels_free_instanced(C, region);
2110  bConstraint *con = (constraints == NULL) ? NULL : constraints->first;
2111  for (int i = 0; con; i++, con = con->next) {
2112  /* Don't show invalid/legacy constraints. */
2113  if (con->type == CONSTRAINT_TYPE_NULL) {
2114  continue;
2115  }
2116  /* Don't show temporary constraints (AutoIK and target-less IK constraints). */
2117  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
2118  bKinematicConstraint *data = con->data;
2119  if (data->flag & CONSTRAINT_IK_TEMP) {
2120  continue;
2121  }
2122  }
2123 
2124  char panel_idname[MAX_NAME];
2125  panel_id_func(con, panel_idname);
2126 
2127  /* Create custom data RNA pointer. */
2128  PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2129  RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
2130 
2131  Panel *new_panel = UI_panel_add_instanced(C, region, &region->panels, panel_idname, con_ptr);
2132 
2133  if (new_panel) {
2134  /* Set the list panel functionality function pointers since we don't do it with python. */
2137  new_panel->type->reorder = constraint_reorder;
2138  }
2139  }
2140  }
2141  else {
2142  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
2143  Panel *panel = region->panels.first;
2145  /* Don't show invalid/legacy constraints. */
2146  if (con->type == CONSTRAINT_TYPE_NULL) {
2147  continue;
2148  }
2149  /* Don't show temporary constraints (AutoIK and target-less IK constraints). */
2150  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
2151  bKinematicConstraint *data = con->data;
2152  if (data->flag & CONSTRAINT_IK_TEMP) {
2153  continue;
2154  }
2155  }
2156 
2157  /* Move to the next instanced panel corresponding to the next constraint. */
2158  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
2159  panel = panel->next;
2160  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than constraint panels. */
2161  }
2162 
2163  PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "constraint panel customdata");
2164  RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
2165  UI_panel_custom_data_set(panel, con_ptr);
2166 
2167  panel = panel->next;
2168  }
2169  }
2170 }
2171 
2172 #undef CONSTRAINT_TYPE_PANEL_PREFIX
2173 #undef CONSTRAINT_BONE_TYPE_PANEL_PREFIX
2174 
2177 /* -------------------------------------------------------------------- */
2184 static void gpencil_modifier_panel_id(void *md_link, char *r_name)
2185 {
2186  ModifierData *md = (ModifierData *)md_link;
2188 }
2189 
2191 {
2192  ARegion *region = CTX_wm_region(C);
2194  ListBase *modifiers = &ob->greasepencil_modifiers;
2195 
2196  const bool panels_match = UI_panel_list_matches_data(
2197  region, modifiers, gpencil_modifier_panel_id);
2198 
2199  if (!panels_match) {
2200  UI_panels_free_instanced(C, region);
2201  GpencilModifierData *md = modifiers->first;
2202  for (int i = 0; md; i++, md = md->next) {
2204  if (mti->panelRegister == NULL) {
2205  continue;
2206  }
2207 
2208  char panel_idname[MAX_NAME];
2209  gpencil_modifier_panel_id(md, panel_idname);
2210 
2211  /* Create custom data RNA pointer. */
2212  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2213  RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
2214 
2215  UI_panel_add_instanced(C, region, &region->panels, panel_idname, md_ptr);
2216  }
2217  }
2218  else {
2219  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
2220  Panel *panel = region->panels.first;
2221  LISTBASE_FOREACH (ModifierData *, md, modifiers) {
2223  if (mti->panelRegister == NULL) {
2224  continue;
2225  }
2226 
2227  /* Move to the next instanced panel corresponding to the next modifier. */
2228  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
2229  panel = panel->next;
2230  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
2231  }
2232 
2233  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2234  RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
2235  UI_panel_custom_data_set(panel, md_ptr);
2236 
2237  panel = panel->next;
2238  }
2239  }
2240 }
2241 
2246 #define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
2247 
2248 /* -------------------------------------------------------------------- */
2258 static void shaderfx_panel_id(void *fx_v, char *r_idname)
2259 {
2260  ShaderFxData *fx = (ShaderFxData *)fx_v;
2261  BKE_shaderfxType_panel_id(fx->type, r_idname);
2262 }
2263 
2268 {
2269  ARegion *region = CTX_wm_region(C);
2271  ListBase *shaderfx = &ob->shader_fx;
2272 
2273  const bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id);
2274 
2275  if (!panels_match) {
2276  UI_panels_free_instanced(C, region);
2277  ShaderFxData *fx = shaderfx->first;
2278  for (int i = 0; fx; i++, fx = fx->next) {
2279  char panel_idname[MAX_NAME];
2280  shaderfx_panel_id(fx, panel_idname);
2281 
2282  /* Create custom data RNA pointer. */
2283  PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2284  RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
2285 
2286  UI_panel_add_instanced(C, region, &region->panels, panel_idname, fx_ptr);
2287  }
2288  }
2289  else {
2290  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
2291  Panel *panel = region->panels.first;
2292  LISTBASE_FOREACH (ShaderFxData *, fx, shaderfx) {
2293  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
2294  if (fxi->panelRegister == NULL) {
2295  continue;
2296  }
2297 
2298  /* Move to the next instanced panel corresponding to the next modifier. */
2299  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
2300  panel = panel->next;
2301  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
2302  }
2303 
2304  PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2305  RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
2306  UI_panel_custom_data_set(panel, fx_ptr);
2307 
2308  panel = panel->next;
2309  }
2310  }
2311 }
2312 
2315 /* -------------------------------------------------------------------- */
2320  const bContext *C;
2322  short flag;
2324 
2325 #ifdef USE_OP_RESET_BUT
2326 static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C),
2327  void *op_pt,
2328  void *UNUSED(arg_dummy2))
2329 {
2331 }
2332 #endif
2333 
2335  struct PropertyRNA *prop,
2336  void *user_data)
2337 {
2339 
2342  return false;
2343  }
2344  return params->op->type->poll_property(params->C, params->op, prop);
2345 }
2346 
2348  const bContext *C,
2349  wmOperator *op,
2350  uiLayout *layout,
2351  const eButLabelAlign label_align,
2352  int layout_flags)
2353 {
2354  uiBlock *block = uiLayoutGetBlock(layout);
2355  eAutoPropButsReturn return_info = 0;
2356 
2357  if (!op->properties) {
2358  const IDPropertyTemplate val = {0};
2359  op->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
2360  }
2361 
2362  /* poll() on this operator may still fail,
2363  * at the moment there is no nice feedback when this happens just fails silently. */
2364  if (!WM_operator_repeat_check(C, op)) {
2365  UI_block_lock_set(block, true, "Operator can't' redo");
2366  return return_info;
2367  }
2368 
2369  /* useful for macros where only one of the steps can't be re-done */
2370  UI_block_lock_clear(block);
2371 
2372  if (layout_flags & UI_TEMPLATE_OP_PROPS_SHOW_TITLE) {
2373  uiItemL(layout, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
2374  }
2375 
2376  /* menu */
2377  if (op->type->flag & OPTYPE_PRESET) {
2378  /* XXX, no simple way to get WM_MT_operator_presets.bl_label
2379  * from python! Label remains the same always! */
2380  PointerRNA op_ptr;
2381  uiLayout *row;
2382 
2383  block->ui_operator = op;
2384 
2385  row = uiLayoutRow(layout, true);
2386  uiItemM(row, "WM_MT_operator_presets", NULL, ICON_NONE);
2387 
2388  wmOperatorType *ot = WM_operatortype_find("WM_OT_operator_preset_add", false);
2389  uiItemFullO_ptr(row, ot, "", ICON_ADD, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
2390  RNA_string_set(&op_ptr, "operator", op->type->idname);
2391 
2392  uiItemFullO_ptr(row, ot, "", ICON_REMOVE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
2393  RNA_string_set(&op_ptr, "operator", op->type->idname);
2394  RNA_boolean_set(&op_ptr, "remove_active", true);
2395  }
2396 
2397  if (op->type->ui) {
2398  op->layout = layout;
2399  op->type->ui((bContext *)C, op);
2400  op->layout = NULL;
2401 
2402  /* UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too. We could
2403  * allow ot.ui callback to return this, but not needed right now. */
2404  }
2405  else {
2407  uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = layout_flags};
2408  const bool use_prop_split = (layout_flags & UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT) == 0;
2409 
2410  PointerRNA ptr;
2411  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
2412 
2413  uiLayoutSetPropSep(layout, use_prop_split);
2414  uiLayoutSetPropDecorate(layout, false);
2415 
2416  /* main draw call */
2417  return_info = uiDefAutoButsRNA(
2418  layout,
2419  &ptr,
2421  op->type->poll_property ? &user_data : NULL,
2422  op->type->prop,
2423  label_align,
2424  (layout_flags & UI_TEMPLATE_OP_PROPS_COMPACT));
2425 
2426  if ((return_info & UI_PROP_BUTS_NONE_ADDED) &&
2427  (layout_flags & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
2428  uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
2429  }
2430  }
2431 
2432 #ifdef USE_OP_RESET_BUT
2433  /* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
2434  * but this is not so important if this button is drawn in those cases
2435  * (which isn't all that likely anyway) - campbell */
2436  if (op->properties->len) {
2437  uiBut *but;
2438  uiLayout *col; /* needed to avoid alignment errors with previous buttons */
2439 
2440  col = uiLayoutColumn(layout, false);
2441  block = uiLayoutGetBlock(col);
2442  but = uiDefIconTextBut(block,
2443  UI_BTYPE_BUT,
2444  0,
2445  ICON_FILE_REFRESH,
2446  IFACE_("Reset"),
2447  0,
2448  0,
2449  UI_UNIT_X,
2450  UI_UNIT_Y,
2451  NULL,
2452  0.0,
2453  0.0,
2454  0.0,
2455  0.0,
2456  TIP_("Reset operator defaults"));
2457  UI_but_func_set(but, ui_layout_operator_buts__reset_cb, op, NULL);
2458  }
2459 #endif
2460 
2461  /* set various special settings for buttons */
2462 
2463  /* Only do this if we're not refreshing an existing UI. */
2464  if (block->oldblock == NULL) {
2465  const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
2466 
2467  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
2468  /* no undo for buttons for operator redo panels */
2470 
2471  /* only for popups, see T36109. */
2472 
2473  /* if button is operator's default property, and a text-field, enable focus for it
2474  * - this is used for allowing operators with popups to rename stuff with fewer clicks
2475  */
2476  if (is_popup) {
2477  if ((but->rnaprop == op->type->prop) && (but->type == UI_BTYPE_TEXT)) {
2479  }
2480  }
2481  }
2482  }
2483 
2484  return return_info;
2485 }
2486 
2488  wmOperator *op,
2489  uiLayout *layout,
2490  const eButLabelAlign label_align,
2491  int layout_flags,
2492  bool *r_has_advanced)
2493 {
2494  if (op->type->flag & OPTYPE_MACRO) {
2495  LISTBASE_FOREACH (wmOperator *, macro_op, &op->macro) {
2497  C, macro_op, layout, label_align, layout_flags, r_has_advanced);
2498  }
2499  }
2500  else {
2501  /* Might want to make label_align adjustable somehow. */
2503  C, op, layout, label_align, layout_flags);
2504  if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) {
2505  if (r_has_advanced) {
2506  *r_has_advanced = true;
2507  }
2508  }
2509  }
2510 }
2511 
2513  wmWindowManager *wm,
2514  wmOperator *op,
2515  int layout_flags)
2516 {
2517  if (op->type->flag & OPTYPE_MACRO) {
2518  LISTBASE_FOREACH (wmOperator *, macro_op, &op->macro) {
2519  if (!ui_layout_operator_properties_only_booleans(C, wm, macro_op, layout_flags)) {
2520  return false;
2521  }
2522  }
2523  }
2524  else {
2525  uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = layout_flags};
2526  PointerRNA ptr;
2527 
2528  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
2529 
2530  RNA_STRUCT_BEGIN (&ptr, prop) {
2531  if (RNA_property_flag(prop) & PROP_HIDDEN) {
2532  continue;
2533  }
2534  if (op->type->poll_property &&
2536  continue;
2537  }
2538  if (RNA_property_type(prop) != PROP_BOOLEAN) {
2539  return false;
2540  }
2541  }
2543  }
2544 
2545  return true;
2546 }
2547 
2554  const bContext *C, uiLayout *layout, wmOperator *op, eButLabelAlign label_align, short flag)
2555 {
2557 
2558  /* If there are only checkbox items, don't use split layout by default. It looks weird if the
2559  * checkboxes only use half the width. */
2560  if (ui_layout_operator_properties_only_booleans(C, wm, op, flag)) {
2562  }
2563 
2564  template_operator_property_buts_draw_recursive(C, op, layout, label_align, flag, NULL);
2565 }
2566 
2568 {
2570  uiBlock *block = uiLayoutGetBlock(layout);
2571 
2572  if (op == NULL) {
2573  return;
2574  }
2575 
2576  /* Disable for now, doesn't fit well in popover. */
2577 #if 0
2578  /* Repeat button with operator name as text. */
2579  uiItemFullO(layout,
2580  "SCREEN_OT_repeat_last",
2581  WM_operatortype_name(op->type, op->ptr),
2582  ICON_NONE,
2583  NULL,
2585  0,
2586  NULL);
2587 #endif
2588 
2589  if (WM_operator_repeat_check(C, op)) {
2590  int layout_flags = 0;
2591  if (block->panel == NULL) {
2592  layout_flags = UI_TEMPLATE_OP_PROPS_SHOW_TITLE;
2593  }
2594 #if 0
2595  bool has_advanced = false;
2596 #endif
2597 
2600  C, op, layout, UI_BUT_LABEL_ALIGN_NONE, layout_flags, NULL /* &has_advanced */);
2601  /* Warning! this leaves the handle function for any other users of this block. */
2602 
2603 #if 0
2604  if (has_advanced) {
2605  uiItemO(layout, IFACE_("More..."), ICON_NONE, "SCREEN_OT_redo_last");
2606  }
2607 #endif
2608  }
2609 }
2610 
2613 /* -------------------------------------------------------------------- */
2617 #define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
2618 
2619 static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
2620 {
2621  ED_object_constraint_active_set(ob_v, con_v);
2622 }
2623 
2624 static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
2625 {
2627  short proxy_protected, xco = 0, yco = 0;
2628  // int rb_col; // UNUSED
2629 
2630  /* determine whether constraint is proxy protected or not */
2631  if (BKE_constraints_proxylocked_owner(ob, pchan)) {
2632  proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
2633  }
2634  else {
2635  proxy_protected = 0;
2636  }
2637 
2638  /* unless button has own callback, it adds this callback to button */
2639  uiBlock *block = uiLayoutGetBlock(layout);
2640  UI_block_func_set(block, constraint_active_func, ob, con);
2641 
2642  PointerRNA ptr;
2643  RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
2644 
2645  uiLayoutSetContextPointer(layout, "constraint", &ptr);
2646 
2647  /* Constraint type icon. */
2648  uiLayout *sub = uiLayoutRow(layout, false);
2649  uiLayoutSetEmboss(sub, false);
2651  uiItemL(sub, "", RNA_struct_ui_icon(ptr.type));
2652 
2654 
2655  if (proxy_protected == 0) {
2656  uiItemR(layout, &ptr, "name", 0, "", ICON_NONE);
2657  }
2658  else {
2659  uiItemL(layout, con->name, ICON_NONE);
2660  }
2661 
2662  /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
2663  if (proxy_protected) {
2665 
2666  /* draw a ghost icon (for proxy) and also a lock beside it,
2667  * to show that constraint is "proxy locked" */
2668  uiDefIconBut(block,
2669  UI_BTYPE_BUT,
2670  0,
2671  ICON_GHOST_ENABLED,
2672  xco + 12.2f * UI_UNIT_X,
2673  yco,
2674  0.95f * UI_UNIT_X,
2675  0.95f * UI_UNIT_Y,
2676  NULL,
2677  0.0,
2678  0.0,
2679  0.0,
2680  0.0,
2681  TIP_("Proxy Protected"));
2682  uiDefIconBut(block,
2683  UI_BTYPE_BUT,
2684  0,
2685  ICON_LOCKED,
2686  xco + 13.1f * UI_UNIT_X,
2687  yco,
2688  0.95f * UI_UNIT_X,
2689  0.95f * UI_UNIT_Y,
2690  NULL,
2691  0.0,
2692  0.0,
2693  0.0,
2694  0.0,
2695  TIP_("Proxy Protected"));
2696 
2698  }
2699  else {
2700  /* enabled */
2702  uiItemR(layout, &ptr, "mute", 0, "", 0);
2704 
2706 
2707  /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
2709  uiItemO(layout, "", ICON_X, "CONSTRAINT_OT_delete");
2711 
2712  /* Some extra padding at the end, so the 'x' icon isn't too close to drag button. */
2713  uiItemS(layout);
2714  }
2715 
2716  /* Set but-locks for protected settings (magic numbers are used here!) */
2717  if (proxy_protected) {
2718  UI_block_lock_set(block, true, TIP_("Cannot edit Proxy-Protected Constraint"));
2719  }
2720 
2721  /* clear any locks set up for proxies/lib-linking */
2722  UI_block_lock_clear(block);
2723 }
2724 
2726 {
2727  /* verify we have valid data */
2729  RNA_warning("Expected constraint on object");
2730  return;
2731  }
2732 
2733  Object *ob = (Object *)ptr->owner_id;
2734  bConstraint *con = ptr->data;
2735 
2736  if (!ob || !(GS(ob->id.name) == ID_OB)) {
2737  RNA_warning("Expected constraint on object");
2738  return;
2739  }
2740 
2742 
2743  draw_constraint_header(layout, ob, con);
2744 }
2745 
2748 /* -------------------------------------------------------------------- */
2752 #include "DNA_light_types.h"
2753 #include "DNA_material_types.h"
2754 #include "DNA_world_types.h"
2755 
2756 #define B_MATPRV 1
2757 
2758 static void do_preview_buttons(bContext *C, void *arg, int event)
2759 {
2760  switch (event) {
2761  case B_MATPRV:
2763  break;
2764  }
2765 }
2766 
2768  bContext *C,
2769  ID *id,
2770  bool show_buttons,
2771  ID *parent,
2772  MTex *slot,
2773  const char *preview_id)
2774 {
2775  Material *ma = NULL;
2776  Tex *tex = (Tex *)id;
2777  short *pr_texture = NULL;
2778  PointerRNA material_ptr;
2779  PointerRNA texture_ptr;
2780 
2781  char _preview_id[UI_MAX_NAME_STR];
2782 
2783  if (id && !ELEM(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA, ID_LS)) {
2784  RNA_warning("Expected ID of type material, texture, light, world or line style");
2785  return;
2786  }
2787 
2788  /* decide what to render */
2789  ID *pid = id;
2790  ID *pparent = NULL;
2791 
2792  if (id && (GS(id->name) == ID_TE)) {
2793  if (parent && (GS(parent->name) == ID_MA)) {
2794  pr_texture = &((Material *)parent)->pr_texture;
2795  }
2796  else if (parent && (GS(parent->name) == ID_WO)) {
2797  pr_texture = &((World *)parent)->pr_texture;
2798  }
2799  else if (parent && (GS(parent->name) == ID_LA)) {
2800  pr_texture = &((Light *)parent)->pr_texture;
2801  }
2802  else if (parent && (GS(parent->name) == ID_LS)) {
2803  pr_texture = &((FreestyleLineStyle *)parent)->pr_texture;
2804  }
2805 
2806  if (pr_texture) {
2807  if (*pr_texture == TEX_PR_OTHER) {
2808  pid = parent;
2809  }
2810  else if (*pr_texture == TEX_PR_BOTH) {
2811  pparent = parent;
2812  }
2813  }
2814  }
2815 
2816  if (!preview_id || (preview_id[0] == '\0')) {
2817  /* If no identifier given, generate one from ID type. */
2818  BLI_snprintf(
2819  _preview_id, UI_MAX_NAME_STR, "uiPreview_%s", BKE_idtype_idcode_to_name(GS(id->name)));
2820  preview_id = _preview_id;
2821  }
2822 
2823  /* Find or add the uiPreview to the current Region. */
2824  ARegion *region = CTX_wm_region(C);
2825  uiPreview *ui_preview = BLI_findstring(
2826  &region->ui_previews, preview_id, offsetof(uiPreview, preview_id));
2827 
2828  if (!ui_preview) {
2829  ui_preview = MEM_callocN(sizeof(uiPreview), "uiPreview");
2830  BLI_strncpy(ui_preview->preview_id, preview_id, sizeof(ui_preview->preview_id));
2831  ui_preview->height = (short)(UI_UNIT_Y * 7.6f);
2832  BLI_addtail(&region->ui_previews, ui_preview);
2833  }
2834 
2835  if (ui_preview->height < UI_UNIT_Y) {
2836  ui_preview->height = UI_UNIT_Y;
2837  }
2838  else if (ui_preview->height > UI_UNIT_Y * 50) { /* Rather high upper limit, yet not insane! */
2839  ui_preview->height = UI_UNIT_Y * 50;
2840  }
2841 
2842  /* layout */
2843  uiBlock *block = uiLayoutGetBlock(layout);
2844  uiLayout *row = uiLayoutRow(layout, false);
2845  uiLayout *col = uiLayoutColumn(row, false);
2846  uiLayoutSetKeepAspect(col, true);
2847 
2848  /* add preview */
2849  uiDefBut(block,
2851  0,
2852  "",
2853  0,
2854  0,
2855  UI_UNIT_X * 10,
2856  ui_preview->height,
2857  pid,
2858  0.0,
2859  0.0,
2860  0,
2861  0,
2862  "");
2863  UI_but_func_drawextra_set(block, ED_preview_draw, pparent, slot);
2865 
2866  uiDefIconButS(block,
2867  UI_BTYPE_GRIP,
2868  0,
2869  ICON_GRIP,
2870  0,
2871  0,
2872  UI_UNIT_X * 10,
2873  (short)(UI_UNIT_Y * 0.3f),
2874  &ui_preview->height,
2875  UI_UNIT_Y,
2876  UI_UNIT_Y * 50.0f,
2877  0.0f,
2878  0.0f,
2879  "");
2880 
2881  /* add buttons */
2882  if (pid && show_buttons) {
2883  if (GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
2884  if (GS(pid->name) == ID_MA) {
2885  ma = (Material *)pid;
2886  }
2887  else {
2888  ma = (Material *)pparent;
2889  }
2890 
2891  /* Create RNA Pointer */
2892  RNA_pointer_create(&ma->id, &RNA_Material, ma, &material_ptr);
2893 
2894  col = uiLayoutColumn(row, true);
2895  uiLayoutSetScaleX(col, 1.5);
2896  uiItemR(col, &material_ptr, "preview_render_type", UI_ITEM_R_EXPAND, "", ICON_NONE);
2897 
2898  /* EEVEE preview file has baked lighting so use_preview_world has no effect,
2899  * just hide the option until this feature is supported. */
2901  uiItemS(col);
2902  uiItemR(col, &material_ptr, "use_preview_world", 0, "", ICON_WORLD);
2903  }
2904  }
2905 
2906  if (pr_texture) {
2907  /* Create RNA Pointer */
2908  RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
2909 
2910  uiLayoutRow(layout, true);
2911  uiDefButS(block,
2912  UI_BTYPE_ROW,
2913  B_MATPRV,
2914  IFACE_("Texture"),
2915  0,
2916  0,
2917  UI_UNIT_X * 10,
2918  UI_UNIT_Y,
2919  pr_texture,
2920  10,
2922  0,
2923  0,
2924  "");
2925  if (GS(parent->name) == ID_MA) {
2926  uiDefButS(block,
2927  UI_BTYPE_ROW,
2928  B_MATPRV,
2929  IFACE_("Material"),
2930  0,
2931  0,
2932  UI_UNIT_X * 10,
2933  UI_UNIT_Y,
2934  pr_texture,
2935  10,
2936  TEX_PR_OTHER,
2937  0,
2938  0,
2939  "");
2940  }
2941  else if (GS(parent->name) == ID_LA) {
2942  uiDefButS(block,
2943  UI_BTYPE_ROW,
2944  B_MATPRV,
2946  0,
2947  0,
2948  UI_UNIT_X * 10,
2949  UI_UNIT_Y,
2950  pr_texture,
2951  10,
2952  TEX_PR_OTHER,
2953  0,
2954  0,
2955  "");
2956  }
2957  else if (GS(parent->name) == ID_WO) {
2958  uiDefButS(block,
2959  UI_BTYPE_ROW,
2960  B_MATPRV,
2961  IFACE_("World"),
2962  0,
2963  0,
2964  UI_UNIT_X * 10,
2965  UI_UNIT_Y,
2966  pr_texture,
2967  10,
2968  TEX_PR_OTHER,
2969  0,
2970  0,
2971  "");
2972  }
2973  else if (GS(parent->name) == ID_LS) {
2974  uiDefButS(block,
2975  UI_BTYPE_ROW,
2976  B_MATPRV,
2977  IFACE_("Line Style"),
2978  0,
2979  0,
2980  UI_UNIT_X * 10,
2981  UI_UNIT_Y,
2982  pr_texture,
2983  10,
2984  TEX_PR_OTHER,
2985  0,
2986  0,
2987  "");
2988  }
2989  uiDefButS(block,
2990  UI_BTYPE_ROW,
2991  B_MATPRV,
2992  IFACE_("Both"),
2993  0,
2994  0,
2995  UI_UNIT_X * 10,
2996  UI_UNIT_Y,
2997  pr_texture,
2998  10,
2999  TEX_PR_BOTH,
3000  0,
3001  0,
3002  "");
3003 
3004  /* Alpha button for texture preview */
3005  if (*pr_texture != TEX_PR_OTHER) {
3006  row = uiLayoutRow(layout, false);
3007  uiItemR(row, &texture_ptr, "use_preview_alpha", 0, NULL, ICON_NONE);
3008  }
3009  }
3010  }
3011 }
3012 
3015 /* -------------------------------------------------------------------- */
3019 typedef struct RNAUpdateCb {
3023 
3024 static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
3025 {
3026  RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
3027 
3028  /* we call update here on the pointer property, this way the
3029  * owner of the curve mapping can still define its own update
3030  * and notifier, even if the CurveMapping struct is shared. */
3031  RNA_property_update(C, &cb->ptr, cb->prop);
3032 }
3033 
3034 enum {
3039 };
3040 
3042 {
3043  CBData data_tmp[MAXCOLORBAND];
3044 
3045  for (int a = 0; a < coba->tot; a++) {
3046  data_tmp[a] = coba->data[coba->tot - (a + 1)];
3047  }
3048  for (int a = 0; a < coba->tot; a++) {
3049  data_tmp[a].pos = 1.0f - data_tmp[a].pos;
3050  coba->data[a] = data_tmp[a];
3051  }
3052 
3053  /* may as well flip the cur*/
3054  coba->cur = coba->tot - (coba->cur + 1);
3055 
3056  ED_undo_push(C, "Flip Color Ramp");
3057 }
3058 
3059 static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly)
3060 {
3061  if (coba->tot > 1) {
3062  const int tot = evenly ? coba->tot - 1 : coba->tot;
3063  const float gap = 1.0f / tot;
3064  float pos = 0.0f;
3065  for (int a = 0; a < coba->tot; a++) {
3066  coba->data[a].pos = pos;
3067  pos += gap;
3068  }
3069  ED_undo_push(C, evenly ? "Distribute Stops Evenly" : "Distribute Stops from Left");
3070  }
3071 }
3072 
3073 static void colorband_tools_dofunc(bContext *C, void *coba_v, int event)
3074 {
3075  ColorBand *coba = coba_v;
3076 
3077  switch (event) {
3078  case CB_FUNC_FLIP:
3079  colorband_flip_cb(C, coba);
3080  break;
3081  case CB_FUNC_DISTRIBUTE_LR:
3082  colorband_distribute_cb(C, coba, false);
3083  break;
3085  colorband_distribute_cb(C, coba, true);
3086  break;
3087  case CB_FUNC_RESET:
3088  BKE_colorband_init(coba, true);
3089  ED_undo_push(C, "Reset Color Ramp");
3090  break;
3091  }
3093 }
3094 
3095 static uiBlock *colorband_tools_func(bContext *C, ARegion *region, void *coba_v)
3096 {
3097  const uiStyle *style = UI_style_get_dpi();
3098  ColorBand *coba = coba_v;
3099  short yco = 0;
3100  const short menuwidth = 10 * UI_UNIT_X;
3101 
3102  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS_PULLDOWN);
3104 
3105  uiLayout *layout = UI_block_layout(block,
3108  0,
3109  0,
3111  0,
3113  style);
3114  UI_block_layout_set_current(block, layout);
3115  {
3116  PointerRNA coba_ptr;
3117  RNA_pointer_create(NULL, &RNA_ColorRamp, coba, &coba_ptr);
3118  uiLayoutSetContextPointer(layout, "color_ramp", &coba_ptr);
3119  }
3120 
3121  /* We could move these to operators,
3122  * although this isn't important unless we want to assign key shortcuts to them. */
3123  {
3124  uiDefIconTextBut(block,
3126  1,
3127  ICON_BLANK1,
3128  IFACE_("Flip Color Ramp"),
3129  0,
3130  yco -= UI_UNIT_Y,
3131  menuwidth,
3132  UI_UNIT_Y,
3133  NULL,
3134  0.0,
3135  0.0,
3136  0,
3137  CB_FUNC_FLIP,
3138  "");
3139  uiDefIconTextBut(block,
3141  1,
3142  ICON_BLANK1,
3143  IFACE_("Distribute Stops from Left"),
3144  0,
3145  yco -= UI_UNIT_Y,
3146  menuwidth,
3147  UI_UNIT_Y,
3148  NULL,
3149  0.0,
3150  0.0,
3151  0,
3153  "");
3154  uiDefIconTextBut(block,
3156  1,
3157  ICON_BLANK1,
3158  IFACE_("Distribute Stops Evenly"),
3159  0,
3160  yco -= UI_UNIT_Y,
3161  menuwidth,
3162  UI_UNIT_Y,
3163  NULL,
3164  0.0,
3165  0.0,
3166  0,
3168  "");
3169 
3170  uiItemO(layout, IFACE_("Eyedropper"), ICON_EYEDROPPER, "UI_OT_eyedropper_colorramp");
3171 
3172  uiDefIconTextBut(block,
3174  1,
3175  ICON_BLANK1,
3176  IFACE_("Reset Color Ramp"),
3177  0,
3178  yco -= UI_UNIT_Y,
3179  menuwidth,
3180  UI_UNIT_Y,
3181  NULL,
3182  0.0,
3183  0.0,
3184  0,
3185  CB_FUNC_RESET,
3186  "");
3187  }
3188 
3190  UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
3191 
3192  return block;
3193 }
3194 
3195 static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
3196 {
3197  ColorBand *coba = coba_v;
3198  float pos = 0.5f;
3199 
3200  if (coba->tot > 1) {
3201  if (coba->cur > 0) {
3202  pos = (coba->data[coba->cur - 1].pos + coba->data[coba->cur].pos) * 0.5f;
3203  }
3204  else {
3205  pos = (coba->data[coba->cur + 1].pos + coba->data[coba->cur].pos) * 0.5f;
3206  }
3207  }
3208 
3209  if (BKE_colorband_element_add(coba, pos)) {
3210  rna_update_cb(C, cb_v, NULL);
3211  ED_undo_push(C, "Add Color Ramp Stop");
3212  }
3213 }
3214 
3215 static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
3216 {
3217  ColorBand *coba = coba_v;
3218 
3219  if (BKE_colorband_element_remove(coba, coba->cur)) {
3220  ED_undo_push(C, "Delete Color Ramp Stop");
3221  rna_update_cb(C, cb_v, NULL);
3222  }
3223 }
3224 
3225 static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
3226 {
3227  uiBut *bt = bt_v;
3228  ColorBand *coba = coba_v;
3229 
3230  /* Sneaky update here, we need to sort the color-band points to be in order,
3231  * however the RNA pointer then is wrong, so we update it */
3233  bt->rnapoin.data = coba->data + coba->cur;
3234 }
3235 
3237  uiBlock *block,
3238  ColorBand *coba,
3239  const rctf *butr,
3240  RNAUpdateCb *cb,
3241  int expand)
3242 {
3243  uiBut *bt;
3244  const float unit = BLI_rctf_size_x(butr) / 14.0f;
3245  const float xs = butr->xmin;
3246  const float ys = butr->ymin;
3247 
3248  PointerRNA ptr;
3250 
3251  uiLayout *split = uiLayoutSplit(layout, 0.4f, false);
3252 
3254  UI_block_align_begin(block);
3255  uiLayout *row = uiLayoutRow(split, false);
3256 
3257  bt = uiDefIconTextBut(block,
3258  UI_BTYPE_BUT,
3259  0,
3260  ICON_ADD,
3261  "",
3262  0,
3263  0,
3264  2.0f * unit,
3265  UI_UNIT_Y,
3266  NULL,
3267  0,
3268  0,
3269  0,
3270  0,
3271  TIP_("Add a new color stop to the color ramp"));
3273 
3274  bt = uiDefIconTextBut(block,
3275  UI_BTYPE_BUT,
3276  0,
3277  ICON_REMOVE,
3278  "",
3279  xs + 2.0f * unit,
3280  ys + UI_UNIT_Y,
3281  2.0f * unit,
3282  UI_UNIT_Y,
3283  NULL,
3284  0,
3285  0,
3286  0,
3287  0,
3288  TIP_("Delete the active position"));
3290 
3291  bt = uiDefIconBlockBut(block,
3293  coba,
3294  0,
3295  ICON_DOWNARROW_HLT,
3296  xs + 4.0f * unit,
3297  ys + UI_UNIT_Y,
3298  2.0f * unit,
3299  UI_UNIT_Y,
3300  TIP_("Tools"));
3302 
3303  UI_block_align_end(block);
3305 
3306  row = uiLayoutRow(split, false);
3307 
3308  UI_block_align_begin(block);
3309  uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE);
3311  uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE);
3312  }
3313  else { /* COLBAND_BLEND_RGB */
3314  uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
3315  }
3316  UI_block_align_end(block);
3317 
3318  row = uiLayoutRow(layout, false);
3319 
3320  bt = uiDefBut(block,
3322  0,
3323  "",
3324  xs,
3325  ys,
3326  BLI_rctf_size_x(butr),
3327  UI_UNIT_Y,
3328  coba,
3329  0,
3330  0,
3331  0,
3332  0,
3333  "");
3335 
3336  row = uiLayoutRow(layout, false);
3337 
3338  if (coba->tot) {
3339  CBData *cbd = coba->data + coba->cur;
3340 
3342 
3343  if (!expand) {
3344  split = uiLayoutSplit(layout, 0.3f, false);
3345 
3346  row = uiLayoutRow(split, false);
3347  bt = uiDefButS(block,
3348  UI_BTYPE_NUM,
3349  0,
3350  "",
3351  0,
3352  0,
3353  5.0f * UI_UNIT_X,
3354  UI_UNIT_Y,
3355  &coba->cur,
3356  0.0,
3357  (float)(MAX2(0, coba->tot - 1)),
3358  0,
3359  0,
3360  TIP_("Choose active color stop"));
3362 
3363  row = uiLayoutRow(split, false);
3364  uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
3365 
3366  row = uiLayoutRow(layout, false);
3367  uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
3368  }
3369  else {
3370  split = uiLayoutSplit(layout, 0.5f, false);
3371  uiLayout *subsplit = uiLayoutSplit(split, 0.35f, false);
3372 
3373  row = uiLayoutRow(subsplit, false);
3374  bt = uiDefButS(block,
3375  UI_BTYPE_NUM,
3376  0,
3377  "",
3378  0,
3379  0,
3380  5.0f * UI_UNIT_X,
3381  UI_UNIT_Y,
3382  &coba->cur,
3383  0.0,
3384  (float)(MAX2(0, coba->tot - 1)),
3385  0,
3386  0,
3387  TIP_("Choose active color stop"));
3389 
3390  row = uiLayoutRow(subsplit, false);
3391  uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
3392 
3393  row = uiLayoutRow(split, false);
3394  uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
3395  }
3396 
3397  /* Some special (rather awkward) treatment to update UI state on certain property changes. */
3398  LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
3399  if (but->rnapoin.data != ptr.data) {
3400  continue;
3401  }
3402  if (!but->rnaprop) {
3403  continue;
3404  }
3405 
3406  const char *prop_identifier = RNA_property_identifier(but->rnaprop);
3407  if (STREQ(prop_identifier, "position")) {
3408  UI_but_func_set(but, colorband_update_cb, but, coba);
3409  }
3410 
3411  if (STREQ(prop_identifier, "color")) {
3413  }
3414  }
3415  }
3416 }
3417 
3418 void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, bool expand)
3419 {
3420  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3421 
3422  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
3423  return;
3424  }
3425 
3426  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
3427  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp)) {
3428  return;
3429  }
3430 
3431  RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
3432  cb->ptr = *ptr;
3433  cb->prop = prop;
3434 
3435  rctf rect;
3436  rect.xmin = 0;
3437  rect.xmax = 10.0f * UI_UNIT_X;
3438  rect.ymin = 0;
3439  rect.ymax = 19.5f * UI_UNIT_X;
3440 
3441  uiBlock *block = uiLayoutAbsoluteBlock(layout);
3442 
3443  ID *id = cptr.owner_id;
3445 
3446  colorband_buttons_layout(layout, block, cptr.data, &rect, cb, expand);
3447 
3448  UI_block_lock_clear(block);
3449 
3450  MEM_freeN(cb);
3451 }
3452 
3455 /* -------------------------------------------------------------------- */
3462 void uiTemplateIcon(uiLayout *layout, int icon_value, float icon_scale)
3463 {
3464  uiBlock *block = uiLayoutAbsoluteBlock(layout);
3465  uiBut *but = uiDefIconBut(block,
3467  0,
3468  ICON_X,
3469  0,
3470  0,
3471  UI_UNIT_X * icon_scale,
3472  UI_UNIT_Y * icon_scale,
3473  NULL,
3474  0.0,
3475  0.0,
3476  0.0,
3477  0.0,
3478  "");
3479  ui_def_but_icon(but, icon_value, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
3480 }
3481 
3484 /* -------------------------------------------------------------------- */
3488 typedef struct IconViewMenuArgs {
3492  float icon_scale;
3494 
3495 /* ID Search browse menu, open */
3496 static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *region, void *arg_litem)
3497 {
3498  static IconViewMenuArgs args;
3499 
3500  /* arg_litem is malloced, can be freed by parent button */
3501  args = *((IconViewMenuArgs *)arg_litem);
3502  const int w = UI_UNIT_X * (args.icon_scale);
3503  const int h = UI_UNIT_X * (args.icon_scale + args.show_labels);
3504 
3505  uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS_PULLDOWN);
3508 
3509  bool free;
3510  const EnumPropertyItem *item;
3511  RNA_property_enum_items(C, &args.ptr, args.prop, &item, NULL, &free);
3512 
3513  for (int a = 0; item[a].identifier; a++) {
3514  const int x = (a % 8) * w;
3515  const int y = -(a / 8) * h;
3516 
3517  const int icon = item[a].icon;
3518  const int value = item[a].value;
3519  uiBut *but;
3520  if (args.show_labels) {
3521  but = uiDefIconTextButR_prop(block,
3522  UI_BTYPE_ROW,
3523  0,
3524  icon,
3525  item[a].name,
3526  x,
3527  y,
3528  w,
3529  h,
3530  &args.ptr,
3531  args.prop,
3532  -1,
3533  0,
3534  value,
3535  -1,
3536  -1,
3537  NULL);
3538  }
3539  else {
3540  but = uiDefIconButR_prop(block,
3541  UI_BTYPE_ROW,
3542  0,
3543  icon,
3544  x,
3545  y,
3546  w,
3547  h,
3548  &args.ptr,
3549  args.prop,
3550  -1,
3551  0,
3552  value,
3553  -1,
3554  -1,
3555  NULL);
3556  }
3558  }
3559 
3560  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
3562 
3563  if (free) {
3564  MEM_freeN((void *)item);
3565  }
3566 
3567  return block;
3568 }
3569 
3574  PointerRNA *ptr,
3575  const char *propname,
3576  bool show_labels,
3577  float icon_scale,
3578  float icon_scale_popup)
3579 {
3580  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3581 
3582  if (!prop || RNA_property_type(prop) != PROP_ENUM) {
3583  RNA_warning(
3584  "property of type Enum not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
3585  return;
3586  }
3587 
3588  uiBlock *block = uiLayoutAbsoluteBlock(layout);
3589 
3590  int tot_items;
3591  bool free_items;
3592  const EnumPropertyItem *items;
3593  RNA_property_enum_items(block->evil_C, ptr, prop, &items, &tot_items, &free_items);
3594  const int value = RNA_property_enum_get(ptr, prop);
3595  int icon = ICON_NONE;
3596  RNA_enum_icon_from_value(items, value, &icon);
3597 
3598  uiBut *but;
3599  if (RNA_property_editable(ptr, prop)) {
3600  IconViewMenuArgs *cb_args = MEM_callocN(sizeof(IconViewMenuArgs), __func__);
3601  cb_args->ptr = *ptr;
3602  cb_args->prop = prop;
3603  cb_args->show_labels = show_labels;
3604  cb_args->icon_scale = icon_scale_popup;
3605 
3606  but = uiDefBlockButN(block,
3608  cb_args,
3609  "",
3610  0,
3611  0,
3612  UI_UNIT_X * icon_scale,
3613  UI_UNIT_Y * icon_scale,
3614  "");
3615  }
3616  else {
3617  but = uiDefIconBut(block,
3619  0,
3620  ICON_X,
3621  0,
3622  0,
3623  UI_UNIT_X * icon_scale,
3624  UI_UNIT_Y * icon_scale,
3625  NULL,
3626  0.0,
3627  0.0,
3628  0.0,
3629  0.0,
3630  "");
3631  }
3632 
3634 
3635  if (free_items) {
3636  MEM_freeN((void *)items);
3637  }
3638 }
3639 
3642 /* -------------------------------------------------------------------- */
3646 void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
3647 {
3648  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3649 
3650  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
3651  return;
3652  }
3653 
3654  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
3655  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Histogram)) {
3656  return;
3657  }
3658  Histogram *hist = (Histogram *)cptr.data;
3659 
3660  if (hist->height < UI_UNIT_Y) {
3661  hist->height = UI_UNIT_Y;
3662  }
3663  else if (hist->height > UI_UNIT_Y * 20) {
3664  hist->height = UI_UNIT_Y * 20;
3665  }
3666 
3667  uiLayout *col = uiLayoutColumn(layout, true);
3668  uiBlock *block = uiLayoutGetBlock(col);
3669 
3670  uiDefBut(
3671  block, UI_BTYPE_HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
3672 
3673  /* Resize grip. */
3674  uiDefIconButI(block,
3675  UI_BTYPE_GRIP,
3676  0,
3677  ICON_GRIP,
3678  0,
3679  0,
3680  UI_UNIT_X * 10,
3681  (short)(UI_UNIT_Y * 0.3f),
3682  &hist->height,
3683  UI_UNIT_Y,
3684  UI_UNIT_Y * 20.0f,
3685  0.0f,
3686  0.0f,
3687  "");
3688 }
3689 
3692 /* -------------------------------------------------------------------- */
3696 void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
3697 {
3698  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3699 
3700  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
3701  return;
3702  }
3703 
3704  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
3705  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
3706  return;
3707  }
3708  Scopes *scopes = (Scopes *)cptr.data;
3709 
3710  uiLayout *col = uiLayoutColumn(layout, true);
3711  uiBlock *block = uiLayoutGetBlock(col);
3712 
3713  if (scopes->wavefrm_height < UI_UNIT_Y) {
3714  scopes->wavefrm_height = UI_UNIT_Y;
3715  }
3716  else if (scopes->wavefrm_height > UI_UNIT_Y * 20) {
3717  scopes->wavefrm_height = UI_UNIT_Y * 20;
3718  }
3719 
3720  uiDefBut(block,
3722  0,
3723  "",
3724  0,
3725  0,
3726  UI_UNIT_X * 10,
3727  scopes->wavefrm_height,
3728  scopes,
3729  0,
3730  0,
3731  0,
3732  0,
3733  "");
3734 
3735  /* Resize grip. */
3736  uiDefIconButI(block,
3737  UI_BTYPE_GRIP,
3738  0,
3739  ICON_GRIP,
3740  0,
3741  0,
3742  UI_UNIT_X * 10,
3743  (short)(UI_UNIT_Y * 0.3f),
3744  &scopes->wavefrm_height,
3745  UI_UNIT_Y,
3746  UI_UNIT_Y * 20.0f,
3747  0.0f,
3748  0.0f,
3749  "");
3750 }
3751 
3754 /* -------------------------------------------------------------------- */
3758 void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propname)
3759 {
3760  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3761 
3762  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
3763  return;
3764  }
3765 
3766  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
3767  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
3768  return;
3769  }
3770  Scopes *scopes = (Scopes *)cptr.data;
3771 
3772  if (scopes->vecscope_height < UI_UNIT_Y) {
3773  scopes->vecscope_height = UI_UNIT_Y;
3774  }
3775  else if (scopes->vecscope_height > UI_UNIT_Y * 20) {
3776  scopes->vecscope_height = UI_UNIT_Y * 20;
3777  }
3778 
3779  uiLayout *col = uiLayoutColumn(layout, true);
3780  uiBlock *block = uiLayoutGetBlock(col);
3781 
3782  uiDefBut(block,
3784  0,
3785  "",
3786  0,
3787  0,
3788  UI_UNIT_X * 10,
3789  scopes->vecscope_height,
3790  scopes,
3791  0,
3792  0,
3793  0,
3794  0,
3795  "");
3796 
3797  /* Resize grip. */
3798  uiDefIconButI(block,
3799  UI_BTYPE_GRIP,
3800  0,
3801  ICON_GRIP,
3802  0,
3803  0,
3804  UI_UNIT_X * 10,
3805  (short)(UI_UNIT_Y * 0.3f),
3806  &scopes->vecscope_height,
3807  UI_UNIT_Y,
3808  UI_UNIT_Y * 20.0f,
3809  0.0f,
3810  0.0f,
3811  "");
3812 }
3813 
3816 /* -------------------------------------------------------------------- */
3820 static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *UNUSED(arg))
3821 {
3822  CurveMapping *cumap = cumap_v;
3823 
3824  /* we allow 20 times zoom */
3825  if (BLI_rctf_size_x(&cumap->curr) > 0.04f * BLI_rctf_size_x(&cumap->clipr)) {
3826  const float dx = 0.1154f * BLI_rctf_size_x(&cumap->curr);
3827  cumap->curr.xmin += dx;
3828  cumap->curr.xmax -= dx;
3829  const float dy = 0.1154f * BLI_rctf_size_y(&cumap->curr);
3830  cumap->curr.ymin += dy;
3831  cumap->curr.ymax -= dy;
3832  }
3833 
3835 }
3836 
3837 static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *UNUSED(unused))
3838 {
3839  CurveMapping *cumap = cumap_v;
3840  float d, d1;
3841 
3842  /* we allow 20 times zoom, but don't view outside clip */
3843  if (BLI_rctf_size_x(&cumap->curr) < 20.0f * BLI_rctf_size_x(&cumap->clipr)) {
3844  d = d1 = 0.15f * BLI_rctf_size_x(&cumap->curr);
3845 
3846  if (cumap->flag & CUMA_DO_CLIP) {
3847  if (cumap->curr.xmin - d < cumap->clipr.xmin) {
3848  d1 = cumap->curr.xmin - cumap->clipr.xmin;
3849  }
3850  }
3851  cumap->curr.xmin -= d1;
3852 
3853  d1 = d;
3854  if (cumap->flag & CUMA_DO_CLIP) {
3855  if (cumap->curr.xmax + d > cumap->clipr.xmax) {
3856  d1 = -cumap->curr.xmax + cumap->clipr.xmax;
3857  }
3858  }
3859  cumap->curr.xmax += d1;
3860 
3861  d = d1 = 0.15f * BLI_rctf_size_y(&cumap->curr);
3862 
3863  if (cumap->flag & CUMA_DO_CLIP) {
3864  if (cumap->curr.ymin - d < cumap->clipr.ymin) {
3865  d1 = cumap->curr.ymin - cumap->clipr.ymin;
3866  }
3867  }
3868  cumap->curr.ymin -= d1;
3869 
3870  d1 = d;
3871  if (cumap->flag & CUMA_DO_CLIP) {
3872  if (cumap->curr.ymax + d > cumap->clipr.ymax) {
3873  d1 = -cumap->curr.ymax + cumap->clipr.ymax;
3874  }
3875  }
3876  cumap->curr.ymax += d1;
3877  }
3878 
3880 }
3881 
3882 static void curvemap_buttons_setclip(bContext *UNUSED(C), void *cumap_v, void *UNUSED(arg))
3883 {
3884  CurveMapping *cumap = cumap_v;
3885 
3886  BKE_curvemapping_changed(cumap, false);
3887 }
3888 
3889 static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v)
3890 {
3891  CurveMapping *cumap = cumap_v;
3892 
3893  BKE_curvemap_remove(cumap->cm + cumap->cur, SELECT);
3894  BKE_curvemapping_changed(cumap, false);
3895 
3896  rna_update_cb(C, cb_v, NULL);
3897 }
3898 
3899 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
3900 static uiBlock *curvemap_clipping_func(bContext *C, ARegion *region, void *cumap_v)
3901 {
3902  CurveMapping *cumap = cumap_v;
3903  uiBut *bt;
3904  const float width = 8 * UI_UNIT_X;
3905 
3906  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
3909 
3910  bt = uiDefButBitI(block,
3912  CUMA_DO_CLIP,
3913  1,
3914  IFACE_("Use Clipping"),
3915  0,
3916  5 * UI_UNIT_Y,
3917  width,
3918  UI_UNIT_Y,
3919  &cumap->flag,
3920  0.0,
3921  0.0,
3922  10,
3923  0,
3924  "");
3926 
3927  UI_block_align_begin(block);
3928  bt = uiDefButF(block,
3929  UI_BTYPE_NUM,
3930  0,
3931  IFACE_("Min X:"),
3932  0,
3933  4 * UI_UNIT_Y,
3934  width,
3935  UI_UNIT_Y,
3936  &cumap->clipr.xmin,
3937  -100.0,
3938  cumap->clipr.xmax,
3939  0,
3940  0,
3941  "");
3944  bt = uiDefButF(block,
3945  UI_BTYPE_NUM,
3946  0,
3947  IFACE_("Min Y:"),
3948  0,
3949  3 * UI_UNIT_Y,
3950  width,
3951  UI_UNIT_Y,
3952  &cumap->clipr.ymin,
3953  -100.0,
3954  cumap->clipr.ymax,
3955  0,
3956  0,
3957  "");
3960  bt = uiDefButF(block,
3961  UI_BTYPE_NUM,
3962  0,
3963  IFACE_("Max X:"),
3964  0,
3965  2 * UI_UNIT_Y,
3966  width,
3967  UI_UNIT_Y,
3968  &cumap->clipr.xmax,
3969  cumap->clipr.xmin,
3970  100.0,
3971  0,
3972  0,
3973  "");
3976  bt = uiDefButF(block,
3977  UI_BTYPE_NUM,
3978  0,
3979  IFACE_("Max Y:"),
3980  0,
3981  UI_UNIT_Y,
3982  width,
3983  UI_UNIT_Y,
3984  &cumap->clipr.ymax,
3985  cumap->clipr.ymin,
3986  100.0,
3987  0,
3988  0,
3989  "");
3992 
3993  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
3995 
3996  return block;
3997 }
3998 
3999 /* only for BKE_curvemap_tools_dofunc */
4000 enum {
4009 };
4010 
4011 static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
4012 {
4013  CurveMapping *cumap = cumap_v;
4014  CurveMap *cuma = cumap->cm + cumap->cur;
4015 
4016  switch (event) {
4018  case UICURVE_FUNC_RESET_POS: /* reset */
4019  BKE_curvemap_reset(cuma,
4020  &cumap->clipr,
4021  cumap->preset,
4024  BKE_curvemapping_changed(cumap, false);
4025  break;
4028  break;
4029  case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */
4031  BKE_curvemapping_changed(cumap, false);
4032  break;
4033  case UICURVE_FUNC_HANDLE_AUTO: /* set auto */
4035  BKE_curvemapping_changed(cumap, false);
4036  break;
4037  case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
4039  BKE_curvemapping_changed(cumap, false);
4040  break;
4041  case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
4042  cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
4043  BKE_curvemapping_changed(cumap, false);
4044  break;
4045  case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */
4046  cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
4047  BKE_curvemapping_changed(cumap, false);
4048  break;
4049  }
4050  ED_undo_push(C, "CurveMap tools");
4052 }
4053 
4055  bContext *C, ARegion *region, CurveMapping *cumap, bool show_extend, int reset_mode)
4056 {
4057  short yco = 0;
4058  const short menuwidth = 10 * UI_UNIT_X;
4059 
4060  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
4062 
4063  {
4064  uiDefIconTextBut(block,
4066  1,
4067  ICON_BLANK1,
4068  IFACE_("Reset View"),
4069  0,
4070  yco -= UI_UNIT_Y,
4071  menuwidth,
4072  UI_UNIT_Y,
4073  NULL,
4074  0.0,
4075  0.0,
4076  0,
4078  "");
4079  uiDefIconTextBut(block,
4081  1,
4082  ICON_BLANK1,
4083  IFACE_("Vector Handle"),
4084  0,
4085  yco -= UI_UNIT_Y,
4086  menuwidth,
4087  UI_UNIT_Y,
4088  NULL,
4089  0.0,
4090  0.0,
4091  0,
4093  "");
4094  uiDefIconTextBut(block,
4096  1,
4097  ICON_BLANK1,
4098  IFACE_("Auto Handle"),
4099  0,
4100  yco -= UI_UNIT_Y,
4101  menuwidth,
4102  UI_UNIT_Y,
4103  NULL,
4104  0.0,
4105  0.0,
4106  0,
4108  "");
4109  uiDefIconTextBut(block,
4111  1,
4112  ICON_BLANK1,
4113  IFACE_("Auto Clamped Handle"),
4114  0,
4115  yco -= UI_UNIT_Y,
4116  menuwidth,
4117  UI_UNIT_Y,
4118  NULL,
4119  0.0,
4120  0.0,
4121  0,
4123  "");
4124  }
4125 
4126  if (show_extend) {
4127  uiDefIconTextBut(block,
4129  1,
4130  ICON_BLANK1,
4131  IFACE_("Extend Horizontal"),
4132  0,
4133  yco -= UI_UNIT_Y,
4134  menuwidth,
4135  UI_UNIT_Y,
4136  NULL,
4137  0.0,
4138  0.0,
4139  0,
4141  "");
4142  uiDefIconTextBut(block,
4144  1,
4145  ICON_BLANK1,
4146  IFACE_("Extend Extrapolated"),
4147  0,
4148  yco -= UI_UNIT_Y,
4149  menuwidth,
4150  UI_UNIT_Y,
4151  NULL,
4152  0.0,
4153  0.0,
4154  0,
4156  "");
4157  }
4158 
4159  {
4160  uiDefIconTextBut(block,
4162  1,
4163  ICON_BLANK1,
4164  IFACE_("Reset Curve"),
4165  0,
4166  yco -= UI_UNIT_Y,
4167  menuwidth,
4168  UI_UNIT_Y,
4169  NULL,
4170  0.0,
4171  0.0,
4172  0,
4173  reset_mode,
4174  "");
4175  }
4176 
4178  UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
4179 
4180  return block;
4181 }
4182 
4183 static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *region, void *cumap_v)
4184 {
4185  return curvemap_tools_func(C, region, cumap_v, true, UICURVE_FUNC_RESET_POS);
4186 }
4187 
4188 static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v)
4189 {
4190  return curvemap_tools_func(C, region, cumap_v, true, UICURVE_FUNC_RESET_NEG);
4191 }
4192 
4193 static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *region, void *cumap_v)
4194 {
4195  return curvemap_tools_func(C, region, cumap_v, false, UICURVE_FUNC_RESET_NEG);
4196 }
4197 
4199 {
4200  return curvemap_tools_func(C, region, cumap_v, false, UICURVE_FUNC_RESET_POS);
4201 }
4202 
4203 static void curvemap_buttons_redraw(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
4204 {
4206 }
4207 
4208 static void curvemap_buttons_update(bContext *C, void *arg1_v, void *cumap_v)
4209 {
4210  CurveMapping *cumap = cumap_v;
4211  BKE_curvemapping_changed(cumap, true);
4212  rna_update_cb(C, arg1_v, NULL);
4213 }
4214 
4215 static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
4216 {
4217  CurveMapping *cumap = cumap_v;
4218  cumap->preset = CURVE_PRESET_LINE;
4219  for (int a = 0; a < CM_TOT; a++) {
4220  BKE_curvemap_reset(cumap->cm + a, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
4221  }
4222 
4223  cumap->black[0] = cumap->black[1] = cumap->black[2] = 0.0f;
4224  cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
4226 
4227  BKE_curvemapping_changed(cumap, false);
4228 
4229  rna_update_cb(C, cb_v, NULL);
4230 }
4231 
4237 static void curvemap_buttons_layout(uiLayout *layout,
4238  PointerRNA *ptr,
4239  char labeltype,
4240  bool levels,
4241  bool brush,
4242  bool neg_slope,
4243  bool tone,
4244  RNAUpdateCb *cb)
4245 {
4246  CurveMapping *cumap = ptr->data;
4247  CurveMap *cm = &cumap->cm[cumap->cur];
4248  uiBut *bt;
4249  const float dx = UI_UNIT_X;
4250  int bg = -1;
4251 
4252  uiBlock *block = uiLayoutGetBlock(layout);
4253 
4254  if (tone) {
4255  uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
4256  uiItemR(uiLayoutRow(split, false), ptr, "tone", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
4257  }
4258 
4259  /* curve chooser */
4260  uiLayout *row = uiLayoutRow(layout, false);
4261 
4262  if (labeltype == 'v') {
4263  /* vector */
4264  uiLayout *sub = uiLayoutRow(row, true);
4266 
4267  if (cumap->cm[0].curve) {
4268  bt = uiDefButI(
4269  block, UI_BTYPE_ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
4271  }
4272  if (cumap->cm[1].curve) {
4273  bt = uiDefButI(
4274  block, UI_BTYPE_ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
4276  }
4277  if (cumap->cm[2].curve) {
4278  bt = uiDefButI(
4279  block, UI_BTYPE_ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
4281  }
4282  }
4283  else if (labeltype == 'c') {
4284  /* color */
4285  uiLayout *sub = uiLayoutRow(row, true);
4287 
4288  if (cumap->cm[3].curve) {
4289  bt = uiDefButI(
4290  block, UI_BTYPE_ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
4292  }
4293  if (cumap->cm[0].curve) {
4294  bt = uiDefButI(
4295  block, UI_BTYPE_ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
4297  }
4298  if (cumap->cm[1].curve) {
4299  bt = uiDefButI(
4300  block, UI_BTYPE_ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
4302  }
4303  if (cumap->cm[2].curve) {
4304  bt = uiDefButI(
4305  block, UI_BTYPE_ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
4307  }
4308  }
4309  else if (labeltype == 'h') {
4310  /* HSV */
4311  uiLayout *sub = uiLayoutRow(row, true);
4313 
4314  if (cumap->cm[0].curve) {
4315  bt = uiDefButI(
4316  block, UI_BTYPE_ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
4318  }
4319  if (cumap->cm[1].curve) {
4320  bt = uiDefButI(
4321  block, UI_BTYPE_ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
4323  }
4324  if (cumap->cm[2].curve) {
4325  bt = uiDefButI(
4326  block, UI_BTYPE_ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
4328  }
4329  }
4330  else {
4332  }
4333 
4334  if (labeltype == 'h') {
4335  bg = UI_GRAD_H;
4336  }
4337 
4338  /* operation buttons */
4339  uiLayoutRow(row, true);
4340 
4342 
4343  bt = uiDefIconBut(block,
4344  UI_BTYPE_BUT,
4345  0,
4346  ICON_ZOOM_IN,
4347  0,
4348  0,
4349  dx,
4350  dx,
4351  NULL,
4352  0.0,
4353  0.0,
4354  0.0,
4355  0.0,
4356  TIP_("Zoom in"));
4358 
4359  bt = uiDefIconBut(block,
4360  UI_BTYPE_BUT,
4361  0,
4362  ICON_ZOOM_OUT,
4363  0,
4364  0,
4365  dx,
4366  dx,
4367  NULL,
4368  0.0,
4369  0.0,
4370  0.0,
4371  0.0,
4372  TIP_("Zoom out"));
4374 
4375  if (brush && neg_slope) {
4376  bt = uiDefIconBlockBut(block,
4378  cumap,
4379  0,
4380  ICON_DOWNARROW_HLT,
4381  0,
4382  0,
4383  dx,
4384  dx,
4385  TIP_("Tools"));
4386  }
4387  else if (brush) {
4388  bt = uiDefIconBlockBut(block,
4390  cumap,
4391  0,
4392  ICON_DOWNARROW_HLT,
4393  0,
4394  0,
4395  dx,
4396  dx,
4397  TIP_("Tools"));
4398  }
4399  else if (neg_slope) {
4400  bt = uiDefIconBlockBut(block,
4402  cumap,
4403  0,
4404  ICON_DOWNARROW_HLT,
4405  0,
4406  0,
4407  dx,
4408  dx,
4409  TIP_("Tools"));
4410  }
4411  else {
4412  bt = uiDefIconBlockBut(block,
4414  cumap,
4415  0,
4416  ICON_DOWNARROW_HLT,
4417  0,
4418  0,
4419  dx,
4420  dx,
4421  TIP_("Tools"));
4422  }
4423 
4425 
4426  const int icon = (cumap->flag & CUMA_DO_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
4427  bt = uiDefIconBlockBut(
4428  block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options"));
4430 
4431  bt = uiDefIconBut(block,
4432  UI_BTYPE_BUT,
4433  0,
4434  ICON_X,
4435  0,
4436  0,
4437  dx,
4438  dx,
4439  NULL,
4440  0.0,
4441  0.0,
4442  0.0,
4443  0.0,
4444  TIP_("Delete points"));
4446 
4448 
4450 
4451  /* curve itself */
4452  const int size = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
4453  row = uiLayoutRow(layout, false);
4455  block, UI_BTYPE_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, 0, 0, "");
4456  curve_but->gradient_type = bg;
4457 
4458  /* sliders for selected point */
4459  CurveMapPoint *cmp = NULL;
4460  for (int i = 0; i < cm->totpoint; i++) {
4461  if (cm->curve[i].flag & CUMA_SELECT) {
4462  cmp = &cm->curve[i];
4463  break;
4464  }
4465  }
4466 
4467  if (cmp) {
4468  rctf bounds;
4469  if (cumap->flag & CUMA_DO_CLIP) {
4470  bounds = cumap->clipr;
4471  }
4472  else {
4473  bounds.xmin = bounds.ymin = -1000.0;
4474  bounds.xmax = bounds.ymax = 1000.0;
4475  }
4476 
4477  uiLayoutRow(layout, true);
4479  bt = uiDefButF(block,
4480  UI_BTYPE_NUM,
4481  0,
4482  "X",
4483  0,
4484  2 * UI_UNIT_Y,
4485  UI_UNIT_X * 10,
4486  UI_UNIT_Y,
4487  &cmp->x,
4488  bounds.xmin,
4489  bounds.xmax,
4490  0,
4491  0,
4492  "");
4495  bt = uiDefButF(block,
4496  UI_BTYPE_NUM,
4497  0,
4498  "Y",
4499  0,
4500  1 * UI_UNIT_Y,
4501  UI_UNIT_X * 10,
4502  UI_UNIT_Y,
4503  &cmp->y,
4504  bounds.ymin,
4505  bounds.ymax,
4506  0,
4507  0,
4508  "");
4511  }
4512 
4513  /* black/white levels */
4514  if (levels) {
4515  uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
4516  uiItemR(uiLayoutColumn(split, false), ptr, "black_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
4517  uiItemR(uiLayoutColumn(split, false), ptr, "white_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
4518 
4519  uiLayoutRow(layout, false);
4520  bt = uiDefBut(block,
4521  UI_BTYPE_BUT,
4522  0,
4523  IFACE_("Reset"),
4524  0,
4525  0,
4526  UI_UNIT_X * 10,
4527  UI_UNIT_Y,
4528  NULL,
4529  0.0f,
4530  0.0f,
4531  0,
4532  0,
4533  TIP_("Reset Black/White point and curves"));
4535  }
4536 
4537  UI_block_funcN_set(block, NULL, NULL, NULL);
4538 }
4539 
4541  PointerRNA *ptr,
4542  const char *propname,
4543  int type,
4544  bool levels,
4545  bool brush,
4546  bool neg_slope,
4547  bool tone)
4548 {
4549  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
4550  uiBlock *block = uiLayoutGetBlock(layout);
4551 
4552  if (!prop) {
4553  RNA_warning("curve property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
4554  return;
4555  }
4556 
4557  if (RNA_property_type(prop) != PROP_POINTER) {
4558  RNA_warning("curve is not a pointer: %s.%s", RNA_struct_identifier(ptr->type), propname);
4559  return;
4560  }
4561 
4562  PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
4563  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveMapping)) {
4564  return;
4565  }
4566 
4567  RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
4568  cb->ptr = *ptr;
4569  cb->prop = prop;
4570 
4571  ID *id = cptr.owner_id;
4573 
4574  curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb);
4575 
4576  UI_block_lock_clear(block);
4577 
4578  MEM_freeN(cb);
4579 }
4580 
4583 /* -------------------------------------------------------------------- */
4587 static void CurveProfile_presets_dofunc(bContext *C, void *profile_v, int event)
4588 {
4589  CurveProfile *profile = profile_v;
4590 
4591  profile->preset = event;
4592  BKE_curveprofile_reset(profile);
4594 
4595  ED_undo_push(C, "CurveProfile tools");
4597 }
4598 
4600 {
4601  short yco = 0;
4602 
4603  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
4605 
4606  uiDefIconTextBut(block,
4608  1,
4609  ICON_BLANK1,
4610  IFACE_("Default"),
4611  0,
4612  yco -= UI_UNIT_Y,
4613  0,
4614  UI_UNIT_Y,
4615  NULL,
4616  0.0,
4617  0.0,
4618  0,
4620  "");
4621  uiDefIconTextBut(block,
4623  1,
4624  ICON_BLANK1,
4625  IFACE_("Support Loops"),
4626  0,
4627  yco -= UI_UNIT_Y,
4628  0,
4629  UI_UNIT_Y,
4630  NULL,
4631  0.0,
4632  0.0,
4633  0,
4635  "");
4636  uiDefIconTextBut(block,
4638  1,
4639  ICON_BLANK1,
4640  IFACE_("Cornice Molding"),
4641  0,
4642  yco -= UI_UNIT_Y,
4643  0,
4644  UI_UNIT_Y,
4645  NULL,
4646  0.0,
4647  0.0,
4648  0,
4650  "");
4651  uiDefIconTextBut(block,
4653  1,
4654  ICON_BLANK1,
4655  IFACE_("Crown Molding"),
4656  0,
4657  yco -= UI_UNIT_Y,
4658  0,
4659  UI_UNIT_Y,
4660  NULL,
4661  0.0,
4662  0.0,
4663  0,
4665  "");
4666  uiDefIconTextBut(block,
4668  1,
4669  ICON_BLANK1,
4670  IFACE_("Steps"),
4671  0,
4672  yco -= UI_UNIT_Y,
4673  0,
4674  UI_UNIT_Y,
4675  NULL,
4676  0.0,
4677  0.0,
4678  0,
4680  "");
4681 
4683  UI_block_bounds_set_text(block, (int)(3.0f * UI_UNIT_X));
4684 
4685  return block;
4686 }
4687 
4688 static uiBlock *CurveProfile_buttons_presets(bContext *C, ARegion *region, void *profile_v)
4689 {
4690  return CurveProfile_presets_func(C, region, (CurveProfile *)profile_v);
4691 }
4692 
4693 /* Only for CurveProfile tools block */
4694 enum {
4697 };
4698 
4699 static void CurveProfile_tools_dofunc(bContext *C, void *profile_v, int event)
4700 {
4701  CurveProfile *profile = profile_v;
4702 
4703  switch (event) {
4704  case UIPROFILE_FUNC_RESET: /* reset */
4705  BKE_curveprofile_reset(profile);
4707  break;
4708  case UIPROFILE_FUNC_RESET_VIEW: /* reset view to clipping rect */
4709  BKE_curveprofile_reset_view(profile);
4710  break;
4711  }
4712  ED_undo_push(C, "CurveProfile tools");
4714 }
4715 
4717 {
4718  short yco = 0;
4719 
4720  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
4722 
4723  uiDefIconTextBut(block,
4725  1,
4726  ICON_BLANK1,
4727  IFACE_("Reset View"),
4728  0,
4729  yco -= UI_UNIT_Y,
4730  0,
4731  UI_UNIT_Y,
4732  NULL,
4733  0.0,
4734  0.0,
4735  0,
4737  "");
4738  uiDefIconTextBut(block,
4740  1,
4741  ICON_BLANK1,
4742  IFACE_("Reset Curve"),
4743  0,
4744  yco -= UI_UNIT_Y,
4745  0,
4746  UI_UNIT_Y,
4747  NULL,
4748  0.0,
4749  0.0,
4750  0,
4752  "");
4753 
4755  UI_block_bounds_set_text(block, (int)(3.0f * UI_UNIT_X));
4756 
4757  return block;
4758 }
4759 
4760 static uiBlock *CurveProfile_buttons_tools(bContext *C, ARegion *region, void *profile_v)
4761 {
4762  return CurveProfile_tools_func(C, region, (CurveProfile *)profile_v);
4763 }
4764 
4765 static void CurveProfile_buttons_zoom_in(bContext *C, void *profile_v, void *UNUSED(arg))
4766 {
4767  CurveProfile *profile = profile_v;
4768 
4769  /* Allow a 20x zoom. */
4770  if (BLI_rctf_size_x(&profile->view_rect) > 0.04f * BLI_rctf_size_x(&profile->clip_rect)) {
4771  const float dx = 0.1154f * BLI_rctf_size_x(&profile->view_rect);
4772  profile->view_rect.xmin += dx;
4773  profile->view_rect.xmax -= dx;
4774  const float dy = 0.1154f * BLI_rctf_size_y(&profile->view_rect);
4775  profile->view_rect.ymin += dy;
4776  profile->view_rect.ymax -= dy;
4777  }
4778 
4780 }
4781 
4782 static void CurveProfile_buttons_zoom_out(bContext *C, void *profile_v, void *UNUSED(arg))
4783 {
4784  CurveProfile *profile = profile_v;
4785 
4786  /* Allow 20 times zoom, but don't view outside clip */
4787  if (BLI_rctf_size_x(&profile->view_rect) < 20.0f * BLI_rctf_size_x(&profile->clip_rect)) {
4788  float d = 0.15f * BLI_rctf_size_x(&profile->view_rect);
4789  float d1 = d;
4790 
4791  if (profile->flag & PROF_USE_CLIP) {
4792  if (profile->view_rect.xmin - d < profile->clip_rect.xmin) {
4793  d1 = profile->view_rect.xmin - profile->clip_rect.xmin;
4794  }
4795  }
4796  profile->view_rect.xmin -= d1;
4797 
4798  d1 = d;
4799  if (profile->flag & PROF_USE_CLIP) {
4800  if (profile->view_rect.xmax + d > profile->clip_rect.xmax) {
4801  d1 = -profile->view_rect.xmax + profile->clip_rect.xmax;
4802  }
4803  }
4804  profile->view_rect.xmax += d1;
4805 
4806  d = d1 = 0.15f * BLI_rctf_size_y(&profile->view_rect);
4807 
4808  if (profile->flag & PROF_USE_CLIP) {
4809  if (profile->view_rect.ymin - d < profile->clip_rect.ymin) {
4810  d1 = profile->view_rect.ymin - profile->clip_rect.ymin;
4811  }
4812  }
4813  profile->view_rect.ymin -= d1;
4814 
4815  d1 = d;
4816  if (profile->flag & PROF_USE_CLIP) {
4817  if (profile->view_rect.ymax + d > profile->clip_rect.ymax) {
4818  d1 = -profile->view_rect.ymax + profile->clip_rect.ymax;
4819  }
4820  }
4821  profile->view_rect.ymax += d1;
4822  }
4823 
4825 }
4826 
4827 static void CurveProfile_clipping_toggle(bContext *C, void *cb_v, void *profile_v)
4828 {
4829  CurveProfile *profile = profile_v;
4830 
4831  profile->flag ^= PROF_USE_CLIP;
4832 
4834  rna_update_cb(C, cb_v, NULL);
4835 }
4836 
4837 static void CurveProfile_buttons_reverse(bContext *C, void *cb_v, void *profile_v)
4838 {
4839  CurveProfile *profile = profile_v;
4840 
4841  BKE_curveprofile_reverse(profile);
4843  rna_update_cb(C, cb_v, NULL);
4844 }
4845 
4846 static void CurveProfile_buttons_delete(bContext *C, void *cb_v, void *profile_v)
4847 {
4848  CurveProfile *profile = profile_v;
4849 
4852 
4853  rna_update_cb(C, cb_v, NULL);
4854 }
4855 
4856 static void CurveProfile_buttons_update(bContext *C, void *arg1_v, void *profile_v)
4857 {
4858  CurveProfile *profile = profile_v;
4860  rna_update_cb(C, arg1_v, NULL);
4861 }
4862 
4863 static void CurveProfile_buttons_reset(bContext *C, void *arg1_v, void *profile_v)
4864 {
4865  CurveProfile *profile = profile_v;
4866  BKE_curveprofile_reset(profile);
4868  rna_update_cb(C, arg1_v, NULL);
4869 }
4870 
4872 {
4873  CurveProfile *profile = ptr->data;
4874  uiBut *bt;
4875 
4876  uiBlock *block = uiLayoutGetBlock(layout);
4877 
4879 
4880  uiLayoutSetPropSep(layout, false);
4881 
4882  /* Preset selector */
4883  /* There is probably potential to use simpler "uiItemR" functions here, but automatic updating
4884  * after a preset is selected would be more complicated. */
4885  uiLayout *row = uiLayoutRow(layout, true);
4886  bt = uiDefBlockBut(
4887  block, CurveProfile_buttons_presets, profile, "Preset", 0, 0, UI_UNIT_X, UI_UNIT_X, "");
4889 
4890  /* Show a "re-apply" preset button when it has been changed from the preset. */
4891  if (profile->flag & PROF_DIRTY_PRESET) {
4892  /* Only for dynamic presets. */
4894  bt = uiDefIconTextBut(block,
4895  UI_BTYPE_BUT,
4896  0,
4897  ICON_NONE,
4898  "Apply Preset",
4899  0,
4900  0,
4901  UI_UNIT_X,
4902  UI_UNIT_X,
4903  NULL,
4904  0.0,
4905  0.0,
4906  0.0,
4907  0.0,
4908  "Reapply and update the preset, removing changes");
4910  }
4911  }
4912 
4913  row = uiLayoutRow(layout, false);
4914 
4915  /* (Left aligned) */
4916  uiLayout *sub = uiLayoutRow(row, true);
4918 
4919  /* Zoom in */
4920  bt = uiDefIconBut(block,
4921  UI_BTYPE_BUT,
4922  0,
4923  ICON_ZOOM_IN,
4924  0,
4925  0,
4926  UI_UNIT_X,
4927  UI_UNIT_X,
4928  NULL,
4929  0.0,
4930  0.0,
4931  0.0,
4932  0.0,
4933  TIP_("Zoom in"));
4935 
4936  /* Zoom out */
4937  bt = uiDefIconBut(block,
4938  UI_BTYPE_BUT,
4939  0,
4940  ICON_ZOOM_OUT,
4941  0,
4942  0,
4943  UI_UNIT_X,
4944  UI_UNIT_X,
4945  NULL,
4946  0.0,
4947  0.0,
4948  0.0,
4949  0.0,
4950  TIP_("Zoom out"));
4952 
4953  /* (Right aligned) */
4954  sub = uiLayoutRow(row, true);
4956 
4957  /* Reset view, reset curve */
4958  bt = uiDefIconBlockBut(
4959  block, CurveProfile_buttons_tools, profile, 0, 0, 0, 0, UI_UNIT_X, UI_UNIT_X, TIP_("Tools"));
4961 
4962  /* Flip path */
4963  bt = uiDefIconBut(block,
4964  UI_BTYPE_BUT,
4965  0,
4966  ICON_ARROW_LEFTRIGHT,
4967  0,
4968  0,
4969  UI_UNIT_X,
4970  UI_UNIT_X,
4971  NULL,
4972  0.0,
4973  0.0,
4974  0.0,
4975  0.0,
4976  TIP_("Reverse Path"));
4978 
4979  /* Clipping toggle */
4980  const int icon = (profile->flag & PROF_USE_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
4981  bt = uiDefIconBut(block,
4982  UI_BTYPE_BUT,
4983  0,
4984  icon,
4985  0,
4986  0,
4987  UI_UNIT_X,
4988  UI_UNIT_X,
4989  NULL,
4990  0.0,
4991  0.0,
4992  0.0,
4993  0.0,
4994  TIP_("Toggle Profile Clipping"));
4996 
4998 
4999  /* The path itself */
5000  int path_width = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
5001  path_width = min_ii(path_width, (int)(16.0f * UI_UNIT_X));
5002  const int path_height = path_width;
5003  uiLayoutRow(layout, false);
5004  uiDefBut(block,
5006  0,
5007  "",
5008  0,
5009  0,
5010  (short)path_width,
5011  (short)path_height,
5012  profile,
5013  0.0f,
5014  1.0f,
5015  -1,
5016  0,
5017  "");
5018 
5019  /* Position sliders for (first) selected point */
5020  int i;
5021  float *selection_x, *selection_y;
5022  bool point_last_or_first = false;
5023  CurveProfilePoint *point = NULL;
5024  for (i = 0; i < profile->path_len; i++) {
5025  if (profile->path[i].flag & PROF_SELECT) {
5026  point = &profile->path[i];
5027  selection_x = &point->x;
5028  selection_y = &point->y;
5029  break;
5030  }
5031  if (profile->path[i].flag & PROF_H1_SELECT) {
5032  point = &profile->path[i];
5033  selection_x = &point->h1_loc[0];
5034  selection_y = &point->h1_loc[1];
5035  }
5036  else if (profile->path[i].flag & PROF_H2_SELECT) {
5037  point = &profile->path[i];
5038  selection_x = &point->h2_loc[0];
5039  selection_y = &point->h2_loc[1];
5040  }
5041  }
5042  if (ELEM(i, 0, profile->path_len - 1)) {
5043  point_last_or_first = true;
5044  }
5045 
5046  /* Selected point data */
5047  rctf bounds;
5048  if (point) {
5049  if (profile->flag & PROF_USE_CLIP) {
5050  bounds = profile->clip_rect;
5051  }
5052  else {
5053  bounds.xmin = bounds.ymin = -1000.0;
5054  bounds.xmax = bounds.ymax = 1000.0;
5055  }
5056 
5057  row = uiLayoutRow(layout, true);
5058 
5059  PointerRNA point_ptr;
5060  RNA_pointer_create(ptr->owner_id, &RNA_CurveProfilePoint, point, &point_ptr);
5061  PropertyRNA *prop_handle_type = RNA_struct_find_property(&point_ptr, "handle_type_1");
5062  uiItemFullR(row,
5063  &point_ptr,
5064  prop_handle_type,
5065  RNA_NO_INDEX,
5066  0,
5068  "",
5069  ICON_NONE);
5070 
5071  /* Position */
5072  bt = uiDefButF(block,
5073  UI_BTYPE_NUM,
5074  0,
5075  "X:",
5076  0,
5077  2 * UI_UNIT_Y,
5078  UI_UNIT_X * 10,
5079  UI_UNIT_Y,
5080  selection_x,
5081  bounds.xmin,
5082  bounds.xmax,
5083  0,
5084  0,
5085  "");
5089  if (point_last_or_first) {
5091  }
5092  bt = uiDefButF(block,
5093  UI_BTYPE_NUM,
5094  0,
5095  "Y:",
5096  0,
5097  1 * UI_UNIT_Y,
5098  UI_UNIT_X * 10,
5099  UI_UNIT_Y,
5100  selection_y,
5101  bounds.ymin,
5102  bounds.ymax,
5103  0,
5104  0,
5105  "");
5109  if (point_last_or_first) {
5111  }
5112 
5113  /* Delete points */
5114  bt = uiDefIconBut(block,
5115  UI_BTYPE_BUT,
5116  0,
5117  ICON_X,
5118  0,
5119  0,
5120  UI_UNIT_X,
5121  UI_UNIT_X,
5122  NULL,
5123  0.0,
5124  0.0,
5125  0.0,
5126  0.0,
5127  TIP_("Delete points"));
5129  if (point_last_or_first) {
5131  }
5132  }
5133 
5134  uiItemR(layout, ptr, "use_sample_straight_edges", 0, NULL, ICON_NONE);
5135  uiItemR(layout, ptr, "use_sample_even_lengths", 0, NULL, ICON_NONE);
5136 
5137  UI_block_funcN_set(block, NULL, NULL, NULL);
5138 }
5139 
5144 void uiTemplateCurveProfile(uiLayout *layout, PointerRNA *ptr, const char *propname)
5145 {
5146  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5147 
5148  uiBlock *block = uiLayoutGetBlock(layout);
5149 
5150  if (!prop) {
5151  RNA_warning(
5152  "Curve Profile property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5153  return;
5154  }
5155 
5156  if (RNA_property_type(prop) != PROP_POINTER) {
5157  RNA_warning(
5158  "Curve Profile is not a pointer: %s.%s", RNA_struct_identifier(ptr->type), propname);
5159  return;
5160  }
5161 
5162  PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
5163  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveProfile)) {
5164  return;
5165  }
5166 
5167  /* Share update functionality with the CurveMapping widget template. */
5168  RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
5169  cb->ptr = *ptr;
5170  cb->prop = prop;
5171 
5172  ID *id = cptr.owner_id;
5174 
5175  CurveProfile_buttons_layout(layout, &cptr, cb);
5176 
5177  UI_block_lock_clear(block);
5178 
5179  MEM_freeN(cb);
5180 }
5181 
5184 /* -------------------------------------------------------------------- */
5188 #define WHEEL_SIZE (5 * U.widget_unit)
5189 
5190 /* This template now follows User Preference for type - name is not correct anymore... */
5192  PointerRNA *ptr,
5193  const char *propname,
5194  bool value_slider,
5195  bool lock,
5196  bool lock_luminosity,
5197  bool cubic)
5198 {
5199  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5200  uiBlock *block = uiLayoutGetBlock(layout);
5201  ColorPicker *cpicker = ui_block_colorpicker_create(block);
5202 
5203  if (!prop) {
5204  RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5205  return;
5206  }
5207 
5208  float softmin, softmax, step, precision;
5209  RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
5210 
5211  uiLayout *col = uiLayoutColumn(layout, true);
5212  uiLayout *row = uiLayoutRow(col, true);
5213 
5214  uiBut *but = NULL;
5215  uiButHSVCube *hsv_but;
5216  switch (U.color_picker_type) {
5217  case USER_CP_SQUARE_SV:
5218  case USER_CP_SQUARE_HS:
5219  case USER_CP_SQUARE_HV:
5220  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5222  0,
5223  "",
5224  0,
5225  0,
5226  WHEEL_SIZE,
5227  WHEEL_SIZE,
5228  ptr,
5229  prop,
5230  -1,
5231  0.0,
5232  0.0,
5233  0,
5234  0,
5235  "");
5236  switch (U.color_picker_type) {
5237  case USER_CP_SQUARE_SV:
5238  hsv_but->gradient_type = UI_GRAD_SV;
5239  break;
5240  case USER_CP_SQUARE_HS:
5241  hsv_but->gradient_type = UI_GRAD_HS;
5242  break;
5243  case USER_CP_SQUARE_HV:
5244  hsv_but->gradient_type = UI_GRAD_HV;
5245  break;
5246  }
5247  but = &hsv_but->but;
5248  break;
5249 
5250  /* user default */
5251  case USER_CP_CIRCLE_HSV:
5252  case USER_CP_CIRCLE_HSL:
5253  default:
5254  but = uiDefButR_prop(block,
5256  0,
5257  "",
5258  0,
5259  0,
5260  WHEEL_SIZE,
5261  WHEEL_SIZE,
5262  ptr,
5263  prop,
5264  -1,
5265  0.0,
5266  0.0,
5267  0,
5268  0,
5269  "");
5270  break;
5271  }
5272 
5273  but->custom_data = cpicker;
5274 
5275  cpicker->use_color_lock = lock;
5276  cpicker->use_color_cubic = cubic;
5277  cpicker->use_luminosity_lock = lock_luminosity;
5278 
5279  if (lock_luminosity) {
5280  float color[4]; /* in case of alpha */
5281  RNA_property_float_get_array(ptr, prop, color);
5282  but->a2 = len_v3(color);
5283  cpicker->luminosity_lock_value = len_v3(color);
5284  }
5285 
5286  if (value_slider) {
5287  switch (U.color_picker_type) {
5288  case USER_CP_CIRCLE_HSL:
5289  uiItemS(row);
5290  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5292  0,
5293  "",
5294  WHEEL_SIZE + 6,
5295  0,
5296  14 * UI_DPI_FAC,
5297  WHEEL_SIZE,
5298  ptr,
5299  prop,
5300  -1,
5301  softmin,
5302  softmax,
5303  0,
5304  0,
5305  "");
5306  hsv_but->gradient_type = UI_GRAD_L_ALT;
5307  break;
5308  case USER_CP_SQUARE_SV:
5309  uiItemS(col);
5310  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5312  0,
5313  "",
5314  0,
5315  4,
5316  WHEEL_SIZE,
5317  18 * UI_DPI_FAC,
5318  ptr,
5319  prop,
5320  -1,
5321  softmin,
5322  softmax,
5323  0,
5324  0,
5325  "");
5326  hsv_but->gradient_type = UI_GRAD_SV + 3;
5327  break;
5328  case USER_CP_SQUARE_HS:
5329  uiItemS(col);
5330  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5332  0,
5333  "",
5334  0,
5335  4,
5336  WHEEL_SIZE,
5337  18 * UI_DPI_FAC,
5338  ptr,
5339  prop,
5340  -1,
5341  softmin,
5342  softmax,
5343  0,
5344  0,
5345  "");
5346  hsv_but->gradient_type = UI_GRAD_HS + 3;
5347  break;
5348  case USER_CP_SQUARE_HV:
5349  uiItemS(col);
5350  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5352  0,
5353  "",
5354  0,
5355  4,
5356  WHEEL_SIZE,
5357  18 * UI_DPI_FAC,
5358  ptr,
5359  prop,
5360  -1,
5361  softmin,
5362  softmax,
5363  0,
5364  0,
5365  "");
5366  hsv_but->gradient_type = UI_GRAD_HV + 3;
5367  break;
5368 
5369  /* user default */
5370  case USER_CP_CIRCLE_HSV:
5371  default:
5372  uiItemS(row);
5373  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5375  0,
5376  "",
5377  WHEEL_SIZE + 6,
5378  0,
5379  14 * UI_DPI_FAC,
5380  WHEEL_SIZE,
5381  ptr,
5382  prop,
5383  -1,
5384  softmin,
5385  softmax,
5386  0,
5387  0,
5388  "");
5389  hsv_but->gradient_type = UI_GRAD_V_ALT;
5390  break;
5391  }
5392 
5393  hsv_but->but.custom_data = cpicker;
5394  }
5395 }
5396 
5397 static void ui_template_palette_menu(bContext *UNUSED(C), uiLayout *layout, void *UNUSED(but_p))
5398 {
5399  uiLayout *row;
5400 
5401  uiItemL(layout, IFACE_("Sort By:"), ICON_NONE);
5402  row = uiLayoutRow(layout, false);
5403  uiItemEnumO_value(row, IFACE_("Hue"), ICON_NONE, "PALETTE_OT_sort", "type", 1);
5404  row = uiLayoutRow(layout, false);
5405  uiItemEnumO_value(row, IFACE_("Saturation"), ICON_NONE, "PALETTE_OT_sort", "type", 2);
5406  row = uiLayoutRow(layout, false);
5407  uiItemEnumO_value(row, IFACE_("Value"), ICON_NONE, "PALETTE_OT_sort", "type", 3);
5408  row = uiLayoutRow(layout, false);
5409  uiItemEnumO_value(row, IFACE_("Luminance"), ICON_NONE, "PALETTE_OT_sort", "type", 4);
5410 }
5411 
5413  PointerRNA *ptr,
5414  const char *propname,
5415  bool UNUSED(colors))
5416 {
5417  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5418  uiBut *but = NULL;
5419 
5420  const int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1);
5421 
5422  if (!prop) {
5423  RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5424  return;
5425  }
5426 
5427  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
5428  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Palette)) {
5429  return;
5430  }
5431 
5432  uiBlock *block = uiLayoutGetBlock(layout);
5433 
5434  Palette *palette = cptr.data;
5435 
5436  uiLayout *col = uiLayoutColumn(layout, true);
5437  uiLayoutRow(col, true);
5438  uiDefIconButO(block,
5439  UI_BTYPE_BUT,
5440  "PALETTE_OT_color_add",
5442  ICON_ADD,
5443  0,
5444  0,
5445  UI_UNIT_X,
5446  UI_UNIT_Y,
5447  NULL);
5448  uiDefIconButO(block,
5449  UI_BTYPE_BUT,
5450  "PALETTE_OT_color_delete",
5452  ICON_REMOVE,
5453  0,
5454  0,
5455  UI_UNIT_X,
5456  UI_UNIT_Y,
5457  NULL);
5458  if (palette->colors.first != NULL) {
5459  but = uiDefIconButO(block,
5460  UI_BTYPE_BUT,
5461  "PALETTE_OT_color_move",
5463  ICON_TRIA_UP,
5464  0,
5465  0,
5466  UI_UNIT_X,
5467  UI_UNIT_Y,
5468  NULL);
5470  RNA_enum_set(but->opptr, "type", -1);
5471 
5472  but = uiDefIconButO(block,
5473  UI_BTYPE_BUT,
5474  "PALETTE_OT_color_move",
5476  ICON_TRIA_DOWN,
5477  0,
5478  0,
5479  UI_UNIT_X,
5480  UI_UNIT_Y,
5481  NULL);
5483  RNA_enum_set(but->opptr, "type", 1);
5484 
5485  /* Menu. */
5487  block, ui_template_palette_menu, NULL, ICON_SORTSIZE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
5488  }
5489 
5490  col = uiLayoutColumn(layout, true);
5491  uiLayoutRow(col, true);
5492 
5493  int row_cols = 0, col_id = 0;
5494  LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) {
5495  if (row_cols >= cols_per_row) {
5496  uiLayoutRow(col, true);
5497  row_cols = 0;
5498  }
5499 
5500  PointerRNA color_ptr;
5501  RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr);
5502  uiButColor *color_but = (uiButColor *)uiDefButR(block,
5504  0,
5505  "",
5506  0,
5507  0,
5508  UI_UNIT_X,
5509  UI_UNIT_Y,
5510  &color_ptr,
5511  "color",
5512  -1,
5513  0.0,
5514  1.0,
5515  0.0,
5516  0.0,
5517  "");
5518  color_but->is_pallete_color = true;
5519  color_but->palette_color_index = col_id;
5520  row_cols++;
5521  col_id++;
5522  }
5523 }
5524 
5525 void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int icon)
5526 {
5527  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5528 
5529  if (!prop) {
5530  RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5531  return;
5532  }
5533 
5534  uiBlock *block = uiLayoutGetBlock(layout);
5535 
5536  uiBut *but = uiDefIconTextButO(block,
5537  UI_BTYPE_BUT,
5538  "UI_OT_eyedropper_color",
5540  icon,
5541  "",
5542  0,
5543  0,
5544  UI_UNIT_X,
5545  UI_UNIT_Y,
5547  but->rnapoin = *ptr;
5548  but->rnaprop = prop;
5549  but->rnaindex = -1;
5550 }
5551 
5554 /* -------------------------------------------------------------------- */
5558 static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
5559 {
5560  uiBut *but = arg1;
5561  const int cur = POINTER_AS_INT(arg2);
5562  wmWindow *win = CTX_wm_window(C);
5563  const int shift = win->eventstate->shift;
5564 
5565  if (!shift) {
5566  const int tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
5567 
5568  /* Normally clicking only selects one layer */
5569  RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, true);
5570  for (int i = 0; i < tot; i++) {
5571  if (i != cur) {
5572  RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, false);
5573  }
5574  }
5575  }
5576 
5577  /* view3d layer change should update depsgraph (invisible object changed maybe) */
5578  /* see view3d_header.c */
5579 }
5580 
5586  PointerRNA *ptr,
5587  const char *propname,
5588  PointerRNA *used_ptr,
5589  const char *used_propname,
5590  int active_layer)
5591 {
5592  const int cols_per_group = 5;
5593 
5594  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5595  if (!prop) {
5596  RNA_warning("layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5597  return;
5598  }
5599 
5600  /* the number of layers determines the way we group them
5601  * - we want 2 rows only (for now)
5602  * - The number of columns (cols) is the total number of buttons per row the 'remainder'
5603  * is added to this, as it will be ok to have first row slightly wider if need be.
5604  * - For now, only split into groups if group will have at least 5 items.
5605  */
5606  const int layers = RNA_property_array_length(ptr, prop);
5607  const int cols = (layers / 2) + (layers % 2);
5608  const int groups = ((cols / 2) < cols_per_group) ? (1) : (cols / cols_per_group);
5609 
5610  PropertyRNA *used_prop = NULL;
5611  if (used_ptr && used_propname) {
5612  used_prop = RNA_struct_find_property(used_ptr, used_propname);
5613  if (!used_prop) {
5614  RNA_warning("used layers property not found: %s.%s",
5616  used_propname);
5617  return;
5618  }
5619 
5620  if (RNA_property_array_length(used_ptr, used_prop) < layers) {
5621  used_prop = NULL;
5622  }
5623  }
5624 
5625  /* layers are laid out going across rows, with the columns being divided into groups */
5626 
5627  for (int group = 0; group < groups; group++) {
5628  uiLayout *uCol = uiLayoutColumn(layout, true);
5629 
5630  for (int row = 0; row < 2; row++) {
5631  uiLayout *uRow = uiLayoutRow(uCol, true);
5632  uiBlock *block = uiLayoutGetBlock(uRow);
5633  int layer = groups * cols_per_group * row + cols_per_group * group;
5634 
5635  /* add layers as toggle buts */
5636  for (int col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) {
5637  int icon = 0;
5638  const int butlay = 1 << layer;
5639 
5640  if (active_layer & butlay) {
5641  icon = ICON_LAYER_ACTIVE;
5642  }
5643  else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer)) {
5644  icon = ICON_LAYER_USED;
5645  }
5646 
5647  uiBut *but = uiDefAutoButR(
5648  block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
5650  but->type = UI_BTYPE_TOGGLE;
5651  }
5652  }
5653  }
5654 }
5655 
5658 /* -------------------------------------------------------------------- */
5662 static void uilist_draw_item_default(struct uiList *ui_list,
5663  struct bContext *UNUSED(C),
5664  struct uiLayout *layout,
5665  struct PointerRNA *UNUSED(dataptr),
5666  struct PointerRNA *itemptr,
5667  int icon,
5668  struct PointerRNA *UNUSED(active_dataptr),
5669  const char *UNUSED(active_propname),
5670  int UNUSED(index),
5671  int UNUSED(flt_flag))
5672 {
5673  PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type);
5674 
5675  /* Simplest one! */
5676  switch (ui_list->layout_type) {
5677  case UILST_LAYOUT_GRID:
5678  uiItemL(layout, "", icon);
5679  break;
5680  case UILST_LAYOUT_DEFAULT:
5681  case UILST_LAYOUT_COMPACT:
5682  default:
5683  if (nameprop) {
5684  uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon);
5685  }
5686  else {
5687  uiItemL(layout, "", icon);
5688  }
5689  break;
5690  }
5691 }
5692 
5693 static void uilist_draw_filter_default(struct uiList *ui_list,
5694  struct bContext *UNUSED(C),
5695  struct uiLayout *layout)
5696 {
5697  PointerRNA listptr;
5698  RNA_pointer_create(NULL, &RNA_UIList, ui_list, &listptr);
5699 
5700  uiLayout *row = uiLayoutRow(layout, false);
5701 
5702  uiLayout *subrow = uiLayoutRow(row, true);
5703  uiItemR(subrow, &listptr, "filter_name", 0, "", ICON_NONE);
5704  uiItemR(subrow,
5705  &listptr,
5706  "use_filter_invert",
5708  "",
5709  ICON_ARROW_LEFTRIGHT);
5710 
5711  if ((ui_list->filter_sort_flag & UILST_FLT_SORT_LOCK) == 0) {
5712  subrow = uiLayoutRow(row, true);
5713  uiItemR(subrow,
5714  &listptr,
5715  "use_filter_sort_alpha",
5717  "",
5718  ICON_NONE);
5719  uiItemR(subrow,
5720  &listptr,
5721  "use_filter_sort_reverse",
5723  "",
5724  (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC);
5725  }
5726 }
5727 
5728 typedef struct {
5729  char name[MAX_IDPROP_NAME];
5730  int org_idx;
5731 } StringCmp;
5732 
5733 static int cmpstringp(const void *p1, const void *p2)
5734 {
5735  /* Case-insensitive comparison. */
5736  return BLI_strcasecmp(((StringCmp *)p1)->name, ((StringCmp *)p2)->name);
5737 }
5738 
5739 static void uilist_filter_items_default(struct uiList *ui_list,
5740  struct bContext *UNUSED(C),
5741  struct PointerRNA *dataptr,
5742  const char *propname)
5743 {
5744  uiListDyn *dyn_data = ui_list->dyn_data;
5745  PropertyRNA *prop = RNA_struct_find_property(dataptr, propname);
5746 
5747  const char *filter_raw = ui_list->filter_byname;
5748  char *filter = (char *)filter_raw, filter_buff[32], *filter_dyn = NULL;
5749  const bool filter_exclude = (ui_list->filter_flag & UILST_FLT_EXCLUDE) != 0;
5750  const bool order_by_name = (ui_list->filter_sort_flag & UILST_FLT_SORT_MASK) ==
5752  const int len = RNA_property_collection_length(dataptr, prop);
5753 
5754  dyn_data->items_shown = dyn_data->items_len = len;
5755 
5756  if (len && (order_by_name || filter_raw[0])) {
5757  StringCmp *names = NULL;
5758  int order_idx = 0, i = 0;
5759 
5760  if (order_by_name) {
5761  names = MEM_callocN(sizeof(StringCmp) * len, "StringCmp");
5762  }
5763  if (filter_raw[0]) {
5764  const size_t slen = strlen(filter_raw);
5765 
5766  dyn_data->items_filter_flags = MEM_callocN(sizeof(int) * len, "items_filter_flags");
5767  dyn_data->items_shown = 0;
5768 
5769  /* Implicitly add heading/trailing wildcards if needed. */
5770  if (slen + 3 <= sizeof(filter_buff)) {
5771  filter = filter_buff;
5772  }
5773  else {
5774  filter = filter_dyn = MEM_mallocN((slen + 3) * sizeof(char), "filter_dyn");
5775  }
5776  BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 3);
5777  }
5778 
5779  RNA_PROP_BEGIN (dataptr, itemptr, prop) {
5780  bool do_order = false;
5781 
5782  char *namebuf = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL);
5783  const char *name = namebuf ? namebuf : "";
5784 
5785  if (filter[0]) {
5786  /* Case-insensitive! */
5787  if (fnmatch(filter, name, FNM_CASEFOLD) == 0) {
5788  dyn_data->items_filter_flags[i] = UILST_FLT_ITEM;
5789  if (!filter_exclude) {
5790  dyn_data->items_shown++;
5791  do_order = order_by_name;
5792  }
5793  // printf("%s: '%s' matches '%s'\n", __func__, name, filter);
5794  }
5795  else if (filter_exclude) {
5796  dyn_data->items_shown++;
5797  do_order = order_by_name;
5798  }
5799  }
5800  else {
5801  do_order = order_by_name;
5802  }
5803 
5804  if (do_order) {
5805  names[order_idx].org_idx = order_idx;
5806  BLI_strncpy(names[order_idx++].name, name, MAX_IDPROP_NAME);
5807  }
5808 
5809  /* free name */
5810  if (namebuf) {
5811  MEM_freeN(namebuf);
5812  }
5813  i++;
5814  }
5815  RNA_PROP_END;
5816 
5817  if (order_by_name) {
5818  int new_idx;
5819  /* note: order_idx equals either to ui_list->items_len if no filtering done,
5820  * or to ui_list->items_shown if filter is enabled,
5821  * or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded.
5822  * This way, we only sort items we actually intend to draw!
5823  */
5824  qsort(names, order_idx, sizeof(StringCmp), cmpstringp);
5825 
5826  dyn_data->items_filter_neworder = MEM_mallocN(sizeof(int) * order_idx,
5827  "items_filter_neworder");
5828  for (new_idx = 0; new_idx < order_idx; new_idx++) {
5829  dyn_data->items_filter_neworder[names[new_idx].org_idx] = new_idx;
5830  }
5831  }
5832 
5833  if (filter_dyn) {
5834  MEM_freeN(filter_dyn);
5835  }
5836  if (names) {
5837  MEM_freeN(names);
5838  }
5839  }
5840 }
5841 
5842 typedef struct {
5844  int org_idx;
5846 } _uilist_item;
5847 
5848 typedef struct {
5849  int visual_items; /* Visual number of items (i.e. number of items we have room to display). */
5850  int start_idx; /* Index of first item to display. */
5851  int end_idx; /* Index of last item to display + 1. */
5853 
5854 static void uilist_prepare(uiList *ui_list,
5855  int len,
5856  int activei,
5857  int rows,
5858  int maxrows,
5859  int columns,
5860  uiListLayoutdata *layoutdata)
5861 {
5862  uiListDyn *dyn_data = ui_list->dyn_data;
5863  const bool use_auto_size = (ui_list->list_grip < (rows - UI_LIST_AUTO_SIZE_THRESHOLD));
5864 
5865  /* default rows */
5866  if (rows <= 0) {
5867  rows = 5;
5868  }
5869  dyn_data->visual_height_min = rows;
5870  if (maxrows < rows) {
5871  maxrows = max_ii(rows, 5);
5872  }
5873  if (columns <= 0) {
5874  columns = 9;
5875  }
5876 
5877  int activei_row;
5878  if (columns > 1) {
5879  dyn_data->height = (int)ceil((double)len / (double)columns);
5880  activei_row = (int)floor((double)activei / (double)columns);
5881  }
5882  else {
5883  dyn_data->height = len;
5884  activei_row = activei;
5885  }
5886 
5887  if (!use_auto_size) {
5888  /* No auto-size, yet we clamp at min size! */
5889  maxrows = rows = max_ii(ui_list->list_grip, rows);
5890  }
5891  else if ((rows != maxrows) && (dyn_data->height > rows)) {
5892  /* Expand size if needed and possible. */
5893  rows = min_ii(dyn_data->height, maxrows);
5894  }
5895 
5896  /* If list length changes or list is tagged to check this,
5897  * and active is out of view, scroll to it .*/
5898  if (ui_list->list_last_len != len || ui_list->flag & UILST_SCROLL_TO_ACTIVE_ITEM) {
5899  if (activei_row < ui_list->list_scroll) {
5900  ui_list->list_scroll = activei_row;
5901  }
5902  else if (activei_row >= ui_list->list_scroll + rows) {
5903  ui_list->list_scroll = activei_row - rows + 1;
5904  }
5905  ui_list->flag &= ~UILST_SCROLL_TO_ACTIVE_ITEM;
5906  }
5907 
5908  const int max_scroll = max_ii(0, dyn_data->height - rows);
5909  CLAMP(ui_list->list_scroll, 0, max_scroll);
5910  ui_list->list_last_len = len;
5911  dyn_data->visual_height = rows;
5912  layoutdata->visual_items = rows * columns;
5913  layoutdata->start_idx = ui_list->list_scroll * columns;
5914  layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len);
5915 }
5916 
5917 static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
5918 {
5919  uiList *ui_list = arg1;
5920  uiListDyn *dyn_data = ui_list->dyn_data;
5921 
5922  /* This way we get diff in number of additional items to show (positive) or hide (negative). */
5923  const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) /
5924  (float)UI_UNIT_Y);
5925 
5926  if (diff != 0) {
5927  ui_list->list_grip += diff;
5928  dyn_data->resize_prev += diff * UI_UNIT_Y;
5929  ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
5930  }
5931 
5932  /* In case uilist is in popup, we need special refreshing */
5934 }
5935 
5936 static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname)
5937 {
5938  if (propname && propname[0] && itemptr && itemptr->data) {
5939  PropertyRNA *prop = RNA_struct_find_property(itemptr, propname);
5940 
5941  if (prop && (RNA_property_type(prop) == PROP_STRING)) {
5942  return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL);
5943  }
5944  }
5945  return NULL;
5946 }
5947 
5948 static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
5949 {
5950  char *dyn_tooltip = argN;
5951  return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
5952 }
5953 
5955  bContext *C,
5956  const char *listtype_name,
5957  const char *list_id,
5958  PointerRNA *dataptr,
5959  const char *propname,
5960  PointerRNA *active_dataptr,
5961  const char *active_propname,
5962  const char *item_dyntip_propname,
5963  int rows,
5964  int maxrows,
5965  int layout_type,
5966  int columns,
5967  bool sort_reverse,
5968  bool sort_lock)
5969 {
5970  PropertyRNA *prop = NULL, *activeprop;
5971  _uilist_item *items_ptr = NULL;
5972  uiLayout *glob = NULL, *box, *row, *col, *subrow, *sub, *overlap;
5973  uiBut *but;
5974 
5975  uiListLayoutdata layoutdata;
5976  char ui_list_id[UI_MAX_NAME_STR];
5977  char numstr[32];
5978  int rnaicon = ICON_NONE, icon = ICON_NONE;
5979  int i = 0, activei = 0;
5980  int len = 0;
5981 
5982  /* validate arguments */
5983  /* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */
5984  if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
5985  RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
5987  return;
5988  }
5989 
5990  uiBlock *block = uiLayoutGetBlock(layout);
5991 
5992  if (!active_dataptr->data) {
5993  RNA_warning("No active data");
5994  return;
5995  }
5996 
5997  if (dataptr->data) {
5998  prop = RNA_struct_find_property(dataptr, propname);
5999  if (!prop) {
6000  RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
6001  return;
6002  }
6003  }
6004 
6005  activeprop = RNA_struct_find_property(active_dataptr, active_propname);
6006  if (!activeprop) {
6007  RNA_warning(
6008  "Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
6009  return;
6010  }
6011 
6012  if (prop) {
6013  const PropertyType type = RNA_property_type(prop);
6014  if (type != PROP_COLLECTION) {
6015  RNA_warning("Expected a collection data property");
6016  return;
6017  }
6018  }
6019 
6020  const PropertyType activetype = RNA_property_type(activeprop);
6021  if (activetype != PROP_INT) {
6022  RNA_warning("Expected an integer active data property");
6023  return;
6024  }
6025 
6026  /* get icon */
6027  if (dataptr->data && prop) {
6028  StructRNA *ptype = RNA_property_pointer_type(dataptr, prop);
6029  rnaicon = RNA_struct_ui_icon(ptype);
6030  }
6031 
6032  /* get active data */
6033  activei = RNA_property_int_get(active_dataptr, activeprop);
6034 
6035  /* Find the uiList type. */
6036  uiListType *ui_list_type = WM_uilisttype_find(listtype_name, false);
6037 
6038  if (ui_list_type == NULL) {
6039  RNA_warning("List type %s not found", listtype_name);
6040  return;
6041  }
6042 
6043  uiListDrawItemFunc draw_item = ui_list_type->draw_item ? ui_list_type->draw_item :
6045  uiListDrawFilterFunc draw_filter = ui_list_type->draw_filter ? ui_list_type->draw_filter :
6047  uiListFilterItemsFunc filter_items = ui_list_type->filter_items ? ui_list_type->filter_items :
6049 
6050  /* Find or add the uiList to the current Region. */
6051  /* We tag the list id with the list type... */
6052  BLI_snprintf(
6053  ui_list_id, sizeof(ui_list_id), "%s_%s", ui_list_type->idname, list_id ? list_id : "");
6054 
6055  /* Allows to work in popups. */
6056  ARegion *region = CTX_wm_menu(C);
6057  if (region == NULL) {
6058  region = CTX_wm_region(C);
6059  }
6060  uiList *ui_list = BLI_findstring(&region->ui_lists, ui_list_id, offsetof(uiList, list_id));
6061 
6062  if (!ui_list) {
6063  ui_list = MEM_callocN(sizeof(uiList), "uiList");
6064  BLI_strncpy(ui_list->list_id, ui_list_id, sizeof(ui_list->list_id));
6065  BLI_addtail(&region->ui_lists, ui_list);
6066  ui_list->list_grip = -UI_LIST_AUTO_SIZE_THRESHOLD; /* Force auto size by default. */
6067  if (sort_reverse) {
6069  }
6070  if (sort_lock) {
6072  }
6073  }
6074 
6075  if (!ui_list->dyn_data) {
6076  ui_list->dyn_data = MEM_callocN(sizeof(uiListDyn), "uiList.dyn_data");
6077  }
6078  uiListDyn *dyn_data = ui_list->dyn_data;
6079 
6080  /* Because we can't actually pass type across save&load... */
6081  ui_list->type = ui_list_type;
6082  ui_list->layout_type = layout_type;
6083 
6084  /* Reset filtering data. */
6085  MEM_SAFE_FREE(dyn_data->items_filter_flags);
6087  dyn_data->items_len = dyn_data->items_shown = -1;
6088 
6089  /* When active item changed since last draw, scroll to it. */
6090  if (activei != ui_list->list_last_activei) {
6091  ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
6092  ui_list->list_last_activei = activei;
6093  }
6094 
6095  /* Filter list items! (not for compact layout, though) */
6096  if (dataptr->data && prop) {
6097  const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
6098  const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0;
6099  int items_shown, idx = 0;
6100 #if 0
6101  int prev_ii = -1, prev_i;
6102 #endif
6103 
6104  if (layout_type == UILST_LAYOUT_COMPACT) {
6105  dyn_data->items_len = dyn_data->items_shown = RNA_property_collection_length(dataptr, prop);
6106  }
6107  else {
6108  // printf("%s: filtering...\n", __func__);
6109  filter_items(ui_list, C, dataptr, propname);
6110  // printf("%s: filtering done.\n", __func__);
6111  }
6112 
6113  items_shown = dyn_data->items_shown;
6114  if (items_shown >= 0) {
6115  bool activei_mapping_pending = true;
6116  items_ptr = MEM_mallocN(sizeof(_uilist_item) * items_shown, __func__);
6117  // printf("%s: items shown: %d.\n", __func__, items_shown);
6118  RNA_PROP_BEGIN (dataptr, itemptr, prop) {
6119  if (!dyn_data->items_filter_flags ||
6120  ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)) {
6121  int ii;
6122  if (dyn_data->items_filter_neworder) {
6123  ii = dyn_data->items_filter_neworder[idx++];
6124  ii = order_reverse ? items_shown - ii - 1 : ii;
6125  }
6126  else {
6127  ii = order_reverse ? items_shown - ++idx : idx++;
6128  }
6129  // printf("%s: ii: %d\n", __func__, ii);
6130  items_ptr[ii].item = itemptr;
6131  items_ptr[ii].org_idx = i;
6132  items_ptr[ii].flt_flag = dyn_data->items_filter_flags ? dyn_data->items_filter_flags[i] :
6133  0;
6134 
6135  if (activei_mapping_pending && activei == i) {
6136  activei = ii;
6137  /* So that we do not map again activei! */
6138  activei_mapping_pending = false;
6139  }
6140 #if 0 /* For now, do not alter active element, even if it will be hidden... */
6141  else if (activei < i) {
6142  /* We do not want an active but invisible item!
6143  * Only exception is when all items are filtered out...
6144  */
6145  if (prev_ii >= 0) {
6146  activei = prev_ii;
6147  RNA_property_int_set(active_dataptr, activeprop, prev_i);
6148  }
6149  else {
6150  activei = ii;
6151  RNA_property_int_set(active_dataptr, activeprop, i);
6152  }
6153  }
6154  prev_i = i;
6155  prev_ii = ii;
6156 #endif
6157  }
6158  i++;
6159  }
6160  RNA_PROP_END;
6161 
6162  if (activei_mapping_pending) {
6163  /* No active item found, set to 'invalid' -1 value... */
6164  activei = -1;
6165  }
6166  }
6167  if (dyn_data->items_shown >= 0) {
6168  len = dyn_data->items_shown;
6169  }
6170  else {
6171  len = dyn_data->items_len;
6172  }
6173  }
6174 
6175  switch (layout_type) {
6176  case UILST_LAYOUT_DEFAULT:
6177  /* layout */
6178  box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
6179  glob = uiLayoutColumn(box, true);
6180  row = uiLayoutRow(glob, false);
6181  col = uiLayoutColumn(row, true);
6182 
6183  /* init numbers */
6184  uilist_prepare(ui_list, len, activei, rows, maxrows, 1, &layoutdata);
6185 
6186  if (dataptr->data && prop) {
6187  /* create list items */
6188  for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
6189  PointerRNA *itemptr = &items_ptr[i].item;
6190  void *dyntip_data;
6191  const int org_i = items_ptr[i].org_idx;
6192  const int flt_flag = items_ptr[i].flt_flag;
6193  uiBlock *subblock = uiLayoutGetBlock(col);
6194 
6195  overlap = uiLayoutOverlap(col);
6196 
6198 
6199  /* list item behind label & other buttons */
6200  sub = uiLayoutRow(overlap, false);
6201 
6202  but = uiDefButR_prop(subblock,
6204  0,
6205  "",
6206  0,
6207  0,
6208  UI_UNIT_X * 10,
6209  UI_UNIT_Y,
6210  active_dataptr,
6211  activeprop,
6212  0,
6213  0,
6214  org_i,
6215  0,
6216  0,
6217  TIP_("Double click to rename"));
6218  if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) {
6220  }
6221 
6222  sub = uiLayoutRow(overlap, false);
6223 
6224  icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
6225  if (icon == ICON_DOT) {
6226  icon = ICON_NONE;
6227  }
6228  draw_item(ui_list,
6229  C,
6230  sub,
6231  dataptr,
6232  itemptr,
6233  icon,
6234  active_dataptr,
6235  active_propname,
6236  org_i,
6237  flt_flag);
6238 
6239  /* Items should be able to set context pointers for the layout. But the list-row button
6240  * swallows events, so it needs the context storage too for handlers to see it. */
6241  but->context = uiLayoutGetContextStore(sub);
6242 
6243  /* If we are "drawing" active item, set all labels as active. */
6244  if (i == activei) {
6246  }
6247 
6249  }
6250  }
6251 
6252  /* add dummy buttons to fill space */
6253  for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
6254  uiItemL(col, "", ICON_NONE);
6255  }
6256 
6257  /* add scrollbar */
6258  if (len > layoutdata.visual_items) {
6259  col = uiLayoutColumn(row, false);
6260  uiDefButI(block,
6262  0,
6263  "",
6264  0,
6265  0,
6267  UI_UNIT_Y * dyn_data->visual_height,
6268  &ui_list->list_scroll,
6269  0,
6270  dyn_data->height - dyn_data->visual_height,
6271  dyn_data->visual_height,
6272  0,
6273  "");
6274  }
6275  break;
6276  case UILST_LAYOUT_COMPACT:
6277  row = uiLayoutRow(layout, true);
6278 
6279  if ((dataptr->data && prop) && (dyn_data->items_shown > 0) && (activei >= 0) &&
6280  (activei < dyn_data->items_shown)) {
6281  PointerRNA *itemptr = &items_ptr[activei].item;
6282  const int org_i = items_ptr[activei].org_idx;
6283 
6284  icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
6285  if (icon == ICON_DOT) {
6286  icon = ICON_NONE;
6287  }
6288  draw_item(
6289  ui_list, C, row, dataptr, itemptr, icon, active_dataptr, active_propname, org_i, 0);
6290  }
6291  /* if list is empty, add in dummy button */
6292  else {
6293  uiItemL(row, "", ICON_NONE);
6294  }
6295 
6296  /* next/prev button */
6297  BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown);
6298  but = uiDefIconTextButR_prop(block,
6299  UI_BTYPE_NUM,
6300  0,
6301  0,
6302  numstr,
6303  0,
6304  0,
6305  UI_UNIT_X * 5,
6306  UI_UNIT_Y,
6307  active_dataptr,
6308  activeprop,
6309  0,
6310  0,
6311  0,
6312  0,
6313  0,
6314  "");
6315  if (dyn_data->items_shown == 0) {
6317  }
6318  break;
6319  case UILST_LAYOUT_GRID:
6320  box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
6321  glob = uiLayoutColumn(box, true);
6322  row = uiLayoutRow(glob, false);
6323  col = uiLayoutColumn(row, true);
6324  subrow = NULL; /* Quite gcc warning! */
6325 
6326  uilist_prepare(ui_list, len, activei, rows, maxrows, columns, &layoutdata);
6327 
6328  if (dataptr->data && prop) {
6329  /* create list items */
6330  for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
6331  PointerRNA *itemptr = &items_ptr[i].item;
6332  const int org_i = items_ptr[i].org_idx;
6333  const int flt_flag = items_ptr[i].flt_flag;
6334 
6335  /* create button */
6336  if (!(i % columns)) {
6337  subrow = uiLayoutRow(col, false);
6338  }
6339 
6340  uiBlock *subblock = uiLayoutGetBlock(subrow);
6341  overlap = uiLayoutOverlap(subrow);
6342 
6344 
6345  /* list item behind label & other buttons */
6346  sub = uiLayoutRow(overlap, false);
6347 
6348  but = uiDefButR_prop(subblock,
6350  0,
6351  "",
6352  0,
6353  0,
6354  UI_UNIT_X * 10,
6355  UI_UNIT_Y,
6356  active_dataptr,
6357  activeprop,
6358  0,
6359  0,
6360  org_i,
6361  0,
6362  0,
6363  NULL);
6365 
6366  sub = uiLayoutRow(overlap, false);
6367 
6368  icon = UI_icon_from_rnaptr(C, itemptr, rnaicon, false);
6369  draw_item(ui_list,
6370  C,
6371  sub,
6372  dataptr,
6373  itemptr,
6374  icon,
6375  active_dataptr,
6376  active_propname,
6377  org_i,
6378  flt_flag);
6379 
6380  /* If we are "drawing" active item, set all labels as active. */
6381  if (i == activei) {
6383  }
6384 
6386  }
6387  }
6388 
6389  /* add dummy buttons to fill space */
6390  for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
6391  if (!(i % columns)) {
6392  subrow = uiLayoutRow(col, false);
6393  }
6394  uiItemL(subrow, "", ICON_NONE);
6395  }
6396 
6397  /* add scrollbar */
6398  if (len > layoutdata.visual_items) {
6399  /* col = */ uiLayoutColumn(row, false);
6400  uiDefButI(block,
6402  0,
6403  "",
6404  0,
6405  0,
6407  UI_UNIT_Y * dyn_data->visual_height,
6408  &ui_list->list_scroll,
6409  0,
6410  dyn_data->height - dyn_data->visual_height,
6411  dyn_data->visual_height,
6412  0,
6413  "");
6414  }
6415  break;
6416  }
6417 
6418  if (glob) {
6419  /* About #UI_BTYPE_GRIP drag-resize:
6420  * We can't directly use results from a grip button, since we have a
6421  * rather complex behavior here (sizing by discrete steps and, overall, auto-size feature).
6422  * Since we *never* know whether we are grip-resizing or not
6423  * (because there is no callback for when a button enters/leaves its "edit mode"),
6424  * we use the fact that grip-controlled value (dyn_data->resize) is completely handled
6425  * by the grip during the grab resize, so settings its value here has no effect at all.
6426  *
6427  * It is only meaningful when we are not resizing,
6428  * in which case this gives us the correct "init drag" value.
6429  * Note we cannot affect `dyn_data->resize_prev here`,
6430  * since this value is not controlled by the grip!
6431  */
6432  dyn_data->resize = dyn_data->resize_prev +
6433  (dyn_data->visual_height - ui_list->list_grip) * UI_UNIT_Y;
6434 
6435  row = uiLayoutRow(glob, true);
6436  uiBlock *subblock = uiLayoutGetBlock(row);
6438 
6439  if (ui_list->filter_flag & UILST_FLT_SHOW) {
6440  but = uiDefIconButBitI(subblock,
6443  0,
6444  ICON_DISCLOSURE_TRI_DOWN,
6445  0,
6446  0,
6447  UI_UNIT_X,
6448  UI_UNIT_Y * 0.5f,
6449  &(ui_list->filter_flag),
6450  0,
6451  0,
6452  0,
6453  0,
6454  TIP_("Hide filtering options"));
6455  UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
6456 
6457  but = uiDefIconButI(subblock,
6458  UI_BTYPE_GRIP,
6459  0,
6460  ICON_GRIP,
6461  0,
6462  0,
6463  UI_UNIT_X * 10.0f,
6464  UI_UNIT_Y * 0.5f,
6465  &dyn_data->resize,
6466  0.0,
6467  0.0,
6468  0,
6469  0,
6470  "");
6472 
6473  UI_block_emboss_set(subblock, UI_EMBOSS);
6474 
6475  col = uiLayoutColumn(glob, false);
6476  subblock = uiLayoutGetBlock(col);
6477  uiDefBut(subblock,
6478  UI_BTYPE_SEPR,
6479  0,
6480  "",
6481  0,
6482  0,
6483  UI_UNIT_X,
6484  UI_UNIT_Y * 0.05f,
6485  NULL,
6486  0.0,
6487  0.0,
6488  0,
6489  0,
6490  "");
6491 
6492  draw_filter(ui_list, C, col);
6493  }
6494  else {
6495  but = uiDefIconButBitI(subblock,
6498  0,
6499  ICON_DISCLOSURE_TRI_RIGHT,
6500  0,
6501  0,
6502  UI_UNIT_X,
6503  UI_UNIT_Y * 0.5f,
6504  &(ui_list->filter_flag),
6505  0,
6506  0,
6507  0,
6508  0,
6509  TIP_("Show filtering options"));
6510  UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
6511 
6512  but = uiDefIconButI(subblock,
6513  UI_BTYPE_GRIP,
6514  0,
6515  ICON_GRIP,
6516  0,
6517  0,
6518  UI_UNIT_X * 10.0f,
6519  UI_UNIT_Y * 0.5f,
6520  &dyn_data->resize,
6521  0.0,
6522  0.0,
6523  0,
6524  0,
6525  "");
6527 
6528  UI_block_emboss_set(subblock, UI_EMBOSS);
6529  }
6530  }
6531 
6532  if (items_ptr) {
6533  MEM_freeN(items_ptr);
6534  }
6535 }
6536 
6539 /* -------------------------------------------------------------------- */
6543 #define B_STOPRENDER 1
6544 #define B_STOPCAST 2
6545 #define B_STOPANIM 3
6546 #define B_STOPCOMPO 4
6547 #define B_STOPSEQ 5
6548 #define B_STOPCLIP 6
6549 #define B_STOPFILE 7
6550 #define B_STOPOTHER 8
6551 
6552 static void do_running_jobs(bContext *C, void *UNUSED(arg), int event)
6553 {
6554  switch (event) {
6555  case B_STOPRENDER:
6556  G.is_break = true;
6557  break;
6558  case B_STOPCAST:
6560  break;
6561  case B_STOPANIM:
6562  WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL);
6563  break;
6564  case B_STOPCOMPO:
6566  break;
6567  case B_STOPSEQ:
6569  break;
6570  case B_STOPCLIP:
6572  break;
6573  case B_STOPFILE:
6575  break;
6576  case B_STOPOTHER:
6577  G.is_break = true;
6578  break;
6579  }
6580 }
6581 
6584  void *owner;
6585 };
6586 
6587 static char *progress_tooltip_func(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
6588 {
6589  struct ProgressTooltip_Store *arg = argN;
6590  wmWindowManager *wm = arg->wm;
6591  void *owner = arg->owner;
6592 
6593  const float progress = WM_jobs_progress(wm, owner);
6594 
6595  /* create tooltip text and associate it with the job */
6596  char elapsed_str[32];
6597  char remaining_str[32] = "Unknown";
6598  const double elapsed = PIL_check_seconds_timer() - WM_jobs_starttime(wm, owner);
6599  BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
6600 
6601  if (progress) {
6602  const double remaining = (elapsed / (double)progress) - elapsed;
6603  BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining);
6604  }
6605 
6606  return BLI_sprintfN(
6607  "Time Remaining: %s\n"
6608  "Time Elapsed: %s",
6609  remaining_str,
6610  elapsed_str);
6611 }
6612 
6614 {
6615  Main *bmain = CTX_data_main(C);
6617  ScrArea *area = CTX_wm_area(C);
6618  void *owner = NULL;
6619  int handle_event, icon = 0;
6620 
6621  uiBlock *block = uiLayoutGetBlock(layout);
6622  UI_block_layout_set_current(block, layout);
6623 
6625 
6626  /* another scene can be rendering too, for example via compositor */
6627  LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
6629  handle_event = B_STOPOTHER;
6630  icon = ICON_NONE;
6631  owner = scene;
6632  }
6633  else {
6634  continue;
6635  }
6636 
6638  handle_event = B_STOPSEQ;
6639  icon = ICON_SEQUENCE;
6640  owner = scene;
6641  break;
6642  }
6644  handle_event = B_STOPSEQ;
6645  icon = ICON_SEQUENCE;
6646  break;
6647  }
6649  handle_event = B_STOPCLIP;
6650  icon = ICON_TRACKER;
6651  break;
6652  }
6654  handle_event = B_STOPCLIP;
6655  icon = ICON_TRACKER;
6656  break;
6657  }
6659  handle_event = B_STOPCLIP;
6660  icon = ICON_TRACKER;
6661  break;
6662  }
6664  handle_event = B_STOPCLIP;
6665  icon = ICON_TRACKER;
6666  break;
6667  }
6669  handle_event = B_STOPFILE;
6670  icon = ICON_FILEBROWSER;
6671  break;
6672  }
6674  handle_event = B_STOPRENDER;
6675  icon = ICON_SCENE;
6676  break;
6677  }
6679  handle_event = B_STOPCOMPO;
6680  icon = ICON_RENDERLAYERS;
6681  break;
6682  }
6685  /* Skip bake jobs in compositor to avoid compo header displaying
6686  * progress bar which is not being updated (bake jobs only need
6687  * to update NC_IMAGE context.
6688  */
6689  if (area->spacetype != SPACE_NODE) {
6690  handle_event = B_STOPOTHER;
6691  icon = ICON_IMAGE;
6692  break;
6693  }
6694  continue;
6695  }
6697  handle_event = B_STOPOTHER;
6698  icon = ICON_MOD_DYNAMICPAINT;
6699  break;
6700  }
6702  handle_event = B_STOPOTHER;
6703  icon = ICON_PHYSICS;
6704  break;
6705  }
6707  handle_event = B_STOPOTHER;
6708  icon = ICON_MOD_FLUIDSIM;
6709  break;
6710  }
6712  handle_event = B_STOPOTHER;
6713  icon = ICON_MOD_OCEAN;
6714  break;
6715  }
6716  }
6717 
6718  if (owner) {
6719  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
6720  const bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner));
6721 
6722  uiLayout *row = uiLayoutRow(layout, false);
6723  block = uiLayoutGetBlock(row);
6724 
6725  /* get percentage done and set it as the UI text */
6726  const float progress = WM_jobs_progress(wm, owner);
6727  char text[8];
6728  BLI_snprintf(text, 8, "%d%%", (int)(progress * 100));
6729 
6730  const char *name = active ? WM_jobs_name(wm, owner) : "Canceling...";
6731 
6732  /* job name and icon */
6733  const int textwidth = UI_fontstyle_string_width(fstyle, name);
6734  uiDefIconTextBut(block,
6736  0,
6737  icon,
6738  name,
6739  0,
6740  0,
6741  textwidth + UI_UNIT_X * 1.5f,
6742  UI_UNIT_Y,
6743  NULL,
6744  0.0f,
6745  0.0f,
6746  0.0f,
6747  0.0f,
6748  "");
6749 
6750  /* stick progress bar and cancel button together */
6751  row = uiLayoutRow(layout, true);
6752  uiLayoutSetActive(row, active);
6753  block = uiLayoutGetBlock(row);
6754 
6755  {
6756  struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__);
6757  tip_arg->wm = wm;
6758  tip_arg->owner = owner;
6759  uiButProgressbar *but_progress = (uiButProgressbar *)uiDefIconTextBut(block,
6761  0,
6762  0,
6763  text,
6764  UI_UNIT_X,
6765  0,
6766  UI_UNIT_X * 6.0f,
6767  UI_UNIT_Y,
6768  NULL,
6769  0.0f,
6770  0.0f,
6771  0.0f,
6772  0,
6773  NULL);
6774 
6775  but_progress->progress = progress;
6776  UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg);
6777  }
6778 
6779  if (!wm->is_interface_locked) {
6780  uiDefIconTextBut(block,
6781  UI_BTYPE_BUT,
6782  handle_event,
6783  ICON_PANEL_CLOSE,
6784  "",
6785  0,
6786  0,
6787  UI_UNIT_X,
6788  UI_UNIT_Y,
6789  NULL,
6790  0.0f,
6791  0.0f,
6792  0,
6793  0,
6794  TIP_("Stop this job"));
6795  }
6796  }
6797 
6799  uiDefIconTextBut(block,
6800  UI_BTYPE_BUT,
6801  B_STOPANIM,
6802  ICON_CANCEL,
6803  IFACE_("Anim Player"),
6804  0,
6805  0,
6806  UI_UNIT_X * 5.0f,
6807  UI_UNIT_Y,
6808  NULL,
6809  0.0f,
6810  0.0f,
6811  0,
6812  0,
6813  TIP_("Stop animation playback"));
6814  }
6815 }
6816 
6819 /* -------------------------------------------------------------------- */
6824 {
6825  ReportList *reports = CTX_wm_reports(C);
6826  Report *report = BKE_reports_last_displayable(reports);
6827  const uiStyle *style = UI_style_get();
6828 
6829  uiBut *but;
6830 
6831  /* if the report display has timed out, don't show */
6832  if (!reports->reporttimer) {
6833  return;
6834  }
6835 
6837 
6838  if (!rti || rti->widthfac == 0.0f || !report) {
6839  return;
6840  }
6841 
6842  uiLayout *ui_abs = uiLayoutAbsolute(layout, false);
6843  uiBlock *block = uiLayoutGetBlock(ui_abs);
6844  eUIEmbossType previous_emboss = UI_block_emboss_get(block);
6845 
6846  UI_fontstyle_set(&style->widgetlabel);
6847  int width = BLF_width(style->widgetlabel.uifont_id, report->message, report->len);
6848  width = min_ii((int)(rti->widthfac * width), width);
6849  width = max_ii(width, 10 * UI_DPI_FAC);
6850 
6851  UI_block_align_begin(block);
6852 
6853  /* Background for icon. */
6854  but = uiDefBut(block,
6856  0,
6857  "",
6858  0,
6859  0,
6860  UI_UNIT_X + (6 * UI_DPI_FAC),
6861  UI_UNIT_Y,
6862  NULL,
6863  0.0f,
6864  0.0f,
6865  0,
6866  0,
6867  "");
6868  /* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
6870 
6871  /* Background for the rest of the message. */
6872  but = uiDefBut(block,
6874  0,
6875  "",
6876  UI_UNIT_X + (6 * UI_DPI_FAC),
6877  0,
6878  UI_UNIT_X + width,
6879  UI_UNIT_Y,
6880  NULL,
6881  0.0f,
6882  0.0f,
6883  0,
6884  0,
6885  "");
6886 
6887  /* Use icon background at low opacity to highlight, but still contrasting with area TH_TEXT. */
6889  but->col[3] = 64;
6890 
6891  UI_block_align_end(block);
6893 
6894  /* The report icon itself. */
6895  but = uiDefIconButO(block,
6896  UI_BTYPE_BUT,
6897  "SCREEN_OT_info_log_show",
6899  UI_icon_from_report_type(report->type),
6900  (3 * UI_DPI_FAC),
6901  0,
6902  UI_UNIT_X,
6903  UI_UNIT_Y,
6904  TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
6906  but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
6907 
6908  /* The report message. */
6909  but = uiDefButO(block,
6910  UI_BTYPE_BUT,
6911  "SCREEN_OT_info_log_show",
6913  report->message,
6914  UI_UNIT_X,
6915  0,
6916  width + UI_UNIT_X,
6917  UI_UNIT_Y,
6918  "Show in Info Log");
6919 
6920  UI_block_emboss_set(block, previous_emboss);
6921 }
6922 
6924 {
6925  wmWindow *win = CTX_wm_window(C);
6926  WorkSpace *workspace = CTX_wm_workspace(C);
6927 
6928  /* Workspace status text has priority. */
6929  if (workspace->status_text) {
6930  uiItemL(layout, workspace->status_text, ICON_NONE);
6931  return;
6932  }
6933 
6934  if (WM_window_modal_keymap_status_draw(C, win, layout)) {
6935  return;
6936  }
6937 
6938  /* Otherwise should cursor keymap status. */
6939  for (int i = 0; i < 3; i++) {
6940  uiLayout *box = uiLayoutRow(layout, false);
6941  uiLayout *col = uiLayoutColumn(box, false);
6942  uiLayout *row = uiLayoutRow(col, true);
6944 
6945  const char *msg = WM_window_cursor_keymap_status_get(win, i, 0);
6946  const char *msg_drag = WM_window_cursor_keymap_status_get(win, i, 1);
6947 
6948  if (msg || (msg_drag == NULL)) {
6949  uiItemL(row, msg ? msg : "", (ICON_MOUSE_LMB + i));
6950  }
6951 
6952  if (msg_drag) {
6953  uiItemL(row, msg_drag, (ICON_MOUSE_LMB_DRAG + i));
6954  }
6955 
6956  /* Use trick with empty string to keep icons in same position. */
6957  row = uiLayoutRow(col, false);
6958  uiItemL(row, " ", ICON_NONE);
6959  }
6960 }
6961 
6964 /* -------------------------------------------------------------------- */
6968 static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED(unused))
6969 {
6970  wmKeyMapItem *kmi = (wmKeyMapItem *)kmi_p;
6972 }
6973 
6974 static void template_keymap_item_properties(uiLayout *layout, const char *title, PointerRNA *ptr)
6975 {
6976  uiItemS(layout);
6977 
6978  if (title) {
6979  uiItemL(layout, title, ICON_NONE);
6980  }
6981 
6982  uiLayout *flow = uiLayoutColumnFlow(layout, 2, false);
6983 
6985  const bool is_set = RNA_property_is_set(ptr, prop);
6986  uiBut *but;
6987 
6988  /* recurse for nested properties */
6989  if (RNA_property_type(prop) == PROP_POINTER) {
6990  PointerRNA propptr = RNA_property_pointer_get(ptr, prop);
6991 
6992  if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) {
6993  const char *name = RNA_property_ui_name(prop);
6994  template_keymap_item_properties(layout, name, &propptr);
6995  continue;
6996  }
6997  }
6998 
6999  uiLayout *box = uiLayoutBox(flow);
7000  uiLayoutSetActive(box, is_set);
7001  uiLayout *row = uiLayoutRow(box, false);
7002 
7003  /* property value */
7004  uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
7005 
7006  if (is_set) {
7007  /* unset operator */
7008  uiBlock *block = uiLayoutGetBlock(row);
7010  but = uiDefIconButO(block,
7011  UI_BTYPE_BUT,
7012  "UI_OT_unset_property_button",
7014  ICON_X,
7015  0,
7016  0,
7017  UI_UNIT_X,
7018  UI_UNIT_Y,
7019  NULL);
7020  but->rnapoin = *ptr;
7021  but->rnaprop = prop;
7023  }
7024  }
7026 }
7027 
7029 {
7030  PointerRNA propptr = RNA_pointer_get(ptr, "properties");
7031 
7032  if (propptr.data) {
7033  uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
7034 
7035  WM_operator_properties_sanitize(&propptr, false);
7036  template_keymap_item_properties(layout, NULL, &propptr);
7037 
7038  /* attach callbacks to compensate for missing properties update,
7039  * we don't know which keymap (item) is being modified there */
7040  for (; but; but = but->next) {
7041  /* operator buttons may store props for use (file selector, T36492) */
7042  if (but->rnaprop) {
7044 
7045  /* Otherwise the keymap will be re-generated which we're trying to edit,
7046  * see: T47685 */
7048  }
7049  }
7050  }
7051 }
7052 
7055 /* -------------------------------------------------------------------- */
7060  const char *text,
7061  const struct wmKeyMapItem *kmi,
7062  bool text_fallback)
7063 {
7064  bool ok = false;
7065 
7066  int icon_mod[4];
7067 #ifdef WITH_HEADLESS
7068  int icon = 0;
7069 #else
7070  const int icon = UI_icon_from_keymap_item(kmi, icon_mod);
7071 #endif
7072  if (icon != 0) {
7073  for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
7074  uiItemL(layout, "", icon_mod[j]);
7075  }
7076  uiItemL(layout, text, icon);
7077  ok = true;
7078  }
7079  else if (text_fallback) {
7080  const char *event_text = WM_key_event_string(kmi->type, true);
7081  uiItemL(layout, event_text, ICON_NONE);
7082  uiItemL(layout, text, ICON_NONE);
7083  ok = true;
7084  }
7085  return ok;
7086 }
7087 
7090 /* -------------------------------------------------------------------- */
7094 void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)
7095 {
7096  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
7097 
7098  if (!prop) {
7099  printf(
7100  "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
7101  return;
7102  }
7103 
7104  PointerRNA colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
7105 
7106  uiItemR(layout, &colorspace_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE);
7107 }
7108 
7110  bContext *UNUSED(C),
7111  PointerRNA *ptr,
7112  const char *propname)
7113 {
7114  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
7115 
7116  if (!prop) {
7117  printf(
7118  "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
7119  return;
7120  }
7121 
7122  PointerRNA view_transform_ptr = RNA_property_pointer_get(ptr, prop);
7123  ColorManagedViewSettings *view_settings = view_transform_ptr.data;
7124 
7125  uiLayout *col = uiLayoutColumn(layout, false);
7126 
7127  uiLayout *row = uiLayoutRow(col, false);
7128  uiItemR(row, &view_transform_ptr, "view_transform", 0, IFACE_("View"), ICON_NONE);
7129 
7130  col = uiLayoutColumn(layout, false);
7131  uiItemR(col, &view_transform_ptr, "exposure", 0, NULL, ICON_NONE);
7132  uiItemR(col, &view_transform_ptr, "gamma", 0, NULL, ICON_NONE);
7133 
7134  uiItemR(col, &view_transform_ptr, "look", 0, IFACE_("Look"), ICON_NONE);
7135 
7136  col = uiLayoutColumn(layout, false);
7137  uiItemR(col, &view_transform_ptr, "use_curve_mapping", 0, NULL, ICON_NONE);
7138  if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
7140  col, &view_transform_ptr, "curve_mapping", 'c', true, false, false, false);
7141  }
7142 }
7143 
7146 /* -------------------------------------------------------------------- */
7150 typedef struct ComponentMenuArgs {
7152  char propname[64]; /* XXX arbitrary */
7154 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
7155 static uiBlock *component_menu(bContext *C, ARegion *region, void *args_v)
7156 {
7157  ComponentMenuArgs *args = (ComponentMenuArgs *)args_v;
7158 
7159  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
7161 
7162  uiLayout *layout = uiLayoutColumn(UI_block_layout(block,
7165  0,
7166  0,
7167  UI_UNIT_X * 6,
7168  UI_UNIT_Y,
7169  0,
7170  UI_style_get()),
7171  0);
7172 
7173  uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE);
7174 
7175  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
7177 
7178  return block;
7179 }
7181  PointerRNA *ptr,
7182  const char *propname,
7183  const char *name)
7184 {
7185  ComponentMenuArgs *args = MEM_callocN(sizeof(ComponentMenuArgs), "component menu template args");
7186 
7187  args->ptr = *ptr;
7188  BLI_strncpy(args->propname, propname, sizeof(args->propname));
7189 
7190  uiBlock *block = uiLayoutGetBlock(layout);
7191  UI_block_align_begin(block);
7192 
7193  uiBut *but = uiDefBlockButN(
7194  block, component_menu, args, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, "");
7195  /* set rna directly, uiDefBlockButN doesn't do this */
7196  but->rnapoin = *ptr;
7197  but->rnaprop = RNA_struct_find_property(ptr, propname);
7198  but->rnaindex = 0;
7199 
7200  UI_block_align_end(block);
7201 }
7202 
7205 /* -------------------------------------------------------------------- */
7209 void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float *color)
7210 {
7211  uiBlock *block = uiLayoutGetBlock(layout);
7212  UI_block_align_begin(block);
7213 
7214  /* XXX using explicit socket colors is not quite ideal.
7215  * Eventually it should be possible to use theme colors for this purpose,
7216  * but this requires a better design for extendable color palettes in user prefs.
7217  */
7218  uiBut *but = uiDefBut(
7219  block, UI_BTYPE_NODE_SOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
7220  rgba_float_to_uchar(but->col, color);
7221 
7222  UI_block_align_end(block);
7223 }
7224 
7227 /* -------------------------------------------------------------------- */
7232  const bContext *C,
7233  PointerRNA *ptr,
7234  const char *propname)
7235 {
7236  if (!ptr->data) {
7237  return;
7238  }
7239 
7240  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
7241 
7242  if (!prop) {
7243  printf(
7244  "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
7245  return;
7246  }
7247 
7248  if (RNA_property_type(prop) != PROP_POINTER) {
7249  printf("%s: expected pointer property for %s.%s\n",
7250  __func__,
7252  propname);
7253  return;
7254  }
7255 
7256  PointerRNA fileptr = RNA_property_pointer_get(ptr, prop);
7257  CacheFile *file = fileptr.data;
7258 
7259  uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr);
7260 
7261  uiTemplateID(layout,
7262  C,
7263  ptr,
7264  propname,
7265  NULL,
7266  "CACHEFILE_OT_open",
7267  NULL,
7269  false,
7270  NULL);
7271 
7272  if (!file) {
7273  return;
7274  }
7275 
7277 
7278  uiLayout *row, *sub, *subsub;
7279 
7280  uiLayoutSetPropSep(layout, true);
7281 
7282  row = uiLayoutRow(layout, true);
7283  uiItemR(row, &fileptr, "filepath", 0, NULL, ICON_NONE);
7284  sub = uiLayoutRow(row, true);
7285  uiItemO(sub, "", ICON_FILE_REFRESH, "cachefile.reload");
7286 
7287  row = uiLayoutRow(layout, false);
7288  uiItemR(row, &fileptr, "is_sequence", 0, NULL, ICON_NONE);
7289 
7290  row = uiLayoutRowWithHeading(layout, true, IFACE_("Override Frame"));
7291  sub = uiLayoutRow(row, true);
7292  uiLayoutSetPropDecorate(sub, false);
7293  uiItemR(sub, &fileptr, "override_frame", 0, "", ICON_NONE);
7294  subsub = uiLayoutRow(sub, true);
7295  uiLayoutSetActive(subsub, RNA_boolean_get(&fileptr, "override_frame"));
7296  uiItemR(subsub, &fileptr, "frame", 0, "", ICON_NONE);
7297  uiItemDecoratorR(row, &fileptr, "frame", 0);
7298 
7299  row = uiLayoutRow(layout, false);
7300  uiItemR(row, &fileptr, "frame_offset", 0, NULL, ICON_NONE);
7301  uiLayoutSetActive(row, !RNA_boolean_get(&fileptr, "is_sequence"));
7302 
7303  if (sbuts->mainb == BCONTEXT_CONSTRAINT) {
7304  row = uiLayoutRow(layout, false);
7305  uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE);
7306  }
7307 
7308  uiItemR(layout, &fileptr, "velocity_name", 0, NULL, ICON_NONE);
7309  uiItemR(layout, &fileptr, "velocity_unit", 0, NULL, ICON_NONE);
7310 
7311  /* TODO: unused for now, so no need to expose. */
7312 #if 0
7313  row = uiLayoutRow(layout, false);
7314  uiItemR(row, &fileptr, "forward_axis", 0, "Forward Axis", ICON_NONE);
7315 
7316  row = uiLayoutRow(layout, false);
7317  uiItemR(row, &fileptr, "up_axis", 0, "Up Axis", ICON_NONE);
7318 #endif
7319 }
7320 
7323 /* -------------------------------------------------------------------- */
7327 int uiTemplateRecentFiles(uiLayout *layout, int rows)
7328 {
7329  int i;
7330  LISTBASE_FOREACH_INDEX (RecentFile *, recent, &G.recent_files, i) {
7331  if (i >= rows) {
7332  break;
7333  }
7334 
7335  const char *filename = BLI_path_basename(recent->filepath);
7336  PointerRNA ptr;
7337  uiItemFullO(layout,
7338  "WM_OT_open_mainfile",
7339  filename,
7340  BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
7341  NULL,
7343  0,
7344  &ptr);
7345  RNA_string_set(&ptr, "filepath", recent->filepath);
7346  RNA_boolean_set(&ptr, "display_file_selector", false);
7347  }
7348 
7349  return i;
7350 }
7351 
7354 /* -------------------------------------------------------------------- */
7359 {
7360  bScreen *screen = CTX_wm_screen(C);
7361  SpaceFile *sfile = CTX_wm_space_file(C);
7362 
7363  ED_file_path_button(screen, sfile, params, uiLayoutGetBlock(layout));
7364 }
7365 
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_active(struct Object *ob)
Definition: action.c:708
#define FOREACH_SCENE_OBJECT_END
void BKE_collection_object_add_from(struct Main *bmain, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst)
Definition: collection.c:1168
bool BKE_collection_has_object_recursive(struct Collection *collection, struct Object *ob)
Definition: collection.c:961
#define FOREACH_SCENE_OBJECT_BEGIN(scene, _instance)
void BKE_colorband_init(struct ColorBand *coba, bool rangetype)
Definition: colorband.c:38
bool BKE_colorband_element_remove(struct ColorBand *coba, int index)
Definition: colorband.c:644
#define MAXCOLORBAND
Definition: BKE_colorband.h:32
struct CBData * BKE_colorband_element_add(struct ColorBand *coba, float position)
Definition: colorband.c:618
void BKE_colorband_update_sort(struct ColorBand *coba)
Definition: colorband.c:596
void BKE_curvemap_handle_set(struct CurveMap *cuma, int type)
Definition: colortools.c:445
void BKE_curvemap_remove(struct CurveMap *cuma, const short flag)
Definition: colortools.c:217
void BKE_curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3])
Definition: colortools.c:168
void BKE_curvemap_reset(struct CurveMap *cuma, const struct rctf *clipr, int preset, int slope)
void BKE_curvemapping_changed(struct CurveMapping *cumap, const bool rem_doubles)
Definition: colortools.c:877
@ CURVEMAP_SLOPE_NEGATIVE
@ CURVEMAP_SLOPE_POSITIVE
void BKE_curvemapping_reset_view(struct CurveMapping *cumap)
Definition: colortools.c:969
const bConstraintTypeInfo * BKE_constraint_typeinfo_from_type(int type)
Definition: constraint.c:5413
bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan)
Definition: constraint.c:5995
struct WorkSpace * CTX_wm_workspace(const bContext *C)
Definition: context.c:704
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ARegion * CTX_wm_menu(const bContext *C)
Definition: context.c:736
struct SpaceProperties * CTX_wm_space_properties(const bContext *C)
Definition: context.c:809
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:751
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct SpaceFile * CTX_wm_space_file(const bContext *C)
Definition: context.c:818
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
@ PROF_UPDATE_CLIP
@ PROF_UPDATE_REMOVE_DOUBLES
@ PROF_UPDATE_NONE
void BKE_curveprofile_reset_view(struct CurveProfile *profile)
Definition: curveprofile.c:441
void BKE_curveprofile_update(struct CurveProfile *profile, const int update_flags)
Definition: curveprofile.c:905
void BKE_curveprofile_remove_by_flag(struct CurveProfile *profile, const short flag)
Definition: curveprofile.c:229
void BKE_curveprofile_reset(struct CurveProfile *profile)
Definition: curveprofile.c:451
void BKE_curveprofile_reverse(struct CurveProfile *profile)
Definition: curveprofile.c:362
void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname)
const GpencilModifierTypeInfo * BKE_gpencil_modifier_get_info(GpencilModifierType type)
struct IDProperty * IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: idprop.c:907
const char * BKE_idtype_idcode_to_translation_context(const short idcode)
Definition: idtype.c:195
const char * BKE_idtype_idcode_to_name(const short idcode)
Definition: idtype.c:168
bool BKE_id_copy_is_allowed(const struct ID *id)
void id_us_min(struct ID *id)
Definition: lib_id.c:297
#define MAX_ID_FULL_NAME_UI
Definition: BKE_lib_id.h:294
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI], const struct ID *id, const bool add_lib_hint, char separator_char, int *r_prefix_len)
void BKE_main_id_clear_newpoins(struct Main *bmain)
Definition: lib_id.c:1738
bool BKE_lib_id_make_local(struct Main *bmain, struct ID *id, const bool test, const int flags)
Definition: lib_id.c:479
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop)
Definition: lib_id.c:747
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void id_us_clear_real(struct ID *id)
Definition: lib_id.c:257
void BKE_id_ordered_list(struct ListBase *ordered_lb, const struct ListBase *lb)
void id_fake_user_clear(struct ID *id)
Definition: lib_id.c:336
void BKE_main_id_flag_listbase(struct ListBase *lb, const int flag, const bool value)
Definition: lib_id.c:937
struct ID * BKE_lib_override_library_create_from_id(struct Main *bmain, struct ID *reference_id, const bool do_tagged_remap)
Definition: lib_override.c:254
void BKE_lib_override_library_make_local(struct ID *id)
Blender kernel freestyle line style functionality.
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:447
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
void BKE_modifier_type_panel_id(ModifierType type, char *r_idname)
General operations, lookup, etc. for blender objects.
bool BKE_packedfile_id_check(struct ID *id)
Definition: packedFile.c:805
Report * BKE_reports_last_displayable(ReportList *reports)
Definition: report.c:295
bool BKE_scene_uses_blender_eevee(const struct Scene *scene)
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:313
void(* uiListFilterItemsFunc)(struct uiList *ui_list, struct bContext *C, struct PointerRNA *, const char *propname)
Definition: BKE_screen.h:330
void(* uiListDrawFilterFunc)(struct uiList *ui_list, struct bContext *C, struct uiLayout *layout)
Definition: BKE_screen.h:325
@ PANEL_TYPE_INSTANCED
Definition: BKE_screen.h:303
void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname)
Definition: shader_fx.c:173
const ShaderFxTypeInfo * BKE_shaderfx_get_info(ShaderFxType type)
Definition: shader_fx.c:157
float BLF_width(int fontid, const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:723
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
Definition: BLI_listbase.h:184
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
Definition: BLI_listbase.h:180
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
Definition: math_color.c:427
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
const char * BLI_path_basename(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1868
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:165
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:666
char * BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, const char pad, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:132
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
void BLI_string_search_free(StringSearch *search)
void BLI_string_search_add(StringSearch *search, const char *str, void *user_data)
StringSearch * BLI_string_search_new(void)
int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data)
size_t BLI_timecode_string_from_time_simple(char *str, const size_t maxncpy, const double time_seconds) ATTR_NONNULL()
Definition: timecode.c:206
#define ARRAY_SIZE(arr)
#define UNUSED_VARS(...)
#define CLAMPIS(a, b, c)
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define MAX2(a, b)
#define ELEM(...)
#define STREQ(a, b)
external readfile function prototypes.
bool BLO_has_bfile_extension(const char *str)
Definition: readfile.c:1684
#define BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE
#define BLT_I18NCONTEXT_ID_WORLD
#define BLT_I18NCONTEXT_ID_ACTION
#define BLT_I18NCONTEXT_ID_TEXT
#define BLT_I18NCONTEXT_ID_VOLUME
#define BLT_I18NCONTEXT_ID_BRUSH
#define BLT_I18NCONTEXT_ID_CURVE
#define BLT_I18NCONTEXT_ID_SIMULATION
#define BLT_I18NCONTEXT_ID_NODETREE
#define BLT_I18NCONTEXT_ID_IMAGE
#define BLT_I18NCONTEXT_ID_SPEAKER
#define BLT_I18NCONTEXT_ID_WORKSPACE
#define TIP_(msgid)
#define BLT_I18NCONTEXT_ID_LATTICE
#define BLT_I18NCONTEXT_ID_GPENCIL
#define BLT_I18NCONTEXT_ID_LIGHT
#define BLT_I18NCONTEXT_ID_POINTCLOUD
#define BLT_I18NCONTEXT_ID_METABALL
#define BLT_I18NCONTEXT_ID_SOUND
#define BLT_I18NCONTEXT_ID_PARTICLESETTINGS
#define BLT_I18NCONTEXT_ID_LIGHTPROBE
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_DEFAULT
#define BLT_I18NCONTEXT_ID_SCREEN
#define BLT_I18NCONTEXT_ID_OBJECT
#define IFACE_(msgid)
#define N_(msgid)
#define BLT_I18NCONTEXT_ID_ARMATURE
#define BLT_I18N_MSGID_MULTI_CTXT(msgid,...)
#define BLT_I18NCONTEXT_ID_SCENE
#define BLT_I18NCONTEXT_ID_HAIR
#define BLT_I18NCONTEXT_ID_MATERIAL
#define BLT_I18NCONTEXT_ID_MESH
#define BLT_I18NCONTEXT_ID_CAMERA
#define BLT_I18NCONTEXT_ID_TEXTURE
typedef double(DMatrix)[4][4]
void DEG_relations_tag_update(struct Main *bmain)
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:524
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
#define ID_IS_OVERRIDABLE_LIBRARY(_id)
Definition: DNA_ID.h:430
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ IDP_GROUP
Definition: DNA_ID.h:101
@ LIB_FAKEUSER
Definition: DNA_ID.h:477
#define MAX_IDPROP_NAME
Definition: DNA_ID.h:92
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:413
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:445
ID_Type
Definition: DNA_ID_enums.h:56
@ ID_WM
Definition: DNA_ID_enums.h:84
@ ID_CA
Definition: DNA_ID_enums.h:68
@ ID_AR
Definition: DNA_ID_enums.h:78
@ ID_MC
Definition: DNA_ID_enums.h:85
@ ID_CF
Definition: DNA_ID_enums.h:90
@ ID_LI
Definition: DNA_ID_enums.h:58
@ ID_TE
Definition: DNA_ID_enums.h:64
@ ID_IM
Definition: DNA_ID_enums.h:65
@ ID_VO
Definition: DNA_ID_enums.h:95
@ ID_WS
Definition: DNA_ID_enums.h:91
@ ID_NT
Definition: DNA_ID_enums.h:80
@ ID_LA
Definition: DNA_ID_enums.h:67
@ ID_KE
Definition: DNA_ID_enums.h:70
@ ID_TXT
Definition: DNA_ID_enums.h:74
@ ID_SO
Definition: DNA_ID_enums.h:76
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_LS
Definition: DNA_ID_enums.h:87
@ ID_MSK
Definition: DNA_ID_enums.h:86
@ ID_GD
Definition: DNA_ID_enums.h:83
@ ID_PAL
Definition: DNA_ID_enums.h:88
@ ID_BR
Definition: DNA_ID_enums.h:81
@ ID_LP
Definition: DNA_ID_enums.h:92
@ ID_HA
Definition: DNA_ID_enums.h:93
@ ID_WO
Definition: DNA_ID_enums.h:71
@ ID_SIM
Definition: DNA_ID_enums.h:96
@ ID_MA
Definition: DNA_ID_enums.h:63
@ ID_AC
Definition: DNA_ID_enums.h:79
@ ID_SCR
Definition: DNA_ID_enums.h:72
@ ID_VF
Definition: DNA_ID_enums.h:73
@ ID_ME
Definition: DNA_ID_enums.h:60
@ ID_IP
Definition: DNA_ID_enums.h:69
@ ID_GR
Definition: DNA_ID_enums.h:77
@ ID_SPK
Definition: DNA_ID_enums.h:75
@ ID_MB
Definition: DNA_ID_enums.h:62
@ ID_LT
Definition: DNA_ID_enums.h:66
@ ID_OB
Definition: DNA_ID_enums.h:59
@ ID_PA
Definition: DNA_ID_enums.h:82
@ ID_PT
Definition: DNA_ID_enums.h:94
@ ID_CU
Definition: DNA_ID_enums.h:61
@ ID_PC
Definition: DNA_ID_enums.h:89
#define CM_TOT
@ CUMA_EXTEND_EXTRAPOLATE
@ CUMA_DO_CLIP
@ COLORMANAGE_VIEW_USE_CURVES
@ CUMA_SELECT
@ CURVE_PRESET_LINE
@ CONSTRAINT_PROXY_LOCAL
@ CONSTRAINT_DISABLE
@ CONSTRAINT_IK_TEMP
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_NULL
@ HD_AUTO_ANIM
@ HD_VECT
@ HD_AUTO
@ PROF_PRESET_CROWN
@ PROF_PRESET_LINE
@ PROF_PRESET_CORNICE
@ PROF_PRESET_SUPPORTS
@ PROF_PRESET_STEPS
@ PROF_DIRTY_PRESET
@ PROF_USE_CLIP
@ PROF_H1_SELECT
@ PROF_H2_SELECT
#define MAX_NAME
Definition: DNA_defs.h:62
@ OB_MODE_EDIT
Object is a sort of wrapper for general info.
#define UI_LIST_AUTO_SIZE_THRESHOLD
@ UILST_LAYOUT_COMPACT
@ UILST_LAYOUT_DEFAULT
@ UILST_LAYOUT_GRID
@ UILST_FLT_ITEM
@ UILST_FLT_EXCLUDE
@ UILST_FLT_SHOW
@ UILST_FLT_SORT_LOCK
@ UILST_FLT_SORT_ALPHA
@ UILST_FLT_SORT_REVERSE
#define UILST_FLT_SORT_MASK
@ UILST_SCROLL_TO_ACTIVE_ITEM
@ RGN_TYPE_TOOL_HEADER
@ SPACE_NODE
@ SPACE_INFO
@ BCONTEXT_CONSTRAINT
#define TEX_PR_BOTH
@ COLBAND_BLEND_HSL
@ COLBAND_BLEND_HSV
#define TEX_PR_OTHER
#define TEX_PR_TEXTURE
@ USER_HIDE_DOT
@ USER_CP_SQUARE_SV
@ USER_CP_CIRCLE_HSL
@ USER_CP_SQUARE_HS
@ USER_CP_SQUARE_HV
@ USER_CP_CIRCLE_HSV
void(* uiListPanelIDFromDataFunc)(void *data_link, char *r_idname)
Definition: ED_anim_api.h:687
void ED_file_path_button(struct bScreen *screen, const struct SpaceFile *sfile, struct FileSelectParams *params, struct uiBlock *block)
void ED_object_constraint_active_set(struct Object *ob, struct bConstraint *con)
void ED_object_single_user(struct Main *bmain, struct Scene *scene, struct Object *ob)
struct Object * ED_object_active_context(const struct bContext *C)
struct ListBase * ED_object_pose_constraint_list(const struct bContext *C)
void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect)
bScreen * ED_screen_animation_no_scrub(const struct wmWindowManager *wm)
void ED_region_tag_refresh_ui(struct ARegion *region)
Definition: area.c:695
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:667
int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco)
void ED_undo_operator_repeat_cb_evt(struct bContext *C, void *arg_op, int arg_unused)
void ED_undo_push(struct bContext *C, const char *str)
Definition: ed_undo.c:117
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum query
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_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
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group RGB to Bright Vector Camera CLAMP
Platform independent time functions.
#define RNA_PROP_END
Definition: RNA_access.h:1268
StructRNA RNA_Scopes
StructRNA RNA_Palette
#define RNA_STRUCT_BEGIN(sptr, prop)
Definition: RNA_access.h:1274
StructRNA RNA_Histogram
StructRNA RNA_Material
#define RNA_STRUCT_END
Definition: RNA_access.h:1294
StructRNA RNA_Modifier
short RNA_type_to_ID_code(const StructRNA *type)
StructRNA RNA_Constraint
#define RNA_STRUCT_BEGIN_SKIP_RNA_TYPE(sptr, prop)
Definition: RNA_access.h:1283
#define RNA_PROP_BEGIN(sptr, itemptr, prop)
Definition: RNA_access.h:1261
StructRNA RNA_ColorRamp
StructRNA RNA_LayerObjects
#define RNA_warning(format,...)
Definition: RNA_access.h:1437
StructRNA RNA_ShaderFx
StructRNA RNA_UIList
StructRNA RNA_ColorRampElement
StructRNA RNA_CurveProfilePoint
StructRNA RNA_OperatorProperties
StructRNA RNA_CurveMapping
StructRNA RNA_PaletteColor
StructRNA RNA_CurveProfile
StructRNA RNA_Texture
StructRNA RNA_GpencilModifier
PropertyType
Definition: RNA_types.h:72
@ PROP_BOOLEAN
Definition: RNA_types.h:73
@ PROP_ENUM
Definition: RNA_types.h:77
@ PROP_INT
Definition: RNA_types.h:74
@ PROP_STRING
Definition: RNA_types.h:76
@ PROP_POINTER
Definition: RNA_types.h:78
@ PROP_COLLECTION
Definition: RNA_types.h:79
@ PROP_NEVER_UNLINK
Definition: RNA_types.h:232
@ PROP_NEVER_NULL
Definition: RNA_types.h:225
@ PROP_ID_SELF_CHECK
Definition: RNA_types.h:218
@ PROP_HIDDEN
Definition: RNA_types.h:202
#define C
Definition: RandGen.cpp:39
int UI_text_colorid_from_report_type(int type)
void UI_but_flag_disable(uiBut *but, int flag)
Definition: interface.c:6082
eAutoPropButsReturn
@ UI_PROP_BUTS_ANY_FAILED_CHECK
@ UI_PROP_BUTS_NONE_ADDED
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.c:5603
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
#define UI_UNIT_Y
uiBut * uiDefButBitI(uiBlock *block, int type, int bit, 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.c:4988
void uiLayoutSetActive(uiLayout *layout, bool active)
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN)
Definition: interface.c:6323
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.c:5951
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_NO_BG
@ UI_ITEM_R_ICON_ONLY
@ UI_ITEM_R_SLIDER
int UI_searchbox_size_x(void)
struct bContextStore * uiLayoutGetContextStore(uiLayout *layout)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_BUT_ICON_LEFT
Definition: UI_interface.h:260
@ UI_BUT_NO_TOOLTIP
Definition: UI_interface.h:263
eUIEmbossType
Definition: UI_interface.h:106
@ UI_EMBOSS_NONE
Definition: UI_interface.h:108
@ UI_EMBOSS
Definition: UI_interface.h:107
@ UI_EMBOSS_PULLDOWN
Definition: UI_interface.h:109
@ UI_EMBOSS_NONE_OR_STATUS
Definition: UI_interface.h:115
void UI_fontstyle_set(const struct uiFontStyle *fs)
eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, bool(*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data, struct PropertyRNA *prop_activate_init, eButLabelAlign label_align, const bool compact)
const struct uiStyle * UI_style_get_dpi(void)
uiBut * uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5223
void UI_block_theme_style_set(uiBlock *block, char theme_style)
Definition: interface.c:3547
int UI_searchbox_size_y(void)
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext)
@ UI_BUT_REDALERT
Definition: UI_interface.h:204
@ UI_BUT_UNDO
Definition: UI_interface.h:208
@ UI_BUT_DISABLED
Definition: UI_interface.h:199
@ UI_BUT_HAS_SEP_CHAR
Definition: UI_interface.h:225
@ UI_BUT_ICON_PREVIEW
Definition: UI_interface.h:193
@ UI_BUT_UPDATE_DELAY
Definition: UI_interface.h:227
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
int UI_icon_from_report_type(int type)
uiLayout * uiLayoutOverlap(uiLayout *layout)
@ UI_LAYOUT_MENU
@ UI_LAYOUT_PANEL
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr)
#define UI_SEP_CHAR
Definition: UI_interface.h:86
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.c:4687
uiBut * uiDefButF(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:4896
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.c:5341
void UI_block_lock_clear(uiBlock *block)
Definition: interface.c:2219
void UI_block_bounds_set_normal(struct uiBlock *block, int addval)
Definition: interface.c:580
struct PointerRNA * UI_but_operator_ptr_get(uiBut *but)
Definition: interface.c:6218
void uiItemL(uiLayout *layout, const char *name, int icon)
const struct uiStyle * UI_style_get(void)
uiBut * uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x, int y, int width, int height)
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int state, const uint8_t name_prefix_offset)
uiBut * uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5527
void uiLayoutSetRedAlert(uiLayout *layout, bool redalert)
uiBut * uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, 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.c:5549
uiBut * UI_context_active_but_get(const struct bContext *C)
struct PointerRNA * UI_panel_custom_data_get(const struct Panel *panel)
char UI_block_emboss_get(uiBlock *block)
Definition: interface.c:3537
uiBut * uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.c:6487
uiLayout * uiLayoutAbsolute(uiLayout *layout, bool align)
void uiLayoutSetScaleX(uiLayout *layout, float scale)
struct ARegion * UI_tooltip_create_from_search_item_generic(struct bContext *C, const struct ARegion *searchbox_region, const struct rcti *item_rect, const uiSearchItemTooltipData *item_tooltip_data)
int UI_icon_colorid_from_report_type(int type)
void(* uiButSearchUpdateFn)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
Definition: UI_interface.h:505
void UI_block_flag_disable(uiBlock *block, int flag)
Definition: interface.c:6072
void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data)
struct Panel * UI_panel_add_instanced(const struct bContext *C, struct ARegion *region, struct ListBase *panels, const char *panel_idname, struct PointerRNA *custom_data)
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.c:6092
uiLayout * uiLayoutBox(uiLayout *layout)
void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
Definition: interface.c:6691
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
uiBlock * uiLayoutAbsoluteBlock(uiLayout *layout)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void UI_but_number_step_size_set(uiBut *but, float step_size)
Definition: interface.c:6827
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
Definition: interface.c:6247
void uiItemS(uiLayout *layout)
eButLabelAlign
@ UI_BUT_LABEL_ALIGN_NONE
void uiItemFullO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
uiLayout * uiLayoutColumnFlow(uiLayout *layout, int number, bool align)
void UI_panels_free_instanced(const struct bContext *C, struct ARegion *region)
@ UI_LAYOUT_ALIGN_LEFT
@ UI_LAYOUT_ALIGN_RIGHT
@ UI_LAYOUT_ALIGN_EXPAND
bool UI_panel_list_matches_data(struct ARegion *region, struct ListBase *data, uiListPanelIDFromDataFunc panel_idname_func)
void UI_but_drag_set_id(uiBut *but, struct ID *id)
Definition: interface.c:6127
uiBut * uiDefIconButS(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5403
@ UI_TEMPLATE_ID_FILTER_AVAILABLE
@ UI_TEMPLATE_ID_FILTER_ALL
#define UI_UL_DEFAULT_CLASS_NAME
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, const bool free_arg, uiButSearchArgFreeFn search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
Definition: interface.c:6613
uiLayout * uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, struct PointerRNA *actptr, struct PropertyRNA *actprop)
uiBut * uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5144
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:90
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
Definition: interface.c:3542
uiBut * uiDefButS(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5020
void uiLayoutSetKeepAspect(uiLayout *layout, bool keepaspect)
int UI_icon_from_keymap_item(const struct wmKeyMapItem *kmi, int r_icon_mod[4])
void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.c:6259
struct ARegion *(* uiButSearchTooltipFn)(struct bContext *C, struct ARegion *region, const struct rcti *item_rect, void *arg, void *active)
Definition: UI_interface.h:515
@ UI_ID_BROWSE
@ UI_ID_DELETE
@ UI_ID_ADD_NEW
@ UI_ID_OPEN
@ UI_ID_PIN
@ UI_ID_RENAME
@ UI_ID_PREVIEWS
@ UI_ID_AUTO_NAME
@ UI_ID_OVERRIDE
@ UI_ID_LOCAL
@ UI_ID_FAKE_USER
@ UI_ID_ALONE
uiBut * uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.c:6355
uiBut * uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.c:5204
#define UI_DPI_FAC
Definition: UI_interface.h:309
@ UI_BLOCK_SEARCH_MENU
Definition: UI_interface.h:152
@ UI_BLOCK_LOOP
Definition: UI_interface.h:140
@ UI_BLOCK_MOVEMOUSE_QUIT
Definition: UI_interface.h:148
@ UI_BLOCK_KEEP_OPEN
Definition: UI_interface.h:149
@ UI_BLOCK_LIST_ITEM
Definition: UI_interface.h:160
@ UI_BLOCK_NO_FLIP
Definition: UI_interface.h:142
uiLayout * UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, const struct uiStyle *style)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void(* uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2)
Definition: UI_interface.h:492
void UI_block_bounds_set_text(uiBlock *block, int addval)
Definition: interface.c:591
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.c:6294
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.c:5166
void UI_block_align_begin(uiBlock *block)
Definition: interface.c:3821
uiBut * uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.c:6338
int UI_fontstyle_string_width(const struct uiFontStyle *fs, const char *str)
uiBut * uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.c:6435
void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss)
int uiLayoutGetWidth(uiLayout *layout)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr)
void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
uiBlock * UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, eUIEmbossType emboss)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
@ UI_GRAD_L_ALT
Definition: UI_interface.h:407
@ UI_GRAD_SV
Definition: UI_interface.h:399
@ UI_GRAD_V_ALT
Definition: UI_interface.h:406
@ UI_GRAD_HV
Definition: UI_interface.h:400
@ UI_GRAD_HS
Definition: UI_interface.h:401
@ UI_GRAD_H
Definition: UI_interface.h:402
void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg)
Definition: interface.c:6253
void UI_but_number_precision_set(uiBut *but, float precision)
Definition: interface.c:6836
void uiItemDecoratorR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int index)
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.c:4958
uiLayout * uiItemL_respect_property_split(uiLayout *layout, const char *text, int icon)
void uiTemplateTextureShow(uiLayout *layout, const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop)
uiBut * uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x, int y, short width, short height, float a1, float a2, const char *tip)
Definition: interface.c:6573
void UI_block_direction_set(uiBlock *block, char direction)
Definition: interface.c:6028
void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but)
Definition: interface.c:6850
@ UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED
@ UI_TEMPLATE_OP_PROPS_SHOW_EMPTY
@ UI_TEMPLATE_OP_PROPS_SHOW_TITLE
@ UI_TEMPLATE_OP_PROPS_COMPACT
@ UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT
void UI_but_func_drawextra_set(uiBlock *block, void(*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect), void *arg1, void *arg2)
#define UI_FSTYLE_WIDGET
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
void uiItemFullR(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int flag, const char *name, int icon)
@ UI_DIR_DOWN
Definition: UI_interface.h:123
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
Definition: interface.c:6301
#define UI_UNIT_X
@ UI_LAYOUT_VERTICAL
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.c:6067
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.c:5371
@ UI_BTYPE_BUT
Definition: UI_interface.h:334
@ UI_BTYPE_TOGGLE
Definition: UI_interface.h:344
@ UI_BTYPE_EXTRA
Definition: UI_interface.h:377
@ UI_BTYPE_TAB
Definition: UI_interface.h:354
@ UI_BTYPE_VECTORSCOPE
Definition: UI_interface.h:383
@ UI_BTYPE_NODE_SOCKET
Definition: UI_interface.h:385
@ UI_BTYPE_ROUNDBOX
Definition: UI_interface.h:363
@ UI_BTYPE_COLORBAND
Definition: UI_interface.h:364
@ UI_BTYPE_BUT_MENU
Definition: UI_interface.h:339
@ UI_BTYPE_HISTOGRAM
Definition: UI_interface.h:381
@ UI_BTYPE_WAVEFORM
Definition: UI_interface.h:382
@ UI_BTYPE_HSVCIRCLE
Definition: UI_interface.h:372
@ UI_BTYPE_LISTROW
Definition: UI_interface.h:371
@ UI_BTYPE_TEXT
Definition: UI_interface.h:336
@ UI_BTYPE_HSVCUBE
Definition: UI_interface.h:360
@ UI_BTYPE_LABEL
Definition: UI_interface.h:358
@ UI_BTYPE_CURVE
Definition: UI_interface.h:367
@ UI_BTYPE_ROW
Definition: UI_interface.h:335
@ UI_BTYPE_PROGRESS_BAR
Definition: UI_interface.h:384
@ UI_BTYPE_SEPR
Definition: UI_interface.h:386
@ UI_BTYPE_NUM
Definition: UI_interface.h:341
@ UI_BTYPE_CURVEPROFILE
Definition: UI_interface.h:369
@ UI_BTYPE_COLOR
Definition: UI_interface.h:353
@ UI_BTYPE_CHECKBOX
Definition: UI_interface.h:351
@ UI_BTYPE_GRIP
Definition: UI_interface.h:391
@ UI_BTYPE_ICON_TOGGLE
Definition: UI_interface.h:346
@ UI_BTYPE_SCROLL
Definition: UI_interface.h:356
#define UI_MAX_NAME_STR
Definition: UI_interface.h:91
uiBut * uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.c:5992
@ UI_BLOCK_THEME_STYLE_POPUP
Definition: UI_interface.h:671
void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2)
Definition: interface.c:6266
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
Definition: interface.c:2211
uiBut * uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.c:5587
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.c:6077
uiBlock *(* uiBlockCreateFunc)(struct bContext *C, struct ARegion *region, void *arg1)
Definition: UI_interface.h:619
void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon)
void UI_block_align_end(uiBlock *block)
Definition: interface.c:3834
int UI_icon_from_library(const struct ID *id)
int UI_icon_from_rnaptr(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big)
void UI_GetThemeColorType4ubv(int colorid, int spacetype, unsigned char col[4])
Definition: resources.c:1406
#define V2D_SCROLL_WIDTH
Definition: UI_view2d.h:68
@ WM_JOB_TYPE_DPAINT_BAKE
Definition: WM_api.h:750
@ WM_JOB_TYPE_SEQ_BUILD_PROXY
Definition: WM_api.h:747
@ WM_JOB_TYPE_COMPOSITE
Definition: WM_api.h:735
@ WM_JOB_TYPE_OBJECT_BAKE
Definition: WM_api.h:741
@ WM_JOB_TYPE_POINTCACHE
Definition: WM_api.h:749
@ WM_JOB_TYPE_CLIP_BUILD_PROXY
Definition: WM_api.h:743
@ WM_JOB_TYPE_CLIP_PREFETCH
Definition: WM_api.h:746
@ WM_JOB_TYPE_SEQ_BUILD_PREVIEW
Definition: WM_api.h:748
@ WM_JOB_TYPE_RENDER
Definition: WM_api.h:736
@ WM_JOB_TYPE_ANY
Definition: WM_api.h:734
@ WM_JOB_TYPE_OBJECT_SIM_OCEAN
Definition: WM_api.h:738
@ WM_JOB_TYPE_CLIP_SOLVE_CAMERA
Definition: WM_api.h:745
@ WM_JOB_TYPE_FILESEL_READDIR
Definition: WM_api.h:742
@ WM_JOB_TYPE_CLIP_TRACK_MARKERS
Definition: WM_api.h:744
@ WM_JOB_TYPE_OBJECT_SIM_FLUID
Definition: WM_api.h:739
@ WM_JOB_TYPE_OBJECT_BAKE_TEXTURE
Definition: WM_api.h:740
#define NC_WINDOW
Definition: WM_types.h:277
@ OPTYPE_PRESET
Definition: WM_types.h:168
@ OPTYPE_MACRO
Definition: WM_types.h:158
#define ND_SHADING_PREVIEW
Definition: WM_types.h:380
@ WM_OP_INVOKE_REGION_WIN
Definition: WM_types.h:198
@ WM_OP_INVOKE_SCREEN
Definition: WM_types.h:202
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:197
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:204
#define NC_MATERIAL
Definition: WM_types.h:281
@ OP_PROP_TAG_ADVANCED
Definition: WM_types.h:214
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint ** constraints
#define SELECT
FILE * file
Scene scene
void * user_data
#define str(s)
uint pos
uint col
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
void ui_def_but_icon(uiBut *but, const int icon, const int flag)
Definition: interface.c:4153
int ui_but_align_opposite_to_area_align_get(const ARegion *region)
int ui_id_icon_get(const bContext *C, ID *id, const bool big)
#define RNA_NO_INDEX
struct ARegion * ui_searchbox_create_generic(struct bContext *C, struct ARegion *butregion, uiButSearch *search_but)
#define UI_MENU_PADDING
void ui_layout_list_set_labels_active(uiLayout *layout)
void ui_rna_collection_search_update_fn(const struct bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
ColorPicker * ui_block_colorpicker_create(struct uiBlock *block)
#define UI_MENU_WIDTH_MIN
@ UI_HAS_ICON
void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname, bool show_labels, float icon_scale, float icon_scale_popup)
static void ui_template_palette_menu(bContext *UNUSED(C), uiLayout *layout, void *UNUSED(but_p))
static void set_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)
struct TemplateID TemplateID
static int cmpstringp(const void *p1, const void *p2)
static uiBlock * id_search_menu(bContext *C, ARegion *region, void *arg_litem)
@ CB_FUNC_RESET
@ CB_FUNC_DISTRIBUTE_LR
@ CB_FUNC_FLIP
@ CB_FUNC_DISTRIBUTE_EVENLY
static void curvemap_buttons_update(bContext *C, void *arg1_v, void *cumap_v)
void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
static void template_keymap_item_properties(uiLayout *layout, const char *title, PointerRNA *ptr)
static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, const rctf *butr, RNAUpdateCb *cb, int expand)
static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
#define template_id_context(type)
#define B_STOPFILE
static bool id_search_add(const bContext *C, TemplateID *template_ui, uiSearchItems *items, ID *id)
static uiBlock * curvemap_clipping_func(bContext *C, ARegion *region, void *cumap_v)
#define WHEEL_SIZE
#define TEMPLATE_SEARCH_TEXTBUT_HEIGHT
void uiTemplateIcon(uiLayout *layout, int icon_value, float icon_scale)
static void bone_constraint_panel_id(void *md_link, char *r_name)
static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
static void CurveProfile_buttons_zoom_out(bContext *C, void *profile_v, void *UNUSED(arg))
void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
static void template_search_add_button_operator(uiBlock *block, const char *const operator_name, const int opcontext, const int icon, const bool editable)
static void id_search_cb_tagged(const bContext *C, void *arg_template, const char *str, uiSearchItems *items)
static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
static uiBlock * CurveProfile_buttons_presets(bContext *C, ARegion *region, void *profile_v)
void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C)
void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *used_ptr, const char *used_propname, int active_layer)
static uiBlock * curvemap_tools_posslope_func(bContext *C, ARegion *region, void *cumap_v)
static void id_search_cb_objects_from_scene(const bContext *C, void *arg_template, const char *str, uiSearchItems *items, const bool UNUSED(is_first))
static void do_running_jobs(bContext *C, void *UNUSED(arg), int event)
void uiTemplateConstraintHeader(uiLayout *layout, PointerRNA *ptr)
void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propname, int type, bool levels, bool brush, bool neg_slope, bool tone)
struct IconViewMenuArgs IconViewMenuArgs
static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
static uiBlock * curvemap_tools_func(bContext *C, ARegion *region, CurveMapping *cumap, bool show_extend, int reset_mode)
static void template_search_exec_fn(bContext *C, void *arg_template, void *item)
static eAutoPropButsReturn template_operator_property_buts_draw_single(const bContext *C, wmOperator *op, uiLayout *layout, const eButLabelAlign label_align, int layout_flags)
static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter, const char *text)
void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propname)
#define TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH
static uiBlock * CurveProfile_tools_func(bContext *C, ARegion *region, CurveProfile *profile)
static void ui_template_id(uiLayout *layout, const bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, const char *menu, const char *text, int flag, int prv_rows, int prv_cols, int filter, bool use_tabs, float scale, const bool live_icon, const bool hide_buttons)
void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
static bool constraint_panel_is_bone(Panel *panel)
void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename, const char *text)
#define B_STOPRENDER
static int template_search_textbut_width(PointerRNA *ptr, PropertyRNA *name_prop)
static uiBlock * ui_icon_view_menu_cb(bContext *C, ARegion *region, void *arg_litem)
static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
struct uiTemplateOperatorPropertyPollParam uiTemplateOperatorPropertyPollParam
void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C)
void UI_context_active_but_prop_get_templateID(bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop)
static void uilist_prepare(uiList *ui_list, int len, int activei, int rows, int maxrows, int columns, uiListLayoutdata *layoutdata)
void uiTemplateFileSelectPath(uiLayout *layout, bContext *C, FileSelectParams *params)
void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, bool expand)
static void CurveProfile_buttons_reset(bContext *C, void *arg1_v, void *profile_v)
static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout)
void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, bool show_buttons, ID *parent, MTex *slot, const char *preview_id)
static uiBlock * CurveProfile_presets_func(bContext *C, ARegion *region, CurveProfile *profile)
void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int icon)
static void CurveProfile_buttons_delete(bContext *C, void *cb_v, void *profile_v)
void uiTemplateOperatorPropertyButs(const bContext *C, uiLayout *layout, wmOperator *op, eButLabelAlign label_align, short flag)
static uiBlock * CurveProfile_buttons_tools(bContext *C, ARegion *region, void *profile_v)
void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname, bool UNUSED(colors))
void uiTemplateGpencilColorPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, int rows, int cols, float scale, int filter)
static void CurveProfile_clipping_toggle(bContext *C, void *cb_v, void *profile_v)
static void template_search_buttons(const bContext *C, uiLayout *layout, TemplateSearch *template_search, const char *newop, const char *unlinkop)
static void CurveProfile_buttons_update(bContext *C, void *arg1_v, void *profile_v)
struct ComponentMenuArgs ComponentMenuArgs
static void template_ID_set_property_exec_fn(bContext *C, void *arg_template, void *item)
@ UIPROFILE_FUNC_RESET
@ UIPROFILE_FUNC_RESET_VIEW
static void colorband_tools_dofunc(bContext *C, void *coba_v, int event)
void uiTemplateColormanagedViewSettings(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr, const char *propname)
static uiBlock * component_menu(bContext *C, ARegion *region, void *args_v)
static void template_ID(const bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, int flag, const char *newop, const char *openop, const char *unlinkop, const char *text, const bool live_icon, const bool hide_buttons)
static void template_ID_tabs(const bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, const char *newop, const char *menu)
static const char * template_id_browse_tip(const StructRNA *type)
void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int rows, int cols, int filter, const bool hide_buttons)
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, bool sort_reverse, bool sort_lock)
static void template_operator_property_buts_draw_recursive(const bContext *C, wmOperator *op, uiLayout *layout, const eButLabelAlign label_align, int layout_flags, bool *r_has_advanced)
static uiBlock * colorband_tools_func(bContext *C, ARegion *region, void *coba_v)
static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *UNUSED(arg))
static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly)
void uiTemplateIDTabs(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *menu, int filter)
void uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *UNUSED(root_ptr), const char *text)
static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED(unused))
static bool id_search_allows_id(TemplateID *template_ui, const int flag, ID *id, const char *query)
#define B_STOPCOMPO
static void object_constraint_panel_id(void *md_link, char *r_name)
void uiTemplateOperatorRedoProperties(uiLayout *layout, const bContext *C)
void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float *color)
static void id_search_cb(const bContext *C, void *arg_template, const char *str, uiSearchItems *items, const bool UNUSED(is_first))
static void colorband_flip_cb(bContext *C, ColorBand *coba)
static char * progress_tooltip_func(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
static uiBlock * template_common_search_menu(const bContext *C, ARegion *region, uiButSearchUpdateFn search_update_fn, void *search_arg, uiButHandleFunc search_exec_fn, void *active_item, uiButSearchTooltipFn item_tooltip_fn, const int preview_rows, const int preview_cols, float scale)
int uiTemplateRecentFiles(uiLayout *layout, int rows)
static void template_search_add_button_name(uiBlock *block, PointerRNA *active_ptr, const StructRNA *type)
bool uiTemplateEventFromKeymapItem(struct uiLayout *layout, const char *text, const struct wmKeyMapItem *kmi, bool text_fallback)
static void CurveProfile_presets_dofunc(bContext *C, void *profile_v, int event)
#define B_STOPSEQ
void uiTemplateCurveProfile(uiLayout *layout, PointerRNA *ptr, const char *propname)
void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
static bool ui_layout_operator_buts_poll_property(struct PointerRNA *UNUSED(ptr), struct PropertyRNA *prop, void *user_data)
void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, bool value_slider, bool lock, bool lock_luminosity, bool cubic)
static void * uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname)
static uiBut * template_id_def_new_but(uiBlock *block, const ID *id, const TemplateID *template_ui, StructRNA *type, const char *const newop, const bool editable, const bool id_open, const bool use_tab_but, int but_height)
@ UICURVE_FUNC_HANDLE_VECTOR
@ UICURVE_FUNC_RESET_POS
@ UICURVE_FUNC_HANDLE_AUTO
@ UICURVE_FUNC_EXTEND_EXP
@ UICURVE_FUNC_HANDLE_AUTO_ANIM
@ UICURVE_FUNC_EXTEND_HOZ
@ UICURVE_FUNC_RESET_NEG
@ UICURVE_FUNC_RESET_VIEW
void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
struct RNAUpdateCb RNAUpdateCb
static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *UNUSED(unused))
static void gpencil_modifier_panel_id(void *md_link, char *r_name)
static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v)
void uiTemplateInputStatus(uiLayout *layout, struct bContext *C)
void uiTemplateSearchPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *searchptr, const char *searchpropname, const char *newop, const char *unlinkop, const int rows, const int cols)
static PropertyRNA * template_search_get_searchprop(PointerRNA *targetptr, PropertyRNA *targetprop, PointerRNA *searchptr, const char *const searchpropname)
static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
static char * uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
static int template_search_textbut_height(void)
static bool ui_layout_operator_properties_only_booleans(const bContext *C, wmWindowManager *wm, wmOperator *op, int layout_flags)
static uiBlock * curvemap_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v)
#define CONSTRAINT_BONE_TYPE_PANEL_PREFIX
static void template_search_add_button_searchmenu(const bContext *C, uiLayout *layout, uiBlock *block, TemplateSearch *template_search, const bool editable, const bool live_icon)
static ARegion * template_ID_search_menu_item_tooltip(bContext *C, ARegion *region, const rcti *item_rect, void *arg, void *active)
static void constraint_reorder(bContext *C, Panel *panel, int new_index)
void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
static void uilist_filter_items_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct PointerRNA *dataptr, const char *propname)
void uiTemplateSearch(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *searchptr, const char *searchpropname, const char *newop, const char *unlinkop)
#define CONSTRAINT_TYPE_PANEL_PREFIX
static uiBlock * curvemap_brush_tools_func(bContext *C, ARegion *region, void *cumap_v)
#define B_STOPOTHER
static uiBlock * template_search_menu(bContext *C, ARegion *region, void *arg_template)
static void shaderfx_panel_id(void *fx_v, char *r_idname)
struct TemplateSearch TemplateSearch
void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_constraints)
static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUpdateCb *cb)
static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, bool levels, bool brush, bool neg_slope, bool tone, RNAUpdateCb *cb)
#define B_STOPCLIP
void uiTemplateCacheFile(uiLayout *layout, const bContext *C, PointerRNA *ptr, const char *propname)
static void modifier_panel_id(void *md_link, char *r_name)
ID * UI_context_active_but_get_tab_ID(bContext *C)
static uiBlock * curvemap_brush_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v)
#define B_MATPRV
static void CurveProfile_buttons_zoom_in(bContext *C, void *profile_v, void *UNUSED(arg))
void UI_template_fix_linking(void)
static void curvemap_buttons_setclip(bContext *UNUSED(C), void *cumap_v, void *UNUSED(arg))
void uiTemplateID(uiLayout *layout, const bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter, const bool live_icon, const char *text)
static short get_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel)
static TemplateSearch * template_search_setup(PointerRNA *ptr, const char *const propname, PointerRNA *searchptr, const char *const searchpropname)
static void template_add_button_search_menu(const bContext *C, uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, uiBlockCreateFunc block_func, void *block_argN, const char *const tip, const bool use_previews, const bool editable, const bool live_icon)
static void do_preview_buttons(bContext *C, void *arg, int event)
static void curvemap_buttons_redraw(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
#define ERROR_LIBDATA_MESSAGE
static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
static void CurveProfile_tools_dofunc(bContext *C, void *profile_v, int event)
#define B_STOPANIM
static void CurveProfile_buttons_reverse(bContext *C, void *cb_v, void *profile_v)
#define B_STOPCAST
void uiTemplateComponentMenu(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name)
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))
void uiTemplateHeader(uiLayout *layout, bContext *C)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define GS(x)
Definition: iris.c:241
static char ** names
Definition: makesdna.c:162
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned a[3]
Definition: RandGen.cpp:92
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
static void area(int d1, int d2, int e1, int e2, float weights[2])
bool active
all scheduled work for the GPU.
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:115
const char * RNA_struct_identifier(const StructRNA *type)
Definition: rna_access.c:723
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
Definition: rna_access.c:2530
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:2627
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:844
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:3033
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:6550
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
bool RNA_struct_is_ID(const StructRNA *type)
Definition: rna_access.c:797
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1145
void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
Definition: rna_access.c:1466
const char * RNA_struct_ui_description(const StructRNA *type)
Definition: rna_access.c:746
char * RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:1049
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
Definition: rna_access.c:3673
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
const char * RNA_struct_ui_name(const StructRNA *type)
Definition: rna_access.c:728
bool RNA_enum_icon_from_value(const EnumPropertyItem *item, int value, int *r_icon)
Definition: rna_access.c:6494
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1155
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3641
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2317
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:3339
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2607
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1567
bool RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
Definition: rna_access.c:1593
int RNA_property_flag(PropertyRNA *prop)
Definition: rna_access.c:1192
int RNA_struct_ui_icon(const StructRNA *type)
Definition: rna_access.c:738
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
Definition: rna_access.c:761
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1218
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3543
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
Definition: rna_access.c:1657
int RNA_property_tags(PropertyRNA *prop)
Definition: rna_access.c:1203
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop_orig)
Definition: rna_access.c:2073
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2453
const char * RNA_property_ui_description(const PropertyRNA *prop)
Definition: rna_access.c:2053
int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3903
const char * RNA_property_ui_name(const PropertyRNA *prop)
Definition: rna_access.c:2043
ListBase ui_previews
ListBase panels
ListBase ui_lists
short regiontype
CBData data[32]
bool use_luminosity_lock
float luminosity_lock_value
short totpoint
CurveMapPoint * curve
float white[3]
CurveMap cm[4]
float black[3]
CurveProfilePoint * path
const char * identifier
Definition: RNA_types.h:446
struct GpencilModifierData * next
void(* panelRegister)(struct ARegionType *region_type)
int len
Definition: DNA_ID.h:84
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
struct Library * lib
Definition: DNA_ID.h:277
short flag
Definition: DNA_ID.h:288
char name[66]
Definition: DNA_ID.h:283
char filepath[1024]
Definition: DNA_ID.h:352
ID id
Definition: DNA_ID.h:349
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase scenes
Definition: BKE_main.h:146
struct ModifierData * next
void(* panelRegister)(struct ARegionType *region_type)
Definition: BKE_modifier.h:379
ListBase constraints
ListBase modifiers
ListBase greasepencil_modifiers
ListBase shader_fx
ListBase colors
short(* get_list_data_expand_flag)(const struct bContext *C, struct Panel *pa)
Definition: BKE_screen.h:278
void(* set_list_data_expand_flag)(const struct bContext *C, struct Panel *pa, short expand_flag)
Definition: BKE_screen.h:285
void(* reorder)(struct bContext *C, struct Panel *pa, int new_index)
Definition: BKE_screen.h:271
struct PanelType * type
char panelname[64]
struct Panel * next
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
PropertyRNA * prop
struct wmTimer * reporttimer
const char * message
struct Collection * master_collection
int wavefrm_height
int vecscope_height
struct ShaderFxData * next
void(* panelRegister)(struct ARegionType *region_type)
PropertyRNA * prop
uiRNACollectionSearch search_data
struct bConstraint * next
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
struct Panel * panel
uiBlock * oldblock
ListBase buttons
struct wmOperator * ui_operator
void * evil_C
eButGradientType gradient_type
eButGradientType gradient_type
struct MenuType * menu
struct bContextStore * context
void * custom_data
struct uiBut * next
void * dragpoin
eButType type
struct PointerRNA * opptr
struct PropertyRNA * rnaprop
void * func_argN
uchar col[4]
struct PointerRNA rnapoin
int * items_filter_neworder
int * items_filter_flags
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:338
uiListFilterItemsFunc filter_items
Definition: BKE_screen.h:342
uiListDrawFilterFunc draw_filter
Definition: BKE_screen.h:341
uiListDrawItemFunc draw_item
Definition: BKE_screen.h:340
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]
char preview_id[64]
char hint[UI_MAX_DRAW_STR]
char description[UI_MAX_DRAW_STR]
uiFontStyle widget
uiFontStyle widgetlabel
short shift
Definition: WM_types.h:618
const char * idname
Definition: WM_types.h:723
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:782
struct StructRNA * srna
Definition: WM_types.h:802
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:787
PropertyRNA * prop
Definition: WM_types.h:814
IDProperty * properties
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
void * customdata
Definition: WM_types.h:702
struct wmEvent * eventstate
double PIL_check_seconds_timer(void)
Definition: time.c:80
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float3 ceil(const float3 &a)
#define G(x, y, z)
uint len
bool WM_window_modal_keymap_status_draw(bContext *C, wmWindow *win, uiLayout *layout)
const char * WM_window_cursor_keymap_status_get(const wmWindow *win, int button_index, int type_index)
int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties)
bool WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
char * WM_jobs_name(wmWindowManager *wm, void *owner)
Definition: wm_jobs.c:292
bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
Definition: wm_jobs.c:223
bool WM_jobs_is_stopped(wmWindowManager *wm, void *owner)
Definition: wm_jobs.c:330
void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
Definition: wm_jobs.c:584
double WM_jobs_starttime(wmWindowManager *wm, void *owner)
Definition: wm_jobs.c:281
float WM_jobs_progress(wmWindowManager *wm, void *owner)
Definition: wm_jobs.c:239
const char * WM_key_event_string(const short type, const bool compact)
Definition: wm_keymap.c:1046
void WM_keyconfig_update_tag(wmKeyMap *keymap, wmKeyMapItem *kmi)
Definition: wm_keymap.c:1739
MenuType * WM_menutype_find(const char *idname, bool quiet)
Definition: wm_menu_type.c:44
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
const char * WM_operatortype_name(struct wmOperatorType *ot, struct PointerRNA *properties)
void WM_operator_properties_reset(wmOperator *op)
Definition: wm_operators.c:685
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
Definition: wm_operators.c:584
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:711
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
Definition: wm_operators.c:620
wmOperator * WM_operator_last_redo(const bContext *C)
uiListType * WM_uilisttype_find(const char *idname, bool quiet)