Blender  V3.3
interface_templates.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <ctype.h>
8 #include <stddef.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "DNA_brush_types.h"
15 #include "DNA_cachefile_types.h"
16 #include "DNA_collection_types.h"
17 #include "DNA_constraint_types.h"
18 #include "DNA_curveprofile_types.h"
20 #include "DNA_node_types.h"
21 #include "DNA_object_force_types.h"
22 #include "DNA_object_types.h"
23 #include "DNA_scene_types.h"
24 #include "DNA_shader_fx_types.h"
25 #include "DNA_texture_types.h"
26 
27 #include "BLI_alloca.h"
28 #include "BLI_fnmatch.h"
29 #include "BLI_listbase.h"
30 #include "BLI_math.h"
31 #include "BLI_path_util.h"
32 #include "BLI_rect.h"
33 #include "BLI_string.h"
34 #include "BLI_string_search.h"
35 #include "BLI_timecode.h"
36 #include "BLI_utildefines.h"
37 
38 #include "BLF_api.h"
39 #include "BLT_translation.h"
40 
41 #include "BKE_action.h"
42 #include "BKE_blender_version.h"
43 #include "BKE_blendfile.h"
44 #include "BKE_cachefile.h"
45 #include "BKE_colorband.h"
46 #include "BKE_colortools.h"
47 #include "BKE_constraint.h"
48 #include "BKE_context.h"
49 #include "BKE_curveprofile.h"
50 #include "BKE_global.h"
51 #include "BKE_gpencil_modifier.h"
52 #include "BKE_idprop.h"
53 #include "BKE_idtype.h"
54 #include "BKE_layer.h"
55 #include "BKE_lib_id.h"
56 #include "BKE_lib_override.h"
57 #include "BKE_linestyle.h"
58 #include "BKE_main.h"
59 #include "BKE_modifier.h"
60 #include "BKE_object.h"
61 #include "BKE_packedFile.h"
62 #include "BKE_particle.h"
63 #include "BKE_report.h"
64 #include "BKE_scene.h"
65 #include "BKE_screen.h"
66 #include "BKE_shader_fx.h"
67 
68 #include "DEG_depsgraph.h"
69 #include "DEG_depsgraph_build.h"
70 #include "DEG_depsgraph_query.h"
71 
72 #include "ED_fileselect.h"
73 #include "ED_info.h"
74 #include "ED_object.h"
75 #include "ED_render.h"
76 #include "ED_screen.h"
77 #include "ED_undo.h"
78 
79 #include "RE_engine.h"
80 
81 #include "RNA_access.h"
82 #include "RNA_prototypes.h"
83 
84 #include "WM_api.h"
85 #include "WM_types.h"
86 
87 #include "BLO_readfile.h"
88 
89 #include "UI_interface.h"
90 #include "UI_interface_icons.h"
91 #include "UI_view2d.h"
92 #include "interface_intern.h"
93 
94 #include "PIL_time.h"
95 
96 /* we may want to make this optional, disable for now. */
97 // #define USE_OP_RESET_BUT
98 
99 /* defines for templateID/TemplateSearch */
100 #define TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH (UI_UNIT_X * 6)
101 #define TEMPLATE_SEARCH_TEXTBUT_HEIGHT UI_UNIT_Y
102 
104 {
105 }
106 
107 /* -------------------------------------------------------------------- */
112 {
113  uiBlock *block = uiLayoutAbsoluteBlock(layout);
114  ED_area_header_switchbutton(C, block, 0);
115 }
116 
119 /* -------------------------------------------------------------------- */
124 {
125  char str[UI_MAX_DRAW_STR];
126  int buf_len = 0;
127 
129 
130  const char *name = RNA_property_string_get_alloc(ptr, name_prop, str, sizeof(str), &buf_len);
131 
132  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
133  const int margin = UI_UNIT_X * 0.75f;
134  const int estimated_width = UI_fontstyle_string_width(fstyle, name) + margin;
135 
136  if (name != str) {
137  MEM_freeN((void *)name);
138  }
139 
140  /* Clamp to some min/max width. */
141  return CLAMPIS(
143 }
144 
146 {
148 }
149 
154  uiLayout *layout,
155  uiBlock *block,
156  PointerRNA *ptr,
157  PropertyRNA *prop,
158  uiBlockCreateFunc block_func,
159  void *block_argN,
160  const char *const tip,
161  const bool use_previews,
162  const bool editable,
163  const bool live_icon)
164 {
165  const PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
166  ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
167  const ID *idfrom = ptr->owner_id;
168  const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
169  uiBut *but;
170 
171  if (use_previews) {
172  ARegion *region = CTX_wm_region(C);
173  /* Ugly tool header exception. */
174  const bool use_big_size = (region->regiontype != RGN_TYPE_TOOL_HEADER);
175  /* Ugly exception for screens here,
176  * drawing their preview in icon size looks ugly/useless */
177  const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
178  const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
179  const short height = UI_UNIT_Y * (use_big_size ? 6 : 1);
180  uiLayout *col = NULL;
181 
182  if (use_big_size) {
183  /* Assume column layout here. To be more correct, we should check if the layout passed to
184  * template_id is a column one, but this should work well in practice. */
185  col = uiLayoutColumn(layout, true);
186  }
187 
188  but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
189  if (use_preview_icon) {
190  const int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
192  }
193  else {
196  }
197 
198  if ((idfrom && idfrom->lib) || !editable) {
200  }
201  if (use_big_size) {
202  uiLayoutRow(col ? col : layout, true);
203  }
204  }
205  else {
206  but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
207 
208  if (live_icon) {
209  const int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type);
211  }
212  else {
214  }
215  if (id) {
216  /* default dragging of icon for id browse buttons */
217  UI_but_drag_set_id(but, id);
218  }
220 
221  if ((idfrom && idfrom->lib) || !editable) {
223  }
224  }
225 }
226 
228  ARegion *region,
229  uiButSearchUpdateFn search_update_fn,
230  void *search_arg,
231  uiButHandleFunc search_exec_fn,
232  void *active_item,
233  uiButSearchTooltipFn item_tooltip_fn,
234  const int preview_rows,
235  const int preview_cols,
236  float scale)
237 {
238  static char search[256];
239  wmWindow *win = CTX_wm_window(C);
240  uiBut *but;
241 
242  /* clear initial search string, then all items show */
243  search[0] = 0;
244 
245  uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
248 
249  /* preview thumbnails */
250  if (preview_rows > 0 && preview_cols > 0) {
251  const int w = 4 * U.widget_unit * preview_cols * scale;
252  const int h = 5 * U.widget_unit * preview_rows * scale;
253 
254  /* fake button, it holds space for search items */
255  uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
256 
257  but = uiDefSearchBut(block,
258  search,
259  0,
260  ICON_VIEWZOOM,
261  sizeof(search),
262  10,
263  0,
264  w,
265  UI_UNIT_Y,
266  preview_rows,
267  preview_cols,
268  "");
269  }
270  /* list view */
271  else {
272  const int searchbox_width = UI_searchbox_size_x();
273  const int searchbox_height = UI_searchbox_size_y();
274 
275  /* fake button, it holds space for search items */
276  uiDefBut(block,
278  0,
279  "",
280  10,
281  15,
282  searchbox_width,
283  searchbox_height,
284  NULL,
285  0,
286  0,
287  0,
288  0,
289  NULL);
290  but = uiDefSearchBut(block,
291  search,
292  0,
293  ICON_VIEWZOOM,
294  sizeof(search),
295  10,
296  0,
297  searchbox_width,
298  UI_UNIT_Y - 1,
299  0,
300  0,
301  "");
302  }
305  search_update_fn,
306  search_arg,
307  false,
308  NULL,
309  search_exec_fn,
310  active_item);
311  UI_but_func_search_set_tooltip(but, item_tooltip_fn);
312 
313  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
315 
316  /* give search-field focus */
317  UI_but_focus_on_enter_event(win, but);
318  /* this type of search menu requires undo */
319  but->flag |= UI_BUT_UNDO;
320 
321  return block;
322 }
323 
326 /* -------------------------------------------------------------------- */
330 typedef struct TemplateID {
333 
335  short idcode;
336  short filter;
338  bool preview;
339  float scale;
341 
342 /* Search browse menu, assign. */
343 static void template_ID_set_property_exec_fn(bContext *C, void *arg_template, void *item)
344 {
345  TemplateID *template_ui = (TemplateID *)arg_template;
346 
347  /* ID */
348  if (item) {
349  PointerRNA idptr;
350 
351  RNA_id_pointer_create(item, &idptr);
352  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
353  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
354  }
355 }
356 
357 static bool id_search_allows_id(TemplateID *template_ui, const int flag, ID *id, const char *query)
358 {
359  ID *id_from = template_ui->ptr.owner_id;
360 
361  /* Do self check. */
362  if ((flag & PROP_ID_SELF_CHECK) && id == id_from) {
363  return false;
364  }
365 
366  /* Use filter. */
367  if (RNA_property_type(template_ui->prop) == PROP_POINTER) {
368  PointerRNA ptr;
370  if (RNA_property_pointer_poll(&template_ui->ptr, template_ui->prop, &ptr) == 0) {
371  return false;
372  }
373  }
374 
375  /* Hide dot prefixed data-blocks, but only if filter does not force them visible. */
376  if (U.uiflag & USER_HIDE_DOT) {
377  if ((id->name[2] == '.') && (query[0] != '.')) {
378  return false;
379  }
380  }
381 
382  return true;
383 }
384 
385 static bool id_search_add(const bContext *C, TemplateID *template_ui, uiSearchItems *items, ID *id)
386 {
387  /* +1 is needed because BKE_id_ui_prefix used 3 letter prefix
388  * followed by ID_NAME-2 characters from id->name
389  */
390  char name_ui[MAX_ID_FULL_NAME_UI];
391  int iconid = ui_id_icon_get(C, id, template_ui->preview);
392  const bool use_lib_prefix = template_ui->preview || iconid;
393  const bool has_sep_char = ID_IS_LINKED(id);
394 
395  /* When using previews, the library hint (linked, overridden, missing) is added with a
396  * character prefix, otherwise we can use a icon. */
397  int name_prefix_offset;
398  BKE_id_full_name_ui_prefix_get(name_ui, id, use_lib_prefix, UI_SEP_CHAR, &name_prefix_offset);
399  if (!use_lib_prefix) {
400  iconid = UI_icon_from_library(id);
401  }
402 
403  if (!UI_search_item_add(items,
404  name_ui,
405  id,
406  iconid,
407  has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0,
408  name_prefix_offset)) {
409  return false;
410  }
411 
412  return true;
413 }
414 
415 /* ID Search browse menu, do the search */
416 static void id_search_cb(const bContext *C,
417  void *arg_template,
418  const char *str,
419  uiSearchItems *items,
420  const bool UNUSED(is_first))
421 {
422  TemplateID *template_ui = (TemplateID *)arg_template;
423  ListBase *lb = template_ui->idlb;
424  const int flag = RNA_property_flag(template_ui->prop);
425 
427 
428  /* ID listbase */
429  LISTBASE_FOREACH (ID *, id, lb) {
430  if (id_search_allows_id(template_ui, flag, id, str)) {
431  BLI_string_search_add(search, id->name + 2, id, 0);
432  }
433  }
434 
435  ID **filtered_ids;
436  const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids);
437 
438  for (int i = 0; i < filtered_amount; i++) {
439  if (!id_search_add(C, template_ui, items, filtered_ids[i])) {
440  break;
441  }
442  }
443 
444  MEM_freeN(filtered_ids);
445  BLI_string_search_free(search);
446 }
447 
451 static void id_search_cb_tagged(const bContext *C,
452  void *arg_template,
453  const char *str,
454  uiSearchItems *items)
455 {
456  TemplateID *template_ui = (TemplateID *)arg_template;
457  ListBase *lb = template_ui->idlb;
458  const int flag = RNA_property_flag(template_ui->prop);
459 
461 
462  /* ID listbase */
463  LISTBASE_FOREACH (ID *, id, lb) {
464  if (id->tag & LIB_TAG_DOIT) {
465  if (id_search_allows_id(template_ui, flag, id, str)) {
466  BLI_string_search_add(search, id->name + 2, id, 0);
467  }
468  id->tag &= ~LIB_TAG_DOIT;
469  }
470  }
471 
472  ID **filtered_ids;
473  const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_ids);
474 
475  for (int i = 0; i < filtered_amount; i++) {
476  if (!id_search_add(C, template_ui, items, filtered_ids[i])) {
477  break;
478  }
479  }
480 
481  MEM_freeN(filtered_ids);
482  BLI_string_search_free(search);
483 }
484 
489  void *arg_template,
490  const char *str,
491  uiSearchItems *items,
492  const bool UNUSED(is_first))
493 {
494  TemplateID *template_ui = (TemplateID *)arg_template;
495  ListBase *lb = template_ui->idlb;
496  Scene *scene = NULL;
497  ID *id_from = template_ui->ptr.owner_id;
498 
499  if (id_from && GS(id_from->name) == ID_SCE) {
500  scene = (Scene *)id_from;
501  }
502  else {
504  }
505 
507 
508  FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
509  ob_iter->id.tag |= LIB_TAG_DOIT;
510  }
512  id_search_cb_tagged(C, arg_template, str, items);
513 }
514 
516  bContext *C, ARegion *region, const rcti *item_rect, void *arg, void *active)
517 {
518  TemplateID *template_ui = arg;
519  ID *active_id = active;
520  StructRNA *type = RNA_property_pointer_type(&template_ui->ptr, template_ui->prop);
521 
522  uiSearchItemTooltipData tooltip_data = {0};
523 
524  tooltip_data.name = active_id->name + 2;
525  BLI_snprintf(tooltip_data.description,
526  sizeof(tooltip_data.description),
527  TIP_("Choose %s data-block to be assigned to this user"),
529  if (ID_IS_LINKED(active_id)) {
530  BLI_snprintf(tooltip_data.hint,
531  sizeof(tooltip_data.hint),
532  TIP_("Source library: %s\n%s"),
533  active_id->lib->id.name + 2,
534  active_id->lib->filepath);
535  }
536 
537  return UI_tooltip_create_from_search_item_generic(C, region, item_rect, &tooltip_data);
538 }
539 
540 /* ID Search browse menu, open */
541 static uiBlock *id_search_menu(bContext *C, ARegion *region, void *arg_litem)
542 {
543  static TemplateID template_ui;
544  PointerRNA active_item_ptr;
545  void (*id_search_update_fn)(
546  const bContext *, void *, const char *, uiSearchItems *, const bool) = id_search_cb;
547 
548  /* arg_litem is malloced, can be freed by parent button */
549  template_ui = *((TemplateID *)arg_litem);
550  active_item_ptr = RNA_property_pointer_get(&template_ui.ptr, template_ui.prop);
551 
552  if (template_ui.filter) {
553  /* Currently only used for objects. */
554  if (template_ui.idcode == ID_OB) {
555  if (template_ui.filter == UI_TEMPLATE_ID_FILTER_AVAILABLE) {
556  id_search_update_fn = id_search_cb_objects_from_scene;
557  }
558  }
559  }
560 
562  region,
563  id_search_update_fn,
564  &template_ui,
566  active_item_ptr.data,
568  template_ui.prv_rows,
569  template_ui.prv_cols,
570  template_ui.scale);
571 }
572 
575 /* -------------------------------------------------------------------- */
579 static void template_id_cb(bContext *C, void *arg_litem, void *arg_event);
580 
585  PointerRNA *r_ptr,
586  PropertyRNA **r_prop)
587 {
589 
590  memset(r_ptr, 0, sizeof(*r_ptr));
591  *r_prop = NULL;
592 
593  if (but && (but->funcN == template_id_cb) && but->func_argN) {
594  TemplateID *template_ui = but->func_argN;
595  *r_ptr = template_ui->ptr;
596  *r_prop = template_ui->prop;
597  }
598 }
599 
601  Collection *collection,
602  const int parent_level,
603  Collection **r_collection_parent_best,
604  int *r_parent_level_best)
605 {
606  if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
607  return;
608  }
609  if (ID_IS_OVERRIDABLE_LIBRARY(collection) || ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
610  if (parent_level > *r_parent_level_best) {
611  *r_parent_level_best = parent_level;
612  *r_collection_parent_best = collection;
613  }
614  }
615  for (CollectionParent *iter = collection->parents.first; iter != NULL; iter = iter->next) {
616  if (iter->collection->id.lib != collection->id.lib && ID_IS_LINKED(iter->collection)) {
617  continue;
618  }
620  iter->collection, parent_level + 1, r_collection_parent_best, r_parent_level_best);
621  }
622 }
623 
625  Collection *root_collection, ID *target_id, const bool do_parents)
626 {
627  root_collection->id.tag |= LIB_TAG_DOIT;
628 
629  /* Tag all local parents of the root collection, so that usages of the root collection and other
630  * linked ones can be replaced by the local overrides in those parents too. */
631  if (do_parents) {
632  for (CollectionParent *iter = root_collection->parents.first; iter != NULL;
633  iter = iter->next) {
634  if (ID_IS_LINKED(iter->collection)) {
635  continue;
636  }
637  iter->collection->id.tag |= LIB_TAG_DOIT;
638  }
639  }
640 
641  for (CollectionChild *iter = root_collection->children.first; iter != NULL; iter = iter->next) {
642  if (iter->collection->id.lib != root_collection->id.lib && ID_IS_LINKED(root_collection)) {
643  continue;
644  }
645  if (ID_IS_LINKED(iter->collection) && iter->collection->id.lib != target_id->lib) {
646  continue;
647  }
648  if (GS(target_id->name) == ID_OB &&
649  !BKE_collection_has_object_recursive(iter->collection, (Object *)target_id)) {
650  continue;
651  }
652  if (GS(target_id->name) == ID_GR &&
653  !BKE_collection_has_collection(iter->collection, (Collection *)target_id)) {
654  continue;
655  }
657  iter->collection, target_id, false);
658  }
659 }
660 
662  bContext *C, Main *bmain, ID *owner_id, ID *id, const char **r_undo_push_label)
663 {
664  const char *undo_push_label;
665  if (r_undo_push_label == NULL) {
666  r_undo_push_label = &undo_push_label;
667  }
668 
669  /* If this is called on an already local override, 'toggle' between user-editable state, and
670  * system override with reset. */
671  if (!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY(id)) {
672  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
673  BKE_lib_override_library_get(bmain, id, NULL, &id);
674  }
676  id->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
677  *r_undo_push_label = "Make Library Override Hierarchy Editable";
678  }
679  else {
680  BKE_lib_override_library_id_reset(bmain, id, true);
681  *r_undo_push_label = "Clear Library Override Hierarchy";
682  }
683 
687  return id;
688  }
689 
690  /* Attempt to perform a hierarchy override, based on contextual data available.
691  * NOTE: do not attempt to perform such hierarchy override at all cost, if there is not enough
692  * context, better to abort than create random overrides all over the place. */
694  RNA_warning("The data-block %s is not overridable", id->name);
695  return NULL;
696  }
697 
698  Object *object_active = CTX_data_active_object(C);
699  if (object_active == NULL && GS(owner_id->name) == ID_OB) {
700  object_active = (Object *)owner_id;
701  }
702  if (object_active != NULL) {
703  if (ID_IS_LINKED(object_active)) {
704  if (object_active->id.lib != id->lib ||
705  !ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(object_active)) {
706  /* The active object is from a different library than the overridden ID, or otherwise
707  * cannot be used in hierarchy. */
708  object_active = NULL;
709  }
710  }
711  else if (!ID_IS_OVERRIDE_LIBRARY_REAL(object_active)) {
712  /* Fully local object cannot be used in override hierarchy either. */
713  object_active = NULL;
714  }
715  }
716 
717  Collection *collection_active = CTX_data_collection(C);
718  if (collection_active == NULL && GS(owner_id->name) == ID_GR) {
719  collection_active = (Collection *)owner_id;
720  }
721  if (collection_active != NULL) {
722  if (ID_IS_LINKED(collection_active)) {
723  if (collection_active->id.lib != id->lib ||
724  !ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(collection_active)) {
725  /* The active collection is from a different library than the overridden ID, or otherwise
726  * cannot be used in hierarchy. */
727  collection_active = NULL;
728  }
729  else {
730  int parent_level_best = -1;
731  Collection *collection_parent_best = NULL;
733  collection_active, 0, &collection_parent_best, &parent_level_best);
734  collection_active = collection_parent_best;
735  }
736  }
737  else if (!ID_IS_OVERRIDE_LIBRARY_REAL(collection_active)) {
738  /* Fully local collection cannot be used in override hierarchy either. */
739  collection_active = NULL;
740  }
741  }
742  if (collection_active == NULL && object_active != NULL &&
743  (ID_IS_LINKED(object_active) || ID_IS_OVERRIDE_LIBRARY_REAL(object_active))) {
744  /* If we failed to find a valid 'active' collection so far for our override hierarchy, but do
745  * have a valid 'active' object, try to find a collection from that object. */
746  LISTBASE_FOREACH (Collection *, collection_iter, &bmain->collections) {
747  if (!(ID_IS_LINKED(collection_iter) || ID_IS_OVERRIDE_LIBRARY_REAL(collection_iter))) {
748  continue;
749  }
750  if (!BKE_collection_has_object_recursive(collection_iter, object_active)) {
751  continue;
752  }
753  int parent_level_best = -1;
754  Collection *collection_parent_best = NULL;
756  collection_iter, 0, &collection_parent_best, &parent_level_best);
757  collection_active = collection_parent_best;
758  break;
759  }
760  }
761 
762  ID *id_override = NULL;
764  ViewLayer *view_layer = CTX_data_view_layer(C);
765  switch (GS(id->name)) {
766  case ID_GR:
767  if (collection_active != NULL &&
768  BKE_collection_has_collection(collection_active, (Collection *)id)) {
770  if (object_active != NULL) {
771  object_active->id.tag |= LIB_TAG_DOIT;
772  }
774  bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override, false);
775  }
776  else if (object_active != NULL && !ID_IS_LINKED(object_active) &&
777  &object_active->instance_collection->id == id) {
778  object_active->id.tag |= LIB_TAG_DOIT;
780  scene,
781  view_layer,
782  id->lib,
783  id,
784  &object_active->id,
785  &object_active->id,
786  &id_override,
787  false);
788  }
789  break;
790  case ID_OB:
791  if (collection_active != NULL &&
792  BKE_collection_has_object_recursive(collection_active, (Object *)id)) {
794  if (object_active != NULL) {
795  object_active->id.tag |= LIB_TAG_DOIT;
796  }
798  bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override, false);
799  }
800  else {
801  if (object_active != NULL) {
802  object_active->id.tag |= LIB_TAG_DOIT;
803  }
805  bmain, scene, view_layer, NULL, id, NULL, NULL, &id_override, false);
806  BKE_scene_collections_object_remove(bmain, scene, (Object *)id, true);
808  }
809  break;
810  case ID_ME:
811  case ID_CU_LEGACY:
812  case ID_MB:
813  case ID_LT:
814  case ID_LA:
815  case ID_CA:
816  case ID_SPK:
817  case ID_AR:
818  case ID_GD:
819  case ID_CV:
820  case ID_PT:
821  case ID_VO:
822  case ID_NT: /* Essentially geometry nodes from modifier currently. */
823  if (object_active != NULL) {
824  if (collection_active != NULL &&
825  BKE_collection_has_object_recursive(collection_active, object_active)) {
827  if (object_active != NULL) {
828  object_active->id.tag |= LIB_TAG_DOIT;
829  }
831  scene,
832  view_layer,
833  NULL,
834  id,
835  &collection_active->id,
836  NULL,
837  &id_override,
838  false);
839  }
840  else {
841  object_active->id.tag |= LIB_TAG_DOIT;
843  bmain, scene, view_layer, NULL, id, &object_active->id, NULL, &id_override, false);
844  }
845  }
846  break;
847  case ID_MA:
848  case ID_TE:
849  case ID_IM:
850  RNA_warning("The type of data-block %s could not yet implemented", id->name);
851  break;
852  case ID_WO:
853  RNA_warning("The type of data-block %s could not yet implemented", id->name);
854  break;
855  case ID_PA:
856  RNA_warning("The type of data-block %s could not yet implemented", id->name);
857  break;
858  default:
859  RNA_warning("The type of data-block %s could not yet implemented", id->name);
860  break;
861  }
862  if (id_override != NULL) {
864  *r_undo_push_label = "Make Library Override Hierarchy";
865 
866  /* In theory we could rely on setting/updating the RNA ID pointer property (as done by calling
867  * code) to be enough.
868  *
869  * However, some rare ID pointers properties (like the 'active object in viewlayer' one used
870  * for the Object templateID in the Object properties) use notifiers that do not enforce a
871  * rebuild of outliner trees, leading to crashes.
872  *
873  * So for now, add some extra notifiers here. */
876  }
877  return id_override;
878 }
879 
881  Main *bmain,
882  TemplateID *template_ui,
883  PointerRNA *idptr,
884  const char **r_undo_push_label)
885 {
886  ID *id = idptr->data;
887  ID *owner_id = template_ui->ptr.owner_id;
888 
890  C, bmain, owner_id, id, r_undo_push_label);
891 
892  if (id_override != NULL) {
893  /* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it
894  * to ensure remapping of the owner property from the linked data to the newly created
895  * liboverride (note that in theory this remapping has already been done by code above), but
896  * only in case owner ID was already local ID (override or pure local data).
897  *
898  * Otherwise, owner ID will also have been overridden, and remapped already to use it's
899  * override of the data too. */
900  if (!ID_IS_LINKED(owner_id)) {
901  RNA_id_pointer_create(id_override, idptr);
902  }
903  }
904  else {
905  RNA_warning("The data-block %s could not be overridden", id->name);
906  }
907 }
908 
909 static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
910 {
911  TemplateID *template_ui = (TemplateID *)arg_litem;
912  PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
913  ID *id = idptr.data;
914  const int event = POINTER_AS_INT(arg_event);
915  const char *undo_push_label = NULL;
916 
917  switch (event) {
918  case UI_ID_NOP:
919  /* Don't do anything, typically set for buttons that execute an operator instead. They may
920  * still assign the callback so the button can be identified as part of an ID-template. See
921  * #UI_context_active_but_prop_get_templateID(). */
922  break;
923  case UI_ID_BROWSE:
924  case UI_ID_PIN:
925  RNA_warning("warning, id event %d shouldn't come here", event);
926  break;
927  case UI_ID_OPEN:
928  case UI_ID_ADD_NEW:
929  /* these call UI_context_active_but_prop_get_templateID */
930  break;
931  case UI_ID_DELETE:
932  memset(&idptr, 0, sizeof(idptr));
933  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
934  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
935 
936  if (id && CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
937  /* only way to force-remove data (on save) */
938  id_us_clear_real(id);
939  id_fake_user_clear(id);
940  id->us = 0;
941  undo_push_label = "Delete Data-Block";
942  }
943  else {
944  undo_push_label = "Unlink Data-Block";
945  }
946 
947  break;
948  case UI_ID_FAKE_USER:
949  if (id) {
950  if (id->flag & LIB_FAKEUSER) {
951  id_us_plus(id);
952  }
953  else {
954  id_us_min(id);
955  }
956  undo_push_label = "Fake User";
957  }
958  else {
959  return;
960  }
961  break;
962  case UI_ID_LOCAL:
963  if (id) {
964  Main *bmain = CTX_data_main(C);
965  if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
966  template_id_liboverride_hierarchy_make(C, bmain, template_ui, &idptr, &undo_push_label);
967  }
968  else {
969  if (BKE_lib_id_make_local(bmain, id, 0)) {
971 
972  /* Reassign to get proper updates/notifiers. */
973  idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
974  undo_push_label = "Make Local";
975  }
976  }
977  if (undo_push_label != NULL) {
978  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
979  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
980  }
981  }
982  break;
983  case UI_ID_OVERRIDE:
984  if (id && ID_IS_OVERRIDE_LIBRARY(id)) {
985  Main *bmain = CTX_data_main(C);
986  if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
987  template_id_liboverride_hierarchy_make(C, bmain, template_ui, &idptr, &undo_push_label);
988  }
989  else {
991  /* Reassign to get proper updates/notifiers. */
992  idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
993  RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
994  RNA_property_update(C, &template_ui->ptr, template_ui->prop);
995  undo_push_label = "Make Local";
996  }
997  }
998  break;
999  case UI_ID_ALONE:
1000  if (id) {
1001  const bool do_scene_obj = ((GS(id->name) == ID_OB) &&
1002  (template_ui->ptr.type == &RNA_LayerObjects));
1003 
1004  /* make copy */
1005  if (do_scene_obj) {
1006  Main *bmain = CTX_data_main(C);
1008  ED_object_single_user(bmain, scene, (struct Object *)id);
1010  DEG_relations_tag_update(bmain);
1011  }
1012  else {
1013  Main *bmain = CTX_data_main(C);
1014  id_single_user(C, id, &template_ui->ptr, template_ui->prop);
1015  DEG_relations_tag_update(bmain);
1016  }
1017  undo_push_label = "Make Single User";
1018  }
1019  break;
1020 #if 0
1021  case UI_ID_AUTO_NAME:
1022  break;
1023 #endif
1024  }
1025 
1026  if (undo_push_label != NULL) {
1027  ED_undo_push(C, undo_push_label);
1028  }
1029 }
1030 
1031 static const char *template_id_browse_tip(const StructRNA *type)
1032 {
1033  if (type) {
1034  switch ((ID_Type)RNA_type_to_ID_code(type)) {
1035  case ID_SCE:
1036  return N_("Browse Scene to be linked");
1037  case ID_OB:
1038  return N_("Browse Object to be linked");
1039  case ID_ME:
1040  return N_("Browse Mesh Data to be linked");
1041  case ID_CU_LEGACY:
1042  return N_("Browse Curve Data to be linked");
1043  case ID_MB:
1044  return N_("Browse Metaball Data to be linked");
1045  case ID_MA:
1046  return N_("Browse Material to be linked");
1047  case ID_TE:
1048  return N_("Browse Texture to be linked");
1049  case ID_IM:
1050  return N_("Browse Image to be linked");
1051  case ID_LS:
1052  return N_("Browse Line Style Data to be linked");
1053  case ID_LT:
1054  return N_("Browse Lattice Data to be linked");
1055  case ID_LA:
1056  return N_("Browse Light Data to be linked");
1057  case ID_CA:
1058  return N_("Browse Camera Data to be linked");
1059  case ID_WO:
1060  return N_("Browse World Settings to be linked");
1061  case ID_SCR:
1062  return N_("Choose Screen layout");
1063  case ID_TXT:
1064  return N_("Browse Text to be linked");
1065  case ID_SPK:
1066  return N_("Browse Speaker Data to be linked");
1067  case ID_SO:
1068  return N_("Browse Sound to be linked");
1069  case ID_AR:
1070  return N_("Browse Armature data to be linked");
1071  case ID_AC:
1072  return N_("Browse Action to be linked");
1073  case ID_NT:
1074  return N_("Browse Node Tree to be linked");
1075  case ID_BR:
1076  return N_("Browse Brush to be linked");
1077  case ID_PA:
1078  return N_("Browse Particle Settings to be linked");
1079  case ID_GD:
1080  return N_("Browse Grease Pencil Data to be linked");
1081  case ID_MC:
1082  return N_("Browse Movie Clip to be linked");
1083  case ID_MSK:
1084  return N_("Browse Mask to be linked");
1085  case ID_PAL:
1086  return N_("Browse Palette Data to be linked");
1087  case ID_PC:
1088  return N_("Browse Paint Curve Data to be linked");
1089  case ID_CF:
1090  return N_("Browse Cache Files to be linked");
1091  case ID_WS:
1092  return N_("Browse Workspace to be linked");
1093  case ID_LP:
1094  return N_("Browse LightProbe to be linked");
1095  case ID_CV:
1096  return N_("Browse Curves Data to be linked");
1097  case ID_PT:
1098  return N_("Browse Point Cloud Data to be linked");
1099  case ID_VO:
1100  return N_("Browse Volume Data to be linked");
1101  case ID_SIM:
1102  return N_("Browse Simulation to be linked");
1103 
1104  /* Use generic text. */
1105  case ID_LI:
1106  case ID_IP:
1107  case ID_KE:
1108  case ID_VF:
1109  case ID_GR:
1110  case ID_WM:
1111  break;
1112  }
1113  }
1114  return N_("Browse ID data to be linked");
1115 }
1116 
1122 static void template_id_workspace_pin_extra_icon(const TemplateID *template_ui, uiBut *but)
1123 {
1124  if ((template_ui->idcode != ID_SCE) || (template_ui->ptr.type != &RNA_Window)) {
1125  return;
1126  }
1127 
1128  const wmWindow *win = template_ui->ptr.data;
1129  const WorkSpace *workspace = WM_window_get_active_workspace(win);
1131  "WORKSPACE_OT_scene_pin_toggle",
1133  (workspace->flags & WORKSPACE_USE_PIN_SCENE) ? ICON_PINNED :
1134  ICON_UNPINNED);
1135 }
1136 
1141 #ifdef WITH_INTERNATIONAL
1142 static const char *template_id_context(StructRNA *type)
1143 {
1144  if (type) {
1146  }
1147  return BLT_I18NCONTEXT_DEFAULT;
1148 }
1149 #else
1150 # define template_id_context(type) 0
1151 #endif
1152 
1154  const ID *id,
1155  const TemplateID *template_ui,
1156  StructRNA *type,
1157  const char *const newop,
1158  const bool editable,
1159  const bool id_open,
1160  const bool use_tab_but,
1161  int but_height)
1162 {
1163  ID *idfrom = template_ui->ptr.owner_id;
1164  uiBut *but;
1165  const int w = id ? UI_UNIT_X : id_open ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
1166  const int but_type = use_tab_but ? UI_BTYPE_TAB : UI_BTYPE_BUT;
1167 
1168  /* i18n markup, does nothing! */
1201  /* NOTE: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters,
1202  * check the definition to see if a new call must be added when the limit
1203  * is exceeded. */
1204 
1205  if (newop) {
1206  but = uiDefIconTextButO(block,
1207  but_type,
1208  newop,
1210  (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
1211  (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
1212  0,
1213  0,
1214  w,
1215  but_height,
1216  NULL);
1219  }
1220  else {
1221  but = uiDefIconTextBut(block,
1222  but_type,
1223  0,
1224  (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
1225  (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
1226  0,
1227  0,
1228  w,
1229  but_height,
1230  NULL,
1231  0,
1232  0,
1233  0,
1234  0,
1235  NULL);
1238  }
1239 
1240  if ((idfrom && idfrom->lib) || !editable) {
1242  }
1243 
1244 #ifndef WITH_INTERNATIONAL
1245  UNUSED_VARS(type);
1246 #endif
1247 
1248  return but;
1249 }
1250 
1251 static void template_ID(const bContext *C,
1252  uiLayout *layout,
1253  TemplateID *template_ui,
1254  StructRNA *type,
1255  int flag,
1256  const char *newop,
1257  const char *openop,
1258  const char *unlinkop,
1259  const char *text,
1260  const bool live_icon,
1261  const bool hide_buttons)
1262 {
1263  uiBut *but;
1264  const bool editable = RNA_property_editable(&template_ui->ptr, template_ui->prop);
1265  const bool use_previews = template_ui->preview = (flag & UI_ID_PREVIEWS) != 0;
1266 
1267  PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
1268  ID *id = idptr.data;
1269  ID *idfrom = template_ui->ptr.owner_id;
1270  // lb = template_ui->idlb;
1271 
1272  /* Allow operators to take the ID from context. */
1273  uiLayoutSetContextPointer(layout, "id", &idptr);
1274 
1275  uiBlock *block = uiLayoutGetBlock(layout);
1276  UI_block_align_begin(block);
1277 
1278  if (idptr.type) {
1279  type = idptr.type;
1280  }
1281 
1282  if (text) {
1283  /* Add label respecting the separated layout property split state. */
1284  uiItemL_respect_property_split(layout, text, ICON_NONE);
1285  }
1286 
1287  if (flag & UI_ID_BROWSE) {
1289  layout,
1290  block,
1291  &template_ui->ptr,
1292  template_ui->prop,
1294  MEM_dupallocN(template_ui),
1296  use_previews,
1297  editable,
1298  live_icon);
1299  }
1300 
1301  /* text button with name */
1302  if (id) {
1303  char name[UI_MAX_NAME_STR];
1304  const bool user_alert = (id->us <= 0);
1305 
1306  const int width = template_search_textbut_width(&idptr,
1307  RNA_struct_find_property(&idptr, "name"));
1308  const int height = template_search_textbut_height();
1309 
1310  // text_idbutton(id, name);
1311  name[0] = '\0';
1312  but = uiDefButR(block,
1313  UI_BTYPE_TEXT,
1314  0,
1315  name,
1316  0,
1317  0,
1318  width,
1319  height,
1320  &idptr,
1321  "name",
1322  -1,
1323  0,
1324  0,
1325  -1,
1326  -1,
1330  if (user_alert) {
1332  }
1333 
1334  template_id_workspace_pin_extra_icon(template_ui, but);
1335 
1336  if (ID_IS_LINKED(id)) {
1337  const bool disabled = !BKE_idtype_idcode_is_localizable(GS(id->name));
1338  if (id->tag & LIB_TAG_INDIRECT) {
1339  but = uiDefIconBut(block,
1340  UI_BTYPE_BUT,
1341  0,
1342  ICON_LIBRARY_DATA_INDIRECT,
1343  0,
1344  0,
1345  UI_UNIT_X,
1346  UI_UNIT_Y,
1347  NULL,
1348  0,
1349  0,
1350  0,
1351  0,
1352  TIP_("Indirect library data-block, cannot be made local, "
1353  "Shift + Click to create a library override hierarchy"));
1354  }
1355  else {
1356  but = uiDefIconBut(block,
1357  UI_BTYPE_BUT,
1358  0,
1359  ICON_LIBRARY_DATA_DIRECT,
1360  0,
1361  0,
1362  UI_UNIT_X,
1363  UI_UNIT_Y,
1364  NULL,
1365  0,
1366  0,
1367  0,
1368  0,
1369  TIP_("Direct linked library data-block, click to make local, "
1370  "Shift + Click to create a library override"));
1371  }
1372  if (disabled) {
1374  }
1375  else {
1378  }
1379  }
1380  else if (ID_IS_OVERRIDE_LIBRARY(id)) {
1381  but = uiDefIconBut(
1382  block,
1383  UI_BTYPE_BUT,
1384  0,
1385  ICON_LIBRARY_DATA_OVERRIDE,
1386  0,
1387  0,
1388  UI_UNIT_X,
1389  UI_UNIT_Y,
1390  NULL,
1391  0,
1392  0,
1393  0,
1394  0,
1395  TIP_("Library override of linked data-block, click to make fully local, "
1396  "Shift + Click to clear the library override and toggle if it can be edited"));
1399  }
1400 
1401  if ((ID_REAL_USERS(id) > 1) && (hide_buttons == false)) {
1402  char numstr[32];
1403  short numstr_len;
1404 
1405  numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id));
1406 
1407  but = uiDefBut(
1408  block,
1409  UI_BTYPE_BUT,
1410  0,
1411  numstr,
1412  0,
1413  0,
1414  numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X,
1415  UI_UNIT_Y,
1416  NULL,
1417  0,
1418  0,
1419  0,
1420  0,
1421  TIP_("Display number of users of this data (click to make a single-user copy)"));
1422  but->flag |= UI_BUT_UNDO;
1423 
1426  if ((!BKE_id_copy_is_allowed(id)) || (idfrom && idfrom->lib) || (!editable) ||
1427  /* object in editmode - don't change data */
1428  (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) {
1430  }
1431  }
1432 
1433  if (user_alert) {
1435  }
1436 
1437  if (!ID_IS_LINKED(id)) {
1438  if (ID_IS_ASSET(id)) {
1439  uiDefIconButO(block,
1440  /* Using `_N` version allows us to get the 'active' state by default. */
1442  "ASSET_OT_clear",
1444  /* 'active' state of a toggle button uses icon + 1, so to get proper asset
1445  * icon we need to pass its value - 1 here. */
1446  ICON_ASSET_MANAGER - 1,
1447  0,
1448  0,
1449  UI_UNIT_X,
1450  UI_UNIT_Y,
1451  NULL);
1452  }
1453  else if (!(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_OB, ID_WS)) &&
1454  (hide_buttons == false)) {
1455  uiDefIconButR(block,
1457  0,
1458  ICON_FAKE_USER_OFF,
1459  0,
1460  0,
1461  UI_UNIT_X,
1462  UI_UNIT_Y,
1463  &idptr,
1464  "use_fake_user",
1465  -1,
1466  0,
1467  0,
1468  -1,
1469  -1,
1470  NULL);
1471  }
1472  }
1473  }
1474 
1475  if ((flag & UI_ID_ADD_NEW) && (hide_buttons == false)) {
1477  block, id, template_ui, type, newop, editable, flag & UI_ID_OPEN, false, UI_UNIT_X);
1478  }
1479 
1480  /* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
1481  * Only for images, sound and fonts */
1482  if (id && BKE_packedfile_id_check(id)) {
1483  but = uiDefIconButO(block,
1484  UI_BTYPE_BUT,
1485  "FILE_OT_unpack_item",
1487  ICON_PACKAGE,
1488  0,
1489  0,
1490  UI_UNIT_X,
1491  UI_UNIT_Y,
1492  TIP_("Packed File, click to unpack"));
1494 
1495  RNA_string_set(but->opptr, "id_name", id->name + 2);
1496  RNA_int_set(but->opptr, "id_type", GS(id->name));
1497  }
1498  else if (flag & UI_ID_OPEN) {
1499  const int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
1500 
1501  if (openop) {
1502  but = uiDefIconTextButO(block,
1503  UI_BTYPE_BUT,
1504  openop,
1506  ICON_FILEBROWSER,
1507  (id) ? "" : IFACE_("Open"),
1508  0,
1509  0,
1510  w,
1511  UI_UNIT_Y,
1512  NULL);
1515  }
1516  else {
1517  but = uiDefIconTextBut(block,
1518  UI_BTYPE_BUT,
1519  0,
1520  ICON_FILEBROWSER,
1521  (id) ? "" : IFACE_("Open"),
1522  0,
1523  0,
1524  w,
1525  UI_UNIT_Y,
1526  NULL,
1527  0,
1528  0,
1529  0,
1530  0,
1531  NULL);
1534  }
1535 
1536  if ((idfrom && idfrom->lib) || !editable) {
1538  }
1539  }
1540 
1541  /* delete button */
1542  /* don't use RNA_property_is_unlink here */
1543  if (id && (flag & UI_ID_DELETE) && (hide_buttons == false)) {
1544  /* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */
1545  but = NULL;
1546 
1547  if (unlinkop) {
1548  but = uiDefIconButO(block,
1549  UI_BTYPE_BUT,
1550  unlinkop,
1552  ICON_X,
1553  0,
1554  0,
1555  UI_UNIT_X,
1556  UI_UNIT_Y,
1557  NULL);
1558  /* so we can access the template from operators, font unlinking needs this */
1561  }
1562  else {
1563  if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) {
1564  but = uiDefIconBut(
1565  block,
1566  UI_BTYPE_BUT,
1567  0,
1568  ICON_X,
1569  0,
1570  0,
1571  UI_UNIT_X,
1572  UI_UNIT_Y,
1573  NULL,
1574  0,
1575  0,
1576  0,
1577  0,
1578  TIP_("Unlink data-block "
1579  "(Shift + Click to set users to zero, data will then not be saved)"));
1582 
1583  if (RNA_property_flag(template_ui->prop) & PROP_NEVER_NULL) {
1585  }
1586  }
1587  }
1588 
1589  if (but) {
1590  if ((idfrom && idfrom->lib) || !editable) {
1592  }
1593  }
1594  }
1595 
1596  if (template_ui->idcode == ID_TE) {
1597  uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop);
1598  }
1599  UI_block_align_end(block);
1600 }
1601 
1603 {
1605 
1606  if (but && but->type == UI_BTYPE_TAB) {
1607  return but->custom_data;
1608  }
1609  return NULL;
1610 }
1611 
1612 static void template_ID_tabs(const bContext *C,
1613  uiLayout *layout,
1614  TemplateID *template,
1615  StructRNA *type,
1616  int flag,
1617  const char *newop,
1618  const char *menu)
1619 {
1620  const ARegion *region = CTX_wm_region(C);
1621  const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, template->prop);
1622  MenuType *mt = menu ? WM_menutype_find(menu, false) : NULL;
1623 
1624  const int but_align = ui_but_align_opposite_to_area_align_get(region);
1625  const int but_height = UI_UNIT_Y * 1.1;
1626 
1627  uiBlock *block = uiLayoutGetBlock(layout);
1628  const uiStyle *style = UI_style_get_dpi();
1629 
1630  ListBase ordered;
1631  BKE_id_ordered_list(&ordered, template->idlb);
1632 
1633  LISTBASE_FOREACH (LinkData *, link, &ordered) {
1634  ID *id = link->data;
1635  const int name_width = UI_fontstyle_string_width(&style->widget, id->name + 2);
1636  const int but_width = name_width + UI_UNIT_X;
1637 
1638  uiButTab *tab = (uiButTab *)uiDefButR_prop(block,
1639  UI_BTYPE_TAB,
1640  0,
1641  id->name + 2,
1642  0,
1643  0,
1644  but_width,
1645  but_height,
1646  &template->ptr,
1647  template->prop,
1648  0,
1649  0.0f,
1650  sizeof(id->name) - 2,
1651  0.0f,
1652  0.0f,
1653  "");
1655  UI_but_drag_set_id(&tab->but, id);
1656  tab->but.custom_data = (void *)id;
1657  tab->menu = mt;
1658 
1659  UI_but_drawflag_enable(&tab->but, but_align);
1660  }
1661 
1662  BLI_freelistN(&ordered);
1663 
1664  if (flag & UI_ID_ADD_NEW) {
1665  const bool editable = RNA_property_editable(&template->ptr, template->prop);
1666  uiBut *but;
1667 
1668  if (active_ptr.type) {
1669  type = active_ptr.type;
1670  }
1671 
1672  but = template_id_def_new_but(block,
1673  active_ptr.data,
1674  template,
1675  type,
1676  newop,
1677  editable,
1678  flag & UI_ID_OPEN,
1679  true,
1680  but_height);
1681  UI_but_drawflag_enable(but, but_align);
1682  }
1683 }
1684 
1685 static void ui_template_id(uiLayout *layout,
1686  const bContext *C,
1687  PointerRNA *ptr,
1688  const char *propname,
1689  const char *newop,
1690  const char *openop,
1691  const char *unlinkop,
1692  /* Only respected by tabs (use_tabs). */
1693  const char *menu,
1694  const char *text,
1695  int flag,
1696  int prv_rows,
1697  int prv_cols,
1698  int filter,
1699  bool use_tabs,
1700  float scale,
1701  const bool live_icon,
1702  const bool hide_buttons)
1703 {
1704  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
1705 
1706  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
1707  RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
1708  return;
1709  }
1710 
1711  TemplateID *template_ui = MEM_callocN(sizeof(TemplateID), "TemplateID");
1712  template_ui->ptr = *ptr;
1713  template_ui->prop = prop;
1714  template_ui->prv_rows = prv_rows;
1715  template_ui->prv_cols = prv_cols;
1716  template_ui->scale = scale;
1717 
1718  if ((flag & UI_ID_PIN) == 0) {
1719  template_ui->filter = filter;
1720  }
1721  else {
1722  template_ui->filter = 0;
1723  }
1724 
1725  if (newop) {
1726  flag |= UI_ID_ADD_NEW;
1727  }
1728  if (openop) {
1729  flag |= UI_ID_OPEN;
1730  }
1731 
1733  short idcode = RNA_type_to_ID_code(type);
1734  template_ui->idcode = idcode;
1735  template_ui->idlb = which_libbase(CTX_data_main(C), idcode);
1736 
1737  /* create UI elements for this template
1738  * - template_ID makes a copy of the template data and assigns it to the relevant buttons
1739  */
1740  if (template_ui->idlb) {
1741  if (use_tabs) {
1742  layout = uiLayoutRow(layout, true);
1743  template_ID_tabs(C, layout, template_ui, type, flag, newop, menu);
1744  }
1745  else {
1746  layout = uiLayoutRow(layout, true);
1747  template_ID(C,
1748  layout,
1749  template_ui,
1750  type,
1751  flag,
1752  newop,
1753  openop,
1754  unlinkop,
1755  text,
1756  live_icon,
1757  hide_buttons);
1758  }
1759  }
1760 
1761  MEM_freeN(template_ui);
1762 }
1763 
1764 void uiTemplateID(uiLayout *layout,
1765  const bContext *C,
1766  PointerRNA *ptr,
1767  const char *propname,
1768  const char *newop,
1769  const char *openop,
1770  const char *unlinkop,
1771  int filter,
1772  const bool live_icon,
1773  const char *text)
1774 {
1775  ui_template_id(layout,
1776  C,
1777  ptr,
1778  propname,
1779  newop,
1780  openop,
1781  unlinkop,
1782  NULL,
1783  text,
1785  0,
1786  0,
1787  filter,
1788  false,
1789  1.0f,
1790  live_icon,
1791  false);
1792 }
1793 
1795  bContext *C,
1796  PointerRNA *ptr,
1797  const char *propname,
1798  const char *newop,
1799  const char *openop,
1800  const char *unlinkop,
1801  int filter,
1802  const char *text)
1803 {
1804  ui_template_id(layout,
1805  C,
1806  ptr,
1807  propname,
1808  newop,
1809  openop,
1810  unlinkop,
1811  NULL,
1812  text,
1814  0,
1815  0,
1816  filter,
1817  false,
1818  1.0f,
1819  false,
1820  false);
1821 }
1822 
1824  bContext *C,
1825  PointerRNA *ptr,
1826  const char *propname,
1827  const char *newop,
1828  const char *openop,
1829  const char *unlinkop,
1830  int rows,
1831  int cols,
1832  int filter,
1833  const bool hide_buttons)
1834 {
1835  ui_template_id(layout,
1836  C,
1837  ptr,
1838  propname,
1839  newop,
1840  openop,
1841  unlinkop,
1842  NULL,
1843  NULL,
1845  rows,
1846  cols,
1847  filter,
1848  false,
1849  1.0f,
1850  false,
1851  hide_buttons);
1852 }
1853 
1855  bContext *C,
1856  PointerRNA *ptr,
1857  const char *propname,
1858  int rows,
1859  int cols,
1860  float scale,
1861  int filter)
1862 {
1863  ui_template_id(layout,
1864  C,
1865  ptr,
1866  propname,
1867  NULL,
1868  NULL,
1869  NULL,
1870  NULL,
1871  NULL,
1873  rows,
1874  cols,
1875  filter,
1876  false,
1877  scale < 0.5f ? 0.5f : scale,
1878  false,
1879  false);
1880 }
1881 
1883  bContext *C,
1884  PointerRNA *ptr,
1885  const char *propname,
1886  const char *newop,
1887  const char *menu,
1888  int filter)
1889 {
1890  ui_template_id(layout,
1891  C,
1892  ptr,
1893  propname,
1894  newop,
1895  NULL,
1896  NULL,
1897  menu,
1898  NULL,
1900  0,
1901  0,
1902  filter,
1903  true,
1904  1.0f,
1905  false,
1906  false);
1907 }
1908 
1911 /* -------------------------------------------------------------------- */
1916  PointerRNA *ptr,
1917  const char *propname,
1918  const char *proptypename,
1919  const char *text)
1920 {
1921  /* get properties... */
1922  PropertyRNA *propID = RNA_struct_find_property(ptr, propname);
1923  PropertyRNA *propType = RNA_struct_find_property(ptr, proptypename);
1924 
1925  if (!propID || RNA_property_type(propID) != PROP_POINTER) {
1926  RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
1927  return;
1928  }
1929  if (!propType || RNA_property_type(propType) != PROP_ENUM) {
1930  RNA_warning(
1931  "pointer-type property not found: %s.%s", RNA_struct_identifier(ptr->type), proptypename);
1932  return;
1933  }
1934 
1935  /* Start drawing UI Elements using standard defines */
1936 
1937  /* NOTE: split amount here needs to be synced with normal labels */
1938  uiLayout *split = uiLayoutSplit(layout, 0.33f, false);
1939 
1940  /* FIRST PART ................................................ */
1941  uiLayout *row = uiLayoutRow(split, false);
1942 
1943  /* Label - either use the provided text, or will become "ID-Block:" */
1944  if (text) {
1945  if (text[0]) {
1946  uiItemL(row, text, ICON_NONE);
1947  }
1948  }
1949  else {
1950  uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
1951  }
1952 
1953  /* SECOND PART ................................................ */
1954  row = uiLayoutRow(split, true);
1955 
1956  /* ID-Type Selector - just have a menu of icons */
1957 
1958  /* HACK: special group just for the enum,
1959  * otherwise we get ugly layout with text included too... */
1960  uiLayout *sub = uiLayoutRow(row, true);
1962 
1963  uiItemFullR(sub, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
1964 
1965  /* ID-Block Selector - just use pointer widget... */
1966 
1967  /* HACK: special group to counteract the effects of the previous enum,
1968  * which now pushes everything too far right. */
1969  sub = uiLayoutRow(row, true);
1971 
1972  uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
1973 }
1974 
1977 /* -------------------------------------------------------------------- */
1981 typedef struct TemplateSearch {
1983 
1987 
1988 static void template_search_exec_fn(bContext *C, void *arg_template, void *item)
1989 {
1990  TemplateSearch *template_search = arg_template;
1991  uiRNACollectionSearch *coll_search = &template_search->search_data;
1992  StructRNA *type = RNA_property_pointer_type(&coll_search->target_ptr, coll_search->target_prop);
1993  PointerRNA item_ptr;
1994 
1995  RNA_pointer_create(NULL, type, item, &item_ptr);
1996  RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr, NULL);
1997  RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
1998 }
1999 
2000 static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_template)
2001 {
2002  static TemplateSearch template_search;
2003 
2004  /* arg_template is malloced, can be freed by parent button */
2005  template_search = *((TemplateSearch *)arg_template);
2006  PointerRNA active_ptr = RNA_property_pointer_get(&template_search.search_data.target_ptr,
2007  template_search.search_data.target_prop);
2008 
2010  region,
2012  &template_search,
2014  active_ptr.data,
2015  NULL,
2016  template_search.preview_rows,
2017  template_search.preview_cols,
2018  1.0f);
2019 }
2020 
2022  uiLayout *layout,
2023  uiBlock *block,
2024  TemplateSearch *template_search,
2025  const bool editable,
2026  const bool live_icon)
2027 {
2028  const char *ui_description = RNA_property_ui_description(
2029  template_search->search_data.target_prop);
2030 
2032  layout,
2033  block,
2034  &template_search->search_data.target_ptr,
2035  template_search->search_data.target_prop,
2037  MEM_dupallocN(template_search),
2038  ui_description,
2039  template_search->use_previews,
2040  editable,
2041  live_icon);
2042 }
2043 
2045  PointerRNA *active_ptr,
2046  const StructRNA *type)
2047 {
2048  /* Skip text button without an active item. */
2049  if (active_ptr->data == NULL) {
2050  return;
2051  }
2052 
2054  const int width = template_search_textbut_width(active_ptr, name_prop);
2055  const int height = template_search_textbut_height();
2056  uiDefAutoButR(block, active_ptr, name_prop, 0, "", ICON_NONE, 0, 0, width, height);
2057 }
2058 
2060  const char *const operator_name,
2061  const wmOperatorCallContext opcontext,
2062  const int icon,
2063  const bool editable)
2064 {
2065  if (!operator_name) {
2066  return;
2067  }
2068 
2069  uiBut *but = uiDefIconButO(
2070  block, UI_BTYPE_BUT, operator_name, opcontext, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
2071 
2072  if (!editable) {
2074  }
2075 }
2076 
2078  uiLayout *layout,
2079  TemplateSearch *template_search,
2080  const char *newop,
2081  const char *unlinkop)
2082 {
2083  uiBlock *block = uiLayoutGetBlock(layout);
2084  uiRNACollectionSearch *search_data = &template_search->search_data;
2085  StructRNA *type = RNA_property_pointer_type(&search_data->target_ptr, search_data->target_prop);
2086  const bool editable = RNA_property_editable(&search_data->target_ptr, search_data->target_prop);
2087  PointerRNA active_ptr = RNA_property_pointer_get(&search_data->target_ptr,
2088  search_data->target_prop);
2089 
2090  if (active_ptr.type) {
2091  /* can only get correct type when there is an active item */
2092  type = active_ptr.type;
2093  }
2094 
2095  uiLayoutRow(layout, true);
2096  UI_block_align_begin(block);
2097 
2098  template_search_add_button_searchmenu(C, layout, block, template_search, editable, false);
2099  template_search_add_button_name(block, &active_ptr, type);
2101  block, newop, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE, editable);
2102  template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
2103 
2104  UI_block_align_end(block);
2105 }
2106 
2108  PropertyRNA *targetprop,
2109  PointerRNA *searchptr,
2110  const char *const searchpropname)
2111 {
2112  PropertyRNA *searchprop;
2113 
2114  if (searchptr && !searchptr->data) {
2115  searchptr = NULL;
2116  }
2117 
2118  if (!searchptr && !searchpropname) {
2119  /* both NULL means we don't use a custom rna collection to search in */
2120  }
2121  else if (!searchptr && searchpropname) {
2122  RNA_warning("searchpropname defined (%s) but searchptr is missing", searchpropname);
2123  }
2124  else if (searchptr && !searchpropname) {
2125  RNA_warning("searchptr defined (%s) but searchpropname is missing",
2126  RNA_struct_identifier(searchptr->type));
2127  }
2128  else if (!(searchprop = RNA_struct_find_property(searchptr, searchpropname))) {
2129  RNA_warning("search collection property not found: %s.%s",
2130  RNA_struct_identifier(searchptr->type),
2131  searchpropname);
2132  }
2133  else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
2134  RNA_warning("search collection property is not a collection type: %s.%s",
2135  RNA_struct_identifier(searchptr->type),
2136  searchpropname);
2137  }
2138  /* check if searchprop has same type as targetprop */
2139  else if (RNA_property_pointer_type(searchptr, searchprop) !=
2140  RNA_property_pointer_type(targetptr, targetprop)) {
2141  RNA_warning("search collection items from %s.%s are not of type %s",
2142  RNA_struct_identifier(searchptr->type),
2143  searchpropname,
2144  RNA_struct_identifier(RNA_property_pointer_type(targetptr, targetprop)));
2145  }
2146  else {
2147  return searchprop;
2148  }
2149 
2150  return NULL;
2151 }
2152 
2154  const char *const propname,
2155  PointerRNA *searchptr,
2156  const char *const searchpropname)
2157 {
2158  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
2159 
2160  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
2161  RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
2162  return NULL;
2163  }
2164  PropertyRNA *searchprop = template_search_get_searchprop(ptr, prop, searchptr, searchpropname);
2165 
2166  TemplateSearch *template_search = MEM_callocN(sizeof(*template_search), __func__);
2167  template_search->search_data.target_ptr = *ptr;
2168  template_search->search_data.target_prop = prop;
2169  template_search->search_data.search_ptr = *searchptr;
2170  template_search->search_data.search_prop = searchprop;
2171 
2172  return template_search;
2173 }
2174 
2176  bContext *C,
2177  PointerRNA *ptr,
2178  const char *propname,
2179  PointerRNA *searchptr,
2180  const char *searchpropname,
2181  const char *newop,
2182  const char *unlinkop)
2183 {
2184  TemplateSearch *template_search = template_search_setup(
2185  ptr, propname, searchptr, searchpropname);
2186  if (template_search != NULL) {
2187  template_search_buttons(C, layout, template_search, newop, unlinkop);
2188  MEM_freeN(template_search);
2189  }
2190 }
2191 
2193  bContext *C,
2194  PointerRNA *ptr,
2195  const char *propname,
2196  PointerRNA *searchptr,
2197  const char *searchpropname,
2198  const char *newop,
2199  const char *unlinkop,
2200  const int rows,
2201  const int cols)
2202 {
2203  TemplateSearch *template_search = template_search_setup(
2204  ptr, propname, searchptr, searchpropname);
2205 
2206  if (template_search != NULL) {
2207  template_search->use_previews = true;
2208  template_search->preview_rows = rows;
2209  template_search->preview_cols = cols;
2210 
2211  template_search_buttons(C, layout, template_search, newop, unlinkop);
2212 
2213  MEM_freeN(template_search);
2214  }
2215 }
2216 
2219 /* -------------------------------------------------------------------- */
2223 /* ---------- */
2224 
2226  PointerRNA *ptr,
2227  const char *propname,
2228  PointerRNA *UNUSED(root_ptr),
2229  const char *text)
2230 {
2231  /* check that properties are valid */
2232  PropertyRNA *propPath = RNA_struct_find_property(ptr, propname);
2233  if (!propPath || RNA_property_type(propPath) != PROP_STRING) {
2234  RNA_warning("path property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
2235  return;
2236  }
2237 
2238  /* Start drawing UI Elements using standard defines */
2239  uiLayout *row = uiLayoutRow(layout, true);
2240 
2241  /* Path (existing string) Widget */
2242  uiItemR(row, ptr, propname, 0, text, ICON_RNA);
2243 
2244  /* TODO: attach something to this to make allow
2245  * searching of nested properties to 'build' the path */
2246 }
2247 
2250 /* -------------------------------------------------------------------- */
2256 static void modifier_panel_id(void *md_link, char *r_name)
2257 {
2258  ModifierData *md = (ModifierData *)md_link;
2259  BKE_modifier_type_panel_id(md->type, r_name);
2260 }
2261 
2263 {
2264  ARegion *region = CTX_wm_region(C);
2265 
2267  ListBase *modifiers = &ob->modifiers;
2268 
2269  const bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id);
2270 
2271  if (!panels_match) {
2272  UI_panels_free_instanced(C, region);
2273  ModifierData *md = modifiers->first;
2274  for (int i = 0; md; i++, md = md->next) {
2275  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
2276  if (mti->panelRegister == NULL) {
2277  continue;
2278  }
2279 
2280  char panel_idname[MAX_NAME];
2281  modifier_panel_id(md, panel_idname);
2282 
2283  /* Create custom data RNA pointer. */
2284  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2285  RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
2286 
2287  UI_panel_add_instanced(C, region, &region->panels, panel_idname, md_ptr);
2288  }
2289  }
2290  else {
2291  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
2292  Panel *panel = region->panels.first;
2293  LISTBASE_FOREACH (ModifierData *, md, modifiers) {
2294  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
2295  if (mti->panelRegister == NULL) {
2296  continue;
2297  }
2298 
2299  /* Move to the next instanced panel corresponding to the next modifier. */
2300  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
2301  panel = panel->next;
2302  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
2303  }
2304 
2305  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2306  RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
2307  UI_panel_custom_data_set(panel, md_ptr);
2308 
2309  panel = panel->next;
2310  }
2311  }
2312 }
2313 
2316 /* -------------------------------------------------------------------- */
2323 #define CONSTRAINT_TYPE_PANEL_PREFIX "OBJECT_PT_"
2324 #define CONSTRAINT_BONE_TYPE_PANEL_PREFIX "BONE_PT_"
2325 
2329 static bool constraint_panel_is_bone(Panel *panel)
2330 {
2331  return (panel->panelname[0] == 'B') && (panel->panelname[1] == 'O') &&
2332  (panel->panelname[2] == 'N') && (panel->panelname[3] == 'E');
2333 }
2334 
2338 static void constraint_reorder(bContext *C, Panel *panel, int new_index)
2339 {
2340  const bool constraint_from_bone = constraint_panel_is_bone(panel);
2341 
2342  PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
2343  bConstraint *con = (bConstraint *)con_ptr->data;
2344 
2345  PointerRNA props_ptr;
2346  wmOperatorType *ot = WM_operatortype_find("CONSTRAINT_OT_move_to_index", false);
2348  RNA_string_set(&props_ptr, "constraint", con->name);
2349  RNA_int_set(&props_ptr, "index", new_index);
2350  /* Set owner to #EDIT_CONSTRAINT_OWNER_OBJECT or #EDIT_CONSTRAINT_OWNER_BONE. */
2351  RNA_enum_set(&props_ptr, "owner", constraint_from_bone ? 1 : 0);
2353  WM_operator_properties_free(&props_ptr);
2354 }
2355 
2359 static short get_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel)
2360 {
2361  PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
2362  bConstraint *con = (bConstraint *)con_ptr->data;
2363 
2364  return con->ui_expand_flag;
2365 }
2366 
2370 static void set_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
2371 {
2372  PointerRNA *con_ptr = UI_panel_custom_data_get(panel);
2373  bConstraint *con = (bConstraint *)con_ptr->data;
2374  con->ui_expand_flag = expand_flag;
2375 }
2376 
2383 static void object_constraint_panel_id(void *md_link, char *r_name)
2384 {
2385  bConstraint *con = (bConstraint *)md_link;
2387 
2388  /* Cannot get TypeInfo for invalid/legacy constraints. */
2389  if (cti == NULL) {
2390  return;
2391  }
2392 
2393  strcpy(r_name, CONSTRAINT_TYPE_PANEL_PREFIX);
2394  strcat(r_name, cti->structName);
2395 }
2396 
2397 static void bone_constraint_panel_id(void *md_link, char *r_name)
2398 {
2399  bConstraint *con = (bConstraint *)md_link;
2401 
2402  /* Cannot get TypeInfo for invalid/legacy constraints. */
2403  if (cti == NULL) {
2404  return;
2405  }
2406 
2407  strcpy(r_name, CONSTRAINT_BONE_TYPE_PANEL_PREFIX);
2408  strcat(r_name, cti->structName);
2409 }
2410 
2411 void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_constraints)
2412 {
2413  ARegion *region = CTX_wm_region(C);
2414 
2416  ListBase *constraints = {NULL};
2417  if (use_bone_constraints) {
2419  }
2420  else if (ob != NULL) {
2421  constraints = &ob->constraints;
2422  }
2423 
2424  /* Switch between the bone panel ID function and the object panel ID function. */
2425  uiListPanelIDFromDataFunc panel_id_func = use_bone_constraints ? bone_constraint_panel_id :
2427 
2428  const bool panels_match = UI_panel_list_matches_data(region, constraints, panel_id_func);
2429 
2430  if (!panels_match) {
2431  UI_panels_free_instanced(C, region);
2432  bConstraint *con = (constraints == NULL) ? NULL : constraints->first;
2433  for (int i = 0; con; i++, con = con->next) {
2434  /* Don't show invalid/legacy constraints. */
2435  if (con->type == CONSTRAINT_TYPE_NULL) {
2436  continue;
2437  }
2438  /* Don't show temporary constraints (AutoIK and target-less IK constraints). */
2439  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
2440  bKinematicConstraint *data = con->data;
2441  if (data->flag & CONSTRAINT_IK_TEMP) {
2442  continue;
2443  }
2444  }
2445 
2446  char panel_idname[MAX_NAME];
2447  panel_id_func(con, panel_idname);
2448 
2449  /* Create custom data RNA pointer. */
2450  PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2451  RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
2452 
2453  Panel *new_panel = UI_panel_add_instanced(C, region, &region->panels, panel_idname, con_ptr);
2454 
2455  if (new_panel) {
2456  /* Set the list panel functionality function pointers since we don't do it with python. */
2459  new_panel->type->reorder = constraint_reorder;
2460  }
2461  }
2462  }
2463  else {
2464  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
2465  Panel *panel = region->panels.first;
2467  /* Don't show invalid/legacy constraints. */
2468  if (con->type == CONSTRAINT_TYPE_NULL) {
2469  continue;
2470  }
2471  /* Don't show temporary constraints (AutoIK and target-less IK constraints). */
2472  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
2473  bKinematicConstraint *data = con->data;
2474  if (data->flag & CONSTRAINT_IK_TEMP) {
2475  continue;
2476  }
2477  }
2478 
2479  /* Move to the next instanced panel corresponding to the next constraint. */
2480  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
2481  panel = panel->next;
2482  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than constraint panels. */
2483  }
2484 
2485  PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "constraint panel customdata");
2486  RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
2487  UI_panel_custom_data_set(panel, con_ptr);
2488 
2489  panel = panel->next;
2490  }
2491  }
2492 }
2493 
2494 #undef CONSTRAINT_TYPE_PANEL_PREFIX
2495 #undef CONSTRAINT_BONE_TYPE_PANEL_PREFIX
2496 
2499 /* -------------------------------------------------------------------- */
2506 static void gpencil_modifier_panel_id(void *md_link, char *r_name)
2507 {
2508  ModifierData *md = (ModifierData *)md_link;
2510 }
2511 
2513 {
2514  ARegion *region = CTX_wm_region(C);
2516  ListBase *modifiers = &ob->greasepencil_modifiers;
2517 
2518  const bool panels_match = UI_panel_list_matches_data(
2519  region, modifiers, gpencil_modifier_panel_id);
2520 
2521  if (!panels_match) {
2522  UI_panels_free_instanced(C, region);
2523  GpencilModifierData *md = modifiers->first;
2524  for (int i = 0; md; i++, md = md->next) {
2526  if (mti->panelRegister == NULL) {
2527  continue;
2528  }
2529 
2530  char panel_idname[MAX_NAME];
2531  gpencil_modifier_panel_id(md, panel_idname);
2532 
2533  /* Create custom data RNA pointer. */
2534  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2535  RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
2536 
2537  UI_panel_add_instanced(C, region, &region->panels, panel_idname, md_ptr);
2538  }
2539  }
2540  else {
2541  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
2542  Panel *panel = region->panels.first;
2543  LISTBASE_FOREACH (ModifierData *, md, modifiers) {
2545  if (mti->panelRegister == NULL) {
2546  continue;
2547  }
2548 
2549  /* Move to the next instanced panel corresponding to the next modifier. */
2550  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
2551  panel = panel->next;
2552  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
2553  }
2554 
2555  PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2556  RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
2557  UI_panel_custom_data_set(panel, md_ptr);
2558 
2559  panel = panel->next;
2560  }
2561  }
2562 }
2563 
2566 #define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
2567 
2568 /* -------------------------------------------------------------------- */
2578 static void shaderfx_panel_id(void *fx_v, char *r_idname)
2579 {
2580  ShaderFxData *fx = (ShaderFxData *)fx_v;
2581  BKE_shaderfxType_panel_id(fx->type, r_idname);
2582 }
2583 
2585 {
2586  ARegion *region = CTX_wm_region(C);
2588  ListBase *shaderfx = &ob->shader_fx;
2589 
2590  const bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id);
2591 
2592  if (!panels_match) {
2593  UI_panels_free_instanced(C, region);
2594  ShaderFxData *fx = shaderfx->first;
2595  for (int i = 0; fx; i++, fx = fx->next) {
2596  char panel_idname[MAX_NAME];
2597  shaderfx_panel_id(fx, panel_idname);
2598 
2599  /* Create custom data RNA pointer. */
2600  PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2601  RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
2602 
2603  UI_panel_add_instanced(C, region, &region->panels, panel_idname, fx_ptr);
2604  }
2605  }
2606  else {
2607  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
2608  Panel *panel = region->panels.first;
2609  LISTBASE_FOREACH (ShaderFxData *, fx, shaderfx) {
2610  const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
2611  if (fxi->panelRegister == NULL) {
2612  continue;
2613  }
2614 
2615  /* Move to the next instanced panel corresponding to the next modifier. */
2616  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
2617  panel = panel->next;
2618  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
2619  }
2620 
2621  PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
2622  RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
2623  UI_panel_custom_data_set(panel, fx_ptr);
2624 
2625  panel = panel->next;
2626  }
2627  }
2628 }
2629 
2632 /* -------------------------------------------------------------------- */
2637  const bContext *C;
2639  short flag;
2641 
2642 #ifdef USE_OP_RESET_BUT
2643 static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C),
2644  void *op_pt,
2645  void *UNUSED(arg_dummy2))
2646 {
2648 }
2649 #endif
2650 
2652  struct PropertyRNA *prop,
2653  void *user_data)
2654 {
2656 
2659  return false;
2660  }
2661  return params->op->type->poll_property(params->C, params->op, prop);
2662 }
2663 
2665  const bContext *C,
2666  wmOperator *op,
2667  uiLayout *layout,
2668  const eButLabelAlign label_align,
2669  int layout_flags)
2670 {
2671  uiBlock *block = uiLayoutGetBlock(layout);
2672  eAutoPropButsReturn return_info = 0;
2673 
2674  if (!op->properties) {
2675  const IDPropertyTemplate val = {0};
2676  op->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
2677  }
2678 
2679  /* poll() on this operator may still fail,
2680  * at the moment there is no nice feedback when this happens just fails silently. */
2681  if (!WM_operator_repeat_check(C, op)) {
2682  UI_block_lock_set(block, true, "Operator can't redo");
2683  return return_info;
2684  }
2685 
2686  /* useful for macros where only one of the steps can't be re-done */
2687  UI_block_lock_clear(block);
2688 
2689  if (layout_flags & UI_TEMPLATE_OP_PROPS_SHOW_TITLE) {
2690  uiItemL(layout, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
2691  }
2692 
2693  /* menu */
2694  if (op->type->flag & OPTYPE_PRESET) {
2695  /* XXX, no simple way to get WM_MT_operator_presets.bl_label
2696  * from python! Label remains the same always! */
2697  PointerRNA op_ptr;
2698  uiLayout *row;
2699 
2700  block->ui_operator = op;
2701 
2702  row = uiLayoutRow(layout, true);
2703  uiItemM(row, "WM_MT_operator_presets", NULL, ICON_NONE);
2704 
2705  wmOperatorType *ot = WM_operatortype_find("WM_OT_operator_preset_add", false);
2706  uiItemFullO_ptr(row, ot, "", ICON_ADD, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
2707  RNA_string_set(&op_ptr, "operator", op->type->idname);
2708 
2709  uiItemFullO_ptr(row, ot, "", ICON_REMOVE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
2710  RNA_string_set(&op_ptr, "operator", op->type->idname);
2711  RNA_boolean_set(&op_ptr, "remove_active", true);
2712  }
2713 
2714  if (op->type->ui) {
2715  op->layout = layout;
2716  op->type->ui((bContext *)C, op);
2717  op->layout = NULL;
2718 
2719  /* #UI_LAYOUT_OP_SHOW_EMPTY ignored. retun_info is ignored too.
2720  * We could allow #wmOperatorType.ui callback to return this, but not needed right now. */
2721  }
2722  else {
2724  uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = layout_flags};
2725  const bool use_prop_split = (layout_flags & UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT) == 0;
2726 
2727  PointerRNA ptr;
2728  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
2729 
2730  uiLayoutSetPropSep(layout, use_prop_split);
2731  uiLayoutSetPropDecorate(layout, false);
2732 
2733  /* main draw call */
2734  return_info = uiDefAutoButsRNA(
2735  layout,
2736  &ptr,
2738  op->type->poll_property ? &user_data : NULL,
2739  op->type->prop,
2740  label_align,
2741  (layout_flags & UI_TEMPLATE_OP_PROPS_COMPACT));
2742 
2743  if ((return_info & UI_PROP_BUTS_NONE_ADDED) &&
2744  (layout_flags & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
2745  uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
2746  }
2747  }
2748 
2749 #ifdef USE_OP_RESET_BUT
2750  /* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
2751  * but this is not so important if this button is drawn in those cases
2752  * (which isn't all that likely anyway) - campbell */
2753  if (op->properties->len) {
2754  uiBut *but;
2755  uiLayout *col; /* needed to avoid alignment errors with previous buttons */
2756 
2757  col = uiLayoutColumn(layout, false);
2758  block = uiLayoutGetBlock(col);
2759  but = uiDefIconTextBut(block,
2760  UI_BTYPE_BUT,
2761  0,
2762  ICON_FILE_REFRESH,
2763  IFACE_("Reset"),
2764  0,
2765  0,
2766  UI_UNIT_X,
2767  UI_UNIT_Y,
2768  NULL,
2769  0.0,
2770  0.0,
2771  0.0,
2772  0.0,
2773  TIP_("Reset operator defaults"));
2774  UI_but_func_set(but, ui_layout_operator_buts__reset_cb, op, NULL);
2775  }
2776 #endif
2777 
2778  /* set various special settings for buttons */
2779 
2780  /* Only do this if we're not refreshing an existing UI. */
2781  if (block->oldblock == NULL) {
2782  const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
2783 
2784  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
2785  /* no undo for buttons for operator redo panels */
2787 
2788  /* only for popups, see T36109. */
2789 
2790  /* if button is operator's default property, and a text-field, enable focus for it
2791  * - this is used for allowing operators with popups to rename stuff with fewer clicks
2792  */
2793  if (is_popup) {
2794  if ((but->rnaprop == op->type->prop) && (but->type == UI_BTYPE_TEXT)) {
2796  }
2797  }
2798  }
2799  }
2800 
2801  return return_info;
2802 }
2803 
2805  wmOperator *op,
2806  uiLayout *layout,
2807  const eButLabelAlign label_align,
2808  int layout_flags,
2809  bool *r_has_advanced)
2810 {
2811  if (op->type->flag & OPTYPE_MACRO) {
2812  LISTBASE_FOREACH (wmOperator *, macro_op, &op->macro) {
2814  C, macro_op, layout, label_align, layout_flags, r_has_advanced);
2815  }
2816  }
2817  else {
2818  /* Might want to make label_align adjustable somehow. */
2820  C, op, layout, label_align, layout_flags);
2821  if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) {
2822  if (r_has_advanced) {
2823  *r_has_advanced = true;
2824  }
2825  }
2826  }
2827 }
2828 
2830  wmWindowManager *wm,
2831  wmOperator *op,
2832  int layout_flags)
2833 {
2834  if (op->type->flag & OPTYPE_MACRO) {
2835  LISTBASE_FOREACH (wmOperator *, macro_op, &op->macro) {
2836  if (!ui_layout_operator_properties_only_booleans(C, wm, macro_op, layout_flags)) {
2837  return false;
2838  }
2839  }
2840  }
2841  else {
2842  uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = layout_flags};
2843  PointerRNA ptr;
2844 
2845  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
2846 
2847  RNA_STRUCT_BEGIN (&ptr, prop) {
2848  if (RNA_property_flag(prop) & PROP_HIDDEN) {
2849  continue;
2850  }
2851  if (op->type->poll_property &&
2853  continue;
2854  }
2855  if (RNA_property_type(prop) != PROP_BOOLEAN) {
2856  return false;
2857  }
2858  }
2860  }
2861 
2862  return true;
2863 }
2864 
2866  const bContext *C, uiLayout *layout, wmOperator *op, eButLabelAlign label_align, short flag)
2867 {
2869 
2870  /* If there are only checkbox items, don't use split layout by default. It looks weird if the
2871  * check-boxes only use half the width. */
2872  if (ui_layout_operator_properties_only_booleans(C, wm, op, flag)) {
2874  }
2875 
2876  template_operator_property_buts_draw_recursive(C, op, layout, label_align, flag, NULL);
2877 }
2878 
2880 {
2882  uiBlock *block = uiLayoutGetBlock(layout);
2883 
2884  if (op == NULL) {
2885  return;
2886  }
2887 
2888  /* Disable for now, doesn't fit well in popover. */
2889 #if 0
2890  /* Repeat button with operator name as text. */
2891  uiItemFullO(layout,
2892  "SCREEN_OT_repeat_last",
2893  WM_operatortype_name(op->type, op->ptr),
2894  ICON_NONE,
2895  NULL,
2897  0,
2898  NULL);
2899 #endif
2900 
2901  if (WM_operator_repeat_check(C, op)) {
2902  int layout_flags = 0;
2903  if (block->panel == NULL) {
2904  layout_flags = UI_TEMPLATE_OP_PROPS_SHOW_TITLE;
2905  }
2906 #if 0
2907  bool has_advanced = false;
2908 #endif
2909 
2912  C, op, layout, UI_BUT_LABEL_ALIGN_NONE, layout_flags, NULL /* &has_advanced */);
2913  /* Warning! this leaves the handle function for any other users of this block. */
2914 
2915 #if 0
2916  if (has_advanced) {
2917  uiItemO(layout, IFACE_("More..."), ICON_NONE, "SCREEN_OT_redo_last");
2918  }
2919 #endif
2920  }
2921 }
2922 
2925 /* -------------------------------------------------------------------- */
2929 #define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
2930 
2931 static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
2932 {
2933  ED_object_constraint_active_set(ob_v, con_v);
2934 }
2935 
2936 static void constraint_ops_extra_draw(bContext *C, uiLayout *layout, void *con_v)
2937 {
2938  PointerRNA op_ptr;
2939  uiLayout *row;
2940  bConstraint *con = (bConstraint *)con_v;
2941 
2942  PointerRNA ptr;
2944 
2945  RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
2946  uiLayoutSetContextPointer(layout, "constraint", &ptr);
2948 
2949  uiLayoutSetUnitsX(layout, 4.0f);
2950 
2952 
2953  /* Apply. */
2954  uiItemO(layout,
2956  ICON_CHECKMARK,
2957  "CONSTRAINT_OT_apply");
2958 
2959  /* Duplicate. */
2960  uiItemO(layout,
2962  ICON_DUPLICATE,
2963  "CONSTRAINT_OT_copy");
2964 
2965  uiItemO(layout,
2966  CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy to Selected"),
2967  0,
2968  "CONSTRAINT_OT_copy_to_selected");
2969 
2970  uiItemS(layout);
2971 
2972  /* Move to first. */
2973  row = uiLayoutColumn(layout, false);
2974  uiItemFullO(row,
2975  "CONSTRAINT_OT_move_to_index",
2976  IFACE_("Move to First"),
2977  ICON_TRIA_UP,
2978  NULL,
2980  0,
2981  &op_ptr);
2982  RNA_int_set(&op_ptr, "index", 0);
2983  if (!con->prev) {
2984  uiLayoutSetEnabled(row, false);
2985  }
2986 
2987  /* Move to last. */
2988  row = uiLayoutColumn(layout, false);
2989  uiItemFullO(row,
2990  "CONSTRAINT_OT_move_to_index",
2991  IFACE_("Move to Last"),
2992  ICON_TRIA_DOWN,
2993  NULL,
2995  0,
2996  &op_ptr);
2997  ListBase *constraint_list = ED_object_constraint_list_from_constraint(ob, con, NULL);
2998  RNA_int_set(&op_ptr, "index", BLI_listbase_count(constraint_list) - 1);
2999  if (!con->next) {
3000  uiLayoutSetEnabled(row, false);
3001  }
3002 }
3003 
3004 static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
3005 {
3006  /* unless button has own callback, it adds this callback to button */
3007  uiBlock *block = uiLayoutGetBlock(layout);
3008  UI_block_func_set(block, constraint_active_func, ob, con);
3009 
3010  PointerRNA ptr;
3011  RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
3012 
3013  if (block->panel) {
3014  UI_panel_context_pointer_set(block->panel, "constraint", &ptr);
3015  }
3016  else {
3017  uiLayoutSetContextPointer(layout, "constraint", &ptr);
3018  }
3019 
3020  /* Constraint type icon. */
3021  uiLayout *sub = uiLayoutRow(layout, false);
3022  uiLayoutSetEmboss(sub, false);
3024  uiItemL(sub, "", RNA_struct_ui_icon(ptr.type));
3025 
3027 
3028  uiLayout *row = uiLayoutRow(layout, true);
3029 
3030  uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
3031 
3032  /* Enabled eye icon. */
3033  uiItemR(row, &ptr, "enabled", 0, "", ICON_NONE);
3034 
3035  /* Extra operators menu. */
3036  uiItemMenuF(row, "", ICON_DOWNARROW_HLT, constraint_ops_extra_draw, con);
3037 
3038  /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
3039  sub = uiLayoutRow(row, false);
3042  uiItemO(sub, "", ICON_X, "CONSTRAINT_OT_delete");
3043 
3044  /* Some extra padding at the end, so the 'x' icon isn't too close to drag button. */
3045  uiItemS(layout);
3046 
3047  /* clear any locks set up for proxies/lib-linking */
3048  UI_block_lock_clear(block);
3049 }
3050 
3052 {
3053  /* verify we have valid data */
3054  if (!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
3055  RNA_warning("Expected constraint on object");
3056  return;
3057  }
3058 
3059  Object *ob = (Object *)ptr->owner_id;
3060  bConstraint *con = ptr->data;
3061 
3062  if (!ob || !(GS(ob->id.name) == ID_OB)) {
3063  RNA_warning("Expected constraint on object");
3064  return;
3065  }
3066 
3068 
3069  draw_constraint_header(layout, ob, con);
3070 }
3071 
3074 /* -------------------------------------------------------------------- */
3078 #include "DNA_light_types.h"
3079 #include "DNA_material_types.h"
3080 #include "DNA_world_types.h"
3081 
3082 #define B_MATPRV 1
3083 
3084 static void do_preview_buttons(bContext *C, void *arg, int event)
3085 {
3086  switch (event) {
3087  case B_MATPRV:
3089  break;
3090  }
3091 }
3092 
3094  bContext *C,
3095  ID *id,
3096  bool show_buttons,
3097  ID *parent,
3098  MTex *slot,
3099  const char *preview_id)
3100 {
3101  Material *ma = NULL;
3102  Tex *tex = (Tex *)id;
3103  short *pr_texture = NULL;
3104  PointerRNA material_ptr;
3105  PointerRNA texture_ptr;
3106 
3107  char _preview_id[UI_MAX_NAME_STR];
3108 
3109  if (id && !ELEM(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA, ID_LS)) {
3110  RNA_warning("Expected ID of type material, texture, light, world or line style");
3111  return;
3112  }
3113 
3114  /* decide what to render */
3115  ID *pid = id;
3116  ID *pparent = NULL;
3117 
3118  if (id && (GS(id->name) == ID_TE)) {
3119  if (parent && (GS(parent->name) == ID_MA)) {
3120  pr_texture = &((Material *)parent)->pr_texture;
3121  }
3122  else if (parent && (GS(parent->name) == ID_WO)) {
3123  pr_texture = &((World *)parent)->pr_texture;
3124  }
3125  else if (parent && (GS(parent->name) == ID_LA)) {
3126  pr_texture = &((Light *)parent)->pr_texture;
3127  }
3128  else if (parent && (GS(parent->name) == ID_LS)) {
3129  pr_texture = &((FreestyleLineStyle *)parent)->pr_texture;
3130  }
3131 
3132  if (pr_texture) {
3133  if (*pr_texture == TEX_PR_OTHER) {
3134  pid = parent;
3135  }
3136  else if (*pr_texture == TEX_PR_BOTH) {
3137  pparent = parent;
3138  }
3139  }
3140  }
3141 
3142  if (!preview_id || (preview_id[0] == '\0')) {
3143  /* If no identifier given, generate one from ID type. */
3144  BLI_snprintf(
3145  _preview_id, UI_MAX_NAME_STR, "uiPreview_%s", BKE_idtype_idcode_to_name(GS(id->name)));
3146  preview_id = _preview_id;
3147  }
3148 
3149  /* Find or add the uiPreview to the current Region. */
3150  ARegion *region = CTX_wm_region(C);
3151  uiPreview *ui_preview = BLI_findstring(
3152  &region->ui_previews, preview_id, offsetof(uiPreview, preview_id));
3153 
3154  if (!ui_preview) {
3155  ui_preview = MEM_callocN(sizeof(uiPreview), "uiPreview");
3156  BLI_strncpy(ui_preview->preview_id, preview_id, sizeof(ui_preview->preview_id));
3157  ui_preview->height = (short)(UI_UNIT_Y * 7.6f);
3158  BLI_addtail(&region->ui_previews, ui_preview);
3159  }
3160 
3161  if (ui_preview->height < UI_UNIT_Y) {
3162  ui_preview->height = UI_UNIT_Y;
3163  }
3164  else if (ui_preview->height > UI_UNIT_Y * 50) { /* Rather high upper limit, yet not insane! */
3165  ui_preview->height = UI_UNIT_Y * 50;
3166  }
3167 
3168  /* layout */
3169  uiBlock *block = uiLayoutGetBlock(layout);
3170  uiLayout *row = uiLayoutRow(layout, false);
3171  uiLayout *col = uiLayoutColumn(row, false);
3172  uiLayoutSetKeepAspect(col, true);
3173 
3174  /* add preview */
3175  uiDefBut(block,
3177  0,
3178  "",
3179  0,
3180  0,
3181  UI_UNIT_X * 10,
3182  ui_preview->height,
3183  pid,
3184  0.0,
3185  0.0,
3186  0,
3187  0,
3188  "");
3189  UI_but_func_drawextra_set(block, ED_preview_draw, pparent, slot);
3191 
3192  uiDefIconButS(block,
3193  UI_BTYPE_GRIP,
3194  0,
3195  ICON_GRIP,
3196  0,
3197  0,
3198  UI_UNIT_X * 10,
3199  (short)(UI_UNIT_Y * 0.3f),
3200  &ui_preview->height,
3201  UI_UNIT_Y,
3202  UI_UNIT_Y * 50.0f,
3203  0.0f,
3204  0.0f,
3205  "");
3206 
3207  /* add buttons */
3208  if (pid && show_buttons) {
3209  if (GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
3210  if (GS(pid->name) == ID_MA) {
3211  ma = (Material *)pid;
3212  }
3213  else {
3214  ma = (Material *)pparent;
3215  }
3216 
3217  /* Create RNA Pointer */
3218  RNA_pointer_create(&ma->id, &RNA_Material, ma, &material_ptr);
3219 
3220  col = uiLayoutColumn(row, true);
3221  uiLayoutSetScaleX(col, 1.5);
3222  uiItemR(col, &material_ptr, "preview_render_type", UI_ITEM_R_EXPAND, "", ICON_NONE);
3223 
3224  /* EEVEE preview file has baked lighting so use_preview_world has no effect,
3225  * just hide the option until this feature is supported. */
3227  uiItemS(col);
3228  uiItemR(col, &material_ptr, "use_preview_world", 0, "", ICON_WORLD);
3229  }
3230  }
3231 
3232  if (pr_texture) {
3233  /* Create RNA Pointer */
3234  RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
3235 
3236  uiLayoutRow(layout, true);
3237  uiDefButS(block,
3238  UI_BTYPE_ROW,
3239  B_MATPRV,
3240  IFACE_("Texture"),
3241  0,
3242  0,
3243  UI_UNIT_X * 10,
3244  UI_UNIT_Y,
3245  pr_texture,
3246  10,
3248  0,
3249  0,
3250  "");
3251  if (GS(parent->name) == ID_MA) {
3252  uiDefButS(block,
3253  UI_BTYPE_ROW,
3254  B_MATPRV,
3255  IFACE_("Material"),
3256  0,
3257  0,
3258  UI_UNIT_X * 10,
3259  UI_UNIT_Y,
3260  pr_texture,
3261  10,
3262  TEX_PR_OTHER,
3263  0,
3264  0,
3265  "");
3266  }
3267  else if (GS(parent->name) == ID_LA) {
3268  uiDefButS(block,
3269  UI_BTYPE_ROW,
3270  B_MATPRV,
3272  0,
3273  0,
3274  UI_UNIT_X * 10,
3275  UI_UNIT_Y,
3276  pr_texture,
3277  10,
3278  TEX_PR_OTHER,
3279  0,
3280  0,
3281  "");
3282  }
3283  else if (GS(parent->name) == ID_WO) {
3284  uiDefButS(block,
3285  UI_BTYPE_ROW,
3286  B_MATPRV,
3287  IFACE_("World"),
3288  0,
3289  0,
3290  UI_UNIT_X * 10,
3291  UI_UNIT_Y,
3292  pr_texture,
3293  10,
3294  TEX_PR_OTHER,
3295  0,
3296  0,
3297  "");
3298  }
3299  else if (GS(parent->name) == ID_LS) {
3300  uiDefButS(block,
3301  UI_BTYPE_ROW,
3302  B_MATPRV,
3303  IFACE_("Line Style"),
3304  0,
3305  0,
3306  UI_UNIT_X * 10,
3307  UI_UNIT_Y,
3308  pr_texture,
3309  10,
3310  TEX_PR_OTHER,
3311  0,
3312  0,
3313  "");
3314  }
3315  uiDefButS(block,
3316  UI_BTYPE_ROW,
3317  B_MATPRV,
3318  IFACE_("Both"),
3319  0,
3320  0,
3321  UI_UNIT_X * 10,
3322  UI_UNIT_Y,
3323  pr_texture,
3324  10,
3325  TEX_PR_BOTH,
3326  0,
3327  0,
3328  "");
3329 
3330  /* Alpha button for texture preview */
3331  if (*pr_texture != TEX_PR_OTHER) {
3332  row = uiLayoutRow(layout, false);
3333  uiItemR(row, &texture_ptr, "use_preview_alpha", 0, NULL, ICON_NONE);
3334  }
3335  }
3336  }
3337 }
3338 
3341 /* -------------------------------------------------------------------- */
3345 typedef struct RNAUpdateCb {
3349 
3350 static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
3351 {
3352  RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
3353 
3354  /* we call update here on the pointer property, this way the
3355  * owner of the curve mapping can still define its own update
3356  * and notifier, even if the CurveMapping struct is shared. */
3357  RNA_property_update(C, &cb->ptr, cb->prop);
3358 }
3359 
3360 enum {
3365 };
3366 
3368 {
3369  CBData data_tmp[MAXCOLORBAND];
3370 
3371  for (int a = 0; a < coba->tot; a++) {
3372  data_tmp[a] = coba->data[coba->tot - (a + 1)];
3373  }
3374  for (int a = 0; a < coba->tot; a++) {
3375  data_tmp[a].pos = 1.0f - data_tmp[a].pos;
3376  coba->data[a] = data_tmp[a];
3377  }
3378 
3379  /* May as well flip the `cur`. */
3380  coba->cur = coba->tot - (coba->cur + 1);
3381 
3382  ED_undo_push(C, "Flip Color Ramp");
3383 }
3384 
3385 static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly)
3386 {
3387  if (coba->tot > 1) {
3388  const int tot = evenly ? coba->tot - 1 : coba->tot;
3389  const float gap = 1.0f / tot;
3390  float pos = 0.0f;
3391  for (int a = 0; a < coba->tot; a++) {
3392  coba->data[a].pos = pos;
3393  pos += gap;
3394  }
3395  ED_undo_push(C, evenly ? "Distribute Stops Evenly" : "Distribute Stops from Left");
3396  }
3397 }
3398 
3399 static void colorband_tools_dofunc(bContext *C, void *coba_v, int event)
3400 {
3401  ColorBand *coba = coba_v;
3402 
3403  switch (event) {
3404  case CB_FUNC_FLIP:
3405  colorband_flip_cb(C, coba);
3406  break;
3407  case CB_FUNC_DISTRIBUTE_LR:
3408  colorband_distribute_cb(C, coba, false);
3409  break;
3411  colorband_distribute_cb(C, coba, true);
3412  break;
3413  case CB_FUNC_RESET:
3414  BKE_colorband_init(coba, true);
3415  ED_undo_push(C, "Reset Color Ramp");
3416  break;
3417  }
3419 }
3420 
3421 static uiBlock *colorband_tools_func(bContext *C, ARegion *region, void *coba_v)
3422 {
3423  const uiStyle *style = UI_style_get_dpi();
3424  ColorBand *coba = coba_v;
3425  short yco = 0;
3426  const short menuwidth = 10 * UI_UNIT_X;
3427 
3428  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS_PULLDOWN);
3430 
3431  uiLayout *layout = UI_block_layout(block,
3434  0,
3435  0,
3437  0,
3439  style);
3440  UI_block_layout_set_current(block, layout);
3441  {
3442  PointerRNA coba_ptr;
3443  RNA_pointer_create(NULL, &RNA_ColorRamp, coba, &coba_ptr);
3444  uiLayoutSetContextPointer(layout, "color_ramp", &coba_ptr);
3445  }
3446 
3447  /* We could move these to operators,
3448  * although this isn't important unless we want to assign key shortcuts to them. */
3449  {
3450  uiDefIconTextBut(block,
3452  1,
3453  ICON_BLANK1,
3454  IFACE_("Flip Color Ramp"),
3455  0,
3456  yco -= UI_UNIT_Y,
3457  menuwidth,
3458  UI_UNIT_Y,
3459  NULL,
3460  0.0,
3461  0.0,
3462  0,
3463  CB_FUNC_FLIP,
3464  "");
3465  uiDefIconTextBut(block,
3467  1,
3468  ICON_BLANK1,
3469  IFACE_("Distribute Stops from Left"),
3470  0,
3471  yco -= UI_UNIT_Y,
3472  menuwidth,
3473  UI_UNIT_Y,
3474  NULL,
3475  0.0,
3476  0.0,
3477  0,
3479  "");
3480  uiDefIconTextBut(block,
3482  1,
3483  ICON_BLANK1,
3484  IFACE_("Distribute Stops Evenly"),
3485  0,
3486  yco -= UI_UNIT_Y,
3487  menuwidth,
3488  UI_UNIT_Y,
3489  NULL,
3490  0.0,
3491  0.0,
3492  0,
3494  "");
3495 
3496  uiItemO(layout, IFACE_("Eyedropper"), ICON_EYEDROPPER, "UI_OT_eyedropper_colorramp");
3497 
3498  uiDefIconTextBut(block,
3500  1,
3501  ICON_BLANK1,
3502  IFACE_("Reset Color Ramp"),
3503  0,
3504  yco -= UI_UNIT_Y,
3505  menuwidth,
3506  UI_UNIT_Y,
3507  NULL,
3508  0.0,
3509  0.0,
3510  0,
3511  CB_FUNC_RESET,
3512  "");
3513  }
3514 
3516  UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
3517 
3518  return block;
3519 }
3520 
3521 static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
3522 {
3523  ColorBand *coba = coba_v;
3524  float pos = 0.5f;
3525 
3526  if (coba->tot > 1) {
3527  if (coba->cur > 0) {
3528  pos = (coba->data[coba->cur - 1].pos + coba->data[coba->cur].pos) * 0.5f;
3529  }
3530  else {
3531  pos = (coba->data[coba->cur + 1].pos + coba->data[coba->cur].pos) * 0.5f;
3532  }
3533  }
3534 
3535  if (BKE_colorband_element_add(coba, pos)) {
3536  rna_update_cb(C, cb_v, NULL);
3537  ED_undo_push(C, "Add Color Ramp Stop");
3538  }
3539 }
3540 
3541 static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
3542 {
3543  ColorBand *coba = coba_v;
3544 
3545  if (BKE_colorband_element_remove(coba, coba->cur)) {
3546  ED_undo_push(C, "Delete Color Ramp Stop");
3547  rna_update_cb(C, cb_v, NULL);
3548  }
3549 }
3550 
3551 static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
3552 {
3553  uiBut *bt = bt_v;
3554  ColorBand *coba = coba_v;
3555 
3556  /* Sneaky update here, we need to sort the color-band points to be in order,
3557  * however the RNA pointer then is wrong, so we update it */
3559  bt->rnapoin.data = coba->data + coba->cur;
3560 }
3561 
3563  uiBlock *block,
3564  ColorBand *coba,
3565  const rctf *butr,
3566  RNAUpdateCb *cb,
3567  int expand)
3568 {
3569  uiBut *bt;
3570  const float unit = BLI_rctf_size_x(butr) / 14.0f;
3571  const float xs = butr->xmin;
3572  const float ys = butr->ymin;
3573 
3574  PointerRNA ptr;
3575  RNA_pointer_create(cb->ptr.owner_id, &RNA_ColorRamp, coba, &ptr);
3576 
3577  uiLayout *split = uiLayoutSplit(layout, 0.4f, false);
3578 
3580  UI_block_align_begin(block);
3581  uiLayout *row = uiLayoutRow(split, false);
3582 
3583  bt = uiDefIconTextBut(block,
3584  UI_BTYPE_BUT,
3585  0,
3586  ICON_ADD,
3587  "",
3588  0,
3589  0,
3590  2.0f * unit,
3591  UI_UNIT_Y,
3592  NULL,
3593  0,
3594  0,
3595  0,
3596  0,
3597  TIP_("Add a new color stop to the color ramp"));
3599 
3600  bt = uiDefIconTextBut(block,
3601  UI_BTYPE_BUT,
3602  0,
3603  ICON_REMOVE,
3604  "",
3605  xs + 2.0f * unit,
3606  ys + UI_UNIT_Y,
3607  2.0f * unit,
3608  UI_UNIT_Y,
3609  NULL,
3610  0,
3611  0,
3612  0,
3613  0,
3614  TIP_("Delete the active position"));
3616 
3617  bt = uiDefIconBlockBut(block,
3619  coba,
3620  0,
3621  ICON_DOWNARROW_HLT,
3622  xs + 4.0f * unit,
3623  ys + UI_UNIT_Y,
3624  2.0f * unit,
3625  UI_UNIT_Y,
3626  TIP_("Tools"));
3628 
3629  UI_block_align_end(block);
3631 
3632  row = uiLayoutRow(split, false);
3633 
3634  UI_block_align_begin(block);
3635  uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE);
3637  uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE);
3638  }
3639  else { /* COLBAND_BLEND_RGB */
3640  uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
3641  }
3642  UI_block_align_end(block);
3643 
3644  row = uiLayoutRow(layout, false);
3645 
3646  bt = uiDefBut(block,
3648  0,
3649  "",
3650  xs,
3651  ys,
3652  BLI_rctf_size_x(butr),
3653  UI_UNIT_Y,
3654  coba,
3655  0,
3656  0,
3657  0,
3658  0,
3659  "");
3661 
3662  row = uiLayoutRow(layout, false);
3663 
3664  if (coba->tot) {
3665  CBData *cbd = coba->data + coba->cur;
3666 
3667  RNA_pointer_create(cb->ptr.owner_id, &RNA_ColorRampElement, cbd, &ptr);
3668 
3669  if (!expand) {
3670  split = uiLayoutSplit(layout, 0.3f, false);
3671 
3672  row = uiLayoutRow(split, false);
3673  bt = uiDefButS(block,
3674  UI_BTYPE_NUM,
3675  0,
3676  "",
3677  0,
3678  0,
3679  5.0f * UI_UNIT_X,
3680  UI_UNIT_Y,
3681  &coba->cur,
3682  0.0,
3683  (float)(MAX2(0, coba->tot - 1)),
3684  0,
3685  0,
3686  TIP_("Choose active color stop"));
3688 
3689  row = uiLayoutRow(split, false);
3690  uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
3691 
3692  row = uiLayoutRow(layout, false);
3693  uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
3694  }
3695  else {
3696  split = uiLayoutSplit(layout, 0.5f, false);
3697  uiLayout *subsplit = uiLayoutSplit(split, 0.35f, false);
3698 
3699  row = uiLayoutRow(subsplit, false);
3700  bt = uiDefButS(block,
3701  UI_BTYPE_NUM,
3702  0,
3703  "",
3704  0,
3705  0,
3706  5.0f * UI_UNIT_X,
3707  UI_UNIT_Y,
3708  &coba->cur,
3709  0.0,
3710  (float)(MAX2(0, coba->tot - 1)),
3711  0,
3712  0,
3713  TIP_("Choose active color stop"));
3715 
3716  row = uiLayoutRow(subsplit, false);
3717  uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
3718 
3719  row = uiLayoutRow(split, false);
3720  uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
3721  }
3722 
3723  /* Some special (rather awkward) treatment to update UI state on certain property changes. */
3724  LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
3725  if (but->rnapoin.data != ptr.data) {
3726  continue;
3727  }
3728  if (!but->rnaprop) {
3729  continue;
3730  }
3731 
3732  const char *prop_identifier = RNA_property_identifier(but->rnaprop);
3733  if (STREQ(prop_identifier, "position")) {
3734  UI_but_func_set(but, colorband_update_cb, but, coba);
3735  }
3736 
3737  if (STREQ(prop_identifier, "color")) {
3739  }
3740  }
3741  }
3742 }
3743 
3744 void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, bool expand)
3745 {
3746  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3747 
3748  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
3749  return;
3750  }
3751 
3752  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
3753  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp)) {
3754  return;
3755  }
3756 
3757  RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
3758  cb->ptr = *ptr;
3759  cb->prop = prop;
3760 
3761  rctf rect;
3762  rect.xmin = 0;
3763  rect.xmax = 10.0f * UI_UNIT_X;
3764  rect.ymin = 0;
3765  rect.ymax = 19.5f * UI_UNIT_X;
3766 
3767  uiBlock *block = uiLayoutAbsoluteBlock(layout);
3768 
3769  ID *id = cptr.owner_id;
3771 
3772  colorband_buttons_layout(layout, block, cptr.data, &rect, cb, expand);
3773 
3774  UI_block_lock_clear(block);
3775 
3776  MEM_freeN(cb);
3777 }
3778 
3781 /* -------------------------------------------------------------------- */
3785 void uiTemplateIcon(uiLayout *layout, int icon_value, float icon_scale)
3786 {
3787  uiBlock *block = uiLayoutAbsoluteBlock(layout);
3788  uiBut *but = uiDefIconBut(block,
3790  0,
3791  ICON_X,
3792  0,
3793  0,
3794  UI_UNIT_X * icon_scale,
3795  UI_UNIT_Y * icon_scale,
3796  NULL,
3797  0.0,
3798  0.0,
3799  0.0,
3800  0.0,
3801  "");
3802  ui_def_but_icon(but, icon_value, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
3803 }
3804 
3807 /* -------------------------------------------------------------------- */
3811 typedef struct IconViewMenuArgs {
3815  float icon_scale;
3817 
3818 /* ID Search browse menu, open */
3819 static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *region, void *arg_litem)
3820 {
3821  static IconViewMenuArgs args;
3822 
3823  /* arg_litem is malloced, can be freed by parent button */
3824  args = *((IconViewMenuArgs *)arg_litem);
3825  const int w = UI_UNIT_X * (args.icon_scale);
3826  const int h = UI_UNIT_X * (args.icon_scale + args.show_labels);
3827 
3828  uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS_PULLDOWN);
3831 
3832  bool free;
3833  const EnumPropertyItem *item;
3834  RNA_property_enum_items(C, &args.ptr, args.prop, &item, NULL, &free);
3835 
3836  for (int a = 0; item[a].identifier; a++) {
3837  const int x = (a % 8) * w;
3838  const int y = -(a / 8) * h;
3839 
3840  const int icon = item[a].icon;
3841  const int value = item[a].value;
3842  uiBut *but;
3843  if (args.show_labels) {
3844  but = uiDefIconTextButR_prop(block,
3845  UI_BTYPE_ROW,
3846  0,
3847  icon,
3848  item[a].name,
3849  x,
3850  y,
3851  w,
3852  h,
3853  &args.ptr,
3854  args.prop,
3855  -1,
3856  0,
3857  value,
3858  -1,
3859  -1,
3860  NULL);
3861  }
3862  else {
3863  but = uiDefIconButR_prop(block,
3864  UI_BTYPE_ROW,
3865  0,
3866  icon,
3867  x,
3868  y,
3869  w,
3870  h,
3871  &args.ptr,
3872  args.prop,
3873  -1,
3874  0,
3875  value,
3876  -1,
3877  -1,
3878  NULL);
3879  }
3881  }
3882 
3883  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
3885 
3886  if (free) {
3887  MEM_freeN((void *)item);
3888  }
3889 
3890  return block;
3891 }
3892 
3894  PointerRNA *ptr,
3895  const char *propname,
3896  bool show_labels,
3897  float icon_scale,
3898  float icon_scale_popup)
3899 {
3900  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3901 
3902  if (!prop || RNA_property_type(prop) != PROP_ENUM) {
3903  RNA_warning(
3904  "property of type Enum not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
3905  return;
3906  }
3907 
3908  uiBlock *block = uiLayoutAbsoluteBlock(layout);
3909 
3910  int tot_items;
3911  bool free_items;
3912  const EnumPropertyItem *items;
3913  RNA_property_enum_items(block->evil_C, ptr, prop, &items, &tot_items, &free_items);
3914  const int value = RNA_property_enum_get(ptr, prop);
3915  int icon = ICON_NONE;
3916  RNA_enum_icon_from_value(items, value, &icon);
3917 
3918  uiBut *but;
3919  if (RNA_property_editable(ptr, prop)) {
3920  IconViewMenuArgs *cb_args = MEM_callocN(sizeof(IconViewMenuArgs), __func__);
3921  cb_args->ptr = *ptr;
3922  cb_args->prop = prop;
3923  cb_args->show_labels = show_labels;
3924  cb_args->icon_scale = icon_scale_popup;
3925 
3926  but = uiDefBlockButN(block,
3928  cb_args,
3929  "",
3930  0,
3931  0,
3932  UI_UNIT_X * icon_scale,
3933  UI_UNIT_Y * icon_scale,
3934  "");
3935  }
3936  else {
3937  but = uiDefIconBut(block,
3939  0,
3940  ICON_X,
3941  0,
3942  0,
3943  UI_UNIT_X * icon_scale,
3944  UI_UNIT_Y * icon_scale,
3945  NULL,
3946  0.0,
3947  0.0,
3948  0.0,
3949  0.0,
3950  "");
3951  }
3952 
3954 
3955  if (free_items) {
3956  MEM_freeN((void *)items);
3957  }
3958 }
3959 
3962 /* -------------------------------------------------------------------- */
3966 void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
3967 {
3968  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
3969 
3970  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
3971  return;
3972  }
3973 
3974  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
3975  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Histogram)) {
3976  return;
3977  }
3978  Histogram *hist = (Histogram *)cptr.data;
3979 
3980  if (hist->height < UI_UNIT_Y) {
3981  hist->height = UI_UNIT_Y;
3982  }
3983  else if (hist->height > UI_UNIT_Y * 20) {
3984  hist->height = UI_UNIT_Y * 20;
3985  }
3986 
3987  uiLayout *col = uiLayoutColumn(layout, true);
3988  uiBlock *block = uiLayoutGetBlock(col);
3989 
3990  uiDefBut(
3991  block, UI_BTYPE_HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
3992 
3993  /* Resize grip. */
3994  uiDefIconButI(block,
3995  UI_BTYPE_GRIP,
3996  0,
3997  ICON_GRIP,
3998  0,
3999  0,
4000  UI_UNIT_X * 10,
4001  (short)(UI_UNIT_Y * 0.3f),
4002  &hist->height,
4003  UI_UNIT_Y,
4004  UI_UNIT_Y * 20.0f,
4005  0.0f,
4006  0.0f,
4007  "");
4008 }
4009 
4012 /* -------------------------------------------------------------------- */
4016 void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
4017 {
4018  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
4019 
4020  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
4021  return;
4022  }
4023 
4024  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
4025  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
4026  return;
4027  }
4028  Scopes *scopes = (Scopes *)cptr.data;
4029 
4030  uiLayout *col = uiLayoutColumn(layout, true);
4031  uiBlock *block = uiLayoutGetBlock(col);
4032 
4033  if (scopes->wavefrm_height < UI_UNIT_Y) {
4034  scopes->wavefrm_height = UI_UNIT_Y;
4035  }
4036  else if (scopes->wavefrm_height > UI_UNIT_Y * 20) {
4037  scopes->wavefrm_height = UI_UNIT_Y * 20;
4038  }
4039 
4040  uiDefBut(block,
4042  0,
4043  "",
4044  0,
4045  0,
4046  UI_UNIT_X * 10,
4047  scopes->wavefrm_height,
4048  scopes,
4049  0,
4050  0,
4051  0,
4052  0,
4053  "");
4054 
4055  /* Resize grip. */
4056  uiDefIconButI(block,
4057  UI_BTYPE_GRIP,
4058  0,
4059  ICON_GRIP,
4060  0,
4061  0,
4062  UI_UNIT_X * 10,
4063  (short)(UI_UNIT_Y * 0.3f),
4064  &scopes->wavefrm_height,
4065  UI_UNIT_Y,
4066  UI_UNIT_Y * 20.0f,
4067  0.0f,
4068  0.0f,
4069  "");
4070 }
4071 
4074 /* -------------------------------------------------------------------- */
4078 void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propname)
4079 {
4080  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
4081 
4082  if (!prop || RNA_property_type(prop) != PROP_POINTER) {
4083  return;
4084  }
4085 
4086  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
4087  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
4088  return;
4089  }
4090  Scopes *scopes = (Scopes *)cptr.data;
4091 
4092  if (scopes->vecscope_height < UI_UNIT_Y) {
4093  scopes->vecscope_height = UI_UNIT_Y;
4094  }
4095  else if (scopes->vecscope_height > UI_UNIT_Y * 20) {
4096  scopes->vecscope_height = UI_UNIT_Y * 20;
4097  }
4098 
4099  uiLayout *col = uiLayoutColumn(layout, true);
4100  uiBlock *block = uiLayoutGetBlock(col);
4101 
4102  uiDefBut(block,
4104  0,
4105  "",
4106  0,
4107  0,
4108  UI_UNIT_X * 10,
4109  scopes->vecscope_height,
4110  scopes,
4111  0,
4112  0,
4113  0,
4114  0,
4115  "");
4116 
4117  /* Resize grip. */
4118  uiDefIconButI(block,
4119  UI_BTYPE_GRIP,
4120  0,
4121  ICON_GRIP,
4122  0,
4123  0,
4124  UI_UNIT_X * 10,
4125  (short)(UI_UNIT_Y * 0.3f),
4126  &scopes->vecscope_height,
4127  UI_UNIT_Y,
4128  UI_UNIT_Y * 20.0f,
4129  0.0f,
4130  0.0f,
4131  "");
4132 }
4133 
4136 /* -------------------------------------------------------------------- */
4140 static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *UNUSED(arg))
4141 {
4142  CurveMapping *cumap = cumap_v;
4143 
4144  /* we allow 20 times zoom */
4145  if (BLI_rctf_size_x(&cumap->curr) > 0.04f * BLI_rctf_size_x(&cumap->clipr)) {
4146  const float dx = 0.1154f * BLI_rctf_size_x(&cumap->curr);
4147  cumap->curr.xmin += dx;
4148  cumap->curr.xmax -= dx;
4149  const float dy = 0.1154f * BLI_rctf_size_y(&cumap->curr);
4150  cumap->curr.ymin += dy;
4151  cumap->curr.ymax -= dy;
4152  }
4153 
4155 }
4156 
4157 static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *UNUSED(unused))
4158 {
4159  CurveMapping *cumap = cumap_v;
4160  float d, d1;
4161 
4162  /* we allow 20 times zoom, but don't view outside clip */
4163  if (BLI_rctf_size_x(&cumap->curr) < 20.0f * BLI_rctf_size_x(&cumap->clipr)) {
4164  d = d1 = 0.15f * BLI_rctf_size_x(&cumap->curr);
4165 
4166  if (cumap->flag & CUMA_DO_CLIP) {
4167  if (cumap->curr.xmin - d < cumap->clipr.xmin) {
4168  d1 = cumap->curr.xmin - cumap->clipr.xmin;
4169  }
4170  }
4171  cumap->curr.xmin -= d1;
4172 
4173  d1 = d;
4174  if (cumap->flag & CUMA_DO_CLIP) {
4175  if (cumap->curr.xmax + d > cumap->clipr.xmax) {
4176  d1 = -cumap->curr.xmax + cumap->clipr.xmax;
4177  }
4178  }
4179  cumap->curr.xmax += d1;
4180 
4181  d = d1 = 0.15f * BLI_rctf_size_y(&cumap->curr);
4182 
4183  if (cumap->flag & CUMA_DO_CLIP) {
4184  if (cumap->curr.ymin - d < cumap->clipr.ymin) {
4185  d1 = cumap->curr.ymin - cumap->clipr.ymin;
4186  }
4187  }
4188  cumap->curr.ymin -= d1;
4189 
4190  d1 = d;
4191  if (cumap->flag & CUMA_DO_CLIP) {
4192  if (cumap->curr.ymax + d > cumap->clipr.ymax) {
4193  d1 = -cumap->curr.ymax + cumap->clipr.ymax;
4194  }
4195  }
4196  cumap->curr.ymax += d1;
4197  }
4198 
4200 }
4201 
4202 static void curvemap_buttons_setclip(bContext *UNUSED(C), void *cumap_v, void *UNUSED(arg))
4203 {
4204  CurveMapping *cumap = cumap_v;
4205 
4206  BKE_curvemapping_changed(cumap, false);
4207 }
4208 
4209 static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v)
4210 {
4211  CurveMapping *cumap = cumap_v;
4212 
4213  BKE_curvemap_remove(cumap->cm + cumap->cur, SELECT);
4214  BKE_curvemapping_changed(cumap, false);
4215 
4216  rna_update_cb(C, cb_v, NULL);
4217 }
4218 
4219 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
4220 static uiBlock *curvemap_clipping_func(bContext *C, ARegion *region, void *cumap_v)
4221 {
4222  CurveMapping *cumap = cumap_v;
4223  uiBut *bt;
4224  const float width = 8 * UI_UNIT_X;
4225 
4226  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
4229 
4230  bt = uiDefButBitI(block,
4232  CUMA_DO_CLIP,
4233  1,
4234  IFACE_("Use Clipping"),
4235  0,
4236  5 * UI_UNIT_Y,
4237  width,
4238  UI_UNIT_Y,
4239  &cumap->flag,
4240  0.0,
4241  0.0,
4242  10,
4243  0,
4244  "");
4246 
4247  UI_block_align_begin(block);
4248  bt = uiDefButF(block,
4249  UI_BTYPE_NUM,
4250  0,
4251  IFACE_("Min X:"),
4252  0,
4253  4 * UI_UNIT_Y,
4254  width,
4255  UI_UNIT_Y,
4256  &cumap->clipr.xmin,
4257  -100.0,
4258  cumap->clipr.xmax,
4259  0,
4260  0,
4261  "");
4264  bt = uiDefButF(block,
4265  UI_BTYPE_NUM,
4266  0,
4267  IFACE_("Min Y:"),
4268  0,
4269  3 * UI_UNIT_Y,
4270  width,
4271  UI_UNIT_Y,
4272  &cumap->clipr.ymin,
4273  -100.0,
4274  cumap->clipr.ymax,
4275  0,
4276  0,
4277  "");
4280  bt = uiDefButF(block,
4281  UI_BTYPE_NUM,
4282  0,
4283  IFACE_("Max X:"),
4284  0,
4285  2 * UI_UNIT_Y,
4286  width,
4287  UI_UNIT_Y,
4288  &cumap->clipr.xmax,
4289  cumap->clipr.xmin,
4290  100.0,
4291  0,
4292  0,
4293  "");
4296  bt = uiDefButF(block,
4297  UI_BTYPE_NUM,
4298  0,
4299  IFACE_("Max Y:"),
4300  0,
4301  UI_UNIT_Y,
4302  width,
4303  UI_UNIT_Y,
4304  &cumap->clipr.ymax,
4305  cumap->clipr.ymin,
4306  100.0,
4307  0,
4308  0,
4309  "");
4312 
4313  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
4315 
4316  return block;
4317 }
4318 
4319 /* only for BKE_curvemap_tools_dofunc */
4320 enum {
4329 };
4330 
4331 static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
4332 {
4333  CurveMapping *cumap = cumap_v;
4334  CurveMap *cuma = cumap->cm + cumap->cur;
4335 
4336  switch (event) {
4338  case UICURVE_FUNC_RESET_POS: /* reset */
4339  BKE_curvemap_reset(cuma,
4340  &cumap->clipr,
4341  cumap->preset,
4344  BKE_curvemapping_changed(cumap, false);
4345  break;
4348  break;
4349  case UICURVE_FUNC_HANDLE_VECTOR: /* Set vector. */
4351  BKE_curvemapping_changed(cumap, false);
4352  break;
4353  case UICURVE_FUNC_HANDLE_AUTO: /* Set auto. */
4355  BKE_curvemapping_changed(cumap, false);
4356  break;
4357  case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* Set auto-clamped. */
4359  BKE_curvemapping_changed(cumap, false);
4360  break;
4361  case UICURVE_FUNC_EXTEND_HOZ: /* Extend horizontal. */
4362  cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
4363  BKE_curvemapping_changed(cumap, false);
4364  break;
4365  case UICURVE_FUNC_EXTEND_EXP: /* Extend extrapolate. */
4366  cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
4367  BKE_curvemapping_changed(cumap, false);
4368  break;
4369  }
4370  ED_undo_push(C, "CurveMap tools");
4372 }
4373 
4375  bContext *C, ARegion *region, CurveMapping *cumap, bool show_extend, int reset_mode)
4376 {
4377  short yco = 0;
4378  const short menuwidth = 10 * UI_UNIT_X;
4379 
4380  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
4382 
4383  {
4384  uiDefIconTextBut(block,
4386  1,
4387  ICON_BLANK1,
4388  IFACE_("Reset View"),
4389  0,
4390  yco -= UI_UNIT_Y,
4391  menuwidth,
4392  UI_UNIT_Y,
4393  NULL,
4394  0.0,
4395  0.0,
4396  0,
4398  "");
4399  }
4400 
4401  if (show_extend) {
4402  uiDefIconTextBut(block,
4404  1,
4405  ICON_BLANK1,
4406  IFACE_("Extend Horizontal"),
4407  0,
4408  yco -= UI_UNIT_Y,
4409  menuwidth,
4410  UI_UNIT_Y,
4411  NULL,
4412  0.0,
4413  0.0,
4414  0,
4416  "");
4417  uiDefIconTextBut(block,
4419  1,
4420  ICON_BLANK1,
4421  IFACE_("Extend Extrapolated"),
4422  0,
4423  yco -= UI_UNIT_Y,
4424  menuwidth,
4425  UI_UNIT_Y,
4426  NULL,
4427  0.0,
4428  0.0,
4429  0,
4431  "");
4432  }
4433 
4434  {
4435  uiDefIconTextBut(block,
4437  1,
4438  ICON_BLANK1,
4439  IFACE_("Reset Curve"),
4440  0,
4441  yco -= UI_UNIT_Y,
4442  menuwidth,
4443  UI_UNIT_Y,
4444  NULL,
4445  0.0,
4446  0.0,
4447  0,
4448  reset_mode,
4449  "");
4450  }
4451 
4453  UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
4454 
4455  return block;
4456 }
4457 
4458 static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *region, void *cumap_v)
4459 {
4460  return curvemap_tools_func(C, region, cumap_v, true, UICURVE_FUNC_RESET_POS);
4461 }
4462 
4463 static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v)
4464 {
4465  return curvemap_tools_func(C, region, cumap_v, true, UICURVE_FUNC_RESET_NEG);
4466 }
4467 
4468 static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *region, void *cumap_v)
4469 {
4470  return curvemap_tools_func(C, region, cumap_v, false, UICURVE_FUNC_RESET_NEG);
4471 }
4472 
4474 {
4475  return curvemap_tools_func(C, region, cumap_v, false, UICURVE_FUNC_RESET_POS);
4476 }
4477 
4478 static void curvemap_tools_handle_vector(bContext *C, void *cumap_v, void *UNUSED(arg))
4479 {
4481 }
4482 
4483 static void curvemap_tools_handle_auto(bContext *C, void *cumap_v, void *UNUSED(arg))
4484 {
4486 }
4487 
4488 static void curvemap_tools_handle_auto_clamped(bContext *C, void *cumap_v, void *UNUSED(arg))
4489 {
4491 }
4492 
4493 static void curvemap_buttons_redraw(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
4494 {
4496 }
4497 
4498 static void curvemap_buttons_update(bContext *C, void *arg1_v, void *cumap_v)
4499 {
4500  CurveMapping *cumap = cumap_v;
4501  BKE_curvemapping_changed(cumap, true);
4502  rna_update_cb(C, arg1_v, NULL);
4503 }
4504 
4505 static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
4506 {
4507  CurveMapping *cumap = cumap_v;
4508  cumap->preset = CURVE_PRESET_LINE;
4509  for (int a = 0; a < CM_TOT; a++) {
4510  BKE_curvemap_reset(cumap->cm + a, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
4511  }
4512 
4513  cumap->black[0] = cumap->black[1] = cumap->black[2] = 0.0f;
4514  cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
4516 
4517  BKE_curvemapping_changed(cumap, false);
4518 
4519  rna_update_cb(C, cb_v, NULL);
4520 }
4521 
4527 static void curvemap_buttons_layout(uiLayout *layout,
4528  PointerRNA *ptr,
4529  char labeltype,
4530  bool levels,
4531  bool brush,
4532  bool neg_slope,
4533  bool tone,
4534  RNAUpdateCb *cb)
4535 {
4536  CurveMapping *cumap = ptr->data;
4537  CurveMap *cm = &cumap->cm[cumap->cur];
4538  uiBut *bt;
4539  const float dx = UI_UNIT_X;
4540  int bg = -1;
4541 
4542  uiBlock *block = uiLayoutGetBlock(layout);
4543 
4545 
4546  if (tone) {
4547  uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
4548  uiItemR(uiLayoutRow(split, false), ptr, "tone", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
4549  }
4550 
4551  /* curve chooser */
4552  uiLayout *row = uiLayoutRow(layout, false);
4553 
4554  if (labeltype == 'v') {
4555  /* vector */
4556  uiLayout *sub = uiLayoutRow(row, true);
4558 
4559  if (cumap->cm[0].curve) {
4560  bt = uiDefButI(
4561  block, UI_BTYPE_ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
4563  }
4564  if (cumap->cm[1].curve) {
4565  bt = uiDefButI(
4566  block, UI_BTYPE_ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
4568  }
4569  if (cumap->cm[2].curve) {
4570  bt = uiDefButI(
4571  block, UI_BTYPE_ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
4573  }
4574  }
4575  else if (labeltype == 'c') {
4576  /* color */
4577  uiLayout *sub = uiLayoutRow(row, true);
4579 
4580  if (cumap->cm[3].curve) {
4581  bt = uiDefButI(
4582  block, UI_BTYPE_ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
4584  }
4585  if (cumap->cm[0].curve) {
4586  bt = uiDefButI(
4587  block, UI_BTYPE_ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
4589  }
4590  if (cumap->cm[1].curve) {
4591  bt = uiDefButI(
4592  block, UI_BTYPE_ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
4594  }
4595  if (cumap->cm[2].curve) {
4596  bt = uiDefButI(
4597  block, UI_BTYPE_ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
4599  }
4600  }
4601  else if (labeltype == 'h') {
4602  /* HSV */
4603  uiLayout *sub = uiLayoutRow(row, true);
4605 
4606  if (cumap->cm[0].curve) {
4607  bt = uiDefButI(
4608  block, UI_BTYPE_ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
4610  }
4611  if (cumap->cm[1].curve) {
4612  bt = uiDefButI(
4613  block, UI_BTYPE_ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
4615  }
4616  if (cumap->cm[2].curve) {
4617  bt = uiDefButI(
4618  block, UI_BTYPE_ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
4620  }
4621  }
4622  else {
4624  }
4625 
4626  if (labeltype == 'h') {
4627  bg = UI_GRAD_H;
4628  }
4629 
4630  /* operation buttons */
4631  /* (Right aligned) */
4632  uiLayout *sub = uiLayoutRow(row, true);
4634 
4635  /* Zoom in */
4636  bt = uiDefIconBut(block,
4637  UI_BTYPE_BUT,
4638  0,
4639  ICON_ZOOM_IN,
4640  0,
4641  0,
4642  dx,
4643  dx,
4644  NULL,
4645  0.0,
4646  0.0,
4647  0.0,
4648  0.0,
4649  TIP_("Zoom in"));
4651 
4652  /* Zoom out */
4653  bt = uiDefIconBut(block,
4654  UI_BTYPE_BUT,
4655  0,
4656  ICON_ZOOM_OUT,
4657  0,
4658  0,
4659  dx,
4660  dx,
4661  NULL,
4662  0.0,
4663  0.0,
4664  0.0,
4665  0.0,
4666  TIP_("Zoom out"));
4668 
4669  /* Clippoing button. */
4670  const int icon = (cumap->flag & CUMA_DO_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
4671  bt = uiDefIconBlockBut(
4672  block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options"));
4673  bt->drawflag &= ~UI_BUT_ICON_LEFT;
4675 
4676  if (brush && neg_slope) {
4677  bt = uiDefIconBlockBut(
4678  block, curvemap_brush_tools_negslope_func, cumap, 0, 0, 0, 0, dx, dx, TIP_("Tools"));
4679  }
4680  else if (brush) {
4681  bt = uiDefIconBlockBut(
4682  block, curvemap_brush_tools_func, cumap, 0, 0, 0, 0, dx, dx, TIP_("Tools"));
4683  }
4684  else if (neg_slope) {
4685  bt = uiDefIconBlockBut(
4686  block, curvemap_tools_negslope_func, cumap, 0, 0, 0, 0, dx, dx, TIP_("Tools"));
4687  }
4688  else {
4689  bt = uiDefIconBlockBut(
4690  block, curvemap_tools_posslope_func, cumap, 0, 0, 0, 0, dx, dx, TIP_("Tools"));
4691  }
4693 
4695 
4696  /* Curve itself. */
4697  const int size = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
4698  row = uiLayoutRow(layout, false);
4700  block, UI_BTYPE_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, -1, 0, "");
4701  curve_but->gradient_type = bg;
4702 
4703  /* Sliders for selected curve point. */
4704  int i;
4705  CurveMapPoint *cmp = NULL;
4706  bool point_last_or_first = false;
4707  for (i = 0; i < cm->totpoint; i++) {
4708  if (cm->curve[i].flag & CUMA_SELECT) {
4709  cmp = &cm->curve[i];
4710  break;
4711  }
4712  }
4713  if (ELEM(i, 0, cm->totpoint - 1)) {
4714  point_last_or_first = true;
4715  }
4716 
4717  if (cmp) {
4718  rctf bounds;
4719  if (cumap->flag & CUMA_DO_CLIP) {
4720  bounds = cumap->clipr;
4721  }
4722  else {
4723  bounds.xmin = bounds.ymin = -1000.0;
4724  bounds.xmax = bounds.ymax = 1000.0;
4725  }
4726 
4728 
4729  uiLayoutRow(layout, true);
4730 
4731  /* Curve handle buttons. */
4732  bt = uiDefIconBut(block,
4733  UI_BTYPE_BUT,
4734  1,
4735  ICON_HANDLE_AUTO,
4736  0,
4737  UI_UNIT_Y,
4738  UI_UNIT_X,
4739  UI_UNIT_Y,
4740  NULL,
4741  0.0,
4742  0.0,
4743  0.0,
4744  0.0,
4745  TIP_("Auto Handle"));
4747  if (((cmp->flag & CUMA_HANDLE_AUTO_ANIM) == false) &&
4748  ((cmp->flag & CUMA_HANDLE_VECTOR) == false)) {
4749  bt->flag |= UI_SELECT_DRAW;
4750  }
4751 
4752  bt = uiDefIconBut(block,
4753  UI_BTYPE_BUT,
4754  1,
4755  ICON_HANDLE_VECTOR,
4756  0,
4757  UI_UNIT_Y,
4758  UI_UNIT_X,
4759  UI_UNIT_Y,
4760  NULL,
4761  0.0,
4762  0.0,
4763  0.0,
4764  0.0,
4765  TIP_("Vector Handle"));
4767  if (cmp->flag & CUMA_HANDLE_VECTOR) {
4768  bt->flag |= UI_SELECT_DRAW;
4769  }
4770 
4771  bt = uiDefIconBut(block,
4772  UI_BTYPE_BUT,
4773  1,
4774  ICON_HANDLE_AUTOCLAMPED,
4775  0,
4776  UI_UNIT_Y,
4777  UI_UNIT_X,
4778  UI_UNIT_Y,
4779  NULL,
4780  0.0,
4781  0.0,
4782  0.0,
4783  0.0,
4784  TIP_("Auto Clamped"));
4786  if (cmp->flag & CUMA_HANDLE_AUTO_ANIM) {
4787  bt->flag |= UI_SELECT_DRAW;
4788  }
4789 
4790  /* Curve handle position */
4792  bt = uiDefButF(block,
4793  UI_BTYPE_NUM,
4794  0,
4795  "X:",
4796  0,
4797  2 * UI_UNIT_Y,
4798  UI_UNIT_X * 10,
4799  UI_UNIT_Y,
4800  &cmp->x,
4801  bounds.xmin,
4802  bounds.xmax,
4803  0,
4804  0,
4805  "");
4808  bt = uiDefButF(block,
4809  UI_BTYPE_NUM,
4810  0,
4811  "Y:",
4812  0,
4813  1 * UI_UNIT_Y,
4814  UI_UNIT_X * 10,
4815  UI_UNIT_Y,
4816  &cmp->y,
4817  bounds.ymin,
4818  bounds.ymax,
4819  0,
4820  0,
4821  "");
4824 
4825  /* Curve handle delete point */
4826  bt = uiDefIconBut(block,
4827  UI_BTYPE_BUT,
4828  0,
4829  ICON_X,
4830  0,
4831  0,
4832  dx,
4833  dx,
4834  NULL,
4835  0.0,
4836  0.0,
4837  0.0,
4838  0.0,
4839  TIP_("Delete points"));
4841  if (point_last_or_first) {
4843  }
4844  }
4845 
4846  /* black/white levels */
4847  if (levels) {
4848  uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
4849  uiItemR(uiLayoutColumn(split, false), ptr, "black_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
4850  uiItemR(uiLayoutColumn(split, false), ptr, "white_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
4851 
4852  uiLayoutRow(layout, false);
4853  bt = uiDefBut(block,
4854  UI_BTYPE_BUT,
4855  0,
4856  IFACE_("Reset"),
4857  0,
4858  0,
4859  UI_UNIT_X * 10,
4860  UI_UNIT_Y,
4861  NULL,
4862  0.0f,
4863  0.0f,
4864  0,
4865  0,
4866  TIP_("Reset Black/White point and curves"));
4868  }
4869 
4870  UI_block_funcN_set(block, NULL, NULL, NULL);
4871 }
4872 
4874  PointerRNA *ptr,
4875  const char *propname,
4876  int type,
4877  bool levels,
4878  bool brush,
4879  bool neg_slope,
4880  bool tone)
4881 {
4882  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
4883  uiBlock *block = uiLayoutGetBlock(layout);
4884 
4885  if (!prop) {
4886  RNA_warning("curve property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
4887  return;
4888  }
4889 
4890  if (RNA_property_type(prop) != PROP_POINTER) {
4891  RNA_warning("curve is not a pointer: %s.%s", RNA_struct_identifier(ptr->type), propname);
4892  return;
4893  }
4894 
4895  PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
4896  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveMapping)) {
4897  return;
4898  }
4899 
4900  RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
4901  cb->ptr = *ptr;
4902  cb->prop = prop;
4903 
4904  ID *id = cptr.owner_id;
4906 
4907  curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb);
4908 
4909  UI_block_lock_clear(block);
4910 
4911  MEM_freeN(cb);
4912 }
4913 
4916 /* -------------------------------------------------------------------- */
4920 static void CurveProfile_presets_dofunc(bContext *C, void *profile_v, int event)
4921 {
4922  CurveProfile *profile = profile_v;
4923 
4924  profile->preset = event;
4925  BKE_curveprofile_reset(profile);
4927 
4928  ED_undo_push(C, "CurveProfile tools");
4930 }
4931 
4933 {
4934  short yco = 0;
4935 
4936  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
4938 
4939  uiDefIconTextBut(block,
4941  1,
4942  ICON_BLANK1,
4943  IFACE_("Default"),
4944  0,
4945  yco -= UI_UNIT_Y,
4946  0,
4947  UI_UNIT_Y,
4948  NULL,
4949  0.0,
4950  0.0,
4951  0,
4953  "");
4954  uiDefIconTextBut(block,
4956  1,
4957  ICON_BLANK1,
4958  IFACE_("Support Loops"),
4959  0,
4960  yco -= UI_UNIT_Y,
4961  0,
4962  UI_UNIT_Y,
4963  NULL,
4964  0.0,
4965  0.0,
4966  0,
4968  "");
4969  uiDefIconTextBut(block,
4971  1,
4972  ICON_BLANK1,
4973  IFACE_("Cornice Molding"),
4974  0,
4975  yco -= UI_UNIT_Y,
4976  0,
4977  UI_UNIT_Y,
4978  NULL,
4979  0.0,
4980  0.0,
4981  0,
4983  "");
4984  uiDefIconTextBut(block,
4986  1,
4987  ICON_BLANK1,
4988  IFACE_("Crown Molding"),
4989  0,
4990  yco -= UI_UNIT_Y,
4991  0,
4992  UI_UNIT_Y,
4993  NULL,
4994  0.0,
4995  0.0,
4996  0,
4998  "");
4999  uiDefIconTextBut(block,
5001  1,
5002  ICON_BLANK1,
5003  IFACE_("Steps"),
5004  0,
5005  yco -= UI_UNIT_Y,
5006  0,
5007  UI_UNIT_Y,
5008  NULL,
5009  0.0,
5010  0.0,
5011  0,
5013  "");
5014 
5016  UI_block_bounds_set_text(block, (int)(3.0f * UI_UNIT_X));
5017 
5018  return block;
5019 }
5020 
5021 static uiBlock *CurveProfile_buttons_presets(bContext *C, ARegion *region, void *profile_v)
5022 {
5023  return CurveProfile_presets_func(C, region, (CurveProfile *)profile_v);
5024 }
5025 
5026 /* Only for CurveProfile tools block */
5027 enum {
5030 };
5031 
5032 static void CurveProfile_tools_dofunc(bContext *C, void *profile_v, int event)
5033 {
5034  CurveProfile *profile = profile_v;
5035 
5036  switch (event) {
5037  case UIPROFILE_FUNC_RESET: /* reset */
5038  BKE_curveprofile_reset(profile);
5040  break;
5041  case UIPROFILE_FUNC_RESET_VIEW: /* reset view to clipping rect */
5042  BKE_curveprofile_reset_view(profile);
5043  break;
5044  }
5045  ED_undo_push(C, "CurveProfile tools");
5047 }
5048 
5050 {
5051  short yco = 0;
5052 
5053  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
5055 
5056  uiDefIconTextBut(block,
5058  1,
5059  ICON_BLANK1,
5060  IFACE_("Reset View"),
5061  0,
5062  yco -= UI_UNIT_Y,
5063  0,
5064  UI_UNIT_Y,
5065  NULL,
5066  0.0,
5067  0.0,
5068  0,
5070  "");
5071  uiDefIconTextBut(block,
5073  1,
5074  ICON_BLANK1,
5075  IFACE_("Reset Curve"),
5076  0,
5077  yco -= UI_UNIT_Y,
5078  0,
5079  UI_UNIT_Y,
5080  NULL,
5081  0.0,
5082  0.0,
5083  0,
5085  "");
5086 
5088  UI_block_bounds_set_text(block, (int)(3.0f * UI_UNIT_X));
5089 
5090  return block;
5091 }
5092 
5093 static uiBlock *CurveProfile_buttons_tools(bContext *C, ARegion *region, void *profile_v)
5094 {
5095  return CurveProfile_tools_func(C, region, (CurveProfile *)profile_v);
5096 }
5097 
5098 static void CurveProfile_buttons_zoom_in(bContext *C, void *profile_v, void *UNUSED(arg))
5099 {
5100  CurveProfile *profile = profile_v;
5101 
5102  /* Allow a 20x zoom. */
5103  if (BLI_rctf_size_x(&profile->view_rect) > 0.04f * BLI_rctf_size_x(&profile->clip_rect)) {
5104  const float dx = 0.1154f * BLI_rctf_size_x(&profile->view_rect);
5105  profile->view_rect.xmin += dx;
5106  profile->view_rect.xmax -= dx;
5107  const float dy = 0.1154f * BLI_rctf_size_y(&profile->view_rect);
5108  profile->view_rect.ymin += dy;
5109  profile->view_rect.ymax -= dy;
5110  }
5111 
5113 }
5114 
5115 static void CurveProfile_buttons_zoom_out(bContext *C, void *profile_v, void *UNUSED(arg))
5116 {
5117  CurveProfile *profile = profile_v;
5118 
5119  /* Allow 20 times zoom, but don't view outside clip */
5120  if (BLI_rctf_size_x(&profile->view_rect) < 20.0f * BLI_rctf_size_x(&profile->clip_rect)) {
5121  float d = 0.15f * BLI_rctf_size_x(&profile->view_rect);
5122  float d1 = d;
5123 
5124  if (profile->flag & PROF_USE_CLIP) {
5125  if (profile->view_rect.xmin - d < profile->clip_rect.xmin) {
5126  d1 = profile->view_rect.xmin - profile->clip_rect.xmin;
5127  }
5128  }
5129  profile->view_rect.xmin -= d1;
5130 
5131  d1 = d;
5132  if (profile->flag & PROF_USE_CLIP) {
5133  if (profile->view_rect.xmax + d > profile->clip_rect.xmax) {
5134  d1 = -profile->view_rect.xmax + profile->clip_rect.xmax;
5135  }
5136  }
5137  profile->view_rect.xmax += d1;
5138 
5139  d = d1 = 0.15f * BLI_rctf_size_y(&profile->view_rect);
5140 
5141  if (profile->flag & PROF_USE_CLIP) {
5142  if (profile->view_rect.ymin - d < profile->clip_rect.ymin) {
5143  d1 = profile->view_rect.ymin - profile->clip_rect.ymin;
5144  }
5145  }
5146  profile->view_rect.ymin -= d1;
5147 
5148  d1 = d;
5149  if (profile->flag & PROF_USE_CLIP) {
5150  if (profile->view_rect.ymax + d > profile->clip_rect.ymax) {
5151  d1 = -profile->view_rect.ymax + profile->clip_rect.ymax;
5152  }
5153  }
5154  profile->view_rect.ymax += d1;
5155  }
5156 
5158 }
5159 
5160 static void CurveProfile_clipping_toggle(bContext *C, void *cb_v, void *profile_v)
5161 {
5162  CurveProfile *profile = profile_v;
5163 
5164  profile->flag ^= PROF_USE_CLIP;
5165 
5167  rna_update_cb(C, cb_v, NULL);
5168 }
5169 
5170 static void CurveProfile_buttons_reverse(bContext *C, void *cb_v, void *profile_v)
5171 {
5172  CurveProfile *profile = profile_v;
5173 
5174  BKE_curveprofile_reverse(profile);
5176  rna_update_cb(C, cb_v, NULL);
5177 }
5178 
5179 static void CurveProfile_buttons_delete(bContext *C, void *cb_v, void *profile_v)
5180 {
5181  CurveProfile *profile = profile_v;
5182 
5185 
5186  rna_update_cb(C, cb_v, NULL);
5187 }
5188 
5189 static void CurveProfile_buttons_update(bContext *C, void *arg1_v, void *profile_v)
5190 {
5191  CurveProfile *profile = profile_v;
5193  rna_update_cb(C, arg1_v, NULL);
5194 }
5195 
5196 static void CurveProfile_buttons_reset(bContext *C, void *arg1_v, void *profile_v)
5197 {
5198  CurveProfile *profile = profile_v;
5199  BKE_curveprofile_reset(profile);
5201  rna_update_cb(C, arg1_v, NULL);
5202 }
5203 
5205 {
5206  CurveProfile *profile = ptr->data;
5207  uiBut *bt;
5208 
5209  uiBlock *block = uiLayoutGetBlock(layout);
5210 
5212 
5213  uiLayoutSetPropSep(layout, false);
5214 
5215  /* Preset selector */
5216  /* There is probably potential to use simpler "uiItemR" functions here, but automatic updating
5217  * after a preset is selected would be more complicated. */
5218  uiLayout *row = uiLayoutRow(layout, true);
5219  bt = uiDefBlockBut(
5220  block, CurveProfile_buttons_presets, profile, "Preset", 0, 0, UI_UNIT_X, UI_UNIT_X, "");
5222 
5223  /* Show a "re-apply" preset button when it has been changed from the preset. */
5224  if (profile->flag & PROF_DIRTY_PRESET) {
5225  /* Only for dynamic presets. */
5227  bt = uiDefIconTextBut(block,
5228  UI_BTYPE_BUT,
5229  0,
5230  ICON_NONE,
5231  "Apply Preset",
5232  0,
5233  0,
5234  UI_UNIT_X,
5235  UI_UNIT_X,
5236  NULL,
5237  0.0,
5238  0.0,
5239  0.0,
5240  0.0,
5241  "Reapply and update the preset, removing changes");
5243  }
5244  }
5245 
5246  row = uiLayoutRow(layout, false);
5247 
5248  /* (Left aligned) */
5249  uiLayout *sub = uiLayoutRow(row, true);
5251 
5252  /* Zoom in */
5253  bt = uiDefIconBut(block,
5254  UI_BTYPE_BUT,
5255  0,
5256  ICON_ZOOM_IN,
5257  0,
5258  0,
5259  UI_UNIT_X,
5260  UI_UNIT_X,
5261  NULL,
5262  0.0,
5263  0.0,
5264  0.0,
5265  0.0,
5266  TIP_("Zoom in"));
5268 
5269  /* Zoom out */
5270  bt = uiDefIconBut(block,
5271  UI_BTYPE_BUT,
5272  0,
5273  ICON_ZOOM_OUT,
5274  0,
5275  0,
5276  UI_UNIT_X,
5277  UI_UNIT_X,
5278  NULL,
5279  0.0,
5280  0.0,
5281  0.0,
5282  0.0,
5283  TIP_("Zoom out"));
5285 
5286  /* (Right aligned) */
5287  sub = uiLayoutRow(row, true);
5289 
5290  /* Flip path */
5291  bt = uiDefIconBut(block,
5292  UI_BTYPE_BUT,
5293  0,
5294  ICON_ARROW_LEFTRIGHT,
5295  0,
5296  0,
5297  UI_UNIT_X,
5298  UI_UNIT_X,
5299  NULL,
5300  0.0,
5301  0.0,
5302  0.0,
5303  0.0,
5304  TIP_("Reverse Path"));
5306 
5307  /* Clipping toggle */
5308  const int icon = (profile->flag & PROF_USE_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
5309  bt = uiDefIconBut(block,
5310  UI_BTYPE_BUT,
5311  0,
5312  icon,
5313  0,
5314  0,
5315  UI_UNIT_X,
5316  UI_UNIT_X,
5317  NULL,
5318  0.0,
5319  0.0,
5320  0.0,
5321  0.0,
5322  TIP_("Toggle Profile Clipping"));
5324 
5325  /* Reset view, reset curve */
5326  bt = uiDefIconBlockBut(
5327  block, CurveProfile_buttons_tools, profile, 0, 0, 0, 0, UI_UNIT_X, UI_UNIT_X, TIP_("Tools"));
5329 
5331 
5332  /* The path itself */
5333  int path_width = max_ii(uiLayoutGetWidth(layout), UI_UNIT_X);
5334  path_width = min_ii(path_width, (int)(16.0f * UI_UNIT_X));
5335  const int path_height = path_width;
5336  uiLayoutRow(layout, false);
5337  uiDefBut(block,
5339  0,
5340  "",
5341  0,
5342  0,
5343  (short)path_width,
5344  (short)path_height,
5345  profile,
5346  0.0f,
5347  1.0f,
5348  -1,
5349  0,
5350  "");
5351 
5352  /* Position sliders for (first) selected point */
5353  int i;
5354  float *selection_x, *selection_y;
5355  bool point_last_or_first = false;
5357  for (i = 0; i < profile->path_len; i++) {
5358  if (profile->path[i].flag & PROF_SELECT) {
5359  point = &profile->path[i];
5360  selection_x = &point->x;
5361  selection_y = &point->y;
5362  break;
5363  }
5364  if (profile->path[i].flag & PROF_H1_SELECT) {
5365  point = &profile->path[i];
5366  selection_x = &point->h1_loc[0];
5367  selection_y = &point->h1_loc[1];
5368  }
5369  else if (profile->path[i].flag & PROF_H2_SELECT) {
5370  point = &profile->path[i];
5371  selection_x = &point->h2_loc[0];
5372  selection_y = &point->h2_loc[1];
5373  }
5374  }
5375  if (ELEM(i, 0, profile->path_len - 1)) {
5376  point_last_or_first = true;
5377  }
5378 
5379  /* Selected point data */
5380  rctf bounds;
5381  if (point) {
5382  if (profile->flag & PROF_USE_CLIP) {
5383  bounds = profile->clip_rect;
5384  }
5385  else {
5386  bounds.xmin = bounds.ymin = -1000.0;
5387  bounds.xmax = bounds.ymax = 1000.0;
5388  }
5389 
5390  row = uiLayoutRow(layout, true);
5391 
5392  PointerRNA point_ptr;
5393  RNA_pointer_create(ptr->owner_id, &RNA_CurveProfilePoint, point, &point_ptr);
5394  PropertyRNA *prop_handle_type = RNA_struct_find_property(&point_ptr, "handle_type_1");
5395  uiItemFullR(row,
5396  &point_ptr,
5397  prop_handle_type,
5398  RNA_NO_INDEX,
5399  0,
5401  "",
5402  ICON_NONE);
5403 
5404  /* Position */
5405  bt = uiDefButF(block,
5406  UI_BTYPE_NUM,
5407  0,
5408  "X:",
5409  0,
5410  2 * UI_UNIT_Y,
5411  UI_UNIT_X * 10,
5412  UI_UNIT_Y,
5413  selection_x,
5414  bounds.xmin,
5415  bounds.xmax,
5416  0,
5417  0,
5418  "");
5422  if (point_last_or_first) {
5424  }
5425  bt = uiDefButF(block,
5426  UI_BTYPE_NUM,
5427  0,
5428  "Y:",
5429  0,
5430  1 * UI_UNIT_Y,
5431  UI_UNIT_X * 10,
5432  UI_UNIT_Y,
5433  selection_y,
5434  bounds.ymin,
5435  bounds.ymax,
5436  0,
5437  0,
5438  "");
5442  if (point_last_or_first) {
5444  }
5445 
5446  /* Delete points */
5447  bt = uiDefIconBut(block,
5448  UI_BTYPE_BUT,
5449  0,
5450  ICON_X,
5451  0,
5452  0,
5453  UI_UNIT_X,
5454  UI_UNIT_X,
5455  NULL,
5456  0.0,
5457  0.0,
5458  0.0,
5459  0.0,
5460  TIP_("Delete points"));
5462  if (point_last_or_first) {
5464  }
5465  }
5466 
5467  uiItemR(layout, ptr, "use_sample_straight_edges", 0, NULL, ICON_NONE);
5468  uiItemR(layout, ptr, "use_sample_even_lengths", 0, NULL, ICON_NONE);
5469 
5470  UI_block_funcN_set(block, NULL, NULL, NULL);
5471 }
5472 
5473 void uiTemplateCurveProfile(uiLayout *layout, PointerRNA *ptr, const char *propname)
5474 {
5475  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5476 
5477  uiBlock *block = uiLayoutGetBlock(layout);
5478 
5479  if (!prop) {
5480  RNA_warning(
5481  "Curve Profile property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5482  return;
5483  }
5484 
5485  if (RNA_property_type(prop) != PROP_POINTER) {
5486  RNA_warning(
5487  "Curve Profile is not a pointer: %s.%s", RNA_struct_identifier(ptr->type), propname);
5488  return;
5489  }
5490 
5491  PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
5492  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveProfile)) {
5493  return;
5494  }
5495 
5496  /* Share update functionality with the CurveMapping widget template. */
5497  RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
5498  cb->ptr = *ptr;
5499  cb->prop = prop;
5500 
5501  ID *id = cptr.owner_id;
5503 
5504  CurveProfile_buttons_layout(layout, &cptr, cb);
5505 
5506  UI_block_lock_clear(block);
5507 
5508  MEM_freeN(cb);
5509 }
5510 
5513 /* -------------------------------------------------------------------- */
5517 #define WHEEL_SIZE (5 * U.widget_unit)
5518 
5520  PointerRNA *ptr,
5521  const char *propname,
5522  bool value_slider,
5523  bool lock,
5524  bool lock_luminosity,
5525  bool cubic)
5526 {
5527  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5528  uiBlock *block = uiLayoutGetBlock(layout);
5529  ColorPicker *cpicker = ui_block_colorpicker_create(block);
5530 
5531  if (!prop) {
5532  RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5533  return;
5534  }
5535 
5536  float softmin, softmax, step, precision;
5537  RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
5538 
5539  uiLayout *col = uiLayoutColumn(layout, true);
5540  uiLayout *row = uiLayoutRow(col, true);
5541 
5542  uiBut *but = NULL;
5543  uiButHSVCube *hsv_but;
5544  switch (U.color_picker_type) {
5545  case USER_CP_SQUARE_SV:
5546  case USER_CP_SQUARE_HS:
5547  case USER_CP_SQUARE_HV:
5548  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5550  0,
5551  "",
5552  0,
5553  0,
5554  WHEEL_SIZE,
5555  WHEEL_SIZE,
5556  ptr,
5557  prop,
5558  -1,
5559  0.0,
5560  0.0,
5561  0,
5562  0,
5563  "");
5564  switch (U.color_picker_type) {
5565  case USER_CP_SQUARE_SV:
5566  hsv_but->gradient_type = UI_GRAD_SV;
5567  break;
5568  case USER_CP_SQUARE_HS:
5569  hsv_but->gradient_type = UI_GRAD_HS;
5570  break;
5571  case USER_CP_SQUARE_HV:
5572  hsv_but->gradient_type = UI_GRAD_HV;
5573  break;
5574  }
5575  but = &hsv_but->but;
5576  break;
5577 
5578  /* user default */
5579  case USER_CP_CIRCLE_HSV:
5580  case USER_CP_CIRCLE_HSL:
5581  default:
5582  but = uiDefButR_prop(block,
5584  0,
5585  "",
5586  0,
5587  0,
5588  WHEEL_SIZE,
5589  WHEEL_SIZE,
5590  ptr,
5591  prop,
5592  -1,
5593  0.0,
5594  0.0,
5595  0,
5596  0,
5597  "");
5598  break;
5599  }
5600 
5601  but->custom_data = cpicker;
5602 
5603  cpicker->use_color_lock = lock;
5604  cpicker->use_color_cubic = cubic;
5605  cpicker->use_luminosity_lock = lock_luminosity;
5606 
5607  if (lock_luminosity) {
5608  float color[4]; /* in case of alpha */
5610  but->a2 = len_v3(color);
5611  cpicker->luminosity_lock_value = len_v3(color);
5612  }
5613 
5614  if (value_slider) {
5615  switch (U.color_picker_type) {
5616  case USER_CP_CIRCLE_HSL:
5617  uiItemS(row);
5618  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5620  0,
5621  "",
5622  WHEEL_SIZE + 6,
5623  0,
5624  14 * UI_DPI_FAC,
5625  WHEEL_SIZE,
5626  ptr,
5627  prop,
5628  -1,
5629  softmin,
5630  softmax,
5631  0,
5632  0,
5633  "");
5634  hsv_but->gradient_type = UI_GRAD_L_ALT;
5635  break;
5636  case USER_CP_SQUARE_SV:
5637  uiItemS(col);
5638  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5640  0,
5641  "",
5642  0,
5643  4,
5644  WHEEL_SIZE,
5645  18 * UI_DPI_FAC,
5646  ptr,
5647  prop,
5648  -1,
5649  softmin,
5650  softmax,
5651  0,
5652  0,
5653  "");
5654  hsv_but->gradient_type = UI_GRAD_SV + 3;
5655  break;
5656  case USER_CP_SQUARE_HS:
5657  uiItemS(col);
5658  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5660  0,
5661  "",
5662  0,
5663  4,
5664  WHEEL_SIZE,
5665  18 * UI_DPI_FAC,
5666  ptr,
5667  prop,
5668  -1,
5669  softmin,
5670  softmax,
5671  0,
5672  0,
5673  "");
5674  hsv_but->gradient_type = UI_GRAD_HS + 3;
5675  break;
5676  case USER_CP_SQUARE_HV:
5677  uiItemS(col);
5678  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5680  0,
5681  "",
5682  0,
5683  4,
5684  WHEEL_SIZE,
5685  18 * UI_DPI_FAC,
5686  ptr,
5687  prop,
5688  -1,
5689  softmin,
5690  softmax,
5691  0,
5692  0,
5693  "");
5694  hsv_but->gradient_type = UI_GRAD_HV + 3;
5695  break;
5696 
5697  /* user default */
5698  case USER_CP_CIRCLE_HSV:
5699  default:
5700  uiItemS(row);
5701  hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
5703  0,
5704  "",
5705  WHEEL_SIZE + 6,
5706  0,
5707  14 * UI_DPI_FAC,
5708  WHEEL_SIZE,
5709  ptr,
5710  prop,
5711  -1,
5712  softmin,
5713  softmax,
5714  0,
5715  0,
5716  "");
5717  hsv_but->gradient_type = UI_GRAD_V_ALT;
5718  break;
5719  }
5720 
5721  hsv_but->but.custom_data = cpicker;
5722  }
5723 }
5724 
5725 static void ui_template_palette_menu(bContext *UNUSED(C), uiLayout *layout, void *UNUSED(but_p))
5726 {
5727  uiLayout *row;
5728 
5729  uiItemL(layout, IFACE_("Sort By:"), ICON_NONE);
5730  row = uiLayoutRow(layout, false);
5731  uiItemEnumO_value(row, IFACE_("Hue"), ICON_NONE, "PALETTE_OT_sort", "type", 1);
5732  row = uiLayoutRow(layout, false);
5733  uiItemEnumO_value(row, IFACE_("Saturation"), ICON_NONE, "PALETTE_OT_sort", "type", 2);
5734  row = uiLayoutRow(layout, false);
5735  uiItemEnumO_value(row, IFACE_("Value"), ICON_NONE, "PALETTE_OT_sort", "type", 3);
5736  row = uiLayoutRow(layout, false);
5737  uiItemEnumO_value(row, IFACE_("Luminance"), ICON_NONE, "PALETTE_OT_sort", "type", 4);
5738 }
5739 
5741  PointerRNA *ptr,
5742  const char *propname,
5743  bool UNUSED(colors))
5744 {
5745  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5746  uiBut *but = NULL;
5747 
5748  const int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1);
5749 
5750  if (!prop) {
5751  RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5752  return;
5753  }
5754 
5755  const PointerRNA cptr = RNA_property_pointer_get(ptr, prop);
5756  if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Palette)) {
5757  return;
5758  }
5759 
5760  uiBlock *block = uiLayoutGetBlock(layout);
5761 
5762  Palette *palette = cptr.data;
5763 
5764  uiLayout *col = uiLayoutColumn(layout, true);
5765  uiLayoutRow(col, true);
5766  uiDefIconButO(block,
5767  UI_BTYPE_BUT,
5768  "PALETTE_OT_color_add",
5770  ICON_ADD,
5771  0,
5772  0,
5773  UI_UNIT_X,
5774  UI_UNIT_Y,
5775  NULL);
5776  uiDefIconButO(block,
5777  UI_BTYPE_BUT,
5778  "PALETTE_OT_color_delete",
5780  ICON_REMOVE,
5781  0,
5782  0,
5783  UI_UNIT_X,
5784  UI_UNIT_Y,
5785  NULL);
5786  if (palette->colors.first != NULL) {
5787  but = uiDefIconButO(block,
5788  UI_BTYPE_BUT,
5789  "PALETTE_OT_color_move",
5791  ICON_TRIA_UP,
5792  0,
5793  0,
5794  UI_UNIT_X,
5795  UI_UNIT_Y,
5796  NULL);
5798  RNA_enum_set(but->opptr, "type", -1);
5799 
5800  but = uiDefIconButO(block,
5801  UI_BTYPE_BUT,
5802  "PALETTE_OT_color_move",
5804  ICON_TRIA_DOWN,
5805  0,
5806  0,
5807  UI_UNIT_X,
5808  UI_UNIT_Y,
5809  NULL);
5811  RNA_enum_set(but->opptr, "type", 1);
5812 
5813  /* Menu. */
5815  block, ui_template_palette_menu, NULL, ICON_SORTSIZE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
5816  }
5817 
5818  col = uiLayoutColumn(layout, true);
5819  uiLayoutRow(col, true);
5820 
5821  int row_cols = 0, col_id = 0;
5822  LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) {
5823  if (row_cols >= cols_per_row) {
5824  uiLayoutRow(col, true);
5825  row_cols = 0;
5826  }
5827 
5828  PointerRNA color_ptr;
5829  RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr);
5830  uiButColor *color_but = (uiButColor *)uiDefButR(block,
5832  0,
5833  "",
5834  0,
5835  0,
5836  UI_UNIT_X,
5837  UI_UNIT_Y,
5838  &color_ptr,
5839  "color",
5840  -1,
5841  0.0,
5842  1.0,
5843  0.0,
5844  0.0,
5845  "");
5846  color_but->is_pallete_color = true;
5847  color_but->palette_color_index = col_id;
5848  row_cols++;
5849  col_id++;
5850  }
5851 }
5852 
5853 void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int icon)
5854 {
5855  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5856 
5857  if (!prop) {
5858  RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5859  return;
5860  }
5861 
5862  uiBlock *block = uiLayoutGetBlock(layout);
5863 
5864  uiBut *but = uiDefIconTextButO(block,
5865  UI_BTYPE_BUT,
5866  "UI_OT_eyedropper_color",
5868  icon,
5869  "",
5870  0,
5871  0,
5872  UI_UNIT_X,
5873  UI_UNIT_Y,
5875  but->rnapoin = *ptr;
5876  but->rnaprop = prop;
5877  but->rnaindex = -1;
5878 }
5879 
5882 /* -------------------------------------------------------------------- */
5886 static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
5887 {
5888  uiBut *but = arg1;
5889  const int cur = POINTER_AS_INT(arg2);
5890  wmWindow *win = CTX_wm_window(C);
5891  const bool shift = win->eventstate->modifier & KM_SHIFT;
5892 
5893  if (!shift) {
5894  const int tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
5895 
5896  /* Normally clicking only selects one layer */
5897  RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, true);
5898  for (int i = 0; i < tot; i++) {
5899  if (i != cur) {
5900  RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, false);
5901  }
5902  }
5903  }
5904 
5905  /* view3d layer change should update depsgraph (invisible object changed maybe) */
5906  /* see view3d_header.c */
5907 }
5908 
5910  PointerRNA *ptr,
5911  const char *propname,
5912  PointerRNA *used_ptr,
5913  const char *used_propname,
5914  int active_layer)
5915 {
5916  const int cols_per_group = 5;
5917 
5918  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
5919  if (!prop) {
5920  RNA_warning("layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
5921  return;
5922  }
5923 
5924  /* the number of layers determines the way we group them
5925  * - we want 2 rows only (for now)
5926  * - The number of columns (cols) is the total number of buttons per row the 'remainder'
5927  * is added to this, as it will be ok to have first row slightly wider if need be.
5928  * - For now, only split into groups if group will have at least 5 items.
5929  */
5930  const int layers = RNA_property_array_length(ptr, prop);
5931  const int cols = (layers / 2) + (layers % 2);
5932  const int groups = ((cols / 2) < cols_per_group) ? (1) : (cols / cols_per_group);
5933 
5934  PropertyRNA *used_prop = NULL;
5935  if (used_ptr && used_propname) {
5936  used_prop = RNA_struct_find_property(used_ptr, used_propname);
5937  if (!used_prop) {
5938  RNA_warning("used layers property not found: %s.%s",
5940  used_propname);
5941  return;
5942  }
5943 
5944  if (RNA_property_array_length(used_ptr, used_prop) < layers) {
5945  used_prop = NULL;
5946  }
5947  }
5948 
5949  /* layers are laid out going across rows, with the columns being divided into groups */
5950 
5951  for (int group = 0; group < groups; group++) {
5952  uiLayout *uCol = uiLayoutColumn(layout, true);
5953 
5954  for (int row = 0; row < 2; row++) {
5955  uiLayout *uRow = uiLayoutRow(uCol, true);
5956  uiBlock *block = uiLayoutGetBlock(uRow);
5957  int layer = groups * cols_per_group * row + cols_per_group * group;
5958 
5959  /* add layers as toggle buts */
5960  for (int col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) {
5961  int icon = 0;
5962  const int butlay = 1 << layer;
5963 
5964  if (active_layer & butlay) {
5965  icon = ICON_LAYER_ACTIVE;
5966  }
5967  else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer)) {
5968  icon = ICON_LAYER_USED;
5969  }
5970 
5971  uiBut *but = uiDefAutoButR(
5972  block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
5974  but->type = UI_BTYPE_TOGGLE;
5975  }
5976  }
5977  }
5978 }
5979 
5982 /* -------------------------------------------------------------------- */
5986 #define B_STOPRENDER 1
5987 #define B_STOPCAST 2
5988 #define B_STOPANIM 3
5989 #define B_STOPCOMPO 4
5990 #define B_STOPSEQ 5
5991 #define B_STOPCLIP 6
5992 #define B_STOPFILE 7
5993 #define B_STOPOTHER 8
5994 
5995 static void do_running_jobs(bContext *C, void *UNUSED(arg), int event)
5996 {
5997  switch (event) {
5998  case B_STOPRENDER:
5999  G.is_break = true;
6000  break;
6001  case B_STOPCAST:
6003  break;
6004  case B_STOPANIM:
6005  WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL, NULL);
6006  break;
6007  case B_STOPCOMPO:
6009  break;
6010  case B_STOPSEQ:
6012  break;
6013  case B_STOPCLIP:
6015  break;
6016  case B_STOPFILE:
6018  break;
6019  case B_STOPOTHER:
6020  G.is_break = true;
6021  break;
6022  }
6023 }
6024 
6027  void *owner;
6028 };
6029 
6030 static char *progress_tooltip_func(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
6031 {
6032  struct ProgressTooltip_Store *arg = argN;
6033  wmWindowManager *wm = arg->wm;
6034  void *owner = arg->owner;
6035 
6036  const float progress = WM_jobs_progress(wm, owner);
6037 
6038  /* create tooltip text and associate it with the job */
6039  char elapsed_str[32];
6040  char remaining_str[32] = "Unknown";
6041  const double elapsed = PIL_check_seconds_timer() - WM_jobs_starttime(wm, owner);
6042  BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
6043 
6044  if (progress) {
6045  const double remaining = (elapsed / (double)progress) - elapsed;
6046  BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining);
6047  }
6048 
6049  return BLI_sprintfN(
6050  "Time Remaining: %s\n"
6051  "Time Elapsed: %s",
6052  remaining_str,
6053  elapsed_str);
6054 }
6055 
6057 {
6058  Main *bmain = CTX_data_main(C);
6060  ScrArea *area = CTX_wm_area(C);
6061  void *owner = NULL;
6062  int handle_event, icon = 0;
6063 
6064  uiBlock *block = uiLayoutGetBlock(layout);
6065  UI_block_layout_set_current(block, layout);
6066 
6068 
6069  /* another scene can be rendering too, for example via compositor */
6070  LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
6072  handle_event = B_STOPOTHER;
6073  icon = ICON_NONE;
6074  owner = scene;
6075  }
6076  else {
6077  continue;
6078  }
6079 
6081  handle_event = B_STOPSEQ;
6082  icon = ICON_SEQUENCE;
6083  owner = scene;
6084  break;
6085  }
6087  handle_event = B_STOPSEQ;
6088  icon = ICON_SEQUENCE;
6089  break;
6090  }
6092  handle_event = B_STOPSEQ;
6093  icon = ICON_SEQUENCE;
6094  break;
6095  }
6097  handle_event = B_STOPCLIP;
6098  icon = ICON_TRACKER;
6099  break;
6100  }
6102  handle_event = B_STOPCLIP;
6103  icon = ICON_TRACKER;
6104  break;
6105  }
6107  handle_event = B_STOPCLIP;
6108  icon = ICON_TRACKER;
6109  break;
6110  }
6112  handle_event = B_STOPCLIP;
6113  icon = ICON_TRACKER;
6114  break;
6115  }
6117  handle_event = B_STOPFILE;
6118  icon = ICON_FILEBROWSER;
6119  break;
6120  }
6122  handle_event = B_STOPRENDER;
6123  icon = ICON_SCENE;
6124  break;
6125  }
6127  handle_event = B_STOPCOMPO;
6128  icon = ICON_RENDERLAYERS;
6129  break;
6130  }
6133  /* Skip bake jobs in compositor to avoid compo header displaying
6134  * progress bar which is not being updated (bake jobs only need
6135  * to update NC_IMAGE context.
6136  */
6137  if (area->spacetype != SPACE_NODE) {
6138  handle_event = B_STOPOTHER;
6139  icon = ICON_IMAGE;
6140  break;
6141  }
6142  continue;
6143  }
6145  handle_event = B_STOPOTHER;
6146  icon = ICON_MOD_DYNAMICPAINT;
6147  break;
6148  }
6150  handle_event = B_STOPOTHER;
6151  icon = ICON_PHYSICS;
6152  break;
6153  }
6155  handle_event = B_STOPOTHER;
6156  icon = ICON_MOD_FLUIDSIM;
6157  break;
6158  }
6160  handle_event = B_STOPOTHER;
6161  icon = ICON_MOD_OCEAN;
6162  break;
6163  }
6164  }
6165 
6166  if (owner) {
6167  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
6168  const bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner));
6169 
6170  uiLayout *row = uiLayoutRow(layout, false);
6171  block = uiLayoutGetBlock(row);
6172 
6173  /* get percentage done and set it as the UI text */
6174  const float progress = WM_jobs_progress(wm, owner);
6175  char text[8];
6176  BLI_snprintf(text, 8, "%d%%", (int)(progress * 100));
6177 
6178  const char *name = active ? WM_jobs_name(wm, owner) : "Canceling...";
6179 
6180  /* job name and icon */
6181  const int textwidth = UI_fontstyle_string_width(fstyle, name);
6182  uiDefIconTextBut(block,
6184  0,
6185  icon,
6186  name,
6187  0,
6188  0,
6189  textwidth + UI_UNIT_X * 1.5f,
6190  UI_UNIT_Y,
6191  NULL,
6192  0.0f,
6193  0.0f,
6194  0.0f,
6195  0.0f,
6196  "");
6197 
6198  /* stick progress bar and cancel button together */
6199  row = uiLayoutRow(layout, true);
6200  uiLayoutSetActive(row, active);
6201  block = uiLayoutGetBlock(row);
6202 
6203  {
6204  struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__);
6205  tip_arg->wm = wm;
6206  tip_arg->owner = owner;
6207  uiButProgressbar *but_progress = (uiButProgressbar *)uiDefIconTextBut(block,
6209  0,
6210  0,
6211  text,
6212  UI_UNIT_X,
6213  0,
6214  UI_UNIT_X * 6.0f,
6215  UI_UNIT_Y,
6216  NULL,
6217  0.0f,
6218  0.0f,
6219  0.0f,
6220  0,
6221  NULL);
6222 
6223  but_progress->progress = progress;
6224  UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg, MEM_freeN);
6225  }
6226 
6227  if (!wm->is_interface_locked) {
6228  uiDefIconTextBut(block,
6229  UI_BTYPE_BUT,
6230  handle_event,
6231  ICON_PANEL_CLOSE,
6232  "",
6233  0,
6234  0,
6235  UI_UNIT_X,
6236  UI_UNIT_Y,
6237  NULL,
6238  0.0f,
6239  0.0f,
6240  0,
6241  0,
6242  TIP_("Stop this job"));
6243  }
6244  }
6245 
6247  uiDefIconTextBut(block,
6248  UI_BTYPE_BUT,
6249  B_STOPANIM,
6250  ICON_CANCEL,
6251  IFACE_("Anim Player"),
6252  0,
6253  0,
6254  UI_UNIT_X * 5.0f,
6255  UI_UNIT_Y,
6256  NULL,
6257  0.0f,
6258  0.0f,
6259  0,
6260  0,
6261  TIP_("Stop animation playback"));
6262  }
6263 }
6264 
6267 /* -------------------------------------------------------------------- */
6272 {
6273  ReportList *reports = CTX_wm_reports(C);
6274  Report *report = BKE_reports_last_displayable(reports);
6275  const uiStyle *style = UI_style_get();
6276 
6277  uiBut *but;
6278 
6279  /* if the report display has timed out, don't show */
6280  if (!reports->reporttimer) {
6281  return;
6282  }
6283 
6285 
6286  if (!rti || rti->widthfac == 0.0f || !report) {
6287  return;
6288  }
6289 
6290  uiLayout *ui_abs = uiLayoutAbsolute(layout, false);
6291  uiBlock *block = uiLayoutGetBlock(ui_abs);
6292  eUIEmbossType previous_emboss = UI_block_emboss_get(block);
6293 
6294  UI_fontstyle_set(&style->widgetlabel);
6295  int width = BLF_width(style->widgetlabel.uifont_id, report->message, report->len);
6296  width = min_ii((int)(rti->widthfac * width), width);
6297  width = max_ii(width, 10 * UI_DPI_FAC);
6298 
6299  UI_block_align_begin(block);
6300 
6301  /* Background for icon. */
6302  but = uiDefBut(block,
6304  0,
6305  "",
6306  0,
6307  0,
6308  UI_UNIT_X + (6 * UI_DPI_FAC),
6309  UI_UNIT_Y,
6310  NULL,
6311  0.0f,
6312  0.0f,
6313  0,
6314  0,
6315  "");
6316  /* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
6318 
6319  /* Background for the rest of the message. */
6320  but = uiDefBut(block,
6322  0,
6323  "",
6324  UI_UNIT_X + (6 * UI_DPI_FAC),
6325  0,
6326  UI_UNIT_X + width,
6327  UI_UNIT_Y,
6328  NULL,
6329  0.0f,
6330  0.0f,
6331  0,
6332  0,
6333  "");
6334 
6335  /* Use icon background at low opacity to highlight, but still contrasting with area TH_TEXT. */
6337  but->col[3] = 64;
6338 
6339  UI_block_align_end(block);
6341 
6342  /* The report icon itself. */
6343  but = uiDefIconButO(block,
6344  UI_BTYPE_BUT,
6345  "SCREEN_OT_info_log_show",
6347  UI_icon_from_report_type(report->type),
6348  (3 * UI_DPI_FAC),
6349  0,
6350  UI_UNIT_X,
6351  UI_UNIT_Y,
6352  TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
6354  but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
6355 
6356  /* The report message. */
6357  but = uiDefButO(block,
6358  UI_BTYPE_BUT,
6359  "SCREEN_OT_info_log_show",
6361  report->message,
6362  UI_UNIT_X,
6363  0,
6364  width + UI_UNIT_X,
6365  UI_UNIT_Y,
6366  "Show in Info Log");
6367 
6368  UI_block_emboss_set(block, previous_emboss);
6369 }
6370 
6372 {
6373  wmWindow *win = CTX_wm_window(C);
6374  WorkSpace *workspace = CTX_wm_workspace(C);
6375 
6376  /* Workspace status text has priority. */
6377  if (workspace->status_text) {
6378  uiItemL(layout, workspace->status_text, ICON_NONE);
6379  return;
6380  }
6381 
6382  if (WM_window_modal_keymap_status_draw(C, win, layout)) {
6383  return;
6384  }
6385 
6386  /* Otherwise should cursor keymap status. */
6387  for (int i = 0; i < 3; i++) {
6388  uiLayout *box = uiLayoutRow(layout, false);
6389  uiLayout *col = uiLayoutColumn(box, false);
6390  uiLayout *row = uiLayoutRow(col, true);
6392 
6393  const char *msg = TIP_(WM_window_cursor_keymap_status_get(win, i, 0));
6394  const char *msg_drag = TIP_(WM_window_cursor_keymap_status_get(win, i, 1));
6395 
6396  if (msg || (msg_drag == NULL)) {
6397  uiItemL(row, msg ? msg : "", (ICON_MOUSE_LMB + i));
6398  }
6399 
6400  if (msg_drag) {
6401  uiItemL(row, msg_drag, (ICON_MOUSE_LMB_DRAG + i));
6402  }
6403 
6404  /* Use trick with empty string to keep icons in same position. */
6405  row = uiLayoutRow(col, false);
6406  uiItemL(row, " ", ICON_NONE);
6407  }
6408 }
6409 
6411 {
6412  Main *bmain = CTX_data_main(C);
6414  ViewLayer *view_layer = CTX_data_view_layer(C);
6415 
6416  if (!bmain->has_forward_compatibility_issues) {
6417  const char *status_info_txt = ED_info_statusbar_string(bmain, scene, view_layer);
6418  uiItemL(layout, status_info_txt, ICON_NONE);
6419  return;
6420  }
6421 
6422  /* Blender version part is shown as warning area when there are forward compatibility issues with
6423  * currently loaded .blend file. */
6424 
6425  const char *status_info_txt = ED_info_statusbar_string_ex(
6426  bmain, scene, view_layer, (U.statusbar_flag & ~STATUSBAR_SHOW_VERSION));
6427  uiItemL(layout, status_info_txt, ICON_NONE);
6428 
6429  status_info_txt = ED_info_statusbar_string_ex(bmain, scene, view_layer, STATUSBAR_SHOW_VERSION);
6430 
6431  uiBut *but;
6432 
6433  const uiStyle *style = UI_style_get();
6434  uiLayout *ui_abs = uiLayoutAbsolute(layout, false);
6435  uiBlock *block = uiLayoutGetBlock(ui_abs);
6436  eUIEmbossType previous_emboss = UI_block_emboss_get(block);
6437 
6438  UI_fontstyle_set(&style->widgetlabel);
6439  int width = (int)BLF_width(
6440  style->widgetlabel.uifont_id, status_info_txt, strlen(status_info_txt));
6441  width = max_ii(width, (int)(10 * UI_DPI_FAC));
6442 
6443  UI_block_align_begin(block);
6444 
6445  /* Background for icon. */
6446  but = uiDefBut(block,
6448  0,
6449  "",
6450  0,
6451  0,
6452  UI_UNIT_X + (6 * UI_DPI_FAC),
6453  UI_UNIT_Y,
6454  NULL,
6455  0.0f,
6456  0.0f,
6457  0,
6458  0,
6459  "");
6460  /* UI_BTYPE_ROUNDBOX's bg color is set in but->col. */
6462 
6463  /* Background for the rest of the message. */
6464  but = uiDefBut(block,
6466  0,
6467  "",
6468  UI_UNIT_X + (6 * UI_DPI_FAC),
6469  0,
6470  UI_UNIT_X + width,
6471  UI_UNIT_Y,
6472  NULL,
6473  0.0f,
6474  0.0f,
6475  0,
6476  0,
6477  "");
6478 
6479  /* Use icon background at low opacity to highlight, but still contrasting with area TH_TEXT. */
6481  but->col[3] = 64;
6482 
6483  UI_block_align_end(block);
6485 
6486  /* The report icon itself. */
6487  static char compat_error_msg[256];
6488  char writer_ver_str[12];
6490  writer_ver_str, sizeof(writer_ver_str), bmain->versionfile, -1);
6491  SNPRINTF(compat_error_msg,
6492  TIP_("File saved by newer Blender\n(%s), expect loss of data"),
6493  writer_ver_str);
6494  but = uiDefIconBut(block,
6495  UI_BTYPE_BUT,
6496  0,
6497  ICON_ERROR,
6498  (int)(3 * UI_DPI_FAC),
6499  0,
6500  UI_UNIT_X,
6501  UI_UNIT_Y,
6502  NULL,
6503  0.0f,
6504  0.0f,
6505  0.0f,
6506  0.0f,
6507  compat_error_msg);
6509  but->col[3] = 255; /* This theme color is RBG only, so have to set alpha here. */
6510 
6511  /* The report message. */
6512  but = uiDefBut(block,
6513  UI_BTYPE_BUT,
6514  0,
6515  status_info_txt,
6516  UI_UNIT_X,
6517  0,
6518  (short)(width + UI_UNIT_X),
6519  UI_UNIT_Y,
6520  NULL,
6521  0.0f,
6522  0.0f,
6523  0.0f,
6524  0.0f,
6525  compat_error_msg);
6526 
6527  UI_block_emboss_set(block, previous_emboss);
6528 }
6529 
6532 /* -------------------------------------------------------------------- */
6536 static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED(unused))
6537 {
6538  wmKeyMapItem *kmi = (wmKeyMapItem *)kmi_p;
6540 }
6541 
6542 static void template_keymap_item_properties(uiLayout *layout, const char *title, PointerRNA *ptr)
6543 {
6544  uiItemS(layout);
6545 
6546  if (title) {
6547  uiItemL(layout, title, ICON_NONE);
6548  }
6549 
6550  uiLayout *flow = uiLayoutColumnFlow(layout, 2, false);
6551 
6553  const bool is_set = RNA_property_is_set(ptr, prop);
6554  uiBut *but;
6555 
6556  /* recurse for nested properties */
6557  if (RNA_property_type(prop) == PROP_POINTER) {
6558  PointerRNA propptr = RNA_property_pointer_get(ptr, prop);
6559 
6560  if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) {
6561  const char *name = RNA_property_ui_name(prop);
6562  template_keymap_item_properties(layout, name, &propptr);
6563  continue;
6564  }
6565  }
6566 
6567  uiLayout *box = uiLayoutBox(flow);
6568  uiLayoutSetActive(box, is_set);
6569  uiLayout *row = uiLayoutRow(box, false);
6570 
6571  /* property value */
6572  uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
6573 
6574  if (is_set) {
6575  /* unset operator */
6576  uiBlock *block = uiLayoutGetBlock(row);
6578  but = uiDefIconButO(block,
6579  UI_BTYPE_BUT,
6580  "UI_OT_unset_property_button",
6582  ICON_X,
6583  0,
6584  0,
6585  UI_UNIT_X,
6586  UI_UNIT_Y,
6587  NULL);
6588  but->rnapoin = *ptr;
6589  but->rnaprop = prop;
6591  }
6592  }
6594 }
6595 
6597 {
6598  PointerRNA propptr = RNA_pointer_get(ptr, "properties");
6599 
6600  if (propptr.data) {
6601  uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
6602 
6603  WM_operator_properties_sanitize(&propptr, false);
6604  template_keymap_item_properties(layout, NULL, &propptr);
6605 
6606  /* attach callbacks to compensate for missing properties update,
6607  * we don't know which keymap (item) is being modified there */
6608  for (; but; but = but->next) {
6609  /* operator buttons may store props for use (file selector, T36492) */
6610  if (but->rnaprop) {
6612 
6613  /* Otherwise the keymap will be re-generated which we're trying to edit,
6614  * see: T47685 */
6616  }
6617  }
6618  }
6619 }
6620 
6623 /* -------------------------------------------------------------------- */
6628  const char *text,
6629  const struct wmKeyMapItem *kmi,
6630  bool text_fallback)
6631 {
6632  bool ok = false;
6633 
6634  int icon_mod[4];
6635 #ifdef WITH_HEADLESS
6636  int icon = 0;
6637 #else
6638  const int icon = UI_icon_from_keymap_item(kmi, icon_mod);
6639 #endif
6640  if (icon != 0) {
6641  for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
6642  uiItemL(layout, "", icon_mod[j]);
6643  }
6644  uiItemL(layout, CTX_TIP_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, text), icon);
6645  ok = true;
6646  }
6647  else if (text_fallback) {
6648  const char *event_text = WM_key_event_string(kmi->type, true);
6649  uiItemL(layout, event_text, ICON_NONE);
6650  uiItemL(layout, CTX_TIP_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, text), ICON_NONE);
6651  ok = true;
6652  }
6653  return ok;
6654 }
6655 
6658 /* -------------------------------------------------------------------- */
6662 void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)
6663 {
6664  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
6665 
6666  if (!prop) {
6667  printf(
6668  "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
6669  return;
6670  }
6671 
6672  PointerRNA colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
6673 
6674  uiItemR(layout, &colorspace_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE);
6675 }
6676 
6678  bContext *UNUSED(C),
6679  PointerRNA *ptr,
6680  const char *propname)
6681 {
6682  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
6683 
6684  if (!prop) {
6685  printf(
6686  "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
6687  return;
6688  }
6689 
6690  PointerRNA view_transform_ptr = RNA_property_pointer_get(ptr, prop);
6691  ColorManagedViewSettings *view_settings = view_transform_ptr.data;
6692 
6693  uiLayout *col = uiLayoutColumn(layout, false);
6694  uiItemR(col, &view_transform_ptr, "view_transform", 0, IFACE_("View"), ICON_NONE);
6695  uiItemR(col, &view_transform_ptr, "look", 0, IFACE_("Look"), ICON_NONE);
6696 
6697  col = uiLayoutColumn(layout, false);
6698  uiItemR(col, &view_transform_ptr, "exposure", 0, NULL, ICON_NONE);
6699  uiItemR(col, &view_transform_ptr, "gamma", 0, NULL, ICON_NONE);
6700 
6701  col = uiLayoutColumn(layout, false);
6702  uiItemR(col, &view_transform_ptr, "use_curve_mapping", 0, NULL, ICON_NONE);
6703  if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
6705  col, &view_transform_ptr, "curve_mapping", 'c', true, false, false, false);
6706  }
6707 }
6708 
6711 /* -------------------------------------------------------------------- */
6715 typedef struct ComponentMenuArgs {
6717  char propname[64]; /* XXX arbitrary */
6719 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
6720 static uiBlock *component_menu(bContext *C, ARegion *region, void *args_v)
6721 {
6722  ComponentMenuArgs *args = (ComponentMenuArgs *)args_v;
6723 
6724  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
6726 
6727  uiLayout *layout = uiLayoutColumn(UI_block_layout(block,
6730  0,
6731  0,
6732  UI_UNIT_X * 6,
6733  UI_UNIT_Y,
6734  0,
6735  UI_style_get()),
6736  0);
6737 
6738  uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE);
6739 
6740  UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
6742 
6743  return block;
6744 }
6746  PointerRNA *ptr,
6747  const char *propname,
6748  const char *name)
6749 {
6750  ComponentMenuArgs *args = MEM_callocN(sizeof(ComponentMenuArgs), "component menu template args");
6751 
6752  args->ptr = *ptr;
6753  BLI_strncpy(args->propname, propname, sizeof(args->propname));
6754 
6755  uiBlock *block = uiLayoutGetBlock(layout);
6756  UI_block_align_begin(block);
6757 
6758  uiBut *but = uiDefBlockButN(
6759  block, component_menu, args, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, "");
6760  /* set rna directly, uiDefBlockButN doesn't do this */
6761  but->rnapoin = *ptr;
6762  but->rnaprop = RNA_struct_find_property(ptr, propname);
6763  but->rnaindex = 0;
6764 
6765  UI_block_align_end(block);
6766 }
6767 
6770 /* -------------------------------------------------------------------- */
6775 {
6776  uiBlock *block = uiLayoutGetBlock(layout);
6777  UI_block_align_begin(block);
6778 
6779  /* XXX using explicit socket colors is not quite ideal.
6780  * Eventually it should be possible to use theme colors for this purpose,
6781  * but this requires a better design for extendable color palettes in user prefs.
6782  */
6783  uiBut *but = uiDefBut(
6784  block, UI_BTYPE_NODE_SOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
6785  rgba_float_to_uchar(but->col, color);
6786 
6787  UI_block_align_end(block);
6788 }
6789 
6792 /* -------------------------------------------------------------------- */
6797 {
6798  if (RNA_pointer_is_null(fileptr)) {
6799  return;
6800  }
6801 
6802  /* Ensure that the context has a CacheFile as this may not be set inside of modifiers panels. */
6803  uiLayoutSetContextPointer(layout, "edit_cachefile", fileptr);
6804 
6805  uiItemR(layout, fileptr, "velocity_name", 0, NULL, ICON_NONE);
6806  uiItemR(layout, fileptr, "velocity_unit", 0, NULL, ICON_NONE);
6807 }
6808 
6810 {
6811  if (RNA_pointer_is_null(fileptr)) {
6812  return;
6813  }
6814 
6815  /* Ensure that the context has a CacheFile as this may not be set inside of modifiers panels. */
6816  uiLayoutSetContextPointer(layout, "edit_cachefile", fileptr);
6817 
6818  uiLayout *row, *sub;
6819 
6820  /* Only enable render procedural option if the active engine supports it. */
6821  const struct RenderEngineType *engine_type = CTX_data_engine_type(C);
6822 
6824  const bool engine_supports_procedural = RE_engine_supports_alembic_procedural(engine_type,
6825  scene);
6826  CacheFile *cache_file = (CacheFile *)fileptr->data;
6828  &cache_file->id);
6829  bool is_alembic = cache_file_eval->type == CACHEFILE_TYPE_ALEMBIC;
6830 
6831  if (!is_alembic) {
6832  row = uiLayoutRow(layout, false);
6833  uiItemL(row, TIP_("Only Alembic Procedurals supported"), ICON_INFO);
6834  }
6835  else if (!engine_supports_procedural) {
6836  row = uiLayoutRow(layout, false);
6837  /* For Cycles, verify that experimental features are enabled. */
6839  uiItemL(
6840  row,
6841  TIP_(
6842  "The Cycles Alembic Procedural is only available with the experimental feature set"),
6843  ICON_INFO);
6844  }
6845  else {
6846  uiItemL(
6847  row, TIP_("The active render engine does not have an Alembic Procedural"), ICON_INFO);
6848  }
6849  }
6850 
6851  row = uiLayoutRow(layout, false);
6852  uiLayoutSetActive(row, is_alembic && engine_supports_procedural);
6853  uiItemR(row, fileptr, "use_render_procedural", 0, NULL, ICON_NONE);
6854 
6855  const bool use_render_procedural = RNA_boolean_get(fileptr, "use_render_procedural");
6856  const bool use_prefetch = RNA_boolean_get(fileptr, "use_prefetch");
6857 
6858  row = uiLayoutRow(layout, false);
6859  uiLayoutSetEnabled(row, use_render_procedural);
6860  uiItemR(row, fileptr, "use_prefetch", 0, NULL, ICON_NONE);
6861 
6862  sub = uiLayoutRow(layout, false);
6863  uiLayoutSetEnabled(sub, use_prefetch && use_render_procedural);
6864  uiItemR(sub, fileptr, "prefetch_cache_size", 0, NULL, ICON_NONE);
6865 }
6866 
6868 {
6869  if (RNA_pointer_is_null(fileptr)) {
6870  return;
6871  }
6872 
6873  /* Ensure that the context has a CacheFile as this may not be set inside of modifiers panels. */
6874  uiLayoutSetContextPointer(layout, "edit_cachefile", fileptr);
6875 
6876  uiLayout *row, *sub, *subsub;
6877 
6878  row = uiLayoutRow(layout, false);
6879  uiItemR(row, fileptr, "is_sequence", 0, NULL, ICON_NONE);
6880 
6881  row = uiLayoutRowWithHeading(layout, true, IFACE_("Override Frame"));
6882  sub = uiLayoutRow(row, true);
6883  uiLayoutSetPropDecorate(sub, false);
6884  uiItemR(sub, fileptr, "override_frame", 0, "", ICON_NONE);
6885  subsub = uiLayoutRow(sub, true);
6886  uiLayoutSetActive(subsub, RNA_boolean_get(fileptr, "override_frame"));
6887  uiItemR(subsub, fileptr, "frame", 0, "", ICON_NONE);
6888  uiItemDecoratorR(row, fileptr, "frame", 0);
6889 
6890  row = uiLayoutRow(layout, false);
6891  uiItemR(row, fileptr, "frame_offset", 0, NULL, ICON_NONE);
6892  uiLayoutSetActive(row, !RNA_boolean_get(fileptr, "is_sequence"));
6893 }
6894 
6895 static void cache_file_layer_item(uiList *UNUSED(ui_list),
6896  bContext *UNUSED(C),
6897  uiLayout *layout,
6898  PointerRNA *UNUSED(dataptr),
6899  PointerRNA *itemptr,
6900  int UNUSED(icon),
6901  PointerRNA *UNUSED(active_dataptr),
6902  const char *UNUSED(active_propname),
6903  int UNUSED(index),
6904  int UNUSED(flt_flag))
6905 {
6906  uiLayout *row = uiLayoutRow(layout, true);
6907  uiItemR(row, itemptr, "hide_layer", UI_ITEM_R_NO_BG, "", ICON_NONE);
6908  uiItemR(row, itemptr, "filepath", UI_ITEM_R_NO_BG, "", ICON_NONE);
6909 }
6910 
6912 {
6913  uiListType *list_type = (uiListType *)MEM_callocN(sizeof(*list_type), __func__);
6914 
6915  BLI_strncpy(list_type->idname, "UI_UL_cache_file_layers", sizeof(list_type->idname));
6916  list_type->draw_item = cache_file_layer_item;
6917 
6918  return list_type;
6919 }
6920 
6921 void uiTemplateCacheFileLayers(uiLayout *layout, const bContext *C, PointerRNA *fileptr)
6922 {
6923  if (RNA_pointer_is_null(fileptr)) {
6924  return;
6925  }
6926 
6927  /* Ensure that the context has a CacheFile as this may not be set inside of modifiers panels. */
6928  uiLayoutSetContextPointer(layout, "edit_cachefile", fileptr);
6929 
6930  uiLayout *row = uiLayoutRow(layout, false);
6931  uiLayout *col = uiLayoutColumn(row, true);
6932 
6934  (bContext *)C,
6935  "UI_UL_cache_file_layers",
6936  "cache_file_layers",
6937  fileptr,
6938  "layers",
6939  fileptr,
6940  "active_index",
6941  "",
6942  1,
6943  5,
6945  1,
6947 
6948  col = uiLayoutColumn(row, true);
6949  uiItemO(col, "", ICON_ADD, "cachefile.layer_add");
6950  uiItemO(col, "", ICON_REMOVE, "cachefile.layer_remove");
6951 
6952  CacheFile *file = fileptr->data;
6953  if (BLI_listbase_count(&file->layers) > 1) {
6954  uiItemS_ex(col, 1.0f);
6955  uiItemO(col, "", ICON_TRIA_UP, "cachefile.layer_move");
6956  uiItemO(col, "", ICON_TRIA_DOWN, "cachefile.layer_move");
6957  }
6958 }
6959 
6960 bool uiTemplateCacheFilePointer(PointerRNA *ptr, const char *propname, PointerRNA *r_file_ptr)
6961 {
6962  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
6963 
6964  if (!prop) {
6965  printf(
6966  "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
6967  return false;
6968  }
6969 
6970  if (RNA_property_type(prop) != PROP_POINTER) {
6971  printf("%s: expected pointer property for %s.%s\n",
6972  __func__,
6974  propname);
6975  return false;
6976  }
6977 
6978  *r_file_ptr = RNA_property_pointer_get(ptr, prop);
6979  return true;
6980 }
6981 
6983  const bContext *C,
6984  PointerRNA *ptr,
6985  const char *propname)
6986 {
6987  if (!ptr->data) {
6988  return;
6989  }
6990 
6991  PointerRNA fileptr;
6992  if (!uiTemplateCacheFilePointer(ptr, propname, &fileptr)) {
6993  return;
6994  }
6995 
6996  CacheFile *file = fileptr.data;
6997 
6998  uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr);
6999 
7000  uiTemplateID(layout,
7001  C,
7002  ptr,
7003  propname,
7004  NULL,
7005  "CACHEFILE_OT_open",
7006  NULL,
7008  false,
7009  NULL);
7010 
7011  if (!file) {
7012  return;
7013  }
7014 
7016 
7017  uiLayout *row, *sub;
7018 
7019  uiLayoutSetPropSep(layout, true);
7020 
7021  row = uiLayoutRow(layout, true);
7022  uiItemR(row, &fileptr, "filepath", 0, NULL, ICON_NONE);
7023  sub = uiLayoutRow(row, true);
7024  uiItemO(sub, "", ICON_FILE_REFRESH, "cachefile.reload");
7025 
7026  if (sbuts->mainb == BCONTEXT_CONSTRAINT) {
7027  row = uiLayoutRow(layout, false);
7028  uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE);
7029  }
7030 
7031  /* TODO: unused for now, so no need to expose. */
7032 #if 0
7033  row = uiLayoutRow(layout, false);
7034  uiItemR(row, &fileptr, "forward_axis", 0, "Forward Axis", ICON_NONE);
7035 
7036  row = uiLayoutRow(layout, false);
7037  uiItemR(row, &fileptr, "up_axis", 0, "Up Axis", ICON_NONE);
7038 #endif
7039 }
7040 
7043 /* -------------------------------------------------------------------- */
7047 int uiTemplateRecentFiles(uiLayout *layout, int rows)
7048 {
7049  int i;
7050  LISTBASE_FOREACH_INDEX (RecentFile *, recent, &G.recent_files, i) {
7051  if (i >= rows) {
7052  break;
7053  }
7054 
7055  const char *filename = BLI_path_basename(recent->filepath);
7056  PointerRNA ptr;
7057  uiItemFullO(layout,
7058  "WM_OT_open_mainfile",
7059  filename,
7060  BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
7061  NULL,
7063  0,
7064  &ptr);
7065  RNA_string_set(&ptr, "filepath", recent->filepath);
7066  RNA_boolean_set(&ptr, "display_file_selector", false);
7067  }
7068 
7069  return i;
7070 }
7071 
7074 /* -------------------------------------------------------------------- */
7079 {
7080  bScreen *screen = CTX_wm_screen(C);
7081  SpaceFile *sfile = CTX_wm_space_file(C);
7082 
7083  ED_file_path_button(screen, sfile, params, uiLayoutGetBlock(layout));
7084 }
7085 
Blender kernel action and pose functionality.
void BKE_blender_version_blendfile_string_from_values(char *str_buff, const size_t str_buff_len, const short file_version, const short file_subversion)
Definition: blender.c:129
#define FOREACH_SCENE_OBJECT_END
bool BKE_collection_has_object_recursive(struct Collection *collection, struct Object *ob)
Definition: collection.c:921
bool BKE_collection_has_collection(const struct Collection *parent, const struct Collection *collection)
bool BKE_scene_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, bool free_us)
Definition: collection.c:1224
#define FOREACH_SCENE_OBJECT_BEGIN(scene, _instance)
void BKE_colorband_init(struct ColorBand *coba, bool rangetype)
Definition: colorband.c:22
bool BKE_colorband_element_remove(struct ColorBand *coba, int index)
Definition: colorband.c:628
#define MAXCOLORBAND
Definition: BKE_colorband.h:16
struct CBData * BKE_colorband_element_add(struct ColorBand *coba, float position)
Definition: colorband.c:602
void BKE_colorband_update_sort(struct ColorBand *coba)
Definition: colorband.c:580
void BKE_curvemap_handle_set(struct CurveMap *cuma, int type)
Definition: colortools.c:424
void BKE_curvemapping_changed(struct CurveMapping *cumap, bool rem_doubles)
Definition: colortools.c:855
void BKE_curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3])
Definition: colortools.c:152
void BKE_curvemap_remove(struct CurveMap *cuma, short flag)
Definition: colortools.c:199
void BKE_curvemap_reset(struct CurveMap *cuma, const struct rctf *clipr, int preset, int slope)
@ CURVEMAP_SLOPE_NEGATIVE
@ CURVEMAP_SLOPE_POSITIVE
void BKE_curvemapping_reset_view(struct CurveMapping *cumap)
Definition: colortools.c:946
const bConstraintTypeInfo * BKE_constraint_typeinfo_from_type(int type)
Definition: constraint.c:5487
struct WorkSpace * CTX_wm_workspace(const bContext *C)
Definition: context.c:728
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct SpaceProperties * CTX_wm_space_properties(const bContext *C)
Definition: context.c:833
struct RenderEngineType * CTX_data_engine_type(const bContext *C)
Definition: context.c:1120
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Collection * CTX_data_collection(const bContext *C)
Definition: context.c:1141
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:733
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:775
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct SpaceFile * CTX_wm_space_file(const bContext *C)
Definition: context.c:842
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
@ PROF_UPDATE_CLIP
@ PROF_UPDATE_REMOVE_DOUBLES
@ PROF_UPDATE_NONE
void BKE_curveprofile_update(struct CurveProfile *profile, int update_flags)
void BKE_curveprofile_reset_view(struct CurveProfile *profile)
void BKE_curveprofile_remove_by_flag(struct CurveProfile *profile, short flag)
void BKE_curveprofile_reset(struct CurveProfile *profile)
void BKE_curveprofile_reverse(struct CurveProfile *profile)
void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname)
const GpencilModifierTypeInfo * BKE_gpencil_modifier_get_info(GpencilModifierType type)
struct IDProperty * IDP_New(char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: idprop.c:887
const char * BKE_idtype_idcode_to_name(short idcode)
Definition: idtype.c:142
const char * BKE_idtype_idcode_to_translation_context(short idcode)
Definition: idtype.c:156
#define BKE_idtype_idcode_is_localizable
Definition: BKE_idtype.h:336
void BKE_id_newptr_and_tag_clear(struct ID *id)
Definition: lib_id.c:359
bool BKE_id_copy_is_allowed(const struct ID *id)
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI], const struct ID *id, bool add_lib_hint, char separator_char, int *r_prefix_len)
void id_us_min(struct ID *id)
Definition: lib_id.c:313
#define MAX_ID_FULL_NAME_UI
Definition: BKE_lib_id.h:551
void BKE_main_id_flag_listbase(struct ListBase *lb, int flag, bool value)
Definition: lib_id.c:941
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop)
Definition: lib_id.c:762
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void id_us_clear_real(struct ID *id)
Definition: lib_id.c:278
bool BKE_lib_id_make_local(struct Main *bmain, struct ID *id, int flags)
Definition: lib_id.c:533
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:351
IDOverrideLibrary * BKE_lib_override_library_get(struct Main *bmain, struct ID *id, struct ID *owner_id_hint, struct ID **r_owner_id)
void BKE_lib_override_library_make_local(struct ID *id)
bool BKE_lib_override_library_create(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, struct Library *owner_library, struct ID *id_root_reference, struct ID *id_hierarchy_root_reference, struct ID *id_instance_hint, struct ID **r_id_root_override, const bool do_fully_editable)
void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root, bool do_reset_system_override)
Blender kernel freestyle line style functionality.
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:567
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(const struct ID *id)
Report * BKE_reports_last_displayable(ReportList *reports)
Definition: report.c:280
bool BKE_scene_uses_blender_eevee(const struct Scene *scene)
bool BKE_scene_uses_cycles(const struct Scene *scene)
bool BKE_scene_uses_cycles_experimental_features(struct Scene *scene)
Definition: scene.cc:2871
@ PANEL_TYPE_INSTANCED
Definition: BKE_screen.h:285
void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname)
Definition: shader_fx.c:155
const ShaderFxTypeInfo * BKE_shaderfx_get_info(ShaderFxType type)
Definition: shader_fx.c:139
float BLF_width(int fontid, const char *str, size_t str_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:688
#define BLI_assert(a)
Definition: BLI_assert.h:46
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
Definition: BLI_listbase.h:348
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
Definition: BLI_listbase.h:344
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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:396
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:1653
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_string_search_add(StringSearch *search, const char *str, void *user_data, int weight)
void BLI_string_search_free(StringSearch *search)
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, size_t maxncpy, double time_seconds) ATTR_NONNULL()
Definition: timecode.c:169
#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:1497
#define BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE
#define BLT_I18NCONTEXT_ID_WINDOWMANAGER
#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_SIMULATION
#define BLT_I18NCONTEXT_ID_NODETREE
#define BLT_I18NCONTEXT_ID_CURVES
#define BLT_I18NCONTEXT_ID_IMAGE
#define BLT_I18NCONTEXT_ID_SPEAKER
#define BLT_I18NCONTEXT_ID_WORKSPACE
#define BLT_I18NCONTEXT_ID_CURVE_LEGACY
#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 BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_ID_ARMATURE
#define BLT_I18N_MSGID_MULTI_CTXT(msgid,...)
#define CTX_TIP_(context, msgid)
#define BLT_I18NCONTEXT_ID_SCENE
#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)
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
@ IDP_GROUP
Definition: DNA_ID.h:141
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition: DNA_ID.h:581
#define ID_IS_OVERRIDABLE_LIBRARY(_id)
Definition: DNA_ID.h:574
#define ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(_id)
Definition: DNA_ID.h:570
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define ID_IS_ASSET(_id)
Definition: DNA_ID.h:598
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:677
@ LIB_TAG_DOIT
Definition: DNA_ID.h:707
@ LIB_FAKEUSER
Definition: DNA_ID.h:630
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:553
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
@ IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED
Definition: DNA_ID.h:327
ID_Type
Definition: DNA_ID_enums.h:44
@ ID_WM
Definition: DNA_ID_enums.h:72
@ ID_CA
Definition: DNA_ID_enums.h:56
@ ID_AR
Definition: DNA_ID_enums.h:66
@ ID_MC
Definition: DNA_ID_enums.h:73
@ ID_CF
Definition: DNA_ID_enums.h:78
@ ID_LI
Definition: DNA_ID_enums.h:46
@ ID_TE
Definition: DNA_ID_enums.h:52
@ ID_IM
Definition: DNA_ID_enums.h:53
@ ID_VO
Definition: DNA_ID_enums.h:83
@ ID_WS
Definition: DNA_ID_enums.h:79
@ ID_NT
Definition: DNA_ID_enums.h:68
@ ID_LA
Definition: DNA_ID_enums.h:55
@ ID_KE
Definition: DNA_ID_enums.h:58
@ ID_TXT
Definition: DNA_ID_enums.h:62
@ ID_SO
Definition: DNA_ID_enums.h:64
@ ID_SCE
Definition: DNA_ID_enums.h:45
@ ID_LS
Definition: DNA_ID_enums.h:75
@ ID_MSK
Definition: DNA_ID_enums.h:74
@ ID_GD
Definition: DNA_ID_enums.h:71
@ ID_CV
Definition: DNA_ID_enums.h:81
@ ID_PAL
Definition: DNA_ID_enums.h:76
@ ID_BR
Definition: DNA_ID_enums.h:69
@ ID_LP
Definition: DNA_ID_enums.h:80
@ ID_WO
Definition: DNA_ID_enums.h:59
@ ID_SIM
Definition: DNA_ID_enums.h:84
@ ID_MA
Definition: DNA_ID_enums.h:51
@ ID_AC
Definition: DNA_ID_enums.h:67
@ ID_SCR
Definition: DNA_ID_enums.h:60
@ ID_CU_LEGACY
Definition: DNA_ID_enums.h:49
@ ID_VF
Definition: DNA_ID_enums.h:61
@ ID_ME
Definition: DNA_ID_enums.h:48
@ ID_IP
Definition: DNA_ID_enums.h:57
@ ID_GR
Definition: DNA_ID_enums.h:65
@ ID_SPK
Definition: DNA_ID_enums.h:63
@ ID_MB
Definition: DNA_ID_enums.h:50
@ ID_LT
Definition: DNA_ID_enums.h:54
@ ID_OB
Definition: DNA_ID_enums.h:47
@ ID_PA
Definition: DNA_ID_enums.h:70
@ ID_PT
Definition: DNA_ID_enums.h:82
@ ID_PC
Definition: DNA_ID_enums.h:77
@ CACHEFILE_TYPE_ALEMBIC
Object groups, one object can be in many groups at once.
#define CM_TOT
@ CUMA_EXTEND_EXTRAPOLATE
@ CUMA_DO_CLIP
@ CUMA_HANDLE_AUTO_ANIM
@ CUMA_SELECT
@ CUMA_HANDLE_VECTOR
@ CURVE_PRESET_LINE
@ COLORMANAGE_VIEW_USE_CURVES
@ CONSTRAINT_DISABLE
@ CONSTRAINT_IK_TEMP
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_NULL
@ HD_AUTO_ANIM
@ HD_VECT
@ HD_AUTO
@ PROF_H1_SELECT
@ PROF_H2_SELECT
@ PROF_PRESET_CROWN
@ PROF_PRESET_LINE
@ PROF_PRESET_CORNICE
@ PROF_PRESET_SUPPORTS
@ PROF_PRESET_STEPS
@ PROF_DIRTY_PRESET
@ PROF_USE_CLIP
#define MAX_NAME
Definition: DNA_defs.h:48
@ OB_MODE_EDIT
Object is a sort of wrapper for general info.
@ UILST_LAYOUT_DEFAULT
@ RGN_TYPE_TOOL_HEADER
@ SPACE_NODE
@ SPACE_INFO
@ BCONTEXT_CONSTRAINT
@ COLBAND_BLEND_HSL
@ COLBAND_BLEND_HSV
#define TEX_PR_BOTH
#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
@ STATUSBAR_SHOW_VERSION
@ WORKSPACE_USE_PIN_SCENE
void(* uiListPanelIDFromDataFunc)(void *data_link, char *r_idname)
Definition: ED_anim_api.h:804
void ED_file_path_button(struct bScreen *screen, const struct SpaceFile *sfile, struct FileSelectParams *params, struct uiBlock *block)
const char * ED_info_statusbar_string(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer)
Definition: info_stats.cc:692
const char * ED_info_statusbar_string_ex(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, const char statusbar_flag)
Definition: info_stats.cc:629
void ED_object_constraint_active_set(struct Object *ob, struct bConstraint *con)
struct ListBase * ED_object_constraint_list_from_constraint(struct Object *ob, struct bConstraint *con, struct bPoseChannel **r_pchan)
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_redraw(struct ARegion *region)
Definition: area.c:655
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:100
_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 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
_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 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
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
Platform independent time functions.
#define RNA_STRUCT_BEGIN(sptr, prop)
Definition: RNA_access.h:569
#define RNA_STRUCT_END
Definition: RNA_access.h:589
short RNA_type_to_ID_code(const StructRNA *type)
#define RNA_STRUCT_BEGIN_SKIP_RNA_TYPE(sptr, prop)
Definition: RNA_access.h:578
#define RNA_warning(format,...)
Definition: RNA_access.h:756
@ PROP_BOOLEAN
Definition: RNA_types.h:59
@ PROP_ENUM
Definition: RNA_types.h:63
@ PROP_STRING
Definition: RNA_types.h:62
@ PROP_POINTER
Definition: RNA_types.h:64
@ PROP_COLLECTION
Definition: RNA_types.h:65
@ PROP_NEVER_UNLINK
Definition: RNA_types.h:246
@ PROP_NEVER_NULL
Definition: RNA_types.h:239
@ PROP_ID_SELF_CHECK
Definition: RNA_types.h:232
@ PROP_HIDDEN
Definition: RNA_types.h:216
#define C
Definition: RandGen.cpp:25
int UI_text_colorid_from_report_type(int type)
@ UI_LAYOUT_ALIGN_LEFT
@ UI_LAYOUT_ALIGN_RIGHT
@ UI_LAYOUT_ALIGN_EXPAND
void uiItemS_ex(uiLayout *layout, float factor)
@ UI_BUT_ICON_LEFT
Definition: UI_interface.h:260
void UI_but_flag_disable(uiBut *but, int flag)
Definition: interface.cc:5863
@ UI_LAYOUT_VERTICAL
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.cc:5623
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.cc:5102
void uiLayoutSetActive(uiLayout *layout, bool active)
uiBut * uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5733
eUIEmbossType UI_block_emboss_get(uiBlock *block)
Definition: interface.cc:3624
int UI_searchbox_size_x(void)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_BUT_REDALERT
Definition: UI_interface.h:201
@ UI_BUT_UNDO
Definition: UI_interface.h:205
@ UI_BUT_DISABLED
Definition: UI_interface.h:196
@ UI_BUT_HAS_SEP_CHAR
Definition: UI_interface.h:222
@ UI_BUT_ICON_PREVIEW
Definition: UI_interface.h:190
@ UI_BUT_UPDATE_DELAY
Definition: UI_interface.h:224
eUIEmbossType
Definition: UI_interface.h:107
@ UI_EMBOSS_NONE
Definition: UI_interface.h:109
@ UI_EMBOSS
Definition: UI_interface.h:108
@ UI_EMBOSS_PULLDOWN
Definition: UI_interface.h:110
void UI_fontstyle_set(const struct uiFontStyle *fs)
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.cc:5336
void UI_block_theme_style_set(uiBlock *block, char theme_style)
Definition: interface.cc:3634
int UI_searchbox_size_y(void)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void UI_panel_context_pointer_set(struct Panel *panel, const char *name, struct PointerRNA *ptr)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
int UI_icon_from_report_type(int type)
uiBut * uiDefButO(uiBlock *block, int type, const char *opname, wmOperatorCallContext opcontext, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5318
#define UI_SEP_CHAR
Definition: UI_interface.h:83
uiBut * uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:4806
uiBut * 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.cc:5042
uiBut * uiDefIconButI(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5392
void UI_block_lock_clear(uiBlock *block)
Definition: interface.cc:2281
void UI_block_bounds_set_normal(struct uiBlock *block, int addval)
Definition: interface.cc:582
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg)
Definition: interface.cc:6029
struct PointerRNA * UI_but_operator_ptr_get(uiBut *but)
Definition: interface.cc:5908
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)
@ UI_BLOCK_THEME_STYLE_POPUP
Definition: UI_interface.h:770
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.cc:5548
void uiLayoutSetRedAlert(uiLayout *layout, bool redalert)
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, bool free_arg, uiFreeArgFunc search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
Definition: interface.cc:6242
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.cc:5570
uiBut * UI_context_active_but_get(const struct bContext *C)
struct PointerRNA * UI_panel_custom_data_get(const struct Panel *panel)
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int but_flag, uint8_t name_prefix_offset)
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.cc:6193
uiLayout * uiLayoutAbsolute(uiLayout *layout, bool align)
void uiLayoutSetScaleX(uiLayout *layout, float scale)
@ UI_LAYOUT_MENU
@ UI_LAYOUT_PANEL
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 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.cc:5873
uiLayout * uiLayoutBox(uiLayout *layout)
void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
Definition: interface.cc:6316
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
@ UI_DIR_DOWN
Definition: UI_interface.h:124
uiBlock * uiLayoutAbsoluteBlock(uiLayout *layout)
@ 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 uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void(* uiButSearchUpdateFn)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items, bool is_first)
Definition: UI_interface.h:524
void UI_but_number_step_size_set(uiBut *but, float step_size)
Definition: interface.cc:6455
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
Definition: interface.cc:5953
void uiItemS(uiLayout *layout)
eButLabelAlign
@ UI_BUT_LABEL_ALIGN_NONE
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
uiLayout * uiLayoutColumnFlow(uiLayout *layout, int number, bool align)
void uiItemFullO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, struct IDProperty *properties, wmOperatorCallContext context, int flag, struct PointerRNA *r_opptr)
void UI_panels_free_instanced(const struct bContext *C, struct ARegion *region)
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)
@ UI_ID_BROWSE
@ UI_ID_DELETE
@ UI_ID_ADD_NEW
@ UI_ID_OPEN
@ UI_ID_PIN
@ UI_ID_RENAME
@ UI_ID_NOP
@ UI_ID_PREVIEWS
@ UI_ID_AUTO_NAME
@ UI_ID_OVERRIDE
@ UI_ID_LOCAL
@ UI_ID_FAKE_USER
@ UI_ID_ALONE
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.cc:5454
void uiLayoutSetUnitsX(uiLayout *layout, float unit)
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_NO_BG
@ UI_ITEM_R_ICON_ONLY
@ UI_ITEM_R_SLIDER
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.cc:5258
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:91
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
Definition: interface.cc:3629
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.cc:5134
uiBut * uiDefIconTextButO(uiBlock *block, int type, const char *opname, wmOperatorCallContext opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5774
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.cc:5965
struct ARegion *(* uiButSearchTooltipFn)(struct bContext *C, struct ARegion *region, const struct rcti *item_rect, void *arg, void *active)
Definition: UI_interface.h:530
uiBut * uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6063
#define UI_DPI_FAC
Definition: UI_interface.h:305
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:505
void UI_block_bounds_set_text(uiBlock *block, int addval)
Definition: interface.cc:592
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.cc:6000
uiBut * uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:5280
void UI_block_align_begin(uiBlock *block)
Definition: interface.cc:3910
uiBut * uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6046
uiBut * uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6143
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)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, wmOperatorCallContext context, int flag, struct PointerRNA *r_opptr)
void uiTemplateList(uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id, struct PointerRNA *dataptr, const char *propname, struct PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, enum uiTemplateListFlags flags)
@ UI_GRAD_L_ALT
Definition: UI_interface.h:408
@ UI_GRAD_SV
Definition: UI_interface.h:400
@ UI_GRAD_V_ALT
Definition: UI_interface.h:407
@ UI_GRAD_HV
Definition: UI_interface.h:401
@ UI_GRAD_HS
Definition: UI_interface.h:402
@ UI_GRAD_H
Definition: UI_interface.h:403
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, bool compact)
void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg)
Definition: interface.cc:5959
void UI_but_number_precision_set(uiBut *but, float precision)
Definition: interface.cc:6464
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.cc:5072
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)
struct PointerRNA * UI_but_extra_operator_icon_add(uiBut *but, const char *opname, wmOperatorCallContext opcontext, int icon)
Definition: interface.cc:1682
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.cc:6217
void UI_block_direction_set(uiBlock *block, char direction)
Definition: interface.cc:5810
void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but)
Definition: interface.cc:6474
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 uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg)
void uiItemFullR(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int flag, const char *name, int icon)
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
Definition: interface.cc:6007
#define UI_UNIT_X
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.cc:5848
@ UI_BTYPE_BUT
Definition: UI_interface.h:330
@ UI_BTYPE_TOGGLE
Definition: UI_interface.h:340
@ UI_BTYPE_EXTRA
Definition: UI_interface.h:373
@ UI_BTYPE_TAB
Definition: UI_interface.h:350
@ UI_BTYPE_VECTORSCOPE
Definition: UI_interface.h:382
@ UI_BTYPE_NODE_SOCKET
Definition: UI_interface.h:384
@ UI_BTYPE_ROUNDBOX
Definition: UI_interface.h:359
@ UI_BTYPE_COLORBAND
Definition: UI_interface.h:360
@ UI_BTYPE_BUT_MENU
Definition: UI_interface.h:335
@ UI_BTYPE_HISTOGRAM
Definition: UI_interface.h:380
@ UI_BTYPE_WAVEFORM
Definition: UI_interface.h:381
@ UI_BTYPE_HSVCIRCLE
Definition: UI_interface.h:368
@ UI_BTYPE_TEXT
Definition: UI_interface.h:332
@ UI_BTYPE_HSVCUBE
Definition: UI_interface.h:356
@ UI_BTYPE_LABEL
Definition: UI_interface.h:354
@ UI_BTYPE_CURVE
Definition: UI_interface.h:363
@ UI_BTYPE_ICON_TOGGLE_N
Definition: UI_interface.h:343
@ UI_BTYPE_ROW
Definition: UI_interface.h:331
@ UI_BTYPE_PROGRESS_BAR
Definition: UI_interface.h:383
@ UI_BTYPE_NUM
Definition: UI_interface.h:337
@ UI_BTYPE_CURVEPROFILE
Definition: UI_interface.h:365
@ UI_BTYPE_COLOR
Definition: UI_interface.h:349
@ UI_BTYPE_CHECKBOX
Definition: UI_interface.h:347
@ UI_BTYPE_GRIP
Definition: UI_interface.h:390
@ UI_BTYPE_ICON_TOGGLE
Definition: UI_interface.h:342
#define UI_MAX_NAME_STR
Definition: UI_interface.h:92
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2)
Definition: interface.cc:5972
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
Definition: interface.cc:2273
@ UI_TEMPLATE_ID_FILTER_AVAILABLE
@ UI_TEMPLATE_ID_FILTER_ALL
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.cc:5858
@ UI_TEMPLATE_LIST_FLAG_NONE
uiBlock *(* uiBlockCreateFunc)(struct bContext *C, struct ARegion *region, void *arg1)
Definition: UI_interface.h:714
int UI_fontstyle_string_width(const struct uiFontStyle *fs, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon)
uiBut * uiDefIconButO(uiBlock *block, int type, const char *opname, wmOperatorCallContext opcontext, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5608
@ UI_BLOCK_SEARCH_MENU
Definition: UI_interface.h:147
@ UI_BLOCK_LOOP
Definition: UI_interface.h:135
@ UI_BLOCK_MOVEMOUSE_QUIT
Definition: UI_interface.h:143
@ UI_BLOCK_KEEP_OPEN
Definition: UI_interface.h:144
@ UI_BLOCK_IS_FLIP
Definition: UI_interface.h:136
@ UI_BLOCK_NO_FLIP
Definition: UI_interface.h:137
void UI_block_align_end(uiBlock *block)
Definition: interface.cc:3923
int UI_icon_from_library(const struct ID *id)
@ TH_INFO_WARNING_TEXT
Definition: UI_resources.h:318
@ TH_INFO_WARNING
Definition: UI_resources.h:317
void UI_GetThemeColorType4ubv(int colorid, int spacetype, unsigned char col[4])
Definition: resources.c:1377
@ WM_JOB_TYPE_DPAINT_BAKE
Definition: WM_api.h:1365
@ WM_JOB_TYPE_SEQ_BUILD_PROXY
Definition: WM_api.h:1362
@ WM_JOB_TYPE_COMPOSITE
Definition: WM_api.h:1348
@ WM_JOB_TYPE_OBJECT_BAKE
Definition: WM_api.h:1356
@ WM_JOB_TYPE_POINTCACHE
Definition: WM_api.h:1364
@ WM_JOB_TYPE_SEQ_DRAW_THUMBNAIL
Definition: WM_api.h:1374
@ WM_JOB_TYPE_CLIP_BUILD_PROXY
Definition: WM_api.h:1358
@ WM_JOB_TYPE_CLIP_PREFETCH
Definition: WM_api.h:1361
@ WM_JOB_TYPE_SEQ_BUILD_PREVIEW
Definition: WM_api.h:1363
@ WM_JOB_TYPE_RENDER
Definition: WM_api.h:1349
@ WM_JOB_TYPE_ANY
Definition: WM_api.h:1347
@ WM_JOB_TYPE_OBJECT_SIM_OCEAN
Definition: WM_api.h:1353
@ WM_JOB_TYPE_CLIP_SOLVE_CAMERA
Definition: WM_api.h:1360
@ WM_JOB_TYPE_FILESEL_READDIR
Definition: WM_api.h:1357
@ WM_JOB_TYPE_CLIP_TRACK_MARKERS
Definition: WM_api.h:1359
@ WM_JOB_TYPE_OBJECT_SIM_FLUID
Definition: WM_api.h:1354
@ WM_JOB_TYPE_OBJECT_BAKE_TEXTURE
Definition: WM_api.h:1355
@ OPTYPE_PRESET
Definition: WM_types.h:161
@ OPTYPE_MACRO
Definition: WM_types.h:151
#define NC_WINDOW
Definition: WM_types.h:325
#define NC_ID
Definition: WM_types.h:345
#define NC_WM
Definition: WM_types.h:324
#define ND_SHADING_PREVIEW
Definition: WM_types.h:428
#define ND_DATACHANGED
Definition: WM_types.h:362
#define ND_LIB_OVERRIDE_CHANGED
Definition: WM_types.h:367
#define NA_ADDED
Definition: WM_types.h:525
#define NC_MATERIAL
Definition: WM_types.h:330
#define NA_REMOVED
Definition: WM_types.h:526
wmOperatorCallContext
Definition: WM_types.h:199
@ WM_OP_INVOKE_REGION_WIN
Definition: WM_types.h:202
@ WM_OP_INVOKE_SCREEN
Definition: WM_types.h:206
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:201
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:208
@ KM_SHIFT
Definition: WM_types.h:238
#define ND_SPACE_VIEW3D
Definition: WM_types.h:471
@ OP_PROP_TAG_ADVANCED
Definition: WM_types.h:224
#define NC_SPACE
Definition: WM_types.h:342
#define ND_SPACE_OUTLINER
Definition: WM_types.h:470
volatile int lock
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
SyclQueue void void size_t num_bytes void
bool RE_engine_supports_alembic_procedural(const RenderEngineType *render_type, Scene *scene)
Definition: engine.c:121
#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.cc:4244
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)
void ui_rna_collection_search_update_fn(const struct bContext *C, void *arg, const char *str, uiSearchItems *items, bool is_first)
#define RNA_NO_INDEX
struct ARegion * ui_searchbox_create_generic(struct bContext *C, struct ARegion *butregion, uiButSearch *search_but)
#define UI_MENU_PADDING
ColorPicker * ui_block_colorpicker_create(struct uiBlock *block)
#define UI_MENU_WIDTH_MIN
@ UI_SELECT_DRAW
@ 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)
ID * ui_template_id_liboverride_hierarchy_make(bContext *C, Main *bmain, ID *owner_id, ID *id, const char **r_undo_push_label)
void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)
struct TemplateID TemplateID
void uiTemplateStatusInfo(uiLayout *layout, bContext *C)
uiListType * UI_UL_cache_file_layers()
static uiBlock * id_search_menu(bContext *C, ARegion *region, void *arg_litem)
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)
static void cache_file_layer_item(uiList *UNUSED(ui_list), bContext *UNUSED(C), uiLayout *layout, PointerRNA *UNUSED(dataptr), PointerRNA *itemptr, int UNUSED(icon), PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname), int UNUSED(index), int UNUSED(flt_flag))
#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)
@ CB_FUNC_RESET
@ CB_FUNC_DISTRIBUTE_LR
@ CB_FUNC_FLIP
@ CB_FUNC_DISTRIBUTE_EVENLY
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))
void uiTemplateCacheFileProcedural(uiLayout *layout, const bContext *C, PointerRNA *fileptr)
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)
void uiTemplateCacheFileLayers(uiLayout *layout, const bContext *C, PointerRNA *fileptr)
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))
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)
bool uiTemplateCacheFilePointer(PointerRNA *ptr, const char *propname, PointerRNA *r_file_ptr)
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)
static void template_id_workspace_pin_extra_icon(const TemplateID *template_ui, uiBut *but)
struct uiTemplateOperatorPropertyPollParam uiTemplateOperatorPropertyPollParam
static void curvemap_tools_handle_auto_clamped(bContext *C, void *cumap_v, void *UNUSED(arg))
void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C)
void UI_context_active_but_prop_get_templateID(bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop)
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)
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)
void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float color[4])
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 void template_id_liboverride_hierarchy_collections_tag_recursive(Collection *root_collection, ID *target_id, const bool do_parents)
@ UIPROFILE_FUNC_RESET
@ UIPROFILE_FUNC_RESET_VIEW
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
void uiTemplateCacheFileVelocity(uiLayout *layout, PointerRNA *fileptr)
static void template_ID_set_property_exec_fn(bContext *C, void *arg_template, void *item)
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 curvemap_tools_handle_vector(bContext *C, void *cumap_v, void *UNUSED(arg))
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)
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)
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 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)
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 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)
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)
@ 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
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 uiTemplateCacheFileTimeSettings(uiLayout *layout, PointerRNA *fileptr)
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 template_id_liboverride_hierarchy_make(bContext *C, Main *bmain, TemplateID *template_ui, PointerRNA *idptr, const char **r_undo_push_label)
static void curvemap_buttons_redraw(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
#define ERROR_LIBDATA_MESSAGE
static void curvemap_tools_handle_auto(bContext *C, void *cumap_v, void *UNUSED(arg))
static void constraint_ops_extra_draw(bContext *C, uiLayout *layout, void *con_v)
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 template_search_add_button_operator(uiBlock *block, const char *const operator_name, const wmOperatorCallContext opcontext, const int icon, const bool editable)
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 template_id_liboverride_hierarchy_collection_root_find_recursive(Collection *collection, const int parent_level, Collection **r_collection_parent_best, int *r_parent_level_best)
void uiTemplateHeader(uiLayout *layout, bContext *C)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define GS(x)
Definition: iris.c:225
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define G(x, y, z)
static unsigned a[3]
Definition: RandGen.cpp:78
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:92
const char * RNA_struct_identifier(const StructRNA *type)
Definition: rna_access.c:586
bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1966
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
Definition: rna_access.c:2352
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:695
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:2879
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5167
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
bool RNA_struct_is_ID(const StructRNA *type)
Definition: rna_access.c:655
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
Definition: rna_access.c:1311
const char * RNA_struct_ui_description(const StructRNA *type)
Definition: rna_access.c:609
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
Definition: rna_access.c:3532
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
const char * RNA_struct_ui_name(const StructRNA *type)
Definition: rna_access.c:591
bool RNA_enum_icon_from_value(const EnumPropertyItem *item, int value, int *r_icon)
Definition: rna_access.c:5096
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:4921
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3493
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2138
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:3178
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1405
bool RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
Definition: rna_access.c:1431
int RNA_property_flag(PropertyRNA *prop)
Definition: rna_access.c:1055
int RNA_struct_ui_icon(const StructRNA *type)
Definition: rna_access.c:601
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
Definition: rna_access.c:624
bool RNA_pointer_is_null(const PointerRNA *ptr)
Definition: rna_access.c:164
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1075
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
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:1495
int RNA_property_tags(PropertyRNA *prop)
Definition: rna_access.c:1060
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2275
const char * RNA_property_ui_description(const PropertyRNA *prop)
Definition: rna_access.c:1885
const char * RNA_property_ui_name(const PropertyRNA *prop)
Definition: rna_access.c:1875
ListBase ui_previews
ListBase panels
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:461
struct GpencilModifierData * next
void(* panelRegister)(struct ARegionType *region_type)
unsigned int flag
Definition: DNA_ID.h:312
int len
Definition: DNA_ID.h:121
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
struct Library * lib
Definition: DNA_ID.h:372
IDOverrideLibrary * override_library
Definition: DNA_ID.h:412
short flag
Definition: DNA_ID.h:383
char name[66]
Definition: DNA_ID.h:378
char filepath[1024]
Definition: DNA_ID.h:461
ID id
Definition: DNA_ID.h:458
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase scenes
Definition: BKE_main.h:168
bool has_forward_compatibility_issues
Definition: BKE_main.h:132
short versionfile
Definition: BKE_main.h:125
ListBase collections
Definition: BKE_main.h:189
struct ModifierData * next
void(* panelRegister)(struct ARegionType *region_type)
Definition: BKE_modifier.h:358
ustring name
Definition: graph/node.h:174
ListBase constraints
struct Collection * instance_collection
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:260
void(* set_list_data_expand_flag)(const struct bContext *C, struct Panel *pa, short expand_flag)
Definition: BKE_screen.h:267
void(* reorder)(struct bContext *C, struct Panel *pa, int new_index)
Definition: BKE_screen.h:253
struct PanelType * type
char panelname[64]
struct Panel * next
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
PropertyRNA * prop
struct wmTimer * reporttimer
const char * message
int wavefrm_height
int vecscope_height
struct ShaderFxData * next
void(* panelRegister)(struct ARegionType *region_type)
PropertyRNA * prop
uiRNACollectionSearch search_data
struct bConstraint * prev
struct bConstraint * next
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
struct Panel * panel
uiBlock * oldblock
ListBase buttons
struct wmOperator * ui_operator
void * evil_C
eButGradientType gradient_type
eButGradientType gradient_type
struct MenuType * menu
void * custom_data
struct uiBut * next
uiButHandleNFunc funcN
eButType type
struct PointerRNA * opptr
struct PropertyRNA * rnaprop
void * func_argN
uchar col[4]
struct PointerRNA rnapoin
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:321
uiListDrawItemFunc draw_item
Definition: BKE_screen.h:323
char preview_id[64]
char hint[UI_MAX_DRAW_STR]
char description[UI_MAX_DRAW_STR]
uiFontStyle widget
uiFontStyle widgetlabel
uint8_t modifier
Definition: WM_types.h:693
const char * idname
Definition: WM_types.h:890
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:949
struct StructRNA * srna
Definition: WM_types.h:969
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:954
PropertyRNA * prop
Definition: WM_types.h:981
IDProperty * properties
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
void * customdata
Definition: WM_types.h:869
struct wmEvent * eventstate
double PIL_check_seconds_timer(void)
Definition: time.c:64
#define N_(msgid)
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_ptr(bContext *C, wmOperatorType *ot, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
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(bContext *C, const char *opstring, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479
const char * WM_jobs_name(const wmWindowManager *wm, const void *owner)
Definition: wm_jobs.c:282
bool WM_jobs_is_stopped(const wmWindowManager *wm, const void *owner)
Definition: wm_jobs.c:309
float WM_jobs_progress(const wmWindowManager *wm, const void *owner)
Definition: wm_jobs.c:230
double WM_jobs_starttime(const wmWindowManager *wm, const void *owner)
Definition: wm_jobs.c:271
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition: wm_jobs.c:214
void WM_jobs_stop(wmWindowManager *wm, const void *owner, void *startjob)
Definition: wm_jobs.c:583
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:1787
MenuType * WM_menutype_find(const char *idname, bool quiet)
Definition: wm_menu_type.c:30
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:757
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
Definition: wm_operators.c:661
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:783
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
Definition: wm_operators.c:701
wmOperator * WM_operator_last_redo(const bContext *C)
WorkSpace * WM_window_get_active_workspace(const wmWindow *win)
Definition: wm_window.c:2266