Blender  V3.3
anim_markers.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2008 Blender Foundation. All rights reserved. */
3 
8 #include <math.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "DNA_object_types.h"
13 #include "DNA_scene_types.h"
14 
15 #include "BLI_blenlib.h"
16 #include "BLI_math.h"
17 #include "BLI_utildefines.h"
18 
19 #include "BLT_translation.h"
20 
21 #include "BKE_context.h"
22 #include "BKE_fcurve.h"
23 #include "BKE_idprop.h"
24 #include "BKE_layer.h"
25 #include "BKE_main.h"
26 #include "BKE_report.h"
27 #include "BKE_scene.h"
28 #include "BKE_screen.h"
29 #include "BKE_unit.h"
30 
31 #include "RNA_access.h"
32 #include "RNA_define.h"
33 #include "RNA_enum_types.h"
34 
35 #include "WM_api.h"
36 #include "WM_types.h"
37 
38 #include "GPU_immediate.h"
39 #include "GPU_matrix.h"
40 #include "GPU_state.h"
41 
42 #include "UI_interface.h"
43 #include "UI_interface_icons.h"
44 #include "UI_resources.h"
45 #include "UI_view2d.h"
46 
47 #include "ED_anim_api.h"
48 #include "ED_markers.h"
49 #include "ED_numinput.h"
50 #include "ED_object.h"
51 #include "ED_screen.h"
52 #include "ED_select_utils.h"
53 #include "ED_transform.h"
54 #include "ED_types.h"
55 #include "ED_util.h"
56 
57 #include "DEG_depsgraph.h"
58 
59 /* -------------------------------------------------------------------- */
63 /* helper function for getting the list of markers to work on */
65 {
66  /* local marker sets... */
67  if (area) {
68  if (area->spacetype == SPACE_ACTION) {
69  SpaceAction *saction = (SpaceAction *)area->spacedata.first;
70 
71  /* local markers can only be shown when there's only a single active action to grab them from
72  * - flag only takes effect when there's an action, otherwise it can get too confusing?
73  */
74  if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) && (saction->action)) {
75  if (saction->flag & SACTION_POSEMARKERS_SHOW) {
76  return &saction->action->markers;
77  }
78  }
79  }
80  }
81 
82  /* default to using the scene's markers */
83  return &scene->markers;
84 }
85 
86 /* ............. */
87 
89 {
91 }
92 
94 {
95  if (ac) {
96  return context_get_markers(ac->scene, ac->area);
97  }
98  return NULL;
99 }
100 
101 /* --------------------------------- */
102 
104  ListBase *markers, Scene *scene, int mode, float value, char side)
105 {
106  TimeMarker *marker;
107  float cfra = (float)scene->r.cfra;
108  int changed_tot = 0;
109 
110  /* sanity check - no markers, or locked markers */
111  if ((scene->toolsettings->lock_markers) || (markers == NULL)) {
112  return changed_tot;
113  }
114 
115  /* affect selected markers - it's unlikely that we will want to affect all in this way? */
116  for (marker = markers->first; marker; marker = marker->next) {
117  if (marker->flag & SELECT) {
118  switch (mode) {
119  case TFM_TIME_TRANSLATE:
120  case TFM_TIME_EXTEND: {
121  /* apply delta if marker is on the right side of the current frame */
122  if ((side == 'B') || (side == 'L' && marker->frame < cfra) ||
123  (side == 'R' && marker->frame >= cfra)) {
124  marker->frame += round_fl_to_int(value);
125  changed_tot++;
126  }
127  break;
128  }
129  case TFM_TIME_SCALE: {
130  /* rescale the distance between the marker and the current frame */
131  marker->frame = cfra + round_fl_to_int((float)(marker->frame - cfra) * value);
132  changed_tot++;
133  break;
134  }
135  }
136  }
137  }
138 
139  return changed_tot;
140 }
141 
142 /* --------------------------------- */
143 
145 {
146  TimeMarker *marker, *nearest = NULL;
147  float dist, min_dist = 1000000;
148 
149  if (markers) {
150  for (marker = markers->first; marker; marker = marker->next) {
151  dist = fabsf((float)marker->frame - x);
152 
153  if (dist < min_dist) {
154  min_dist = dist;
155  nearest = marker;
156  }
157  }
158  }
159 
160  return nearest;
161 }
162 
164 {
166  return (nearest) ? (nearest->frame) : round_fl_to_int(x);
167 }
168 
169 void ED_markers_get_minmax(ListBase *markers, short sel, float *r_first, float *r_last)
170 {
171  TimeMarker *marker;
172  float min, max;
173 
174  /* sanity check */
175  // printf("markers = %p - %p, %p\n", markers, markers->first, markers->last);
176  if (ELEM(NULL, markers, markers->first, markers->last)) {
177  *r_first = 0.0f;
178  *r_last = 0.0f;
179  return;
180  }
181 
182  min = FLT_MAX;
183  max = -FLT_MAX;
184  for (marker = markers->first; marker; marker = marker->next) {
185  if (!sel || (marker->flag & SELECT)) {
186  if (marker->frame < min) {
187  min = (float)marker->frame;
188  }
189  if (marker->frame > max) {
190  max = (float)marker->frame;
191  }
192  }
193  }
194 
195  /* set the min/max values */
196  *r_first = min;
197  *r_last = max;
198 }
199 
205 {
207  if (area == NULL) {
208  return false;
209  }
210 
211  switch (area->spacetype) {
212  case SPACE_ACTION: {
213  SpaceAction *saction = area->spacedata.first;
214  if (saction->flag & SACTION_SHOW_MARKERS) {
215  return true;
216  }
217  break;
218  }
219  case SPACE_GRAPH: {
220  SpaceGraph *sipo = area->spacedata.first;
221  if (sipo->mode != SIPO_MODE_DRIVERS && sipo->flag & SIPO_SHOW_MARKERS) {
222  return true;
223  }
224  break;
225  }
226  case SPACE_NLA: {
227  SpaceNla *snla = area->spacedata.first;
228  if (snla->flag & SNLA_SHOW_MARKERS) {
229  return true;
230  }
231  break;
232  }
233  case SPACE_SEQ: {
234  SpaceSeq *seq = area->spacedata.first;
235  if (seq->flag & SEQ_SHOW_MARKERS) {
236  return true;
237  }
238  break;
239  }
240  }
241  return false;
242 }
243 
244 static bool region_position_is_over_marker(View2D *v2d, ListBase *markers, float region_x)
245 {
247  return false;
248  }
249 
250  float frame_at_position = UI_view2d_region_to_view_x(v2d, region_x);
251  TimeMarker *nearest_marker = ED_markers_find_nearest_marker(markers, frame_at_position);
252  float pixel_distance = UI_view2d_scale_get_x(v2d) *
253  fabsf(nearest_marker->frame - frame_at_position);
254 
255  return pixel_distance <= UI_DPI_ICON_SIZE;
256 }
257 
258 /* --------------------------------- */
259 
260 /* Adds a marker to list of cfra elems */
261 static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel)
262 {
263  CfraElem *ce, *cen;
264 
265  /* should this one only be considered if it is selected? */
266  if ((only_sel) && ((marker->flag & SELECT) == 0)) {
267  return;
268  }
269 
270  /* insertion sort - try to find a previous cfra elem */
271  for (ce = lb->first; ce; ce = ce->next) {
272  if (ce->cfra == marker->frame) {
273  /* do because of double keys */
274  if (marker->flag & SELECT) {
275  ce->sel = marker->flag;
276  }
277  return;
278  }
279  if (ce->cfra > marker->frame) {
280  break;
281  }
282  }
283 
284  cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
285  if (ce) {
286  BLI_insertlinkbefore(lb, ce, cen);
287  }
288  else {
289  BLI_addtail(lb, cen);
290  }
291 
292  cen->cfra = marker->frame;
293  cen->sel = marker->flag;
294 }
295 
297 {
298  TimeMarker *marker;
299 
300  if (lb) {
301  /* Clear the list first, since callers have no way of knowing
302  * whether this terminated early otherwise. This may lead
303  * to crashes if the user didn't clear the memory first.
304  */
305  lb->first = lb->last = NULL;
306  }
307  else {
308  return;
309  }
310 
311  if (markers == NULL) {
312  return;
313  }
314 
315  for (marker = markers->first; marker; marker = marker->next) {
316  add_marker_to_cfra_elem(lb, marker, only_sel);
317  }
318 }
319 
321 {
322  if (action == SEL_TOGGLE) {
324  }
325 
326  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
327  if (action == SEL_SELECT) {
328  marker->flag |= SELECT;
329  }
330  else if (action == SEL_DESELECT) {
331  marker->flag &= ~SELECT;
332  }
333  else if (action == SEL_INVERT) {
334  marker->flag ^= SELECT;
335  }
336  else {
337  BLI_assert(0);
338  }
339  }
340 }
341 
342 /* --------------------------------- */
343 
345 {
346  TimeMarker *marker;
347 
348  if (markers) {
349  for (marker = markers->first; marker; marker = marker->next) {
350  if (marker->flag & SELECT) {
351  return marker;
352  }
353  }
354  }
355 
356  return NULL;
357 }
358 
359 /* --------------------------------- */
360 
362 {
363  /* NOTE: do NOT make static or put in if-defs as "unused code".
364  * That's too much trouble when we need to use for quick debugging! */
365 
366  TimeMarker *marker;
367 
368  if (markers == NULL) {
369  printf("No markers list to print debug for\n");
370  return;
371  }
372 
373  printf("List of markers follows: -----\n");
374 
375  for (marker = markers->first; marker; marker = marker->next) {
376  printf(
377  "\t'%s' on %d at %p with %u\n", marker->name, marker->frame, (void *)marker, marker->flag);
378  }
379 
380  printf("End of list ------------------\n");
381 }
382 
385 /* -------------------------------------------------------------------- */
389 static void marker_color_get(const TimeMarker *marker, uchar *r_text_color, uchar *r_line_color)
390 {
391  if (marker->flag & SELECT) {
392  UI_GetThemeColor4ubv(TH_TEXT_HI, r_text_color);
394  }
395  else {
396  UI_GetThemeColor4ubv(TH_TEXT, r_text_color);
398  }
399 }
400 
401 static void draw_marker_name(const uchar *text_color,
402  const uiFontStyle *fstyle,
403  TimeMarker *marker,
404  float marker_x,
405  float text_y)
406 {
407  const char *name = marker->name;
408  uchar final_text_color[4];
409 
410  copy_v4_v4_uchar(final_text_color, text_color);
411 
412 #ifdef DURIAN_CAMERA_SWITCH
413  if (marker->camera) {
414  Object *camera = marker->camera;
415  name = camera->id.name + 2;
416  if (camera->visibility_flag & OB_HIDE_RENDER) {
417  final_text_color[3] = 100;
418  }
419  }
420 #endif
421 
422  int name_x = marker_x + UI_DPI_ICON_SIZE * 0.6;
423  UI_fontstyle_draw_simple(fstyle, name_x, text_y, name, final_text_color);
424 }
425 
426 static void draw_marker_line(const uchar *color, int xpos, int ymin, int ymax)
427 {
430 
432 
433  float viewport_size[4];
434  GPU_viewport_size_get_f(viewport_size);
435  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
436 
438  immUniform1i("colors_len", 0); /* "simple" mode */
439  immUniform1f("dash_width", 6.0f);
440  immUniform1f("dash_factor", 0.5f);
441 
443  immVertex2f(pos, xpos, ymin);
444  immVertex2f(pos, xpos, ymax);
445  immEnd();
446 
448 }
449 
450 static int marker_get_icon_id(TimeMarker *marker, int flag)
451 {
452  if (flag & DRAW_MARKERS_LOCAL) {
453  return (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
454  (marker->flag & SELECT) ? ICON_PMARKER_SEL :
455  ICON_PMARKER;
456  }
457 #ifdef DURIAN_CAMERA_SWITCH
458  if (marker->camera) {
459  return (marker->flag & SELECT) ? ICON_OUTLINER_OB_CAMERA : ICON_CAMERA_DATA;
460  }
461 #endif
462  return (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER;
463 }
464 
465 static void draw_marker(
466  const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int xpos, int flag, int region_height)
467 {
468  uchar line_color[4], text_color[4];
469 
470  marker_color_get(marker, text_color, line_color);
471 
473 
474  draw_marker_line(line_color, xpos, UI_DPI_FAC * 20, region_height);
475 
476  int icon_id = marker_get_icon_id(marker, flag);
477  UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, UI_DPI_FAC * 18, icon_id);
478 
480 
481  float name_y = UI_DPI_FAC * 18;
482  /* Give an offset to the marker name when selected,
483  * or when near the current frame (5 frames range, starting from the current one). */
484  if ((marker->flag & SELECT) || (cfra - 4 <= marker->frame && marker->frame <= cfra)) {
485  name_y += UI_DPI_FAC * 10;
486  }
487  draw_marker_name(text_color, fstyle, marker, xpos, name_y);
488 }
489 
490 static void draw_markers_background(rctf *rect)
491 {
494 
495  uchar shade[4];
497 
498  immUniformColor4ubv(shade);
499 
501 
502  immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
503 
505 
507 }
508 
509 static bool marker_is_in_frame_range(TimeMarker *marker, const int frame_range[2])
510 {
511  if (marker->frame < frame_range[0]) {
512  return false;
513  }
514  if (marker->frame > frame_range[1]) {
515  return false;
516  }
517  return true;
518 }
519 
520 static void get_marker_region_rect(View2D *v2d, rctf *rect)
521 {
522  rect->xmin = v2d->cur.xmin;
523  rect->xmax = v2d->cur.xmax;
524  rect->ymin = 0;
525  rect->ymax = UI_MARKER_MARGIN_Y;
526 }
527 
528 static void get_marker_clip_frame_range(View2D *v2d, float xscale, int r_range[2])
529 {
530  float font_width_max = (10 * UI_DPI_FAC) / xscale;
531  r_range[0] = v2d->cur.xmin - sizeof(((TimeMarker *)NULL)->name) * font_width_max;
532  r_range[1] = v2d->cur.xmax + font_width_max;
533 }
534 
535 void ED_markers_draw(const bContext *C, int flag)
536 {
539  return;
540  }
541 
542  ARegion *region = CTX_wm_region(C);
544  int cfra = CTX_data_scene(C)->r.cfra;
545 
546  GPU_line_width(1.0f);
547 
548  rctf markers_region_rect;
549  get_marker_region_rect(v2d, &markers_region_rect);
550 
551  draw_markers_background(&markers_region_rect);
552 
553  /* no time correction for framelen! space is drawn with old values */
554  float xscale, dummy;
555  UI_view2d_scale_get(v2d, &xscale, &dummy);
556  GPU_matrix_push();
557  GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
558 
559  int clip_frame_range[2];
560  get_marker_clip_frame_range(v2d, xscale, clip_frame_range);
561 
562  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
563 
564  /* Separate loops in order to draw selected markers on top */
565  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
566  if ((marker->flag & SELECT) == 0) {
567  if (marker_is_in_frame_range(marker, clip_frame_range)) {
568  draw_marker(fstyle, marker, cfra, marker->frame * xscale, flag, region->winy);
569  }
570  }
571  }
572  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
573  if (marker->flag & SELECT) {
574  if (marker_is_in_frame_range(marker, clip_frame_range)) {
575  draw_marker(fstyle, marker, cfra, marker->frame * xscale, flag, region->winy);
576  }
577  }
578  }
579 
580  GPU_matrix_pop();
581 }
582 
585 /* -------------------------------------------------------------------- */
593 /* ------------------------ */
594 
595 /* special poll() which checks if there are selected markers first */
597 {
599 
601  return 0;
602  }
603 
604  /* check if some marker is selected */
606 }
607 
609 {
612 
614  return 0;
615  }
616 
617  /* check if some marker is selected */
619 }
620 
621 /* special poll() which checks if there are any markers at all first */
623 {
626 
628  return 0;
629  }
630 
631  /* list of markers must exist, as well as some markers in it! */
632  return (markers && markers->first);
633 }
634 
637 /* -------------------------------------------------------------------- */
641 /* add TimeMarker at current frame */
643 {
645  TimeMarker *marker;
646  int frame = CTX_data_scene(C)->r.cfra;
647 
648  if (markers == NULL) {
649  return OPERATOR_CANCELLED;
650  }
651 
652  /* prefer not having 2 markers at the same place,
653  * though the user can move them to overlap once added */
654  for (marker = markers->first; marker; marker = marker->next) {
655  if (marker->frame == frame) {
656  return OPERATOR_CANCELLED;
657  }
658  }
659 
660  /* deselect all */
661  for (marker = markers->first; marker; marker = marker->next) {
662  marker->flag &= ~SELECT;
663  }
664 
665  marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
666  marker->flag = SELECT;
667  marker->frame = frame;
668  BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); /* XXX: temp code only. */
669  BLI_addtail(markers, marker);
670 
673 
674  return OPERATOR_FINISHED;
675 }
676 
678 {
679  /* identifiers */
680  ot->name = "Add Time Marker";
681  ot->description = "Add a new time marker";
682  ot->idname = "MARKER_OT_add";
683 
684  /* api callbacks */
687 
688  /* flags */
690 }
691 
694 /* -------------------------------------------------------------------- */
698 /* operator state vars used:
699  * frs: delta movement
700  *
701  * functions:
702  *
703  * init() check selection, add customdata with old values and some lookups
704  *
705  * apply() do the actual movement
706  *
707  * exit() cleanup, send notifier
708  *
709  * cancel() to escape from modal
710  *
711  * callbacks:
712  *
713  * exec() calls init, apply, exit
714  *
715  * invoke() calls init, adds modal handler
716  *
717  * modal() accept modal events while doing it, ends with apply and exit, or cancel
718  */
719 
720 typedef struct MarkerMove {
723  short event_type, event_val; /* store invoke-event, to verify */
727 
729 {
730  if (((mm->slink->spacetype == SPACE_SEQ) && !(((SpaceSeq *)mm->slink)->flag & SEQ_DRAWFRAMES)) ||
731  ((mm->slink->spacetype == SPACE_ACTION) &&
732  (((SpaceAction *)mm->slink)->flag & SACTION_DRAWTIME)) ||
733  ((mm->slink->spacetype == SPACE_GRAPH) &&
734  (((SpaceGraph *)mm->slink)->flag & SIPO_DRAWTIME)) ||
735  ((mm->slink->spacetype == SPACE_NLA) && (((SpaceNla *)mm->slink)->flag & SNLA_DRAWTIME))) {
736  return true;
737  }
738 
739  return false;
740 }
741 
743 {
745  MarkerMove *mm = op->customdata;
746  TimeMarker *marker, *selmarker = NULL;
747  const int ofs = RNA_int_get(op->ptr, "frames");
748  char str[UI_MAX_DRAW_STR];
749  char str_ofs[NUM_STR_REP_LEN];
750  int totmark;
751  const bool use_time = ed_marker_move_use_time(mm);
752 
753  for (totmark = 0, marker = mm->markers->first; marker; marker = marker->next) {
754  if (marker->flag & SELECT) {
755  selmarker = marker;
756  totmark++;
757  }
758  }
759 
760  if (hasNumInput(&mm->num)) {
761  outputNumInput(&mm->num, str_ofs, &scene->unit);
762  }
763  else if (use_time) {
764  BLI_snprintf(str_ofs, sizeof(str_ofs), "%.2f", FRA2TIME(ofs));
765  }
766  else {
767  BLI_snprintf(str_ofs, sizeof(str_ofs), "%d", ofs);
768  }
769 
770  if (totmark == 1 && selmarker) {
771  /* we print current marker value */
772  if (use_time) {
773  BLI_snprintf(
774  str, sizeof(str), TIP_("Marker %.2f offset %s"), FRA2TIME(selmarker->frame), str_ofs);
775  }
776  else {
777  BLI_snprintf(str, sizeof(str), TIP_("Marker %d offset %s"), selmarker->frame, str_ofs);
778  }
779  }
780  else {
781  BLI_snprintf(str, sizeof(str), TIP_("Marker offset %s"), str_ofs);
782  }
783 
785 }
786 
787 /* copy selection to temp buffer */
788 /* return 0 if not OK */
790 {
793  MarkerMove *mm;
794  TimeMarker *marker;
795  int a, totmark;
796 
797  if (markers == NULL) {
798  return false;
799  }
800 
801  for (totmark = 0, marker = markers->first; marker; marker = marker->next) {
802  if (marker->flag & SELECT) {
803  totmark++;
804  }
805  }
806 
807  if (totmark == 0) {
808  return false;
809  }
810 
811  op->customdata = mm = MEM_callocN(sizeof(MarkerMove), "Markermove");
812  mm->slink = CTX_wm_space_data(C);
813  mm->markers = markers;
814  mm->oldframe = MEM_callocN(totmark * sizeof(int), "MarkerMove oldframe");
815 
816  initNumInput(&mm->num);
817  mm->num.idx_max = 0; /* one axis */
818  mm->num.val_flag[0] |= NUM_NO_FRACTION;
819  mm->num.unit_sys = scene->unit.system;
820  /* No time unit supporting frames currently... */
822 
823  for (a = 0, marker = markers->first; marker; marker = marker->next) {
824  if (marker->flag & SELECT) {
825  mm->oldframe[a] = marker->frame;
826  a++;
827  }
828  }
829 
830  return true;
831 }
832 
833 /* free stuff */
835 {
836  MarkerMove *mm = op->customdata;
837 
838  /* free data */
839  MEM_freeN(mm->oldframe);
840  MEM_freeN(op->customdata);
841  op->customdata = NULL;
842 
843  /* clear custom header prints */
845 }
846 
847 static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
848 {
849  const bool tweak = RNA_struct_find_property(op->ptr, "tweak") &&
850  RNA_boolean_get(op->ptr, "tweak");
851 
852  if (tweak) {
853  ARegion *region = CTX_wm_region(C);
854  View2D *v2d = &region->v2d;
856  if (!region_position_is_over_marker(v2d, markers, event->xy[0] - region->winrct.xmin)) {
858  }
859  }
860 
861  if (ed_marker_move_init(C, op)) {
862  MarkerMove *mm = op->customdata;
863 
864  mm->evtx = event->xy[0];
865  mm->firstx = event->xy[0];
866  mm->event_type = event->type;
867  mm->event_val = event->val;
868 
869  /* add temp handler */
871 
872  /* reset frs delta */
873  RNA_int_set(op->ptr, "frames", 0);
874 
876 
877  return OPERATOR_RUNNING_MODAL;
878  }
879 
880  return OPERATOR_CANCELLED;
881 }
882 
883 /* NOTE: init has to be called successfully. */
885 {
886 #ifdef DURIAN_CAMERA_SWITCH
887  bScreen *screen = CTX_wm_screen(C);
890 #endif
891  MarkerMove *mm = op->customdata;
892  TimeMarker *marker;
893  int a, ofs;
894 
895  ofs = RNA_int_get(op->ptr, "frames");
896  for (a = 0, marker = mm->markers->first; marker; marker = marker->next) {
897  if (marker->flag & SELECT) {
898  marker->frame = mm->oldframe[a] + ofs;
899  a++;
900  }
901  }
902 
905 
906 #ifdef DURIAN_CAMERA_SWITCH
907  /* so we get view3d redraws */
909 
910  if (camera != scene->camera) {
913  }
914 #endif
915 }
916 
917 /* only for modal */
919 {
920  RNA_int_set(op->ptr, "frames", 0);
921  ed_marker_move_apply(C, op);
922  ed_marker_move_exit(C, op);
923 }
924 
925 static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
926 {
928  MarkerMove *mm = op->customdata;
930  const bool has_numinput = hasNumInput(&mm->num);
931  const bool use_time = ed_marker_move_use_time(mm);
932 
933  /* Modal numinput active, try to handle numeric inputs first... */
934  if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &mm->num, event)) {
935  float value = (float)RNA_int_get(op->ptr, "frames");
936 
937  applyNumInput(&mm->num, &value);
938  if (use_time) {
939  value = TIME2FRA(value);
940  }
941 
942  RNA_int_set(op->ptr, "frames", (int)value);
943  ed_marker_move_apply(C, op);
945  }
946  else {
947  bool handled = false;
948  switch (event->type) {
949  case EVT_ESCKEY:
951  return OPERATOR_CANCELLED;
952  case RIGHTMOUSE:
953  /* press = user manually demands transform to be canceled */
954  if (event->val == KM_PRESS) {
956  return OPERATOR_CANCELLED;
957  }
958  /* else continue; <--- see if release event should be caught for tweak-end */
960 
961  case EVT_RETKEY:
962  case EVT_PADENTER:
963  case LEFTMOUSE:
964  case MIDDLEMOUSE:
965  if (WM_event_is_modal_drag_exit(event, mm->event_type, mm->event_val)) {
966  ed_marker_move_exit(C, op);
969  return OPERATOR_FINISHED;
970  }
971  break;
972  case MOUSEMOVE:
973  if (!has_numinput) {
974  float dx;
975 
976  dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
977 
978  if (event->xy[0] != mm->evtx) { /* XXX maybe init for first time */
979  float fac;
980 
981  mm->evtx = event->xy[0];
982  fac = ((float)(event->xy[0] - mm->firstx) * dx);
983 
984  apply_keyb_grid((event->modifier & KM_SHIFT) != 0,
985  (event->modifier & KM_CTRL) != 0,
986  &fac,
987  0.0,
988  FPS,
989  0.1 * FPS,
990  0);
991 
992  RNA_int_set(op->ptr, "frames", (int)fac);
993  ed_marker_move_apply(C, op);
995  }
996  }
997  break;
998  }
999 
1000  if (!handled && event->val == KM_PRESS && handleNumInput(C, &mm->num, event)) {
1001  float value = (float)RNA_int_get(op->ptr, "frames");
1002 
1003  applyNumInput(&mm->num, &value);
1004  if (use_time) {
1005  value = TIME2FRA(value);
1006  }
1007 
1008  RNA_int_set(op->ptr, "frames", (int)value);
1009  ed_marker_move_apply(C, op);
1011  }
1012  }
1013 
1014  return OPERATOR_RUNNING_MODAL;
1015 }
1016 
1018 {
1019  if (ed_marker_move_init(C, op)) {
1020  ed_marker_move_apply(C, op);
1021  ed_marker_move_exit(C, op);
1022  return OPERATOR_FINISHED;
1023  }
1024  return OPERATOR_PASS_THROUGH;
1025 }
1026 
1028 {
1029  /* identifiers */
1030  ot->name = "Move Time Marker";
1031  ot->description = "Move selected time marker(s)";
1032  ot->idname = "MARKER_OT_move";
1033 
1034  /* api callbacks */
1040 
1041  /* flags */
1043 
1044  /* rna storage */
1045  RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
1046  PropertyRNA *prop = RNA_def_boolean(
1047  ot->srna, "tweak", 0, "Tweak", "Operator has been activated using a click-drag event");
1049 }
1050 
1053 /* -------------------------------------------------------------------- */
1057 /* operator state vars used:
1058  * frs: delta movement
1059  *
1060  * functions:
1061  *
1062  * apply() do the actual duplicate
1063  *
1064  * callbacks:
1065  *
1066  * exec() calls apply, move_exec
1067  *
1068  * invoke() calls apply, move_invoke
1069  *
1070  * modal() uses move_modal
1071  */
1072 
1073 /* duplicate selected TimeMarkers */
1075 {
1077  TimeMarker *marker, *newmarker;
1078 
1079  if (markers == NULL) {
1080  return;
1081  }
1082 
1083  /* go through the list of markers, duplicate selected markers and add duplicated copies
1084  * to the beginning of the list (unselect original markers)
1085  */
1086  for (marker = markers->first; marker; marker = marker->next) {
1087  if (marker->flag & SELECT) {
1088  /* unselect selected marker */
1089  marker->flag &= ~SELECT;
1090 
1091  /* create and set up new marker */
1092  newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
1093  newmarker->flag = SELECT;
1094  newmarker->frame = marker->frame;
1095  BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
1096 
1097 #ifdef DURIAN_CAMERA_SWITCH
1098  newmarker->camera = marker->camera;
1099 #endif
1100 
1101  if (marker->prop != NULL) {
1102  newmarker->prop = IDP_CopyProperty(marker->prop);
1103  }
1104 
1105  /* new marker is added to the beginning of list */
1106  /* FIXME: bad ordering! */
1107  BLI_addhead(markers, newmarker);
1108  }
1109  }
1110 }
1111 
1113 {
1115  ed_marker_move_exec(C, op); /* assumes frs delta set */
1116 
1117  return OPERATOR_FINISHED;
1118 }
1119 
1120 static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1121 {
1123  return ed_marker_move_invoke(C, op, event);
1124 }
1125 
1127 {
1128  /* identifiers */
1129  ot->name = "Duplicate Time Marker";
1130  ot->description = "Duplicate selected time marker(s)";
1131  ot->idname = "MARKER_OT_duplicate";
1132 
1133  /* api callbacks */
1139 
1140  /* flags */
1142 
1143  /* rna storage */
1144  RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
1145 }
1146 
1149 /* -------------------------------------------------------------------- */
1156 {
1157  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
1158  marker->flag &= ~SELECT;
1159  }
1160 }
1161 
1163  int frame,
1164  bool extend,
1165  bool wait_to_deselect_others)
1166 {
1167  TimeMarker *marker, *marker_cycle_selected = NULL;
1168  int ret_val = OPERATOR_FINISHED;
1169 
1170  if (extend) {
1171  wait_to_deselect_others = false;
1172  }
1173 
1174  /* support for selection cycling */
1175  for (marker = markers->first; marker; marker = marker->next) {
1176  if (marker->frame == frame) {
1177  if (marker->flag & SELECT) {
1178  marker_cycle_selected = marker->next ? marker->next : markers->first;
1179  break;
1180  }
1181  }
1182  }
1183 
1184  if (wait_to_deselect_others && marker_cycle_selected) {
1185  ret_val = OPERATOR_RUNNING_MODAL;
1186  }
1187  /* if extend is not set, then deselect markers */
1188  else {
1189  if (extend == false) {
1191  }
1192 
1193  LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_cycle_selected) {
1194  /* this way a not-extend select will always give 1 selected marker */
1195  if (marker->frame == frame) {
1196  marker->flag ^= SELECT;
1197  break;
1198  }
1199  }
1200  LISTBASE_CIRCULAR_FORWARD_END(markers, marker, marker_cycle_selected);
1201  }
1202 
1203  return ret_val;
1204 }
1205 
1207  bContext *C, bool camera, bool extend, ListBase *markers, int cfra)
1208 {
1209 #ifdef DURIAN_CAMERA_SWITCH
1210  if (camera) {
1213  ViewLayer *view_layer = CTX_data_view_layer(C);
1214  Base *base;
1215  TimeMarker *marker;
1216  int sel = 0;
1217 
1218  if (!extend) {
1220  }
1221 
1222  for (marker = markers->first; marker; marker = marker->next) {
1223  if (marker->frame == cfra) {
1224  sel = (marker->flag & SELECT);
1225  break;
1226  }
1227  }
1228 
1229  for (marker = markers->first; marker; marker = marker->next) {
1230  if (marker->camera) {
1231  if (marker->frame == cfra) {
1232  base = BKE_view_layer_base_find(view_layer, marker->camera);
1233  if (base) {
1234  ED_object_base_select(base, sel);
1235  if (sel) {
1236  ED_object_base_activate(C, base);
1237  }
1238  }
1239  }
1240  }
1241  }
1242 
1245  }
1246 #else
1247  (void)camera;
1248 #endif
1249 }
1250 
1251 static int ed_marker_select(
1252  bContext *C, const int mval[2], bool extend, bool camera, bool wait_to_deselect_others)
1253 {
1255  View2D *v2d = UI_view2d_fromcontext(C);
1256  int ret_val = OPERATOR_FINISHED;
1257 
1258  if (region_position_is_over_marker(v2d, markers, mval[0])) {
1259  float frame_at_mouse_position = UI_view2d_region_to_view_x(v2d, mval[0]);
1260  int cfra = ED_markers_find_nearest_marker_time(markers, frame_at_mouse_position);
1261  ret_val = select_timeline_marker_frame(markers, cfra, extend, wait_to_deselect_others);
1262 
1263  select_marker_camera_switch(C, camera, extend, markers, cfra);
1264  }
1265  else {
1267  }
1268 
1271 
1272  /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails, see T25987. */
1273  return ret_val | OPERATOR_PASS_THROUGH;
1274 }
1275 
1277 {
1278  const bool extend = RNA_boolean_get(op->ptr, "extend");
1279  const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
1280  bool camera = false;
1281 #ifdef DURIAN_CAMERA_SWITCH
1282  camera = RNA_boolean_get(op->ptr, "camera");
1283  if (camera) {
1284  /* Supporting mode switching from this operator doesn't seem so useful.
1285  * So only allow setting the active camera in object-mode. */
1287  BKE_report(
1288  op->reports, RPT_WARNING, "Selecting the camera is only supported in object mode");
1289  camera = false;
1290  }
1291  }
1292 #endif
1293  int mval[2];
1294  mval[0] = RNA_int_get(op->ptr, "mouse_x");
1295  mval[1] = RNA_int_get(op->ptr, "mouse_y");
1296 
1297  return ed_marker_select(C, mval, extend, camera, wait_to_deselect_others);
1298 }
1299 
1301 {
1302  PropertyRNA *prop;
1303 
1304  /* identifiers */
1305  ot->name = "Select Time Marker";
1306  ot->description = "Select time marker(s)";
1307  ot->idname = "MARKER_OT_select";
1308 
1309  /* api callbacks */
1314 
1315  /* flags */
1317 
1319  prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
1321 #ifdef DURIAN_CAMERA_SWITCH
1322  prop = RNA_def_boolean(ot->srna, "camera", 0, "Camera", "Select the camera");
1324 #endif
1325 }
1326 
1329 /* -------------------------------------------------------------------- */
1333 /* operator state vars used: (added by default WM callbacks)
1334  * xmin, ymin
1335  * xmax, ymax
1336  *
1337  * customdata: the wmGesture pointer, with subwindow
1338  *
1339  * callbacks:
1340  *
1341  * exec() has to be filled in by user
1342  *
1343  * invoke() default WM function
1344  * adds modal handler
1345  *
1346  * modal() default WM function
1347  * accept modal events while doing it, calls exec(), handles ESC and border drawing
1348  *
1349  * poll() has to be filled in by user for context
1350  */
1351 
1353 {
1354  ARegion *region = CTX_wm_region(C);
1355  View2D *v2d = &region->v2d;
1356 
1358  bool over_marker = region_position_is_over_marker(
1359  v2d, markers, event->xy[0] - region->winrct.xmin);
1360 
1361  bool tweak = RNA_boolean_get(op->ptr, "tweak");
1362  if (tweak && over_marker) {
1364  }
1365 
1366  return WM_gesture_box_invoke(C, op, event);
1367 }
1368 
1370 {
1371  View2D *v2d = UI_view2d_fromcontext(C);
1373  rctf rect;
1374 
1376  UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
1377 
1378  if (markers == NULL) {
1379  return 0;
1380  }
1381 
1382  const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
1383  const bool select = (sel_op != SEL_OP_SUB);
1384  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
1386  }
1387 
1388  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
1389  if (BLI_rctf_isect_x(&rect, marker->frame)) {
1390  SET_FLAG_FROM_TEST(marker->flag, select, SELECT);
1391  }
1392  }
1393 
1396 
1397  return 1;
1398 }
1399 
1401 {
1402  /* identifiers */
1403  ot->name = "Marker Box Select";
1404  ot->description = "Select all time markers using box selection";
1405  ot->idname = "MARKER_OT_select_box";
1406 
1407  /* api callbacks */
1412 
1414 
1415  /* flags */
1417 
1418  /* properties */
1421 
1422  PropertyRNA *prop = RNA_def_boolean(
1423  ot->srna, "tweak", 0, "Tweak", "Operator has been activated using a click-drag event");
1425 }
1426 
1429 /* -------------------------------------------------------------------- */
1434 {
1436  if (markers == NULL) {
1437  return OPERATOR_CANCELLED;
1438  }
1439 
1440  int action = RNA_enum_get(op->ptr, "action");
1442 
1445 
1446  return OPERATOR_FINISHED;
1447 }
1448 
1450 {
1451  /* identifiers */
1452  ot->name = "(De)select all Markers";
1453  ot->description = "Change selection of all time markers";
1454  ot->idname = "MARKER_OT_select_all";
1455 
1456  /* api callbacks */
1459 
1460  /* flags */
1462 
1463  /* rna */
1465 }
1466 
1469 /* -------------------------------------------------------------------- */
1477 
1479  {MARKERS_LRSEL_LEFT, "LEFT", 0, "Before Current Frame", ""},
1480  {MARKERS_LRSEL_RIGHT, "RIGHT", 0, "After Current Frame", ""},
1481  {0, NULL, 0, NULL, NULL},
1482 };
1483 
1485  const eMarkers_LeftRightSelect_Mode mode,
1486  const bool extend)
1487 {
1488  ListBase *markers = ac->markers;
1489  Scene *scene = ac->scene;
1490 
1491  if (markers == NULL) {
1492  return;
1493  }
1494 
1495  if (!extend) {
1497  }
1498 
1499  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
1500  if ((mode == MARKERS_LRSEL_LEFT && marker->frame <= scene->r.cfra) ||
1501  (mode == MARKERS_LRSEL_RIGHT && marker->frame >= scene->r.cfra)) {
1502  marker->flag |= SELECT;
1503  }
1504  }
1505 }
1506 
1508 {
1509  const eMarkers_LeftRightSelect_Mode mode = RNA_enum_get(op->ptr, "mode");
1510  const bool extend = RNA_boolean_get(op->ptr, "extend");
1511 
1512  bAnimContext ac;
1513  if (ANIM_animdata_get_context(C, &ac) == 0) {
1514  return OPERATOR_CANCELLED;
1515  }
1516 
1517  ED_markers_select_leftright(&ac, mode, extend);
1518 
1520 
1521  return OPERATOR_FINISHED;
1522 }
1523 
1525 {
1526  /* identifiers */
1527  ot->name = "Select Markers Before/After Current Frame";
1528  ot->description = "Select markers on and left/right of the current frame";
1529  ot->idname = "MARKER_OT_select_leftright";
1530 
1531  /* api callbacks */
1534 
1535  /* flags */
1537 
1538  /* rna storage */
1539  RNA_def_enum(
1540  ot->srna, "mode", prop_markers_select_leftright_modes, MARKERS_LRSEL_LEFT, "mode", "Mode");
1541  RNA_def_boolean(ot->srna, "extend", false, "extend", "Extend");
1542 }
1543 
1546 /* -------------------------------------------------------------------- */
1553 
1554 {
1556  TimeMarker *marker, *nmarker;
1557  bool changed = false;
1558 
1559  if (markers == NULL) {
1560  return OPERATOR_CANCELLED;
1561  }
1562 
1563  for (marker = markers->first; marker; marker = nmarker) {
1564  nmarker = marker->next;
1565  if (marker->flag & SELECT) {
1566  if (marker->prop != NULL) {
1567  IDP_FreePropertyContent(marker->prop);
1568  MEM_freeN(marker->prop);
1569  }
1570  BLI_freelinkN(markers, marker);
1571  changed = true;
1572  }
1573  }
1574 
1575  if (changed) {
1578  }
1579 
1580  return OPERATOR_FINISHED;
1581 }
1582 
1584 {
1585  /* identifiers */
1586  ot->name = "Delete Markers";
1587  ot->description = "Delete selected time marker(s)";
1588  ot->idname = "MARKER_OT_delete";
1589 
1590  /* api callbacks */
1594 
1595  /* flags */
1598 }
1599 
1602 /* -------------------------------------------------------------------- */
1609 {
1611 
1612  if (marker) {
1613  RNA_string_get(op->ptr, "name", marker->name);
1614 
1617 
1618  return OPERATOR_FINISHED;
1619  }
1620 
1621  return OPERATOR_CANCELLED;
1622 }
1623 
1624 static int ed_marker_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1625 {
1626  /* must initialize the marker name first if there is a marker selected */
1628  if (marker) {
1629  RNA_string_set(op->ptr, "name", marker->name);
1630  }
1631 
1632  return WM_operator_props_popup_confirm(C, op, event);
1633 }
1634 
1636 {
1637  /* identifiers */
1638  ot->name = "Rename Marker";
1639  ot->description = "Rename first selected time marker";
1640  ot->idname = "MARKER_OT_rename";
1641 
1642  /* api callbacks */
1646 
1647  /* flags */
1649 
1650  /* properties */
1652  "name",
1653  "RenamedMarker",
1654  sizeof(((TimeMarker *)NULL)->name),
1655  "Name",
1656  "New name for marker");
1657 #if 0
1659  "ensure_unique",
1660  0,
1661  "Ensure Unique",
1662  "Ensure that new name is unique within collection of markers");
1663 #endif
1664 }
1665 
1668 /* -------------------------------------------------------------------- */
1673 {
1674  Main *bmain = CTX_data_main(C);
1676  Scene *scene_to = BLI_findlink(&bmain->scenes, RNA_enum_get(op->ptr, "scene"));
1677  TimeMarker *marker, *marker_new;
1678 
1679  if (scene_to == NULL) {
1680  BKE_report(op->reports, RPT_ERROR, "Scene not found");
1681  return OPERATOR_CANCELLED;
1682  }
1683 
1684  if (scene_to == CTX_data_scene(C)) {
1685  BKE_report(op->reports, RPT_ERROR, "Cannot re-link markers into the same scene");
1686  return OPERATOR_CANCELLED;
1687  }
1688 
1689  if (scene_to->toolsettings->lock_markers) {
1690  BKE_report(op->reports, RPT_ERROR, "Target scene has locked markers");
1691  return OPERATOR_CANCELLED;
1692  }
1693 
1694  /* copy markers */
1695  for (marker = markers->first; marker; marker = marker->next) {
1696  if (marker->flag & SELECT) {
1697  marker_new = MEM_dupallocN(marker);
1698  marker_new->prev = marker_new->next = NULL;
1699 
1700  BLI_addtail(&scene_to->markers, marker_new);
1701  }
1702  }
1703 
1704  return OPERATOR_FINISHED;
1705 }
1706 
1708 {
1709  PropertyRNA *prop;
1710 
1711  /* identifiers */
1712  ot->name = "Make Links to Scene";
1713  ot->description = "Copy selected markers to another scene";
1714  ot->idname = "MARKER_OT_make_links_scene";
1715 
1716  /* api callbacks */
1720 
1721  /* flags */
1723 
1724  /* properties */
1725  prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
1728  ot->prop = prop;
1729 }
1730 
1733 /* -------------------------------------------------------------------- */
1737 #ifdef DURIAN_CAMERA_SWITCH
1738 
1739 static int ed_marker_camera_bind_exec(bContext *C, wmOperator *op)
1740 {
1741  bScreen *screen = CTX_wm_screen(C);
1745  TimeMarker *marker;
1746 
1747  /* Don't do anything if we don't have a camera selected */
1748  if (ob == NULL) {
1749  BKE_report(op->reports, RPT_ERROR, "Select a camera to bind to a marker on this frame");
1750  return OPERATOR_CANCELLED;
1751  }
1752 
1753  /* add new marker, unless we already have one on this frame, in which case, replace it */
1754  if (markers == NULL) {
1755  return OPERATOR_CANCELLED;
1756  }
1757 
1759  if ((marker == NULL) || (marker->frame != scene->r.cfra)) {
1760  marker = MEM_callocN(sizeof(TimeMarker), "Camera TimeMarker");
1761  marker->flag = SELECT;
1762  marker->frame = scene->r.cfra;
1763  BLI_addtail(markers, marker);
1764 
1765  /* deselect all others, so that the user can then move it without problems */
1767  if (m != marker) {
1768  m->flag &= ~SELECT;
1769  }
1770  }
1771  }
1772 
1773  /* bind to the nominated camera (as set in operator props) */
1774  marker->camera = ob;
1775 
1776  /* camera may have changes */
1779 
1782  WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene); /* so we get view3d redraws */
1783 
1784  return OPERATOR_FINISHED;
1785 }
1786 
1787 static void MARKER_OT_camera_bind(wmOperatorType *ot)
1788 {
1789  /* identifiers */
1790  ot->name = "Bind Camera to Markers";
1791  ot->description = "Bind the selected camera to a marker on the current frame";
1792  ot->idname = "MARKER_OT_camera_bind";
1793 
1794  /* api callbacks */
1795  ot->exec = ed_marker_camera_bind_exec;
1797 
1798  /* flags */
1800 }
1801 
1802 #endif
1803 
1806 /* -------------------------------------------------------------------- */
1811 {
1822 #ifdef DURIAN_CAMERA_SWITCH
1823  WM_operatortype_append(MARKER_OT_camera_bind);
1824 #endif
1825 }
1826 
1828 {
1829  WM_keymap_ensure(keyconf, "Markers", 0, 0);
1830 }
1831 
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
@ CTX_MODE_OBJECT
Definition: BKE_context.h:118
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
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 SpaceLink * CTX_wm_space_data(const bContext *C)
Definition: context.c:743
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1282
enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
Definition: context.c:1228
void IDP_FreePropertyContent(struct IDProperty *prop)
Definition: idprop.c:1082
struct IDProperty * IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer)
Definition: layer.c:388
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:379
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
bool BKE_scene_camera_switch_update(struct Scene *scene)
Definition: scene.cc:2295
void BKE_screen_view3d_scene_sync(struct bScreen *screen, struct Scene *scene)
Definition: screen.c:994
@ B_UNIT_NONE
Definition: BKE_unit.h:100
@ B_UNIT_TIME
Definition: BKE_unit.h:106
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define ATTR_FALLTHROUGH
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:314
#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:318
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:340
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int round_fl_to_int(float a)
MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
bool BLI_rctf_isect_x(const rctf *rect, float x)
Definition: rct.c:92
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
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
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define TIP_(msgid)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SELECT
Definition: DNA_ID.h:818
@ SACTCONT_ACTION
@ SACTCONT_SHAPEKEY
@ SACTION_POSEMARKERS_SHOW
@ SACTION_SHOW_MARKERS
@ SACTION_DRAWTIME
Object is a sort of wrapper for general info.
@ OB_HIDE_RENDER
#define TIME2FRA(a)
#define FPS
#define FRA2TIME(a)
@ SPACE_ACTION
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_GRAPH
@ SIPO_MODE_DRIVERS
@ SIPO_DRAWTIME
@ SIPO_SHOW_MARKERS
@ SNLA_DRAWTIME
@ SNLA_SHOW_MARKERS
@ SEQ_DRAWFRAMES
@ SEQ_SHOW_MARKERS
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
@ DRAW_MARKERS_LOCAL
Definition: ED_markers.h:27
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:87
void initNumInput(NumInput *n)
Definition: numinput.c:69
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:13
@ NUM_NO_FRACTION
Definition: ED_numinput.h:58
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:189
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event)
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode)
Definition: object_select.c:76
void ED_object_base_activate(struct bContext *C, struct Base *base)
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:792
#define SEL_OP_USE_PRE_DESELECT(sel_op)
@ SEL_SELECT
@ SEL_INVERT
@ SEL_DESELECT
@ SEL_TOGGLE
eSelectOp
@ SEL_OP_SUB
@ TFM_TIME_TRANSLATE
Definition: ED_transform.h:50
@ TFM_TIME_SCALE
Definition: ED_transform.h:52
@ TFM_TIME_EXTEND
Definition: ED_transform.h:53
#define ACTIVE
Definition: ED_types.h:19
void apply_keyb_grid(bool shift, bool ctrl, float *val, float fac1, float fac2, float fac3, int invert)
Definition: ed_util.c:332
void immUniformColor4ubv(const unsigned char rgba[4])
void immUniform2f(const char *name, float x, float y)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniform1i(const char *name, int x)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat(void)
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:216
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:349
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_line_width(float width)
Definition: gpu_state.cc:158
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:259
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
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 or normal between camera
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
const EnumPropertyItem * RNA_scene_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free)
@ PROP_ENUM_NO_TRANSLATE
Definition: RNA_types.h:294
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
#define C
Definition: RandGen.cpp:25
void UI_fontstyle_draw_simple(const struct uiFontStyle *fs, float x, float y, const char *str, const uchar col[4])
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:91
#define UI_DPI_ICON_SIZE
Definition: UI_interface.h:307
#define UI_DPI_FAC
Definition: UI_interface.h:305
#define UI_FSTYLE_WIDGET
void UI_icon_draw(float x, float y, int icon_id)
@ TH_TIME_SCRUB_BACKGROUND
Definition: UI_resources.h:98
@ TH_TIME_MARKER_LINE
Definition: UI_resources.h:99
@ TH_TIME_MARKER_LINE_SELECTED
Definition: UI_resources.h:100
@ TH_TEXT
Definition: UI_resources.h:42
@ TH_TEXT_HI
Definition: UI_resources.h:43
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1352
void UI_view2d_scale_get(const struct View2D *v2d, float *r_x, float *r_y)
#define UI_MARKER_MARGIN_Y
Definition: UI_view2d.h:449
struct View2D * UI_view2d_fromcontext(const struct bContext *C)
void UI_view2d_region_to_view_rctf(const struct View2D *v2d, const struct rctf *rect_src, struct rctf *rect_dst) ATTR_NONNULL()
float UI_view2d_region_to_view_x(const struct View2D *v2d, float x)
Definition: view2d.cc:1655
float UI_view2d_scale_get_x(const struct View2D *v2d)
@ KM_PRESS
Definition: WM_types.h:267
@ OPTYPE_BLOCKING
Definition: WM_types.h:150
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
@ OPTYPE_GRAB_CURSOR_X
Definition: WM_types.h:156
#define NC_ANIMATION
Definition: WM_types.h:338
#define ND_OB_SELECT
Definition: WM_types.h:390
#define NC_SCENE
Definition: WM_types.h:328
#define NA_EDITED
Definition: WM_types.h:523
#define ND_MARKERS
Definition: WM_types.h:381
@ KM_CTRL
Definition: WM_types.h:239
@ KM_SHIFT
Definition: WM_types.h:238
#define ND_KEYFRAME
Definition: WM_types.h:442
#define NA_SELECTED
Definition: WM_types.h:528
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
Definition: anim_filter.c:379
static int ed_marker_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static ListBase * context_get_markers(Scene *scene, ScrArea *area)
Definition: anim_markers.c:64
static void ed_marker_duplicate_apply(bContext *C)
void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel)
Definition: anim_markers.c:296
void ED_keymap_marker(wmKeyConfig *keyconf)
static void ed_marker_move_update_header(bContext *C, wmOperator *op)
Definition: anim_markers.c:742
static void ed_marker_move_exit(bContext *C, wmOperator *op)
Definition: anim_markers.c:834
static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: anim_markers.c:925
static void marker_color_get(const TimeMarker *marker, uchar *r_text_color, uchar *r_line_color)
Definition: anim_markers.c:389
static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel)
Definition: anim_markers.c:261
static int ed_marker_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
eMarkers_LeftRightSelect_Mode
@ MARKERS_LRSEL_RIGHT
@ MARKERS_LRSEL_LEFT
static bool ED_operator_markers_region_active(bContext *C)
Definition: anim_markers.c:204
static int ed_marker_select_exec(bContext *C, wmOperator *op)
int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, float value, char side)
Definition: anim_markers.c:103
static void MARKER_OT_move(wmOperatorType *ot)
static int ed_marker_make_links_scene_exec(bContext *C, wmOperator *op)
static void select_marker_camera_switch(bContext *C, bool camera, bool extend, ListBase *markers, int cfra)
static void MARKER_OT_select_leftright(wmOperatorType *ot)
static void draw_markers_background(rctf *rect)
Definition: anim_markers.c:490
static void MARKER_OT_add(wmOperatorType *ot)
Definition: anim_markers.c:677
static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op))
static void draw_marker_line(const uchar *color, int xpos, int ymin, int ymax)
Definition: anim_markers.c:426
static int ed_marker_select_leftright_exec(bContext *C, wmOperator *op)
void ED_markers_get_minmax(ListBase *markers, short sel, float *r_first, float *r_last)
Definition: anim_markers.c:169
static const EnumPropertyItem prop_markers_select_leftright_modes[]
static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op))
Definition: anim_markers.c:642
static bool ed_markers_poll_selected_no_locked_markers(bContext *C)
Definition: anim_markers.c:608
static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
TimeMarker * ED_markers_get_first_selected(ListBase *markers)
Definition: anim_markers.c:344
static int ed_marker_rename_exec(bContext *C, wmOperator *op)
int ED_markers_find_nearest_marker_time(ListBase *markers, float x)
Definition: anim_markers.c:163
static void get_marker_region_rect(View2D *v2d, rctf *rect)
Definition: anim_markers.c:520
ListBase * ED_context_get_markers(const bContext *C)
Definition: anim_markers.c:88
static void deselect_markers(ListBase *markers)
static bool ed_markers_poll_selected_markers(bContext *C)
Definition: anim_markers.c:596
static bool ed_marker_move_init(bContext *C, wmOperator *op)
Definition: anim_markers.c:789
TimeMarker * ED_markers_find_nearest_marker(ListBase *markers, float x)
Definition: anim_markers.c:144
static void MARKER_OT_duplicate(wmOperatorType *ot)
static void ed_marker_move_apply(bContext *C, wmOperator *op)
Definition: anim_markers.c:884
struct MarkerMove MarkerMove
static void ED_markers_select_leftright(bAnimContext *ac, const eMarkers_LeftRightSelect_Mode mode, const bool extend)
static void draw_marker(const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int xpos, int flag, int region_height)
Definition: anim_markers.c:465
void ED_operatortypes_marker(void)
static void MARKER_OT_delete(wmOperatorType *ot)
static bool region_position_is_over_marker(View2D *v2d, ListBase *markers, float region_x)
Definition: anim_markers.c:244
static void MARKER_OT_select_all(wmOperatorType *ot)
static void MARKER_OT_rename(wmOperatorType *ot)
static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: anim_markers.c:847
static void MARKER_OT_make_links_scene(wmOperatorType *ot)
static void MARKER_OT_select(wmOperatorType *ot)
static void draw_marker_name(const uchar *text_color, const uiFontStyle *fstyle, TimeMarker *marker, float marker_x, float text_y)
Definition: anim_markers.c:401
static bool marker_is_in_frame_range(TimeMarker *marker, const int frame_range[2])
Definition: anim_markers.c:509
static bool ed_markers_poll_markers_exist(bContext *C)
Definition: anim_markers.c:622
static int ed_marker_box_select_exec(bContext *C, wmOperator *op)
static void MARKER_OT_select_box(wmOperatorType *ot)
static int ed_marker_move_exec(bContext *C, wmOperator *op)
static int ed_marker_select(bContext *C, const int mval[2], bool extend, bool camera, bool wait_to_deselect_others)
static bool ed_marker_move_use_time(MarkerMove *mm)
Definition: anim_markers.c:728
void ED_markers_deselect_all(ListBase *markers, int action)
Definition: anim_markers.c:320
ListBase * ED_animcontext_get_markers(const bAnimContext *ac)
Definition: anim_markers.c:93
static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void debug_markers_print_list(ListBase *markers)
Definition: anim_markers.c:361
static int select_timeline_marker_frame(ListBase *markers, int frame, bool extend, bool wait_to_deselect_others)
static int marker_get_icon_id(TimeMarker *marker, int flag)
Definition: anim_markers.c:450
static void ed_marker_move_cancel(bContext *C, wmOperator *op)
Definition: anim_markers.c:918
static void get_marker_clip_frame_range(View2D *v2d, float xscale, int r_range[2])
Definition: anim_markers.c:528
static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
void ED_markers_draw(const bContext *C, int flag)
Definition: anim_markers.c:535
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: avxb.h:154
#define SELECT
Scene scene
SyclQueue void void size_t num_bytes void
#define str(s)
uint pos
const vector< Marker > & markers
format
Definition: logImageCore.h:38
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
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned a[3]
Definition: RandGen.cpp:78
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:4921
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:5116
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3687
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3830
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
const EnumPropertyItem DummyRNA_NULL_items[]
Definition: rna_rna.c:26
#define min(a, b)
Definition: sort.c:35
float cfra
Definition: BKE_fcurve.h:40
struct CfraElem * next
Definition: BKE_fcurve.h:39
int sel
Definition: BKE_fcurve.h:41
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
short event_type
Definition: anim_markers.c:723
NumInput num
Definition: anim_markers.c:725
short event_val
Definition: anim_markers.c:723
SpaceLink * slink
Definition: anim_markers.c:721
int * oldframe
Definition: anim_markers.c:724
ListBase * markers
Definition: anim_markers.c:722
short idx_max
Definition: ED_numinput.h:20
short val_flag[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:29
int unit_sys
Definition: ED_numinput.h:21
int unit_type[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:23
struct ToolSettings * toolsettings
struct RenderData r
struct UnitSettings unit
struct Object * camera
ListBase markers
bAction * action
char name[64]
struct TimeMarker * prev
struct IDProperty * prop
struct Object * camera
unsigned int flag
struct TimeMarker * next
ListBase markers
ListBase * markers
Definition: ED_anim_api.h:92
struct Scene * scene
Definition: ED_anim_api.h:84
struct ScrArea * area
Definition: ED_anim_api.h:72
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
int xmin
Definition: DNA_vec_types.h:63
short val
Definition: WM_types.h:680
int xy[2]
Definition: WM_types.h:682
uint8_t modifier
Definition: WM_types.h:693
short type
Definition: WM_types.h:678
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
PropertyRNA * prop
Definition: WM_types.h:981
struct ReportList * reports
struct PointerRNA * ptr
float max
bool WM_event_is_modal_drag_exit(const wmEvent *event, const short init_event_type, const short init_event_val)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ EVT_PADENTER
@ MOUSEMOVE
@ LEFTMOUSE
@ MIDDLEMOUSE
@ EVT_ESCKEY
@ EVT_RETKEY
wmOperatorType * ot
Definition: wm_files.c:3479
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:852
void WM_operator_properties_gesture_box(wmOperatorType *ot)
void WM_operator_properties_confirm_or_exec(wmOperatorType *ot)
void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
void WM_operator_properties_generic_select(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
void WM_operator_properties_border_to_rctf(struct wmOperator *op, rctf *rect)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
int WM_operator_confirm_or_exec(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
int WM_operator_props_popup_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
int WM_generic_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: wm_operators.c:962
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: wm_operators.c:903