Blender  V3.3
fmodifier_ui.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 Blender Foundation. All rights reserved. */
3 
15 #include <string.h>
16 
17 #include "DNA_anim_types.h"
18 #include "DNA_scene_types.h"
19 #include "DNA_space_types.h"
20 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLT_translation.h"
24 
25 #include "BLI_blenlib.h"
26 #include "BLI_utildefines.h"
27 
28 #include "BKE_context.h"
29 #include "BKE_fcurve.h"
30 #include "BKE_screen.h"
31 
32 #include "WM_api.h"
33 #include "WM_types.h"
34 
35 #include "RNA_access.h"
36 #include "RNA_prototypes.h"
37 
38 #include "UI_interface.h"
39 #include "UI_resources.h"
40 
41 #include "ED_anim_api.h"
42 #include "ED_undo.h"
43 
44 #include "DEG_depsgraph.h"
45 
46 typedef void (*PanelDrawFn)(const bContext *, struct Panel *);
47 static void fmodifier_panel_header(const bContext *C, Panel *panel);
48 
49 /* -------------------------------------------------------------------- */
57 {
59 
60  if (area->spacetype == SPACE_GRAPH) {
62  return &fcu->modifiers;
63  }
64 
65  if (area->spacetype == SPACE_NLA) {
67  return &strip->modifiers;
68  }
69 
70  /* This should not be called in any other space. */
71  BLI_assert(false);
72  return NULL;
73 }
74 
79 static PointerRNA *fmodifier_get_pointers(const bContext *C, const Panel *panel, ID **r_owner_id)
80 {
82 
83  if (r_owner_id != NULL) {
84  *r_owner_id = ptr->owner_id;
85  }
86 
87  if (C != NULL && CTX_wm_space_graph(C)) {
89  uiLayoutSetActive(panel->layout, !(fcu->flag & FCURVE_MOD_OFF));
90  }
91 
92  return ptr;
93 }
94 
98 static void fmodifier_reorder(bContext *C, Panel *panel, int new_index)
99 {
100  ID *owner_id;
101  PointerRNA *ptr = fmodifier_get_pointers(NULL, panel, &owner_id);
102  FModifier *fcm = ptr->data;
103  const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(fcm->type);
104 
105  /* Cycles modifier has to be the first, so make sure it's kept that way. */
107  WM_report(RPT_ERROR, "Modifier requires original data");
108  return;
109  }
110 
112 
113  /* Again, make sure we don't move a modifier before a cycles modifier. */
114  FModifier *fcm_first = modifiers->first;
115  const FModifierTypeInfo *fmi_first = get_fmodifier_typeinfo(fcm_first->type);
116  if (fmi_first->requires & FMI_REQUIRES_ORIGINAL_DATA && new_index == 0) {
117  WM_report(RPT_ERROR, "Modifier requires original data");
118  return;
119  }
120 
121  int current_index = BLI_findindex(modifiers, fcm);
122  BLI_assert(current_index >= 0);
123  BLI_assert(new_index >= 0);
124 
125  /* Don't do anything if the drag didn't change the index. */
126  if (current_index == new_index) {
127  return;
128  }
129 
130  /* Move the FModifier in the list. */
131  BLI_listbase_link_move(modifiers, fcm, new_index - current_index);
132 
133  ED_undo_push(C, "Reorder F-Curve Modifier");
134 
137 }
138 
139 static short get_fmodifier_expand_flag(const bContext *UNUSED(C), Panel *panel)
140 {
142  FModifier *fcm = (FModifier *)ptr->data;
143 
144  return fcm->ui_expand_flag;
145 }
146 
147 static void set_fmodifier_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
148 {
150  FModifier *fcm = (FModifier *)ptr->data;
151 
152  fcm->ui_expand_flag = expand_flag;
153 }
154 
157  PanelDrawFn draw,
158  PanelTypePollFn poll,
159  const char *id_prefix)
160 {
161  PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
162 
163  /* Intentionally leave the label field blank. The header is filled with buttons. */
165  BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_PT_%s", id_prefix, fmi->name);
166  BLI_strncpy(panel_type->category, "Modifiers", BKE_ST_MAXNAME);
168 
169  panel_type->draw_header = fmodifier_panel_header;
170  panel_type->draw = draw;
171  panel_type->poll = poll;
172 
173  /* Give the panel the special flag that says it was built here and corresponds to a
174  * modifier rather than a #PanelType. */
176  panel_type->reorder = fmodifier_reorder;
179 
180  BLI_addtail(&region_type->paneltypes, panel_type);
181 
182  return panel_type;
183 }
184 
192  const char *name,
193  const char *label,
194  PanelDrawFn draw_header,
195  PanelDrawFn draw,
196  PanelTypePollFn poll,
197  PanelType *parent)
198 {
199  PanelType *panel_type = MEM_callocN(sizeof(PanelType), __func__);
200 
201  BLI_snprintf(panel_type->idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
202  BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
203  BLI_strncpy(panel_type->category, "Modifiers", BKE_ST_MAXNAME);
205 
206  panel_type->draw_header = draw_header;
207  panel_type->draw = draw;
208  panel_type->poll = poll;
209  panel_type->flag = PANEL_TYPE_DEFAULT_CLOSED;
210 
211  BLI_assert(parent != NULL);
212  BLI_strncpy(panel_type->parent_id, parent->idname, BKE_ST_MAXNAME);
213  panel_type->parent = parent;
214  BLI_addtail(&parent->children, BLI_genericNodeN(panel_type));
215  BLI_addtail(&region_type->paneltypes, panel_type);
216 
217  return panel_type;
218 }
219 
222 /* -------------------------------------------------------------------- */
226 /* XXX! -------------------------------- */
227 /* Temporary definition for limits of float number buttons
228  * (FLT_MAX tends to infinity with old system). */
229 #define UI_FLT_MAX 10000.0f
230 
231 #define B_REDR 1
232 #define B_FMODIFIER_REDRAW 20
233 
234 /* Callback to remove the given modifier. */
235 typedef struct FModifierDeleteContext {
239 
240 static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
241 {
243  ListBase *modifiers = ctx->modifiers;
244  FModifier *fcm = (FModifier *)fcm_v;
245 
246  /* remove the given F-Modifier from the active modifier-stack */
247  remove_fmodifier(modifiers, fcm);
248 
249  ED_undo_push(C, "Delete F-Curve Modifier");
250 
253 }
254 
256 {
257  FModifier *fcm = (FModifier *)ptr->data;
258  uiItemS(layout);
259 
260  uiLayout *row = uiLayoutRowWithHeading(layout, true, IFACE_("Influence"));
261  uiItemR(row, ptr, "use_influence", 0, "", ICON_NONE);
262  uiLayout *sub = uiLayoutRow(row, true);
263 
265  uiItemR(sub, ptr, "influence", 0, "", ICON_NONE);
266 }
267 
269 {
270  uiLayout *layout = panel->layout;
271 
273 
274  uiItemR(layout, ptr, "use_restricted_range", 0, NULL, ICON_NONE);
275 }
276 
277 static void fmodifier_frame_range_draw(const bContext *C, Panel *panel)
278 {
279  uiLayout *col;
280  uiLayout *layout = panel->layout;
281 
283 
284  uiLayoutSetPropSep(layout, true);
285  uiLayoutSetPropDecorate(layout, false);
286 
287  FModifier *fcm = (FModifier *)ptr->data;
289 
290  col = uiLayoutColumn(layout, true);
291  uiItemR(col, ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
292  uiItemR(col, ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
293 
294  col = uiLayoutColumn(layout, true);
295  uiItemR(col, ptr, "blend_in", 0, IFACE_("Blend In"), ICON_NONE);
296  uiItemR(col, ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
297 }
298 
299 static void fmodifier_panel_header(const bContext *C, Panel *panel)
300 {
301  uiLayout *layout = panel->layout;
302 
303  ID *owner_id;
304  PointerRNA *ptr = fmodifier_get_pointers(C, panel, &owner_id);
305  FModifier *fcm = (FModifier *)ptr->data;
306  const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
307 
308  uiBlock *block = uiLayoutGetBlock(layout);
309 
310  uiLayout *sub = uiLayoutRow(layout, true);
313 
314  /* Checkbox for 'active' status (for now). */
315  uiItemR(sub, ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
316 
317  /* Name. */
318  if (fmi) {
319  uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
320  }
321  else {
322  uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
323  }
324 
325  /* Right align. */
326  sub = uiLayoutRow(layout, true);
329 
330  /* 'Mute' button. */
331  uiItemR(sub, ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
332 
333  /* Delete button. */
334  uiBut *but = uiDefIconBut(block,
335  UI_BTYPE_BUT,
336  B_REDR,
337  ICON_X,
338  0,
339  0,
340  UI_UNIT_X,
341  UI_UNIT_Y,
342  NULL,
343  0.0,
344  0.0,
345  0.0,
346  0.0,
347  TIP_("Delete Modifier"));
349  ctx->owner_id = owner_id;
351  BLI_assert(ctx->modifiers != NULL);
352 
353  UI_but_funcN_set(but, delete_fmodifier_cb, ctx, fcm);
354 
355  uiItemS(layout);
356 }
357 
360 /* -------------------------------------------------------------------- */
364 static void generator_panel_draw(const bContext *C, Panel *panel)
365 {
366  uiLayout *layout = panel->layout;
367 
368  ID *owner_id;
369  PointerRNA *ptr = fmodifier_get_pointers(C, panel, &owner_id);
370  FModifier *fcm = (FModifier *)ptr->data;
372 
373  uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
374 
375  uiLayoutSetPropSep(layout, true);
376  uiLayoutSetPropDecorate(layout, false);
377 
378  uiItemR(layout, ptr, "use_additive", 0, NULL, ICON_NONE);
379 
380  uiItemR(layout, ptr, "poly_order", 0, IFACE_("Order"), ICON_NONE);
381 
382  PropertyRNA *prop = RNA_struct_find_property(ptr, "coefficients");
383  uiLayout *col = uiLayoutColumn(layout, true);
384  switch (data->mode) {
385  case FCM_GENERATOR_POLYNOMIAL: /* Polynomial expression. */
386  {
387 
388  char xval[32];
389 
390  /* The first value gets a "Coefficient" label. */
391  BLI_strncpy(xval, N_("Coefficient"), sizeof(xval));
392 
393  for (int i = 0; i < data->arraysize; i++) {
394  uiItemFullR(col, ptr, prop, i, 0, 0, IFACE_(xval), ICON_NONE);
395  BLI_snprintf(xval, sizeof(xval), "x^%d", i + 1);
396  }
397  break;
398  }
399  case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */
400  {
401  {
402  /* Add column labels above the buttons to prevent confusion.
403  * Fake the property split layout, otherwise the labels use the full row. */
404  uiLayout *split = uiLayoutSplit(col, 0.4f, false);
405  uiLayoutColumn(split, false);
406  uiLayout *title_col = uiLayoutColumn(split, false);
407  uiLayout *title_row = uiLayoutRow(title_col, true);
408  uiItemL(title_row, IFACE_("A"), ICON_NONE);
409  uiItemL(title_row, IFACE_("B"), ICON_NONE);
410  }
411 
412  uiLayout *first_row = uiLayoutRow(col, true);
413  uiItemFullR(first_row, ptr, prop, 0, 0, 0, IFACE_("y = (Ax + B)"), ICON_NONE);
414  uiItemFullR(first_row, ptr, prop, 1, 0, 0, "", ICON_NONE);
415  for (int i = 2; i < data->arraysize - 1; i += 2) {
416  /* \u2715 is the multiplication symbol. */
417  uiLayout *row = uiLayoutRow(col, true);
418  uiItemFullR(row, ptr, prop, i, 0, 0, IFACE_("\u2715 (Ax + B)"), ICON_NONE);
419  uiItemFullR(row, ptr, prop, i + 1, 0, 0, "", ICON_NONE);
420  }
421  break;
422  }
423  }
424 
425  fmodifier_influence_draw(layout, ptr);
426 }
427 
428 static void panel_register_generator(ARegionType *region_type,
429  const char *id_prefix,
430  PanelTypePollFn poll_fn)
431 {
432  PanelType *panel_type = fmodifier_panel_register(
433  region_type, FMODIFIER_TYPE_GENERATOR, generator_panel_draw, poll_fn, id_prefix);
434  fmodifier_subpanel_register(region_type,
435  "frame_range",
436  "",
439  poll_fn,
440  panel_type);
441 }
442 
445 /* -------------------------------------------------------------------- */
449 static void fn_generator_panel_draw(const bContext *C, Panel *panel)
450 {
451  uiLayout *col;
452  uiLayout *layout = panel->layout;
453 
455 
456  uiItemR(layout, ptr, "function_type", 0, "", ICON_NONE);
457 
458  uiLayoutSetPropSep(layout, true);
459  uiLayoutSetPropDecorate(layout, false);
460 
461  col = uiLayoutColumn(layout, false);
462  uiItemR(col, ptr, "use_additive", 0, NULL, ICON_NONE);
463 
464  col = uiLayoutColumn(layout, false);
465  uiItemR(col, ptr, "amplitude", 0, NULL, ICON_NONE);
466  uiItemR(col, ptr, "phase_multiplier", 0, NULL, ICON_NONE);
467  uiItemR(col, ptr, "phase_offset", 0, NULL, ICON_NONE);
468  uiItemR(col, ptr, "value_offset", 0, NULL, ICON_NONE);
469 
470  fmodifier_influence_draw(layout, ptr);
471 }
472 
473 static void panel_register_fn_generator(ARegionType *region_type,
474  const char *id_prefix,
475  PanelTypePollFn poll_fn)
476 {
477  PanelType *panel_type = fmodifier_panel_register(
478  region_type, FMODIFIER_TYPE_FN_GENERATOR, fn_generator_panel_draw, poll_fn, id_prefix);
479  fmodifier_subpanel_register(region_type,
480  "frame_range",
481  "",
484  poll_fn,
485  panel_type);
486 }
487 
490 /* -------------------------------------------------------------------- */
494 static void cycles_panel_draw(const bContext *C, Panel *panel)
495 {
496  uiLayout *col;
497  uiLayout *layout = panel->layout;
498 
500 
501  uiLayoutSetPropSep(layout, true);
502  uiLayoutSetPropDecorate(layout, false);
503 
504  /* Before. */
505  col = uiLayoutColumn(layout, false);
506  uiItemR(col, ptr, "mode_before", 0, NULL, ICON_NONE);
507  uiItemR(col, ptr, "cycles_before", 0, IFACE_("Count"), ICON_NONE);
508 
509  /* After. */
510  col = uiLayoutColumn(layout, false);
511  uiItemR(col, ptr, "mode_after", 0, NULL, ICON_NONE);
512  uiItemR(col, ptr, "cycles_after", 0, IFACE_("Count"), ICON_NONE);
513 
514  fmodifier_influence_draw(layout, ptr);
515 }
516 
517 static void panel_register_cycles(ARegionType *region_type,
518  const char *id_prefix,
519  PanelTypePollFn poll_fn)
520 {
521  PanelType *panel_type = fmodifier_panel_register(
522  region_type, FMODIFIER_TYPE_CYCLES, cycles_panel_draw, poll_fn, id_prefix);
523  fmodifier_subpanel_register(region_type,
524  "frame_range",
525  "",
528  poll_fn,
529  panel_type);
530 }
531 
534 /* -------------------------------------------------------------------- */
538 static void noise_panel_draw(const bContext *C, Panel *panel)
539 {
540  uiLayout *col;
541  uiLayout *layout = panel->layout;
542 
544 
545  uiLayoutSetPropSep(layout, true);
546  uiLayoutSetPropDecorate(layout, false);
547 
548  uiItemR(layout, ptr, "blend_type", 0, NULL, ICON_NONE);
549 
550  col = uiLayoutColumn(layout, false);
551  uiItemR(col, ptr, "scale", 0, NULL, ICON_NONE);
552  uiItemR(col, ptr, "strength", 0, NULL, ICON_NONE);
553  uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE);
554  uiItemR(col, ptr, "phase", 0, NULL, ICON_NONE);
555  uiItemR(col, ptr, "depth", 0, NULL, ICON_NONE);
556 
557  fmodifier_influence_draw(layout, ptr);
558 }
559 
560 static void panel_register_noise(ARegionType *region_type,
561  const char *id_prefix,
562  PanelTypePollFn poll_fn)
563 {
564  PanelType *panel_type = fmodifier_panel_register(
565  region_type, FMODIFIER_TYPE_NOISE, noise_panel_draw, poll_fn, id_prefix);
566  fmodifier_subpanel_register(region_type,
567  "frame_range",
568  "",
571  poll_fn,
572  panel_type);
573 }
574 
577 /* -------------------------------------------------------------------- */
581 static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(arg))
582 {
584  FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
585  FCM_EnvelopeData *fedn;
586  FCM_EnvelopeData fed;
587 
588  /* init template data */
589  fed.min = -1.0f;
590  fed.max = 1.0f;
591  fed.time = (float)scene->r.cfra; /* XXX make this int for ease of use? */
592  fed.f1 = fed.f2 = 0;
593 
594  /* check that no data exists for the current frame... */
595  if (env->data) {
596  bool exists;
597  int i = BKE_fcm_envelope_find_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
598 
599  /* binarysearch_...() will set exists by default to 0,
600  * so if it is non-zero, that means that the point exists already */
601  if (exists) {
602  return;
603  }
604 
605  /* add new */
606  fedn = MEM_callocN((env->totvert + 1) * sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
607 
608  /* add the points that should occur before the point to be pasted */
609  if (i > 0) {
610  memcpy(fedn, env->data, i * sizeof(FCM_EnvelopeData));
611  }
612 
613  /* add point to paste at index i */
614  *(fedn + i) = fed;
615 
616  /* add the points that occur after the point to be pasted */
617  if (i < env->totvert) {
618  memcpy(fedn + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
619  }
620 
621  /* replace (+ free) old with new */
622  MEM_freeN(env->data);
623  env->data = fedn;
624 
625  env->totvert++;
626  }
627  else {
628  env->data = MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
629  *(env->data) = fed;
630 
631  env->totvert = 1;
632  }
633 }
634 
635 /* callback to remove envelope data point */
636 /* TODO: should we have a separate file for things like this? */
637 static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void *ind_v)
638 {
639  FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
640  FCM_EnvelopeData *fedn;
641  int index = POINTER_AS_INT(ind_v);
642 
643  /* check that no data exists for the current frame... */
644  if (env->totvert > 1) {
645  /* allocate a new smaller array */
646  fedn = MEM_callocN(sizeof(FCM_EnvelopeData) * (env->totvert - 1), "FCM_EnvelopeData");
647 
648  memcpy(fedn, env->data, sizeof(FCM_EnvelopeData) * (index));
649  memcpy(fedn + index,
650  env->data + (index + 1),
651  sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
652 
653  /* free old array, and set the new */
654  MEM_freeN(env->data);
655  env->data = fedn;
656  env->totvert--;
657  }
658  else {
659  /* just free array, since the only vert was deleted */
660  MEM_SAFE_FREE(env->data);
661  env->totvert = 0;
662  }
663 }
664 
665 /* draw settings for envelope modifier */
666 static void envelope_panel_draw(const bContext *C, Panel *panel)
667 {
668  uiLayout *row, *col;
669  uiLayout *layout = panel->layout;
670 
671  ID *owner_id;
672  PointerRNA *ptr = fmodifier_get_pointers(C, panel, &owner_id);
673  FModifier *fcm = (FModifier *)ptr->data;
674  FMod_Envelope *env = (FMod_Envelope *)fcm->data;
675 
676  uiLayoutSetPropSep(layout, true);
677  uiLayoutSetPropDecorate(layout, false);
678 
679  /* General settings. */
680  col = uiLayoutColumn(layout, true);
681  uiItemR(col, ptr, "reference_value", 0, IFACE_("Reference"), ICON_NONE);
682  uiItemR(col, ptr, "default_min", 0, IFACE_("Min"), ICON_NONE);
683  uiItemR(col, ptr, "default_max", 0, IFACE_("Max"), ICON_NONE);
684 
685  /* Control points list. */
686 
687  row = uiLayoutRow(layout, false);
688  uiBlock *block = uiLayoutGetBlock(row);
689 
690  uiBut *but = uiDefBut(block,
691  UI_BTYPE_BUT,
693  IFACE_("Add Control Point"),
694  0,
695  0,
696  7.5 * UI_UNIT_X,
697  UI_UNIT_Y,
698  NULL,
699  0,
700  0,
701  0,
702  0,
703  TIP_("Add a new control-point to the envelope on the current frame"));
705 
706  col = uiLayoutColumn(layout, false);
707  uiLayoutSetPropSep(col, false);
708 
709  FCM_EnvelopeData *fed = env->data;
710  for (int i = 0; i < env->totvert; i++, fed++) {
711  PointerRNA ctrl_ptr;
712  RNA_pointer_create(owner_id, &RNA_FModifierEnvelopeControlPoint, fed, &ctrl_ptr);
713 
714  /* get a new row to operate on */
715  row = uiLayoutRow(col, true);
716  block = uiLayoutGetBlock(row);
717 
718  uiItemR(row, &ctrl_ptr, "frame", 0, NULL, ICON_NONE);
719  uiItemR(row, &ctrl_ptr, "min", 0, IFACE_("Min"), ICON_NONE);
720  uiItemR(row, &ctrl_ptr, "max", 0, IFACE_("Max"), ICON_NONE);
721 
722  but = uiDefIconBut(block,
723  UI_BTYPE_BUT,
725  ICON_X,
726  0,
727  0,
728  0.9 * UI_UNIT_X,
729  UI_UNIT_Y,
730  NULL,
731  0.0,
732  0.0,
733  0.0,
734  0.0,
735  TIP_("Delete envelope control point"));
737  UI_block_align_begin(block);
738  }
739 
740  fmodifier_influence_draw(layout, ptr);
741 }
742 
743 static void panel_register_envelope(ARegionType *region_type,
744  const char *id_prefix,
745  PanelTypePollFn poll_fn)
746 {
747  PanelType *panel_type = fmodifier_panel_register(
748  region_type, FMODIFIER_TYPE_ENVELOPE, envelope_panel_draw, poll_fn, id_prefix);
749  fmodifier_subpanel_register(region_type,
750  "frame_range",
751  "",
754  poll_fn,
755  panel_type);
756 }
757 
760 /* -------------------------------------------------------------------- */
764 static void limits_panel_draw(const bContext *C, Panel *panel)
765 {
766  uiLayout *col, *row, *sub;
767  uiLayout *layout = panel->layout;
768 
770 
771  uiLayoutSetPropSep(layout, true);
772  uiLayoutSetPropDecorate(layout, false);
773 
774  /* Minimums. */
775  col = uiLayoutColumn(layout, false);
776  row = uiLayoutRowWithHeading(col, true, IFACE_("Minimum X"));
777  uiItemR(row, ptr, "use_min_x", 0, "", ICON_NONE);
778  sub = uiLayoutColumn(row, true);
779  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min_x"));
780  uiItemR(sub, ptr, "min_x", 0, "", ICON_NONE);
781 
782  row = uiLayoutRowWithHeading(col, true, IFACE_("Y"));
783  uiItemR(row, ptr, "use_min_y", 0, "", ICON_NONE);
784  sub = uiLayoutColumn(row, true);
785  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min_y"));
786  uiItemR(sub, ptr, "min_y", 0, "", ICON_NONE);
787 
788  /* Maximums. */
789  col = uiLayoutColumn(layout, false);
790  row = uiLayoutRowWithHeading(col, true, IFACE_("Maximum X"));
791  uiItemR(row, ptr, "use_max_x", 0, "", ICON_NONE);
792  sub = uiLayoutColumn(row, true);
793  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max_x"));
794  uiItemR(sub, ptr, "max_x", 0, "", ICON_NONE);
795 
796  row = uiLayoutRowWithHeading(col, true, IFACE_("Y"));
797  uiItemR(row, ptr, "use_max_y", 0, "", ICON_NONE);
798  sub = uiLayoutColumn(row, true);
799  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max_y"));
800  uiItemR(sub, ptr, "max_y", 0, "", ICON_NONE);
801 
802  fmodifier_influence_draw(layout, ptr);
803 }
804 
805 static void panel_register_limits(ARegionType *region_type,
806  const char *id_prefix,
807  PanelTypePollFn poll_fn)
808 {
809  PanelType *panel_type = fmodifier_panel_register(
810  region_type, FMODIFIER_TYPE_LIMITS, limits_panel_draw, poll_fn, id_prefix);
811  fmodifier_subpanel_register(region_type,
812  "frame_range",
813  "",
816  poll_fn,
817  panel_type);
818 }
819 
822 /* -------------------------------------------------------------------- */
826 static void stepped_panel_draw(const bContext *C, Panel *panel)
827 {
828  uiLayout *col, *sub, *row;
829  uiLayout *layout = panel->layout;
830 
832 
833  uiLayoutSetPropSep(layout, true);
834  uiLayoutSetPropDecorate(layout, false);
835 
836  /* Stepping Settings. */
837  col = uiLayoutColumn(layout, false);
838  uiItemR(col, ptr, "frame_step", 0, NULL, ICON_NONE);
839  uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE);
840 
841  /* Start range settings. */
842  row = uiLayoutRowWithHeading(layout, true, IFACE_("Start Frame"));
843  uiItemR(row, ptr, "use_frame_start", 0, "", ICON_NONE);
844  sub = uiLayoutColumn(row, true);
845  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_frame_start"));
846  uiItemR(sub, ptr, "frame_start", 0, "", ICON_NONE);
847 
848  /* End range settings. */
849  row = uiLayoutRowWithHeading(layout, true, IFACE_("End Frame"));
850  uiItemR(row, ptr, "use_frame_end", 0, "", ICON_NONE);
851  sub = uiLayoutColumn(row, true);
852  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_frame_end"));
853  uiItemR(sub, ptr, "frame_end", 0, "", ICON_NONE);
854 
855  fmodifier_influence_draw(layout, ptr);
856 }
857 
858 static void panel_register_stepped(ARegionType *region_type,
859  const char *id_prefix,
860  PanelTypePollFn poll_fn)
861 {
862  PanelType *panel_type = fmodifier_panel_register(
863  region_type, FMODIFIER_TYPE_STEPPED, stepped_panel_draw, poll_fn, id_prefix);
864  fmodifier_subpanel_register(region_type,
865  "frame_range",
866  "",
869  poll_fn,
870  panel_type);
871 }
872 
875 /* -------------------------------------------------------------------- */
880  ID *owner_id,
881  ListBase *fmodifiers,
882  uiListPanelIDFromDataFunc panel_id_fn)
883 {
884  ARegion *region = CTX_wm_region(C);
885 
886  bool panels_match = UI_panel_list_matches_data(region, fmodifiers, panel_id_fn);
887 
888  if (!panels_match) {
889  UI_panels_free_instanced(C, region);
890  FModifier *fcm = fmodifiers->first;
891  for (int i = 0; fcm; i++, fcm = fcm->next) {
892  char panel_idname[MAX_NAME];
893  panel_id_fn(fcm, panel_idname);
894 
895  PointerRNA *fcm_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
896  RNA_pointer_create(owner_id, &RNA_FModifier, fcm, fcm_ptr);
897 
898  UI_panel_add_instanced(C, region, &region->panels, panel_idname, fcm_ptr);
899  }
900  }
901  else {
902  /* Assuming there's only one group of instanced panels, update the custom data pointers. */
903  Panel *panel = region->panels.first;
904  LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
905 
906  /* Move to the next instanced panel corresponding to the next modifier. */
907  while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
908  panel = panel->next;
909  BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
910  }
911 
912  PointerRNA *fcm_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
913  RNA_pointer_create(owner_id, &RNA_FModifier, fcm, fcm_ptr);
914  UI_panel_custom_data_set(panel, fcm_ptr);
915 
916  panel = panel->next;
917  }
918  }
919 }
920 
922  const char *modifier_panel_prefix,
923  PanelTypePollFn poll_function)
924 {
925  panel_register_generator(region_type, modifier_panel_prefix, poll_function);
926  panel_register_fn_generator(region_type, modifier_panel_prefix, poll_function);
927  panel_register_noise(region_type, modifier_panel_prefix, poll_function);
928  panel_register_envelope(region_type, modifier_panel_prefix, poll_function);
929  panel_register_limits(region_type, modifier_panel_prefix, poll_function);
930  panel_register_stepped(region_type, modifier_panel_prefix, poll_function);
931 }
932 
934  const char *modifier_panel_prefix,
935  PanelTypePollFn poll_function)
936 {
937  panel_register_cycles(region_type, modifier_panel_prefix, poll_function);
938 }
939 
942 /* -------------------------------------------------------------------- */
949 /* Copy/Paste Buffer itself (list of FModifier 's) */
951 
952 /* ---------- */
953 
955 {
956  /* just free the whole buffer */
958 }
959 
961 {
962  bool ok = true;
963 
964  /* sanity checks */
965  if (ELEM(NULL, modifiers, modifiers->first)) {
966  return 0;
967  }
968 
969  /* copy the whole list, or just the active one? */
970  if (active) {
971  FModifier *fcm = find_active_fmodifier(modifiers);
972 
973  if (fcm) {
974  FModifier *fcmN = copy_fmodifier(fcm);
976  }
977  else {
978  ok = 0;
979  }
980  }
981  else {
983  }
984 
985  /* did we succeed? */
986  return ok;
987 }
988 
989 bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *curve)
990 {
991  FModifier *fcm;
992  bool ok = false;
993 
994  /* sanity checks */
995  if (modifiers == NULL) {
996  return 0;
997  }
998 
999  bool was_cyclic = curve && BKE_fcurve_is_cyclic(curve);
1000 
1001  /* if replacing the list, free the existing modifiers */
1002  if (replace) {
1003  free_fmodifiers(modifiers);
1004  }
1005 
1006  /* now copy over all the modifiers in the buffer to the end of the list */
1007  for (fcm = fmodifier_copypaste_buf.first; fcm; fcm = fcm->next) {
1008  /* make a copy of it */
1009  FModifier *fcmN = copy_fmodifier(fcm);
1010 
1011  fcmN->curve = curve;
1012 
1013  /* make sure the new one isn't active, otherwise the list may get several actives */
1014  fcmN->flag &= ~FMODIFIER_FLAG_ACTIVE;
1015 
1016  /* now add it to the end of the list */
1017  BLI_addtail(modifiers, fcmN);
1018  ok = 1;
1019  }
1020 
1021  /* adding or removing the Cycles modifier requires an update to handles */
1022  if (curve && BKE_fcurve_is_cyclic(curve) != was_cyclic) {
1024  }
1025 
1026  /* did we succeed? */
1027  return ok;
1028 }
1029 
typedef float(TangentPoint)[2]
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 SpaceGraph * CTX_wm_space_graph(const bContext *C)
Definition: context.c:887
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct FModifier * copy_fmodifier(const struct FModifier *src)
int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array, float frame, int arraylen, bool *r_exists)
void copy_fmodifiers(ListBase *dst, const ListBase *src)
Definition: fmodifier.c:1164
const FModifierTypeInfo * fmodifier_get_typeinfo(const struct FModifier *fcm)
struct FModifier * find_active_fmodifier(ListBase *modifiers)
Definition: fmodifier.c:1246
const FModifierTypeInfo * get_fmodifier_typeinfo(int type)
Definition: fmodifier.c:1052
@ FMI_REQUIRES_ORIGINAL_DATA
Definition: BKE_fcurve.h:110
bool remove_fmodifier(ListBase *modifiers, struct FModifier *fcm)
Definition: fmodifier.c:1190
void BKE_fcurve_handles_recalc(struct FCurve *fcu)
Definition: fcurve.c:1303
void free_fmodifiers(ListBase *modifiers)
Definition: fmodifier.c:1230
bool BKE_fcurve_is_cyclic(struct FCurve *fcu)
Definition: fcurve.c:1192
@ PANEL_TYPE_INSTANCED
Definition: BKE_screen.h:285
@ PANEL_TYPE_DEFAULT_CLOSED
Definition: BKE_screen.h:279
@ PANEL_TYPE_HEADER_EXPAND
Definition: BKE_screen.h:282
#define BKE_ST_MAXNAME
Definition: BKE_screen.h:53
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:842
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
Definition: listbase.c:405
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT 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
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define ELEM(...)
#define TIP_(msgid)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_ANIMATION
Definition: DNA_ID.h:794
eFModifier_Types
@ FMODIFIER_TYPE_CYCLES
@ FMODIFIER_TYPE_STEPPED
@ FMODIFIER_TYPE_FN_GENERATOR
@ FMODIFIER_TYPE_NOISE
@ FMODIFIER_TYPE_GENERATOR
@ FMODIFIER_TYPE_ENVELOPE
@ FMODIFIER_TYPE_LIMITS
@ FCM_GENERATOR_POLYNOMIAL_FACTORISED
@ FCM_GENERATOR_POLYNOMIAL
@ FMODIFIER_FLAG_USEINFLUENCE
@ FMODIFIER_FLAG_ACTIVE
@ FMODIFIER_FLAG_RANGERESTRICT
@ FCURVE_MOD_OFF
#define MAX_NAME
Definition: DNA_defs.h:48
@ SPACE_NLA
@ SPACE_GRAPH
bool(* PanelTypePollFn)(const struct bContext *C, struct PanelType *pt)
Definition: ED_anim_api.h:802
struct NlaStrip * ANIM_nla_context_strip(const struct bContext *C)
void(* uiListPanelIDFromDataFunc)(void *data_link, char *r_idname)
Definition: ED_anim_api.h:804
struct FCurve * ANIM_graph_context_fcurve(const struct bContext *C)
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 type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:25
@ UI_LAYOUT_ALIGN_LEFT
@ UI_LAYOUT_ALIGN_RIGHT
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
#define UI_UNIT_Y
void uiLayoutSetActive(uiLayout *layout, bool active)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
@ UI_EMBOSS_NONE
Definition: UI_interface.h:109
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
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
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
void uiItemL(uiLayout *layout, const char *name, int icon)
struct PointerRNA * UI_panel_custom_data_get(const struct Panel *panel)
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 uiLayoutSetAlignment(uiLayout *layout, char alignment)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
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)
@ UI_ITEM_R_ICON_ONLY
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.cc:6000
void UI_block_align_begin(uiBlock *block)
Definition: interface.cc:3910
void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
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
@ UI_BTYPE_BUT
Definition: UI_interface.h:330
#define NC_ANIMATION
Definition: WM_types.h:338
#define NA_EDITED
Definition: WM_types.h:523
#define ND_KEYFRAME
Definition: WM_types.h:442
const char * label
Scene scene
Curve curve
SyclQueue void void size_t num_bytes void
#define B_FMODIFIER_REDRAW
Definition: fmodifier_ui.c:232
static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
Definition: fmodifier_ui.c:240
static void panel_register_noise(ARegionType *region_type, const char *id_prefix, PanelTypePollFn poll_fn)
Definition: fmodifier_ui.c:560
bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *curve)
Definition: fmodifier_ui.c:989
static void fmodifier_frame_range_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:277
static void fmodifier_panel_header(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:299
static void cycles_panel_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:494
static void set_fmodifier_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
Definition: fmodifier_ui.c:147
void ANIM_fmodifiers_copybuf_free(void)
Definition: fmodifier_ui.c:954
static void panel_register_stepped(ARegionType *region_type, const char *id_prefix, PanelTypePollFn poll_fn)
Definition: fmodifier_ui.c:858
static void fmodifier_frame_range_header_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:268
static PanelType * fmodifier_panel_register(ARegionType *region_type, eFModifier_Types type, PanelDrawFn draw, PanelTypePollFn poll, const char *id_prefix)
Definition: fmodifier_ui.c:155
static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(arg))
Definition: fmodifier_ui.c:581
static void fmodifier_reorder(bContext *C, Panel *panel, int new_index)
Definition: fmodifier_ui.c:98
static PointerRNA * fmodifier_get_pointers(const bContext *C, const Panel *panel, ID **r_owner_id)
Definition: fmodifier_ui.c:79
static void generator_panel_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:364
struct FModifierDeleteContext FModifierDeleteContext
static void fn_generator_panel_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:449
#define B_REDR
Definition: fmodifier_ui.c:231
static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void *ind_v)
Definition: fmodifier_ui.c:637
static void panel_register_cycles(ARegionType *region_type, const char *id_prefix, PanelTypePollFn poll_fn)
Definition: fmodifier_ui.c:517
static void noise_panel_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:538
static ListBase fmodifier_copypaste_buf
Definition: fmodifier_ui.c:950
void ANIM_modifier_panels_register_graph_only(ARegionType *region_type, const char *modifier_panel_prefix, PanelTypePollFn poll_function)
Definition: fmodifier_ui.c:933
static void fmodifier_influence_draw(uiLayout *layout, PointerRNA *ptr)
Definition: fmodifier_ui.c:255
void ANIM_modifier_panels_register_graph_and_NLA(ARegionType *region_type, const char *modifier_panel_prefix, PanelTypePollFn poll_function)
Definition: fmodifier_ui.c:921
void(* PanelDrawFn)(const bContext *, struct Panel *)
Definition: fmodifier_ui.c:46
static void panel_register_limits(ARegionType *region_type, const char *id_prefix, PanelTypePollFn poll_fn)
Definition: fmodifier_ui.c:805
static ListBase * fmodifier_list_space_specific(const bContext *C)
Definition: fmodifier_ui.c:56
static void panel_register_envelope(ARegionType *region_type, const char *id_prefix, PanelTypePollFn poll_fn)
Definition: fmodifier_ui.c:743
static short get_fmodifier_expand_flag(const bContext *UNUSED(C), Panel *panel)
Definition: fmodifier_ui.c:139
static void panel_register_generator(ARegionType *region_type, const char *id_prefix, PanelTypePollFn poll_fn)
Definition: fmodifier_ui.c:428
static void limits_panel_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:764
static void envelope_panel_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:666
static PanelType * fmodifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelTypePollFn poll, PanelType *parent)
Definition: fmodifier_ui.c:191
bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active)
Definition: fmodifier_ui.c:960
static void stepped_panel_draw(const bContext *C, Panel *panel)
Definition: fmodifier_ui.c:826
void ANIM_fmodifier_panels(const bContext *C, ID *owner_id, ListBase *fmodifiers, uiListPanelIDFromDataFunc panel_id_fn)
Definition: fmodifier_ui.c:879
static void panel_register_fn_generator(ARegionType *region_type, const char *id_prefix, PanelTypePollFn poll_fn)
Definition: fmodifier_ui.c:473
uint col
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
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
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
ListBase paneltypes
Definition: BKE_screen.h:198
ListBase panels
short flag
ListBase modifiers
FCM_EnvelopeData * data
struct FCurve * curve
struct FModifier * next
short ui_expand_flag
void * data
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
ListBase modifiers
short(* get_list_data_expand_flag)(const struct bContext *C, struct Panel *pa)
Definition: BKE_screen.h:260
void(* draw)(const struct bContext *C, struct Panel *panel)
Definition: BKE_screen.h:248
bool(* poll)(const struct bContext *C, struct PanelType *pt)
Definition: BKE_screen.h:242
void(* draw_header)(const struct bContext *C, struct Panel *panel)
Definition: BKE_screen.h:244
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:223
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
char translation_context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:226
ListBase children
Definition: BKE_screen.h:271
char category[BKE_ST_MAXNAME]
Definition: BKE_screen.h:228
struct PanelType * parent
Definition: BKE_screen.h:270
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:224
char parent_id[BKE_ST_MAXNAME]
Definition: BKE_screen.h:230
struct PanelType * type
struct uiLayout * layout
struct Panel * next
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
struct RenderData r
#define N_(msgid)
void WM_report(eReportType type, const char *message)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3480