Blender  V2.93
anim_markers.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 
31 #include "BLI_blenlib.h"
32 #include "BLI_math.h"
33 #include "BLI_utildefines.h"
34 
35 #include "BLT_translation.h"
36 
37 #include "BKE_context.h"
38 #include "BKE_fcurve.h"
39 #include "BKE_idprop.h"
40 #include "BKE_layer.h"
41 #include "BKE_main.h"
42 #include "BKE_report.h"
43 #include "BKE_scene.h"
44 #include "BKE_screen.h"
45 #include "BKE_unit.h"
46 
47 #include "RNA_access.h"
48 #include "RNA_define.h"
49 #include "RNA_enum_types.h"
50 
51 #include "WM_api.h"
52 #include "WM_types.h"
53 
54 #include "GPU_immediate.h"
55 #include "GPU_matrix.h"
56 #include "GPU_state.h"
57 
58 #include "UI_interface.h"
59 #include "UI_interface_icons.h"
60 #include "UI_resources.h"
61 #include "UI_view2d.h"
62 
63 #include "ED_anim_api.h"
64 #include "ED_markers.h"
65 #include "ED_numinput.h"
66 #include "ED_object.h"
67 #include "ED_screen.h"
68 #include "ED_select_utils.h"
69 #include "ED_transform.h"
70 #include "ED_types.h"
71 #include "ED_util.h"
72 
73 #include "DEG_depsgraph.h"
74 
75 /* ************* Marker API **************** */
76 
77 /* helper function for getting the list of markers to work on */
79 {
80  /* local marker sets... */
81  if (area) {
82  if (area->spacetype == SPACE_ACTION) {
83  SpaceAction *saction = (SpaceAction *)area->spacedata.first;
84 
85  /* local markers can only be shown when there's only a single active action to grab them from
86  * - flag only takes effect when there's an action, otherwise it can get too confusing?
87  */
88  if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) && (saction->action)) {
89  if (saction->flag & SACTION_POSEMARKERS_SHOW) {
90  return &saction->action->markers;
91  }
92  }
93  }
94  }
95 
96  /* default to using the scene's markers */
97  return &scene->markers;
98 }
99 
100 /* ............. */
101 
102 /* public API for getting markers from context */
104 {
106 }
107 
108 /* public API for getting markers from "animation" context */
110 {
111  if (ac) {
112  return context_get_markers(ac->scene, ac->area);
113  }
114  return NULL;
115 }
116 
117 /* --------------------------------- */
118 
131  ListBase *markers, Scene *scene, int mode, float value, char side)
132 {
133  TimeMarker *marker;
134  float cfra = (float)CFRA;
135  int changed_tot = 0;
136 
137  /* sanity check - no markers, or locked markers */
138  if ((scene->toolsettings->lock_markers) || (markers == NULL)) {
139  return changed_tot;
140  }
141 
142  /* affect selected markers - it's unlikely that we will want to affect all in this way? */
143  for (marker = markers->first; marker; marker = marker->next) {
144  if (marker->flag & SELECT) {
145  switch (mode) {
146  case TFM_TIME_TRANSLATE:
147  case TFM_TIME_EXTEND: {
148  /* apply delta if marker is on the right side of the current frame */
149  if ((side == 'B') || (side == 'L' && marker->frame < cfra) ||
150  (side == 'R' && marker->frame >= cfra)) {
151  marker->frame += round_fl_to_int(value);
152  changed_tot++;
153  }
154  break;
155  }
156  case TFM_TIME_SCALE: {
157  /* rescale the distance between the marker and the current frame */
158  marker->frame = cfra + round_fl_to_int((float)(marker->frame - cfra) * value);
159  changed_tot++;
160  break;
161  }
162  }
163  }
164  }
165 
166  return changed_tot;
167 }
168 
169 /* --------------------------------- */
170 
171 /* Get the marker that is closest to this point */
172 /* XXX for select, the min_dist should be small */
174 {
175  TimeMarker *marker, *nearest = NULL;
176  float dist, min_dist = 1000000;
177 
178  if (markers) {
179  for (marker = markers->first; marker; marker = marker->next) {
180  dist = fabsf((float)marker->frame - x);
181 
182  if (dist < min_dist) {
183  min_dist = dist;
184  nearest = marker;
185  }
186  }
187  }
188 
189  return nearest;
190 }
191 
192 /* Return the time of the marker that occurs on a frame closest to the given time */
194 {
196  return (nearest) ? (nearest->frame) : round_fl_to_int(x);
197 }
198 
199 void ED_markers_get_minmax(ListBase *markers, short sel, float *r_first, float *r_last)
200 {
201  TimeMarker *marker;
202  float min, max;
203 
204  /* sanity check */
205  // printf("markers = %p - %p, %p\n", markers, markers->first, markers->last);
206  if (ELEM(NULL, markers, markers->first, markers->last)) {
207  *r_first = 0.0f;
208  *r_last = 0.0f;
209  return;
210  }
211 
212  min = FLT_MAX;
213  max = -FLT_MAX;
214  for (marker = markers->first; marker; marker = marker->next) {
215  if (!sel || (marker->flag & SELECT)) {
216  if (marker->frame < min) {
217  min = (float)marker->frame;
218  }
219  if (marker->frame > max) {
220  max = (float)marker->frame;
221  }
222  }
223  }
224 
225  /* set the min/max values */
226  *r_first = min;
227  *r_last = max;
228 }
229 
235 {
237  if (area == NULL) {
238  return false;
239  }
240 
241  switch (area->spacetype) {
242  case SPACE_ACTION: {
243  SpaceAction *saction = area->spacedata.first;
244  if (saction->flag & SACTION_SHOW_MARKERS) {
245  return true;
246  }
247  break;
248  }
249  case SPACE_GRAPH: {
250  SpaceGraph *sipo = area->spacedata.first;
251  if (sipo->mode != SIPO_MODE_DRIVERS && sipo->flag & SIPO_SHOW_MARKERS) {
252  return true;
253  }
254  break;
255  }
256  case SPACE_NLA: {
257  SpaceNla *snla = area->spacedata.first;
258  if (snla->flag & SNLA_SHOW_MARKERS) {
259  return true;
260  }
261  break;
262  }
263  case SPACE_SEQ: {
264  SpaceSeq *seq = area->spacedata.first;
265  if (seq->flag & SEQ_SHOW_MARKERS) {
266  return true;
267  }
268  break;
269  }
270  }
271  return false;
272 }
273 
274 static bool region_position_is_over_marker(View2D *v2d, ListBase *markers, float region_x)
275 {
277  return false;
278  }
279 
280  float frame_at_position = UI_view2d_region_to_view_x(v2d, region_x);
281  TimeMarker *nearest_marker = ED_markers_find_nearest_marker(markers, frame_at_position);
282  float pixel_distance = UI_view2d_scale_get_x(v2d) *
283  fabsf(nearest_marker->frame - frame_at_position);
284 
285  return pixel_distance <= UI_DPI_ICON_SIZE;
286 }
287 
288 /* --------------------------------- */
289 
290 /* Adds a marker to list of cfra elems */
291 static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel)
292 {
293  CfraElem *ce, *cen;
294 
295  /* should this one only be considered if it is selected? */
296  if ((only_sel) && ((marker->flag & SELECT) == 0)) {
297  return;
298  }
299 
300  /* insertion sort - try to find a previous cfra elem */
301  for (ce = lb->first; ce; ce = ce->next) {
302  if (ce->cfra == marker->frame) {
303  /* do because of double keys */
304  if (marker->flag & SELECT) {
305  ce->sel = marker->flag;
306  }
307  return;
308  }
309  if (ce->cfra > marker->frame) {
310  break;
311  }
312  }
313 
314  cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
315  if (ce) {
316  BLI_insertlinkbefore(lb, ce, cen);
317  }
318  else {
319  BLI_addtail(lb, cen);
320  }
321 
322  cen->cfra = marker->frame;
323  cen->sel = marker->flag;
324 }
325 
326 /* This function makes a list of all the markers. The only_sel
327  * argument is used to specify whether only the selected markers
328  * are added.
329  */
331 {
332  TimeMarker *marker;
333 
334  if (lb) {
335  /* Clear the list first, since callers have no way of knowing
336  * whether this terminated early otherwise. This may lead
337  * to crashes if the user didn't clear the memory first.
338  */
339  lb->first = lb->last = NULL;
340  }
341  else {
342  return;
343  }
344 
345  if (markers == NULL) {
346  return;
347  }
348 
349  for (marker = markers->first; marker; marker = marker->next) {
350  add_marker_to_cfra_elem(lb, marker, only_sel);
351  }
352 }
353 
355 {
356  if (action == SEL_TOGGLE) {
358  }
359 
360  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
361  if (action == SEL_SELECT) {
362  marker->flag |= SELECT;
363  }
364  else if (action == SEL_DESELECT) {
365  marker->flag &= ~SELECT;
366  }
367  else if (action == SEL_INVERT) {
368  marker->flag ^= SELECT;
369  }
370  else {
371  BLI_assert(0);
372  }
373  }
374 }
375 
376 /* --------------------------------- */
377 
378 /* Get the first selected marker */
380 {
381  TimeMarker *marker;
382 
383  if (markers) {
384  for (marker = markers->first; marker; marker = marker->next) {
385  if (marker->flag & SELECT) {
386  return marker;
387  }
388  }
389  }
390 
391  return NULL;
392 }
393 
394 /* --------------------------------- */
395 
396 /* Print debugging prints of list of markers
397  * BSI's: do NOT make static or put in if-defs as "unused code".
398  * That's too much trouble when we need to use for quick debugging!
399  */
401 {
402  TimeMarker *marker;
403 
404  if (markers == NULL) {
405  printf("No markers list to print debug for\n");
406  return;
407  }
408 
409  printf("List of markers follows: -----\n");
410 
411  for (marker = markers->first; marker; marker = marker->next) {
412  printf(
413  "\t'%s' on %d at %p with %u\n", marker->name, marker->frame, (void *)marker, marker->flag);
414  }
415 
416  printf("End of list ------------------\n");
417 }
418 
419 /* ************* Marker Drawing ************ */
420 
421 static void marker_color_get(const TimeMarker *marker, uchar *r_text_color, uchar *r_line_color)
422 {
423  if (marker->flag & SELECT) {
424  UI_GetThemeColor4ubv(TH_TEXT_HI, r_text_color);
426  }
427  else {
428  UI_GetThemeColor4ubv(TH_TEXT, r_text_color);
430  }
431 }
432 
433 static void draw_marker_name(const uchar *text_color,
434  const uiFontStyle *fstyle,
435  TimeMarker *marker,
436  float marker_x,
437  float text_y)
438 {
439  const char *name = marker->name;
440  uchar final_text_color[4];
441 
442  copy_v4_v4_uchar(final_text_color, text_color);
443 
444 #ifdef DURIAN_CAMERA_SWITCH
445  if (marker->camera) {
446  Object *camera = marker->camera;
447  name = camera->id.name + 2;
448  if (camera->restrictflag & OB_RESTRICT_RENDER) {
449  final_text_color[3] = 100;
450  }
451  }
452 #endif
453 
454  int name_x = marker_x + UI_DPI_ICON_SIZE * 0.6;
455  UI_fontstyle_draw_simple(fstyle, name_x, text_y, name, final_text_color);
456 }
457 
458 static void draw_marker_line(const uchar *color, int xpos, int ymin, int ymax)
459 {
462 
464 
465  float viewport_size[4];
466  GPU_viewport_size_get_f(viewport_size);
467  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
468 
469  immUniformColor4ubv(color);
470  immUniform1i("colors_len", 0); /* "simple" mode */
471  immUniform1f("dash_width", 6.0f);
472  immUniform1f("dash_factor", 0.5f);
473 
475  immVertex2f(pos, xpos, ymin);
476  immVertex2f(pos, xpos, ymax);
477  immEnd();
478 
480 }
481 
482 static int marker_get_icon_id(TimeMarker *marker, int flag)
483 {
484  if (flag & DRAW_MARKERS_LOCAL) {
485  return (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
486  (marker->flag & SELECT) ? ICON_PMARKER_SEL : ICON_PMARKER;
487  }
488 #ifdef DURIAN_CAMERA_SWITCH
489  if (marker->camera) {
490  return (marker->flag & SELECT) ? ICON_OUTLINER_OB_CAMERA : ICON_CAMERA_DATA;
491  }
492 #endif
493  return (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER;
494 }
495 
496 static void draw_marker(
497  const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int xpos, int flag, int region_height)
498 {
499  uchar line_color[4], text_color[4];
500 
501  marker_color_get(marker, text_color, line_color);
502 
504 
505  draw_marker_line(line_color, xpos, UI_DPI_FAC * 20, region_height);
506 
507  int icon_id = marker_get_icon_id(marker, flag);
508  UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, UI_DPI_FAC * 18, icon_id);
509 
511 
512  float name_y = UI_DPI_FAC * 18;
513  /* Give an offset to the marker name when selected,
514  * or when near the current frame (5 frames range, starting from the current one). */
515  if ((marker->flag & SELECT) || (cfra - 4 <= marker->frame && marker->frame <= cfra)) {
516  name_y += UI_DPI_FAC * 10;
517  }
518  draw_marker_name(text_color, fstyle, marker, xpos, name_y);
519 }
520 
521 static void draw_markers_background(rctf *rect)
522 {
525 
526  uchar shade[4];
528 
529  immUniformColor4ubv(shade);
530 
532 
533  immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
534 
536 
538 }
539 
540 static bool marker_is_in_frame_range(TimeMarker *marker, const int frame_range[2])
541 {
542  if (marker->frame < frame_range[0]) {
543  return false;
544  }
545  if (marker->frame > frame_range[1]) {
546  return false;
547  }
548  return true;
549 }
550 
551 static void get_marker_region_rect(View2D *v2d, rctf *rect)
552 {
553  rect->xmin = v2d->cur.xmin;
554  rect->xmax = v2d->cur.xmax;
555  rect->ymin = 0;
556  rect->ymax = UI_MARKER_MARGIN_Y;
557 }
558 
559 static void get_marker_clip_frame_range(View2D *v2d, float xscale, int r_range[2])
560 {
561  float font_width_max = (10 * UI_DPI_FAC) / xscale;
562  r_range[0] = v2d->cur.xmin - sizeof(((TimeMarker *)NULL)->name) * font_width_max;
563  r_range[1] = v2d->cur.xmax + font_width_max;
564 }
565 
566 /* Draw Scene-Markers in time window */
567 void ED_markers_draw(const bContext *C, int flag)
568 {
571  return;
572  }
573 
574  ARegion *region = CTX_wm_region(C);
576  int cfra = CTX_data_scene(C)->r.cfra;
577 
578  rctf markers_region_rect;
579  get_marker_region_rect(v2d, &markers_region_rect);
580 
581  draw_markers_background(&markers_region_rect);
582 
583  /* no time correction for framelen! space is drawn with old values */
584  float xscale, dummy;
585  UI_view2d_scale_get(v2d, &xscale, &dummy);
586  GPU_matrix_push();
587  GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
588 
589  int clip_frame_range[2];
590  get_marker_clip_frame_range(v2d, xscale, clip_frame_range);
591 
592  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
593 
594  /* Separate loops in order to draw selected markers on top */
595  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
596  if ((marker->flag & SELECT) == 0) {
597  if (marker_is_in_frame_range(marker, clip_frame_range)) {
598  draw_marker(fstyle, marker, cfra, marker->frame * xscale, flag, region->winy);
599  }
600  }
601  }
602  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
603  if (marker->flag & SELECT) {
604  if (marker_is_in_frame_range(marker, clip_frame_range)) {
605  draw_marker(fstyle, marker, cfra, marker->frame * xscale, flag, region->winy);
606  }
607  }
608  }
609 
610  GPU_matrix_pop();
611 }
612 
613 /* ************************ Marker Wrappers API ********************* */
614 /* These wrappers allow marker operators to function within the confines
615  * of standard animation editors, such that they can coexist with the
616  * primary operations of those editors.
617  */
618 
619 /* ------------------------ */
620 
621 /* special poll() which checks if there are selected markers first */
623 {
625 
627  return 0;
628  }
629 
630  /* check if some marker is selected */
632 }
633 
635 {
638 
640  return 0;
641  }
642 
643  /* check if some marker is selected */
645 }
646 
647 /* special poll() which checks if there are any markers at all first */
649 {
652 
654  return 0;
655  }
656 
657  /* list of markers must exist, as well as some markers in it! */
658  return (markers && markers->first);
659 }
660 
661 /* ************************** add markers *************************** */
662 
663 /* add TimeMarker at current frame */
665 {
667  TimeMarker *marker;
668  int frame = CTX_data_scene(C)->r.cfra;
669 
670  if (markers == NULL) {
671  return OPERATOR_CANCELLED;
672  }
673 
674  /* prefer not having 2 markers at the same place,
675  * though the user can move them to overlap once added */
676  for (marker = markers->first; marker; marker = marker->next) {
677  if (marker->frame == frame) {
678  return OPERATOR_CANCELLED;
679  }
680  }
681 
682  /* deselect all */
683  for (marker = markers->first; marker; marker = marker->next) {
684  marker->flag &= ~SELECT;
685  }
686 
687  marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
688  marker->flag = SELECT;
689  marker->frame = frame;
690  BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); /* XXX - temp code only */
691  BLI_addtail(markers, marker);
692 
695 
696  return OPERATOR_FINISHED;
697 }
698 
700 {
701  /* identifiers */
702  ot->name = "Add Time Marker";
703  ot->description = "Add a new time marker";
704  ot->idname = "MARKER_OT_add";
705 
706  /* api callbacks */
709 
710  /* flags */
712 }
713 
714 /* ************************** transform markers *************************** */
715 
716 /* operator state vars used:
717  * frs: delta movement
718  *
719  * functions:
720  *
721  * init() check selection, add customdata with old values and some lookups
722  *
723  * apply() do the actual movement
724  *
725  * exit() cleanup, send notifier
726  *
727  * cancel() to escape from modal
728  *
729  * callbacks:
730  *
731  * exec() calls init, apply, exit
732  *
733  * invoke() calls init, adds modal handler
734  *
735  * modal() accept modal events while doing it, ends with apply and exit, or cancel
736  */
737 
738 typedef struct MarkerMove {
741  int event_type; /* store invoke-event, to verify */
745 
747 {
748  if (((mm->slink->spacetype == SPACE_SEQ) && !(((SpaceSeq *)mm->slink)->flag & SEQ_DRAWFRAMES)) ||
749  ((mm->slink->spacetype == SPACE_ACTION) &&
750  (((SpaceAction *)mm->slink)->flag & SACTION_DRAWTIME)) ||
751  ((mm->slink->spacetype == SPACE_GRAPH) &&
752  (((SpaceGraph *)mm->slink)->flag & SIPO_DRAWTIME)) ||
753  ((mm->slink->spacetype == SPACE_NLA) && (((SpaceNla *)mm->slink)->flag & SNLA_DRAWTIME))) {
754  return true;
755  }
756 
757  return false;
758 }
759 
761 {
763  MarkerMove *mm = op->customdata;
764  TimeMarker *marker, *selmarker = NULL;
765  const int ofs = RNA_int_get(op->ptr, "frames");
766  char str[UI_MAX_DRAW_STR];
767  char str_ofs[NUM_STR_REP_LEN];
768  int totmark;
769  const bool use_time = ed_marker_move_use_time(mm);
770 
771  for (totmark = 0, marker = mm->markers->first; marker; marker = marker->next) {
772  if (marker->flag & SELECT) {
773  selmarker = marker;
774  totmark++;
775  }
776  }
777 
778  if (hasNumInput(&mm->num)) {
779  outputNumInput(&mm->num, str_ofs, &scene->unit);
780  }
781  else if (use_time) {
782  BLI_snprintf(str_ofs, sizeof(str_ofs), "%.2f", FRA2TIME(ofs));
783  }
784  else {
785  BLI_snprintf(str_ofs, sizeof(str_ofs), "%d", ofs);
786  }
787 
788  if (totmark == 1 && selmarker) {
789  /* we print current marker value */
790  if (use_time) {
791  BLI_snprintf(
792  str, sizeof(str), TIP_("Marker %.2f offset %s"), FRA2TIME(selmarker->frame), str_ofs);
793  }
794  else {
795  BLI_snprintf(str, sizeof(str), TIP_("Marker %d offset %s"), selmarker->frame, str_ofs);
796  }
797  }
798  else {
799  BLI_snprintf(str, sizeof(str), TIP_("Marker offset %s"), str_ofs);
800  }
801 
803 }
804 
805 /* copy selection to temp buffer */
806 /* return 0 if not OK */
808 {
811  MarkerMove *mm;
812  TimeMarker *marker;
813  int a, totmark;
814 
815  if (markers == NULL) {
816  return false;
817  }
818 
819  for (totmark = 0, marker = markers->first; marker; marker = marker->next) {
820  if (marker->flag & SELECT) {
821  totmark++;
822  }
823  }
824 
825  if (totmark == 0) {
826  return false;
827  }
828 
829  op->customdata = mm = MEM_callocN(sizeof(MarkerMove), "Markermove");
830  mm->slink = CTX_wm_space_data(C);
831  mm->markers = markers;
832  mm->oldframe = MEM_callocN(totmark * sizeof(int), "MarkerMove oldframe");
833 
834  initNumInput(&mm->num);
835  mm->num.idx_max = 0; /* one axis */
836  mm->num.val_flag[0] |= NUM_NO_FRACTION;
837  mm->num.unit_sys = scene->unit.system;
838  /* No time unit supporting frames currently... */
840 
841  for (a = 0, marker = markers->first; marker; marker = marker->next) {
842  if (marker->flag & SELECT) {
843  mm->oldframe[a] = marker->frame;
844  a++;
845  }
846  }
847 
848  return true;
849 }
850 
851 /* free stuff */
853 {
854  MarkerMove *mm = op->customdata;
855 
856  /* free data */
857  MEM_freeN(mm->oldframe);
858  MEM_freeN(op->customdata);
859  op->customdata = NULL;
860 
861  /* clear custom header prints */
863 }
864 
865 static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
866 {
867  const bool tweak = RNA_struct_find_property(op->ptr, "tweak") &&
868  RNA_boolean_get(op->ptr, "tweak");
869 
870  if (tweak) {
871  ARegion *region = CTX_wm_region(C);
872  View2D *v2d = &region->v2d;
874  if (!region_position_is_over_marker(v2d, markers, event->x - region->winrct.xmin)) {
876  }
877  }
878 
879  if (ed_marker_move_init(C, op)) {
880  MarkerMove *mm = op->customdata;
881 
882  mm->evtx = event->x;
883  mm->firstx = event->x;
884  mm->event_type = event->type;
885 
886  /* add temp handler */
888 
889  /* reset frs delta */
890  RNA_int_set(op->ptr, "frames", 0);
891 
893 
894  return OPERATOR_RUNNING_MODAL;
895  }
896 
897  return OPERATOR_CANCELLED;
898 }
899 
900 /* note, init has to be called successfully */
902 {
903 #ifdef DURIAN_CAMERA_SWITCH
904  bScreen *screen = CTX_wm_screen(C);
906  Object *camera = scene->camera;
907 #endif
908  MarkerMove *mm = op->customdata;
909  TimeMarker *marker;
910  int a, ofs;
911 
912  ofs = RNA_int_get(op->ptr, "frames");
913  for (a = 0, marker = mm->markers->first; marker; marker = marker->next) {
914  if (marker->flag & SELECT) {
915  marker->frame = mm->oldframe[a] + ofs;
916  a++;
917  }
918  }
919 
922 
923 #ifdef DURIAN_CAMERA_SWITCH
924  /* so we get view3d redraws */
926 
927  if (camera != scene->camera) {
930  }
931 #endif
932 }
933 
934 /* only for modal */
936 {
937  RNA_int_set(op->ptr, "frames", 0);
938  ed_marker_move_apply(C, op);
939  ed_marker_move_exit(C, op);
940 }
941 
942 static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
943 {
945  MarkerMove *mm = op->customdata;
947  const bool has_numinput = hasNumInput(&mm->num);
948  const bool use_time = ed_marker_move_use_time(mm);
949 
950  /* Modal numinput active, try to handle numeric inputs first... */
951  if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &mm->num, event)) {
952  float value = (float)RNA_int_get(op->ptr, "frames");
953 
954  applyNumInput(&mm->num, &value);
955  if (use_time) {
956  value = TIME2FRA(value);
957  }
958 
959  RNA_int_set(op->ptr, "frames", (int)value);
960  ed_marker_move_apply(C, op);
962  }
963  else {
964  bool handled = false;
965  switch (event->type) {
966  case EVT_ESCKEY:
968  return OPERATOR_CANCELLED;
969  case RIGHTMOUSE:
970  /* press = user manually demands transform to be canceled */
971  if (event->val == KM_PRESS) {
973  return OPERATOR_CANCELLED;
974  }
975  /* else continue; <--- see if release event should be caught for tweak-end */
977 
978  case EVT_RETKEY:
979  case EVT_PADENTER:
980  case LEFTMOUSE:
981  case MIDDLEMOUSE:
982  if (WM_event_is_modal_tweak_exit(event, mm->event_type)) {
983  ed_marker_move_exit(C, op);
986  return OPERATOR_FINISHED;
987  }
988  break;
989  case MOUSEMOVE:
990  if (!has_numinput) {
991  float dx;
992 
993  dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
994 
995  if (event->x != mm->evtx) { /* XXX maybe init for first time */
996  float fac;
997 
998  mm->evtx = event->x;
999  fac = ((float)(event->x - mm->firstx) * dx);
1000 
1001  apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
1002 
1003  RNA_int_set(op->ptr, "frames", (int)fac);
1004  ed_marker_move_apply(C, op);
1006  }
1007  }
1008  break;
1009  }
1010 
1011  if (!handled && event->val == KM_PRESS && handleNumInput(C, &mm->num, event)) {
1012  float value = (float)RNA_int_get(op->ptr, "frames");
1013 
1014  applyNumInput(&mm->num, &value);
1015  if (use_time) {
1016  value = TIME2FRA(value);
1017  }
1018 
1019  RNA_int_set(op->ptr, "frames", (int)value);
1020  ed_marker_move_apply(C, op);
1022  }
1023  }
1024 
1025  return OPERATOR_RUNNING_MODAL;
1026 }
1027 
1029 {
1030  if (ed_marker_move_init(C, op)) {
1031  ed_marker_move_apply(C, op);
1032  ed_marker_move_exit(C, op);
1033  return OPERATOR_FINISHED;
1034  }
1035  return OPERATOR_PASS_THROUGH;
1036 }
1037 
1039 {
1040  /* identifiers */
1041  ot->name = "Move Time Marker";
1042  ot->description = "Move selected time marker(s)";
1043  ot->idname = "MARKER_OT_move";
1044 
1045  /* api callbacks */
1051 
1052  /* flags */
1054 
1055  /* rna storage */
1056  RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
1057  PropertyRNA *prop = RNA_def_boolean(
1058  ot->srna, "tweak", 0, "Tweak", "Operator has been activated using a tweak event");
1060 }
1061 
1062 /* ************************** duplicate markers *************************** */
1063 
1064 /* operator state vars used:
1065  * frs: delta movement
1066  *
1067  * functions:
1068  *
1069  * apply() do the actual duplicate
1070  *
1071  * callbacks:
1072  *
1073  * exec() calls apply, move_exec
1074  *
1075  * invoke() calls apply, move_invoke
1076  *
1077  * modal() uses move_modal
1078  */
1079 
1080 /* duplicate selected TimeMarkers */
1082 {
1084  TimeMarker *marker, *newmarker;
1085 
1086  if (markers == NULL) {
1087  return;
1088  }
1089 
1090  /* go through the list of markers, duplicate selected markers and add duplicated copies
1091  * to the beginning of the list (unselect original markers)
1092  */
1093  for (marker = markers->first; marker; marker = marker->next) {
1094  if (marker->flag & SELECT) {
1095  /* unselect selected marker */
1096  marker->flag &= ~SELECT;
1097 
1098  /* create and set up new marker */
1099  newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
1100  newmarker->flag = SELECT;
1101  newmarker->frame = marker->frame;
1102  BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
1103 
1104 #ifdef DURIAN_CAMERA_SWITCH
1105  newmarker->camera = marker->camera;
1106 #endif
1107 
1108  if (marker->prop != NULL) {
1109  newmarker->prop = IDP_CopyProperty(marker->prop);
1110  }
1111 
1112  /* new marker is added to the beginning of list */
1113  /* FIXME: bad ordering! */
1114  BLI_addhead(markers, newmarker);
1115  }
1116  }
1117 }
1118 
1120 {
1122  ed_marker_move_exec(C, op); /* assumes frs delta set */
1123 
1124  return OPERATOR_FINISHED;
1125 }
1126 
1127 static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1128 {
1130  return ed_marker_move_invoke(C, op, event);
1131 }
1132 
1134 {
1135  /* identifiers */
1136  ot->name = "Duplicate Time Marker";
1137  ot->description = "Duplicate selected time marker(s)";
1138  ot->idname = "MARKER_OT_duplicate";
1139 
1140  /* api callbacks */
1146 
1147  /* flags */
1149 
1150  /* rna storage */
1151  RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
1152 }
1153 
1154 /* ************************** selection ************************************/
1155 
1157 {
1158  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
1159  marker->flag &= ~SELECT;
1160  }
1161 }
1162 
1163 /* select/deselect TimeMarker at current frame */
1165  int frame,
1166  bool extend,
1167  bool wait_to_deselect_others)
1168 {
1169  TimeMarker *marker, *marker_selected = NULL;
1170  int ret_val = OPERATOR_FINISHED;
1171 
1172  if (extend) {
1173  wait_to_deselect_others = false;
1174  }
1175 
1176  /* support for selection cycling */
1177  for (marker = markers->first; marker; marker = marker->next) {
1178  if (marker->frame == frame) {
1179  if (marker->flag & SELECT) {
1180  marker_selected = marker->next;
1181  break;
1182  }
1183  }
1184  }
1185 
1186  if (wait_to_deselect_others && marker_selected) {
1187  ret_val = OPERATOR_RUNNING_MODAL;
1188  }
1189  /* if extend is not set, then deselect markers */
1190  else {
1191  if (extend == false) {
1193  }
1194 
1195  LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_selected) {
1196  /* this way a not-extend select will always give 1 selected marker */
1197  if (marker->frame == frame) {
1198  marker->flag ^= SELECT;
1199  break;
1200  }
1201  }
1202  LISTBASE_CIRCULAR_FORWARD_END(markers, marker, marker_selected);
1203  }
1204 
1205  return ret_val;
1206 }
1207 
1209  bContext *C, bool camera, bool extend, ListBase *markers, int cfra)
1210 {
1211 #ifdef DURIAN_CAMERA_SWITCH
1212  if (camera) {
1215  ViewLayer *view_layer = CTX_data_view_layer(C);
1216  Base *base;
1217  TimeMarker *marker;
1218  int sel = 0;
1219 
1220  if (!extend) {
1222  }
1223 
1224  for (marker = markers->first; marker; marker = marker->next) {
1225  if (marker->frame == cfra) {
1226  sel = (marker->flag & SELECT);
1227  break;
1228  }
1229  }
1230 
1231  for (marker = markers->first; marker; marker = marker->next) {
1232  if (marker->camera) {
1233  if (marker->frame == cfra) {
1234  base = BKE_view_layer_base_find(view_layer, marker->camera);
1235  if (base) {
1236  ED_object_base_select(base, sel);
1237  if (sel) {
1238  ED_object_base_activate(C, base);
1239  }
1240  }
1241  }
1242  }
1243  }
1244 
1247  }
1248 #else
1249  (void)camera;
1250 #endif
1251 }
1252 
1253 static int ed_marker_select(
1254  bContext *C, const int mval[2], bool extend, bool camera, bool wait_to_deselect_others)
1255 {
1257  View2D *v2d = UI_view2d_fromcontext(C);
1258  int ret_val = OPERATOR_FINISHED;
1259 
1260  if (region_position_is_over_marker(v2d, markers, mval[0])) {
1261  float frame_at_mouse_position = UI_view2d_region_to_view_x(v2d, mval[0]);
1262  int cfra = ED_markers_find_nearest_marker_time(markers, frame_at_mouse_position);
1263  ret_val = select_timeline_marker_frame(markers, cfra, extend, wait_to_deselect_others);
1264 
1265  select_marker_camera_switch(C, camera, extend, markers, cfra);
1266  }
1267  else {
1269  }
1270 
1273 
1274  /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails, see T25987. */
1275  return ret_val | OPERATOR_PASS_THROUGH;
1276 }
1277 
1279 {
1280  const bool extend = RNA_boolean_get(op->ptr, "extend");
1281  const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
1282  bool camera = false;
1283 #ifdef DURIAN_CAMERA_SWITCH
1284  camera = RNA_boolean_get(op->ptr, "camera");
1285  if (camera) {
1286  /* Supporting mode switching from this operator doesn't seem so useful.
1287  * So only allow setting the active camera in object-mode. */
1289  BKE_report(
1290  op->reports, RPT_WARNING, "Selecting the camera is only supported in object mode");
1291  camera = false;
1292  }
1293  }
1294 #endif
1295  int mval[2];
1296  mval[0] = RNA_int_get(op->ptr, "mouse_x");
1297  mval[1] = RNA_int_get(op->ptr, "mouse_y");
1298 
1299  return ed_marker_select(C, mval, extend, camera, wait_to_deselect_others);
1300 }
1301 
1303 {
1304  PropertyRNA *prop;
1305 
1306  /* identifiers */
1307  ot->name = "Select Time Marker";
1308  ot->description = "Select time marker(s)";
1309  ot->idname = "MARKER_OT_select";
1310 
1311  /* api callbacks */
1316 
1317  /* flags */
1319 
1321  prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
1323 #ifdef DURIAN_CAMERA_SWITCH
1324  prop = RNA_def_boolean(ot->srna, "camera", 0, "Camera", "Select the camera");
1326 #endif
1327 }
1328 
1329 /* *************************** box select markers **************** */
1330 
1331 /* operator state vars used: (added by default WM callbacks)
1332  * xmin, ymin
1333  * xmax, ymax
1334  *
1335  * customdata: the wmGesture pointer, with subwindow
1336  *
1337  * callbacks:
1338  *
1339  * exec() has to be filled in by user
1340  *
1341  * invoke() default WM function
1342  * adds modal handler
1343  *
1344  * modal() default WM function
1345  * accept modal events while doing it, calls exec(), handles ESC and border drawing
1346  *
1347  * poll() has to be filled in by user for context
1348  */
1349 
1351 {
1352  ARegion *region = CTX_wm_region(C);
1353  View2D *v2d = &region->v2d;
1354 
1356  bool over_marker = region_position_is_over_marker(v2d, markers, event->x - region->winrct.xmin);
1357 
1358  bool tweak = RNA_boolean_get(op->ptr, "tweak");
1359  if (tweak && over_marker) {
1361  }
1362 
1363  return WM_gesture_box_invoke(C, op, event);
1364 }
1365 
1367 {
1368  View2D *v2d = UI_view2d_fromcontext(C);
1370  rctf rect;
1371 
1373  UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
1374 
1375  if (markers == NULL) {
1376  return 0;
1377  }
1378 
1379  const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
1380  const bool select = (sel_op != SEL_OP_SUB);
1381  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
1383  }
1384 
1385  LISTBASE_FOREACH (TimeMarker *, marker, markers) {
1386  if (BLI_rctf_isect_x(&rect, marker->frame)) {
1387  SET_FLAG_FROM_TEST(marker->flag, select, SELECT);
1388  }
1389  }
1390 
1393 
1394  return 1;
1395 }
1396 
1398 {
1399  /* identifiers */
1400  ot->name = "Marker Box Select";
1401  ot->description = "Select all time markers using box selection";
1402  ot->idname = "MARKER_OT_select_box";
1403 
1404  /* api callbacks */
1409 
1411 
1412  /* flags */
1414 
1415  /* properties */
1418 
1419  PropertyRNA *prop = RNA_def_boolean(
1420  ot->srna, "tweak", 0, "Tweak", "Operator has been activated using a tweak event");
1422 }
1423 
1424 /* *********************** (de)select all ***************** */
1425 
1427 {
1429  if (markers == NULL) {
1430  return OPERATOR_CANCELLED;
1431  }
1432 
1433  int action = RNA_enum_get(op->ptr, "action");
1435 
1438 
1439  return OPERATOR_FINISHED;
1440 }
1441 
1443 {
1444  /* identifiers */
1445  ot->name = "(De)select all Markers";
1446  ot->description = "Change selection of all time markers";
1447  ot->idname = "MARKER_OT_select_all";
1448 
1449  /* api callbacks */
1452 
1453  /* flags */
1455 
1456  /* rna */
1458 }
1459 
1460 /* ***************** remove marker *********************** */
1461 
1462 /* remove selected TimeMarkers */
1464 {
1466  TimeMarker *marker, *nmarker;
1467  bool changed = false;
1468 
1469  if (markers == NULL) {
1470  return OPERATOR_CANCELLED;
1471  }
1472 
1473  for (marker = markers->first; marker; marker = nmarker) {
1474  nmarker = marker->next;
1475  if (marker->flag & SELECT) {
1476  if (marker->prop != NULL) {
1477  IDP_FreePropertyContent(marker->prop);
1478  MEM_freeN(marker->prop);
1479  }
1480  BLI_freelinkN(markers, marker);
1481  changed = true;
1482  }
1483  }
1484 
1485  if (changed) {
1488  }
1489 
1490  return OPERATOR_FINISHED;
1491 }
1492 
1494 {
1495  /* identifiers */
1496  ot->name = "Delete Markers";
1497  ot->description = "Delete selected time marker(s)";
1498  ot->idname = "MARKER_OT_delete";
1499 
1500  /* api callbacks */
1504 
1505  /* flags */
1507 }
1508 
1509 /* **************** rename marker ***************** */
1510 
1511 /* rename first selected TimeMarker */
1513 {
1515 
1516  if (marker) {
1517  RNA_string_get(op->ptr, "name", marker->name);
1518 
1521 
1522  return OPERATOR_FINISHED;
1523  }
1524 
1525  return OPERATOR_CANCELLED;
1526 }
1527 
1528 static int ed_marker_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1529 {
1530  /* must initialize the marker name first if there is a marker selected */
1532  if (marker) {
1533  RNA_string_set(op->ptr, "name", marker->name);
1534  }
1535 
1536  return WM_operator_props_popup_confirm(C, op, event);
1537 }
1538 
1540 {
1541  /* identifiers */
1542  ot->name = "Rename Marker";
1543  ot->description = "Rename first selected time marker";
1544  ot->idname = "MARKER_OT_rename";
1545 
1546  /* api callbacks */
1550 
1551  /* flags */
1553 
1554  /* properties */
1556  "name",
1557  "RenamedMarker",
1558  sizeof(((TimeMarker *)NULL)->name),
1559  "Name",
1560  "New name for marker");
1561 #if 0
1563  "ensure_unique",
1564  0,
1565  "Ensure Unique",
1566  "Ensure that new name is unique within collection of markers");
1567 #endif
1568 }
1569 
1570 /* **************** make links to scene ***************** */
1571 
1573 {
1574  Main *bmain = CTX_data_main(C);
1576  Scene *scene_to = BLI_findlink(&bmain->scenes, RNA_enum_get(op->ptr, "scene"));
1577  TimeMarker *marker, *marker_new;
1578 
1579  if (scene_to == NULL) {
1580  BKE_report(op->reports, RPT_ERROR, "Scene not found");
1581  return OPERATOR_CANCELLED;
1582  }
1583 
1584  if (scene_to == CTX_data_scene(C)) {
1585  BKE_report(op->reports, RPT_ERROR, "Cannot re-link markers into the same scene");
1586  return OPERATOR_CANCELLED;
1587  }
1588 
1589  if (scene_to->toolsettings->lock_markers) {
1590  BKE_report(op->reports, RPT_ERROR, "Target scene has locked markers");
1591  return OPERATOR_CANCELLED;
1592  }
1593 
1594  /* copy markers */
1595  for (marker = markers->first; marker; marker = marker->next) {
1596  if (marker->flag & SELECT) {
1597  marker_new = MEM_dupallocN(marker);
1598  marker_new->prev = marker_new->next = NULL;
1599 
1600  BLI_addtail(&scene_to->markers, marker_new);
1601  }
1602  }
1603 
1604  return OPERATOR_FINISHED;
1605 }
1606 
1608 {
1609  PropertyRNA *prop;
1610 
1611  /* identifiers */
1612  ot->name = "Make Links to Scene";
1613  ot->description = "Copy selected markers to another scene";
1614  ot->idname = "MARKER_OT_make_links_scene";
1615 
1616  /* api callbacks */
1620 
1621  /* flags */
1623 
1624  /* properties */
1625  prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
1628  ot->prop = prop;
1629 }
1630 
1631 #ifdef DURIAN_CAMERA_SWITCH
1632 /* ******************************* camera bind marker ***************** */
1633 
1634 static int ed_marker_camera_bind_exec(bContext *C, wmOperator *op)
1635 {
1636  bScreen *screen = CTX_wm_screen(C);
1640  TimeMarker *marker;
1641 
1642  /* Don't do anything if we don't have a camera selected */
1643  if (ob == NULL) {
1644  BKE_report(op->reports, RPT_ERROR, "Select a camera to bind to a marker on this frame");
1645  return OPERATOR_CANCELLED;
1646  }
1647 
1648  /* add new marker, unless we already have one on this frame, in which case, replace it */
1649  if (markers == NULL) {
1650  return OPERATOR_CANCELLED;
1651  }
1652 
1654  if ((marker == NULL) || (marker->frame != CFRA)) {
1655  marker = MEM_callocN(sizeof(TimeMarker), "Camera TimeMarker");
1656  marker->flag = SELECT;
1657  marker->frame = CFRA;
1658  BLI_addtail(markers, marker);
1659 
1660  /* deselect all others, so that the user can then move it without problems */
1662  if (m != marker) {
1663  m->flag &= ~SELECT;
1664  }
1665  }
1666  }
1667 
1668  /* bind to the nominated camera (as set in operator props) */
1669  marker->camera = ob;
1670 
1671  /* camera may have changes */
1674 
1677  WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene); /* so we get view3d redraws */
1678 
1679  return OPERATOR_FINISHED;
1680 }
1681 
1682 static void MARKER_OT_camera_bind(wmOperatorType *ot)
1683 {
1684  /* identifiers */
1685  ot->name = "Bind Camera to Markers";
1686  ot->description = "Bind the selected camera to a marker on the current frame";
1687  ot->idname = "MARKER_OT_camera_bind";
1688 
1689  /* api callbacks */
1690  ot->exec = ed_marker_camera_bind_exec;
1692 
1693  /* flags */
1695 }
1696 #endif
1697 
1698 /* ************************** registration **********************************/
1699 
1700 /* called in screen_ops.c:ED_operatortypes_screen() */
1702 {
1712 #ifdef DURIAN_CAMERA_SWITCH
1713  WM_operatortype_append(MARKER_OT_camera_bind);
1714 #endif
1715 }
1716 
1717 /* called in screen_ops.c:ED_keymap_screen() */
1719 {
1720  WM_keymap_ensure(keyconf, "Markers", 0, 0);
1721 }
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
@ CTX_MODE_OBJECT
Definition: BKE_context.h:128
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct SpaceLink * CTX_wm_space_data(const bContext *C)
Definition: context.c:719
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1208
enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
Definition: context.c:1174
void IDP_FreePropertyContent(struct IDProperty *prop)
Definition: idprop.c:1029
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:403
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:394
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
bool BKE_scene_camera_switch_update(struct Scene *scene)
Definition: scene.c:2349
void BKE_screen_view3d_scene_sync(struct bScreen *screen, struct Scene *scene)
Definition: screen.c:1041
@ B_UNIT_NONE
Definition: BKE_unit.h:78
@ B_UNIT_TIME
Definition: BKE_unit.h:84
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define ATTR_FALLTHROUGH
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:150
#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init)
Definition: BLI_listbase.h:154
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:395
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, const float x)
Definition: rct.c:114
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
#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:638
@ SACTCONT_ACTION
@ SACTCONT_SHAPEKEY
@ SACTION_POSEMARKERS_SHOW
@ SACTION_SHOW_MARKERS
@ SACTION_DRAWTIME
Object is a sort of wrapper for general info.
@ OB_RESTRICT_RENDER
#define CFRA
#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:41
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:102
void initNumInput(NumInput *n)
Definition: numinput.c:83
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:27
@ NUM_NO_FRACTION
Definition: ED_numinput.h:72
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:207
bool hasNumInput(const NumInput *n)
Definition: numinput.c:185
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:98
void ED_object_base_activate(struct bContext *C, struct Base *base)
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:815
#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:65
@ TFM_TIME_SCALE
Definition: ED_transform.h:67
@ TFM_TIME_EXTEND
Definition: ED_transform.h:68
#define ACTIVE
Definition: ED_types.h:35
void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, float fac3, int invert)
Definition: ed_util.c:304
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:142
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:232
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:365
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:279
@ 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.
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:279
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
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:90
#define UI_DPI_ICON_SIZE
Definition: UI_interface.h:311
#define UI_DPI_FAC
Definition: UI_interface.h:309
#define UI_FSTYLE_WIDGET
void UI_icon_draw(float x, float y, int icon_id)
@ TH_TIME_SCRUB_BACKGROUND
Definition: UI_resources.h:114
@ TH_TIME_MARKER_LINE
Definition: UI_resources.h:115
@ TH_TIME_MARKER_LINE_SELECTED
Definition: UI_resources.h:116
@ TH_TEXT
Definition: UI_resources.h:58
@ TH_TEXT_HI
Definition: UI_resources.h:59
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1381
void UI_view2d_scale_get(const struct View2D *v2d, float *r_x, float *r_y)
#define UI_MARKER_MARGIN_Y
Definition: UI_view2d.h:282
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.c:1659
float UI_view2d_scale_get_x(const struct View2D *v2d)
@ OPTYPE_BLOCKING
Definition: WM_types.h:157
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_GRAB_CURSOR_XY
Definition: WM_types.h:161
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define NC_ANIMATION
Definition: WM_types.h:289
#define ND_OB_SELECT
Definition: WM_types.h:342
#define NC_SCENE
Definition: WM_types.h:279
#define NA_EDITED
Definition: WM_types.h:462
#define KM_PRESS
Definition: WM_types.h:242
#define ND_MARKERS
Definition: WM_types.h:333
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:78
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:330
void ED_keymap_marker(wmKeyConfig *keyconf)
static void ed_marker_move_update_header(bContext *C, wmOperator *op)
Definition: anim_markers.c:760
static void ed_marker_move_exit(bContext *C, wmOperator *op)
Definition: anim_markers.c:852
static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: anim_markers.c:942
static void marker_color_get(const TimeMarker *marker, uchar *r_text_color, uchar *r_line_color)
Definition: anim_markers.c:421
static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel)
Definition: anim_markers.c:291
static int ed_marker_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool ED_operator_markers_region_active(bContext *C)
Definition: anim_markers.c:234
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:130
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 draw_markers_background(rctf *rect)
Definition: anim_markers.c:521
static void MARKER_OT_add(wmOperatorType *ot)
Definition: anim_markers.c:699
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:458
void ED_markers_get_minmax(ListBase *markers, short sel, float *r_first, float *r_last)
Definition: anim_markers.c:199
static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op))
Definition: anim_markers.c:664
static bool ed_markers_poll_selected_no_locked_markers(bContext *C)
Definition: anim_markers.c:634
static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
TimeMarker * ED_markers_get_first_selected(ListBase *markers)
Definition: anim_markers.c:379
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:193
static void get_marker_region_rect(View2D *v2d, rctf *rect)
Definition: anim_markers.c:551
ListBase * ED_context_get_markers(const bContext *C)
Definition: anim_markers.c:103
static void deselect_markers(ListBase *markers)
static bool ed_markers_poll_selected_markers(bContext *C)
Definition: anim_markers.c:622
static bool ed_marker_move_init(bContext *C, wmOperator *op)
Definition: anim_markers.c:807
TimeMarker * ED_markers_find_nearest_marker(ListBase *markers, float x)
Definition: anim_markers.c:173
static void MARKER_OT_duplicate(wmOperatorType *ot)
static void ed_marker_move_apply(bContext *C, wmOperator *op)
Definition: anim_markers.c:901
struct MarkerMove MarkerMove
static void draw_marker(const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int xpos, int flag, int region_height)
Definition: anim_markers.c:496
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:274
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:865
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:433
static bool marker_is_in_frame_range(TimeMarker *marker, const int frame_range[2])
Definition: anim_markers.c:540
static bool ed_markers_poll_markers_exist(bContext *C)
Definition: anim_markers.c:648
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:746
void ED_markers_deselect_all(ListBase *markers, int action)
Definition: anim_markers.c:354
ListBase * ED_animcontext_get_markers(const bAnimContext *ac)
Definition: anim_markers.c:109
static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void debug_markers_print_list(ListBase *markers)
Definition: anim_markers.c:400
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:482
static void ed_marker_move_cancel(bContext *C, wmOperator *op)
Definition: anim_markers.c:935
static void get_marker_clip_frame_range(View2D *v2d, float xscale, int r_range[2])
Definition: anim_markers.c:559
static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
void ED_markers_draw(const bContext *C, int flag)
Definition: anim_markers.c:567
#define SELECT
Scene scene
#define str(s)
uint pos
const vector< Marker > & markers
#define fabsf(x)
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
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:6550
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
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:3675
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
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:3585
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3819
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:3771
const EnumPropertyItem DummyRNA_NULL_items[]
Definition: rna_rna.c:40
#define min(a, b)
Definition: sort.c:51
float cfra
Definition: BKE_fcurve.h:56
struct CfraElem * next
Definition: BKE_fcurve.h:55
int sel
Definition: BKE_fcurve.h:57
char name[66]
Definition: DNA_ID.h:283
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase scenes
Definition: BKE_main.h:146
NumInput num
Definition: anim_markers.c:743
SpaceLink * slink
Definition: anim_markers.c:739
int * oldframe
Definition: anim_markers.c:742
ListBase * markers
Definition: anim_markers.c:740
short idx_max
Definition: ED_numinput.h:34
short val_flag[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:43
int unit_sys
Definition: ED_numinput.h:35
int unit_type[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:37
char restrictflag
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
struct Scene * scene
Definition: ED_anim_api.h:97
struct ScrArea * area
Definition: ED_anim_api.h:85
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int xmin
Definition: DNA_vec_types.h:79
short shift
Definition: WM_types.h:618
short ctrl
Definition: WM_types.h:618
short val
Definition: WM_types.h:579
int x
Definition: WM_types.h:581
short type
Definition: WM_types.h:577
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct ReportList * reports
struct PointerRNA * ptr
float max
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167
bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event)
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:3156
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_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(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:905
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982
int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: wm_operators.c:838