Blender  V3.3
nla_draw.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 Blender Foundation, Joshua Leung. All rights reserved. */
3 
8 #include <float.h>
9 #include <math.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "DNA_anim_types.h"
15 #include "DNA_node_types.h"
16 #include "DNA_screen_types.h"
17 #include "DNA_space_types.h"
19 
20 #include "BLI_blenlib.h"
21 #include "BLI_dlrbTree.h"
22 #include "BLI_range.h"
23 #include "BLI_utildefines.h"
24 
25 #include "BKE_context.h"
26 #include "BKE_fcurve.h"
27 #include "BKE_nla.h"
28 #include "BKE_screen.h"
29 
30 #include "ED_anim_api.h"
31 #include "ED_keyframes_draw.h"
32 #include "ED_keyframes_keylist.h"
33 
34 #include "GPU_immediate.h"
35 #include "GPU_immediate_util.h"
36 #include "GPU_state.h"
37 
38 #include "WM_types.h"
39 
40 #include "UI_interface.h"
41 #include "UI_resources.h"
42 #include "UI_view2d.h"
43 
44 #include "nla_intern.h" /* own include */
45 #include "nla_private.h"
46 
47 /* *********************************************** */
48 /* Strips */
49 
50 /* Action-Line ---------------------- */
51 
52 void nla_action_get_color(AnimData *adt, bAction *act, float color[4])
53 {
54  if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
55  /* greenish color (same as tweaking strip) */
57  }
58  else {
59  if (act) {
60  /* reddish color - same as dopesheet summary */
62  }
63  else {
64  /* grayish-red color */
66  }
67  }
68 
69  /* when an NLA track is tagged "solo", action doesn't contribute,
70  * so shouldn't be as prominent */
71  if (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) {
72  color[3] *= 0.15f;
73  }
74 }
75 
76 /* draw the keyframes in the specified Action */
78  View2D *v2d, AnimData *adt, bAction *act, float y, float ymin, float ymax)
79 {
80  if (act == NULL) {
81  return;
82  }
83 
84  /* get a list of the keyframes with NLA-scaling applied */
85  struct AnimKeylist *keylist = ED_keylist_create();
86  action_to_keylist(adt, act, keylist, 0);
87 
88  if (ED_keylist_is_empty(keylist)) {
89  ED_keylist_free(keylist);
90  return;
91  }
92 
93  /* draw a darkened region behind the strips
94  * - get and reset the background color, this time without the alpha to stand out better
95  * (amplified alpha is used instead, but clamped to avoid 100% opacity)
96  */
97  float color[4];
98  nla_action_get_color(adt, act, color);
99  color[3] = min_ff(0.7f, color[3] * 2.5f);
100 
103 
105 
107 
108  /* - draw a rect from the first to the last frame (no extra overlaps for now)
109  * that is slightly stumpier than the track background (hardcoded 2-units here)
110  */
111 
112  Range2f frame_range;
113  ED_keylist_all_keys_frame_range(keylist, &frame_range);
114  immRectf(pos_id, frame_range.min, ymin + 2, frame_range.max, ymax - 2);
116 
117  /* Count keys before drawing. */
118  /* NOTE: It's safe to cast #DLRBT_Tree, as it's designed to degrade down to a #ListBase. */
119  const ListBase *keys = ED_keylist_listbase(keylist);
120  uint key_len = BLI_listbase_count(keys);
121 
122  if (key_len > 0) {
124  KeyframeShaderBindings sh_bindings;
126  sh_bindings.size_id = GPU_vertformat_attr_add(
127  format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
128  sh_bindings.color_id = GPU_vertformat_attr_add(
131  format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
132  sh_bindings.flags_id = GPU_vertformat_attr_add(
133  format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
134 
137  immUniform1f("outline_scale", 1.0f);
138  immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
139  immBegin(GPU_PRIM_POINTS, key_len);
140 
141  /* - disregard the selection status of keyframes so they draw a certain way
142  * - size is 6.0f which is smaller than the editable keyframes, so that there is a distinction
143  */
144  LISTBASE_FOREACH (const ActKeyColumn *, ak, keys) {
145  draw_keyframe_shape(ak->cfra,
146  y,
147  6.0f,
148  false,
149  ak->key_type,
151  1.0f,
152  &sh_bindings,
155  }
156 
157  immEnd();
158  GPU_program_point_size(false);
160  }
161 
162  /* free icons */
163  ED_keylist_free(keylist);
164 }
165 
166 /* Strip Markers ------------------------ */
167 
168 /* Markers inside an action strip */
170  NlaStrip *strip, float yminc, float ymaxc, int shade, const bool dashed)
171 {
172  const bAction *act = strip->act;
173 
174  if (ELEM(NULL, act, act->markers.first)) {
175  return;
176  }
177 
178  const uint shdr_pos = GPU_vertformat_attr_add(
180  if (dashed) {
182 
183  float viewport_size[4];
184  GPU_viewport_size_get_f(viewport_size);
185  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
186 
187  immUniform1i("colors_len", 0); /* "simple" mode */
188  immUniform1f("dash_width", 6.0f);
189  immUniform1f("dash_factor", 0.5f);
190  }
191  else {
193  }
195 
197  LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
198  if ((marker->frame > strip->actstart) && (marker->frame < strip->actend)) {
199  float frame = nlastrip_get_frame(strip, marker->frame, NLATIME_CONVERT_MAP);
200 
201  /* just a simple line for now */
202  /* XXX: draw a triangle instead... */
203  immVertex2f(shdr_pos, frame, yminc + 1);
204  immVertex2f(shdr_pos, frame, ymaxc - 1);
205  }
206  }
207  immEnd();
208 
210 }
211 
212 /* Markers inside a NLA-Strip */
213 static void nla_strip_draw_markers(NlaStrip *strip, float yminc, float ymaxc)
214 {
215  GPU_line_width(2.0f);
216 
217  if (strip->type == NLASTRIP_TYPE_CLIP) {
218  /* try not to be too conspicuous, while being visible enough when transforming */
219  int shade = (strip->flag & NLASTRIP_FLAG_SELECT) ? -60 : -40;
220 
221  /* just draw the markers in this clip */
222  nla_actionclip_draw_markers(strip, yminc, ymaxc, shade, true);
223  }
224  else if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
225  /* just a solid color, so that it is very easy to spot */
226  int shade = 20;
227  /* draw the markers in the first level of strips only (if they are actions) */
228  LISTBASE_FOREACH (NlaStrip *, nls, &strip->strips) {
229  if (nls->type == NLASTRIP_TYPE_CLIP) {
230  nla_actionclip_draw_markers(nls, yminc, ymaxc, shade, false);
231  }
232  }
233  }
234 
235  GPU_line_width(1.0f);
236 }
237 
238 /* Strips (Proper) ---------------------- */
239 
240 /* get colors for drawing NLA-Strips */
241 static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float color[3])
242 {
243  if (strip->type == NLASTRIP_TYPE_TRANSITION) {
244  /* Transition Clip */
245  if (strip->flag & NLASTRIP_FLAG_SELECT) {
246  /* selected - use a bright blue color */
248  }
249  else {
250  /* normal, unselected strip - use (hardly noticeable) blue tinge */
252  }
253  }
254  else if (strip->type == NLASTRIP_TYPE_META) {
255  /* Meta Clip */
256  /* TODO: should temporary meta-strips get different colors too? */
257  if (strip->flag & NLASTRIP_FLAG_SELECT) {
258  /* selected - use a bold purple color */
260  }
261  else {
262  /* normal, unselected strip - use (hardly noticeable) dark purple tinge */
264  }
265  }
266  else if (strip->type == NLASTRIP_TYPE_SOUND) {
267  /* Sound Clip */
268  if (strip->flag & NLASTRIP_FLAG_SELECT) {
269  /* selected - use a bright teal color */
271  }
272  else {
273  /* normal, unselected strip - use (hardly noticeable) teal tinge */
275  }
276  }
277  else {
278  /* Action Clip (default/normal type of strip) */
279  if (adt && (adt->flag & ADT_NLA_EDIT_ON) && (adt->actstrip == strip)) {
280  /* active strip should be drawn green when it is acting as the tweaking strip.
281  * however, this case should be skipped for when not in EditMode...
282  */
284  }
285  else if (strip->flag & NLASTRIP_FLAG_TWEAKUSER) {
286  /* alert user that this strip is also used by the tweaking track (this is set when going into
287  * 'editmode' for that strip), since the edits made here may not be what the user anticipated
288  */
290  }
291  else if (strip->flag & NLASTRIP_FLAG_SELECT) {
292  /* selected strip - use theme color for selected */
294  }
295  else {
296  /* normal, unselected strip - use standard strip theme color */
298  }
299  }
300 }
301 
302 /* helper call for drawing influence/time control curves for a given NLA-strip */
303 static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uint pos)
304 {
305  const float yheight = ymaxc - yminc;
306 
307  /* draw with AA'd line */
308  GPU_line_smooth(true);
310 
311  /* Fully opaque line on selected strips. */
312  if (strip->flag & NLASTRIP_FLAG_SELECT) {
313  /* TODO: Use theme setting. */
314  immUniformColor3f(1.0f, 1.0f, 1.0f);
315  }
316  else {
317  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
318  }
319 
320  /* influence -------------------------- */
321  if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) {
322  FCurve *fcu = BKE_fcurve_find(&strip->fcurves, "influence", 0);
323  float cfra;
324 
325  /* plot the curve (over the strip's main region) */
326  if (fcu) {
327  immBegin(GPU_PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1));
328 
329  /* sample at 1 frame intervals, and draw
330  * - min y-val is yminc, max is y-maxc, so clamp in those regions
331  */
332  for (cfra = strip->start; cfra <= strip->end; cfra += 1.0f) {
333  float y = evaluate_fcurve(fcu, cfra); /* assume this to be in 0-1 range */
334  CLAMP(y, 0.0f, 1.0f);
335  immVertex2f(pos, cfra, ((y * yheight) + yminc));
336  }
337 
338  immEnd();
339  }
340  }
341  else {
342  /* use blend in/out values only if both aren't zero */
343  if ((IS_EQF(strip->blendin, 0.0f) && IS_EQF(strip->blendout, 0.0f)) == 0) {
345 
346  /* start of strip - if no blendin, start straight at 1,
347  * otherwise from 0 to 1 over blendin frames */
348  if (IS_EQF(strip->blendin, 0.0f) == 0) {
349  immVertex2f(pos, strip->start, yminc);
350  immVertex2f(pos, strip->start + strip->blendin, ymaxc);
351  }
352  else {
353  immVertex2f(pos, strip->start, ymaxc);
354  }
355 
356  /* end of strip */
357  if (IS_EQF(strip->blendout, 0.0f) == 0) {
358  immVertex2f(pos, strip->end - strip->blendout, ymaxc);
359  immVertex2f(pos, strip->end, yminc);
360  }
361  else {
362  immVertex2f(pos, strip->end, ymaxc);
363  }
364 
365  immEnd();
366  }
367  }
368 
369  /* turn off AA'd lines */
370  GPU_line_smooth(false);
372 }
373 
374 /* helper call to setup dashed-lines for strip outlines */
375 static uint nla_draw_use_dashed_outlines(const float color[4], bool muted)
376 {
377  /* Note that we use dashed shader here, and make it draw solid lines if not muted... */
378  uint shdr_pos = GPU_vertformat_attr_add(
381 
382  float viewport_size[4];
383  GPU_viewport_size_get_f(viewport_size);
384  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
385 
386  immUniform1i("colors_len", 0); /* Simple dashes. */
388 
389  /* line style: dotted for muted */
390  if (muted) {
391  /* dotted - and slightly thicker for readability of the dashes */
392  immUniform1f("dash_width", 5.0f);
393  immUniform1f("dash_factor", 0.4f);
394  GPU_line_width(1.5f);
395  }
396  else {
397  /* solid line */
398  immUniform1f("dash_factor", 2.0f);
399  GPU_line_width(1.0f);
400  }
401 
402  return shdr_pos;
403 }
404 
409 static bool is_nlastrip_enabled(AnimData *adt, NlaTrack *nlt, NlaStrip *strip)
410 {
412  BLI_assert(adt);
413  if (!adt) {
414  return true;
415  }
416 
417  if ((nlt->flag & NLATRACK_DISABLED) == 0) {
418  return true;
419  }
420 
422  return adt->actstrip == strip;
423 }
424 
425 /* main call for drawing a single NLA-strip */
426 static void nla_draw_strip(SpaceNla *snla,
427  AnimData *adt,
428  NlaTrack *nlt,
429  NlaStrip *strip,
430  View2D *v2d,
431  float yminc,
432  float ymaxc)
433 {
434  const bool non_solo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) &&
435  (nlt->flag & NLATRACK_SOLO) == 0);
436  const bool muted = ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED));
437  float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
438  uint shdr_pos;
439 
440  /* get color of strip */
441  nla_strip_get_color_inside(adt, strip, color);
442 
445 
446  /* draw extrapolation info first (as backdrop)
447  * - but this should only be drawn if track has some contribution
448  */
449  if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) {
450  /* enable transparency... */
452 
453  switch (strip->extendmode) {
454  /* since this does both sides,
455  * only do the 'before' side, and leave the rest to the next case */
457  /* only need to draw here if there's no strip before since
458  * it only applies in such a situation
459  */
460  if (strip->prev == NULL) {
461  /* set the drawing color to the color of the strip, but with very faint alpha */
463 
464  /* draw the rect to the edge of the screen */
465  immRectf(shdr_pos, v2d->cur.xmin, yminc, strip->start, ymaxc);
466  }
468 
469  /* this only draws after the strip */
471  /* only need to try and draw if the next strip doesn't occur immediately after */
472  if ((strip->next == NULL) || (IS_EQF(strip->next->start, strip->end) == 0)) {
473  /* set the drawing color to the color of the strip, but this time less faint */
475 
476  /* draw the rect to the next strip or the edge of the screen */
477  float x2 = strip->next ? strip->next->start : v2d->cur.xmax;
478  immRectf(shdr_pos, strip->end, yminc, x2, ymaxc);
479  }
480  break;
481  }
482 
484  }
485 
486  /* draw 'inside' of strip itself */
487  if (non_solo == 0 && is_nlastrip_enabled(adt, nlt, strip)) {
489 
490  /* strip is in normal track */
491  UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */
493  &(const rctf){
494  .xmin = strip->start,
495  .xmax = strip->end,
496  .ymin = yminc,
497  .ymax = ymaxc,
498  },
499  true,
500  0.0f,
501  color);
502 
503  /* restore current vertex format & program (roundbox trashes it) */
506  }
507  else {
508  /* strip is in disabled track - make less visible */
510 
512  immRectf(shdr_pos, strip->start, yminc, strip->end, ymaxc);
514  }
515 
516  /* draw strip's control 'curves'
517  * - only if user hasn't hidden them...
518  */
519  if ((snla->flag & SNLA_NOSTRIPCURVES) == 0) {
520  nla_draw_strip_curves(strip, yminc, ymaxc, shdr_pos);
521  }
522 
524 
525  /* draw markings indicating locations of local markers
526  * (useful for lining up different actions) */
527  if ((snla->flag & SNLA_NOLOCALMARKERS) == 0) {
528  nla_strip_draw_markers(strip, yminc, ymaxc);
529  }
530 
531  /* draw strip outline
532  * - color used here is to indicate active vs non-active
533  */
535  /* strip should appear 'sunken', so draw a light border around it */
536  color[0] = color[1] = color[2] = 1.0f; /* FIXME: hardcoded temp-hack colors */
537  }
538  else {
539  /* strip should appear to stand out, so draw a dark border around it */
540  color[0] = color[1] = color[2] = 0.0f; /* FIXME: or 1.0f ?? */
541  }
542 
543  /* draw outline
544  * - dashed-line shader is loaded after this block
545  */
546  if (muted) {
547  /* muted - draw dotted, squarish outline (for simplicity) */
548  shdr_pos = nla_draw_use_dashed_outlines(color, muted);
549  imm_draw_box_wire_2d(shdr_pos, strip->start, yminc, strip->end, ymaxc);
550  }
551  else {
552  /* non-muted - draw solid, rounded outline */
554  &(const rctf){
555  .xmin = strip->start,
556  .xmax = strip->end,
557  .ymin = yminc,
558  .ymax = ymaxc,
559  },
560  false,
561  0.0f,
562  color);
563 
564  /* restore current vertex format & program (roundbox trashes it) */
565  shdr_pos = nla_draw_use_dashed_outlines(color, muted);
566  }
567 
568  /* if action-clip strip, draw lines delimiting repeats too (in the same color as outline) */
569  if ((strip->type == NLASTRIP_TYPE_CLIP) && strip->repeat > 1.0f) {
570  float repeatLen = (strip->actend - strip->actstart) * strip->scale;
571 
572  /* only draw lines for whole-numbered repeats, starting from the first full-repeat
573  * up to the last full repeat (but not if it lies on the end of the strip)
574  */
576  for (int i = 1; i < strip->repeat; i++) {
577  float repeatPos = strip->start + (repeatLen * i);
578 
579  /* don't draw if line would end up on or after the end of the strip */
580  if (repeatPos < strip->end) {
581  immVertex2f(shdr_pos, repeatPos, yminc + 4);
582  immVertex2f(shdr_pos, repeatPos, ymaxc - 4);
583  }
584  }
585  immEnd();
586  }
587  /* or if meta-strip, draw lines delimiting extents of sub-strips
588  * (in same color as outline, if more than 1 exists) */
589  else if ((strip->type == NLASTRIP_TYPE_META) && (strip->strips.first != strip->strips.last)) {
590  const float y = (ymaxc - yminc) * 0.5f + yminc;
591 
592  /* up to 2 lines per strip */
594 
595  /* only draw first-level of child-strips, but don't draw any lines on the endpoints */
596  LISTBASE_FOREACH (NlaStrip *, cs, &strip->strips) {
597  /* draw start-line if not same as end of previous (and only if not the first strip)
598  * - on upper half of strip
599  */
600  if ((cs->prev) && IS_EQF(cs->prev->end, cs->start) == 0) {
601  immVertex2f(shdr_pos, cs->start, y);
602  immVertex2f(shdr_pos, cs->start, ymaxc);
603  }
604 
605  /* draw end-line if not the last strip
606  * - on lower half of strip
607  */
608  if (cs->next) {
609  immVertex2f(shdr_pos, cs->end, yminc);
610  immVertex2f(shdr_pos, cs->end, y);
611  }
612  }
613 
614  immEnd();
615  }
616 
618 }
619 
621 static void nla_draw_strip_text(AnimData *adt,
622  NlaTrack *nlt,
623  NlaStrip *strip,
624  View2D *v2d,
625  float xminc,
626  float xmaxc,
627  float yminc,
628  float ymaxc)
629 {
630  const bool non_solo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) &&
631  (nlt->flag & NLATRACK_SOLO) == 0);
632  char str[256];
633  size_t str_len;
634  uchar col[4];
635 
636  /* just print the name and the range */
637  if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
638  str_len = BLI_snprintf_rlen(str, sizeof(str), "Temp-Meta");
639  }
640  else {
641  str_len = BLI_strncpy_rlen(str, strip->name, sizeof(str));
642  }
643 
644  /* set text color - if colors (see above) are light, draw black text, otherwise draw white */
646  col[0] = col[1] = col[2] = 0;
647  }
648  else {
649  col[0] = col[1] = col[2] = 255;
650  }
651 
652  /* text opacity depends on whether if there's a solo'd track, this isn't it */
653  if (non_solo == 0) {
654  col[3] = 255;
655  }
656  else {
657  col[3] = 128;
658  }
659 
660  /* set bounding-box for text
661  * - padding of 2 'units' on either side
662  */
663  /* TODO: make this centered? */
664  rctf rect = {
665  .xmin = xminc,
666  .ymin = yminc,
667  .xmax = xmaxc,
668  .ymax = ymaxc,
669  };
670 
671  /* add this string to the cache of texts to draw */
672  UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col);
673 }
674 
680  NlaTrack *UNUSED(nlt), NlaStrip *strip, View2D *v2d, float UNUSED(yminc), float ymaxc)
681 {
682  const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */
683  const uchar col[4] = {220, 220, 220, 255}; /* light gray */
684  char numstr[32];
685  size_t numstr_len;
686 
687  /* Always draw times above the strip, whereas sequencer drew below + above.
688  * However, we should be fine having everything on top, since these tend to be
689  * quite spaced out.
690  * - 1 dp is compromise between lack of precision (ints only, as per sequencer)
691  * while also preserving some accuracy, since we do use floats
692  */
693  /* start frame */
694  numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->start);
695  UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, numstr_len, col);
696 
697  /* end frame */
698  numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->end);
699  UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, numstr_len, col);
700 }
701 
702 /* ---------------------- */
703 
710 {
711  if (BLI_listbase_is_empty(&nlt->strips)) {
712  ListBase empty = {NULL, NULL};
713  return empty;
714  }
715 
716  NlaStrip *first = NULL;
717  NlaStrip *last = NULL;
718 
719  /* Find the first strip that is within the bounds of the view. */
720  LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
721  if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
722  first = last = strip;
723  break;
724  }
725  }
726 
727  const bool has_strips_within_bounds = first != NULL;
728 
729  if (has_strips_within_bounds) {
730  /* Find the last visible strip. */
731  for (NlaStrip *strip = first->next; strip; strip = strip->next) {
732  if (!BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
733  break;
734  }
735  last = strip;
736  }
737  /* Check if the first strip is adjacent to a strip outside the view to the left
738  * that has an extendmode region that should be drawn.
739  * If so, adjust the first strip to include drawing that strip as well.
740  */
741  NlaStrip *prev = first->prev;
742  if (prev && prev->extendmode != NLASTRIP_EXTEND_NOTHING) {
743  first = prev;
744  }
745  }
746  else {
747  /* No immediately visible strips.
748  * Figure out where our view is relative to the strips, then determine
749  * if the view is adjacent to a strip that should have its extendmode
750  * rendered.
751  */
752  NlaStrip *first_strip = nlt->strips.first;
753  NlaStrip *last_strip = nlt->strips.last;
754  if (first_strip && v2d->cur.xmax < first_strip->start &&
755  first_strip->extendmode == NLASTRIP_EXTEND_HOLD) {
756  /* The view is to the left of all strips and the first strip has an
757  * extendmode that should be drawn.
758  */
759  first = last = first_strip;
760  }
761  else if (last_strip && v2d->cur.xmin > last_strip->end &&
762  last_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
763  /* The view is to the right of all strips and the last strip has an
764  * extendmode that should be drawn.
765  */
766  first = last = last_strip;
767  }
768  else {
769  /* The view is in the middle of two strips. */
770  LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
771  /* Find the strip to the left by finding the strip to the right and getting its prev. */
772  if (v2d->cur.xmax < strip->start) {
773  /* If the strip to the left has an extendmode, set that as the only visible strip. */
774  if (strip->prev && strip->prev->extendmode != NLASTRIP_EXTEND_NOTHING) {
775  first = last = strip->prev;
776  }
777  break;
778  }
779  }
780  }
781  }
782 
783  ListBase visible_strips = {first, last};
784  return visible_strips;
785 }
786 
788 {
789  View2D *v2d = &region->v2d;
790  const float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
791  const float text_margin_x = (8 * UI_DPI_FAC) * pixelx;
792 
793  /* build list of channels to draw */
794  ListBase anim_data = {NULL, NULL};
797  size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
798 
799  /* Update max-extent of channels here (taking into account scrollers):
800  * - this is done to allow the channel list to be scrollable, but must be done here
801  * to avoid regenerating the list again and/or also because channels list is drawn first
802  * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
803  * start of list offset, and the second is as a correction for the scrollers.
804  */
805  int height = NLACHANNEL_TOT_HEIGHT(ac, items);
806  v2d->tot.ymin = -height;
807 
808  /* Loop through channels, and set up drawing depending on their type. */
809  float ymax = NLACHANNEL_FIRST_TOP(ac);
810 
811  for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
812  float ymin = ymax - NLACHANNEL_HEIGHT(snla);
813  float ycenter = (ymax + ymin) / 2.0f;
814 
815  /* check if visible */
816  if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) ||
817  IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) {
818  /* data to draw depends on the type of channel */
819  switch (ale->type) {
820  case ANIMTYPE_NLATRACK: {
821  AnimData *adt = ale->adt;
822  NlaTrack *nlt = (NlaTrack *)ale->data;
823  ListBase visible_nla_strips = get_visible_nla_strips(nlt, v2d);
824 
825  /* Draw each visible strip in the track. */
826  LISTBASE_FOREACH (NlaStrip *, strip, &visible_nla_strips) {
827  const float xminc = strip->start + text_margin_x;
828  const float xmaxc = strip->end - text_margin_x;
829 
830  /* draw the visualization of the strip */
831  nla_draw_strip(snla, adt, nlt, strip, v2d, ymin, ymax);
832 
833  /* add the text for this strip to the cache */
834  if (xminc < xmaxc) {
835  nla_draw_strip_text(adt, nlt, strip, v2d, xminc, xmaxc, ymin, ymax);
836  }
837 
838  /* if transforming strips (only real reason for temp-metas currently),
839  * add to the cache the frame numbers of the strip's extents
840  */
841  if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
842  nla_draw_strip_frames_text(nlt, strip, v2d, ymin, ymax);
843  }
844  }
845  break;
846  }
847  case ANIMTYPE_NLAACTION: {
848  AnimData *adt = ale->adt;
849 
850  /* Draw the manually set intended playback frame range highlight. */
851  if (ale->data) {
852  ANIM_draw_action_framerange(adt, ale->data, v2d, ymin, ymax);
853  }
854 
858 
859  /* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
860  * and a second darker rect within which we draw keyframe indicator dots if there's data
861  */
863 
864  /* get colors for drawing */
865  float color[4];
866  nla_action_get_color(adt, ale->data, color);
868 
869  /* draw slightly shifted up for greater separation from standard channels,
870  * but also slightly shorter for some more contrast when viewing the strips
871  */
872  immRectf(
873  pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP, v2d->cur.xmax, ymax - NLACHANNEL_SKIP);
874 
876 
877  /* draw keyframes in the action */
879  v2d, adt, ale->data, ycenter, ymin + NLACHANNEL_SKIP, ymax - NLACHANNEL_SKIP);
880 
882  break;
883  }
884  }
885  }
886  }
887 
888  /* free tempolary channels */
889  ANIM_animdata_freelist(&anim_data);
890 }
891 
892 /* *********************************************** */
893 /* Channel List */
894 
896 {
897  ListBase anim_data = {NULL, NULL};
898  bAnimListElem *ale;
899  int filter;
900 
901  SpaceNla *snla = (SpaceNla *)ac->sl;
902  View2D *v2d = &region->v2d;
903  size_t items;
904 
905  /* build list of channels to draw */
908  items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
909 
910  /* Update max-extent of channels here (taking into account scrollers):
911  * - this is done to allow the channel list to be scrollable, but must be done here
912  * to avoid regenerating the list again and/or also because channels list is drawn first
913  * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
914  * start of list offset, and the second is as a correction for the scrollers.
915  */
916  int height = NLACHANNEL_TOT_HEIGHT(ac, items);
917  v2d->tot.ymin = -height;
918 
919  /* need to do a view-sync here, so that the keys area doesn't jump around
920  * (it must copy this) */
922 
923  /* draw channels */
924  { /* first pass: just the standard GL-drawing for backdrop + text */
925  size_t channel_index = 0;
926  float ymax = NLACHANNEL_FIRST_TOP(ac);
927 
928  for (ale = anim_data.first; ale;
929  ale = ale->next, ymax -= NLACHANNEL_STEP(snla), channel_index++) {
930  float ymin = ymax - NLACHANNEL_HEIGHT(snla);
931 
932  /* check if visible */
933  if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) ||
934  IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) {
935  /* draw all channels using standard channel-drawing API */
936  ANIM_channel_draw(ac, ale, ymin, ymax, channel_index);
937  }
938  }
939  }
940  { /* second pass: UI widgets */
941  uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
942  size_t channel_index = 0;
943  float ymax = NLACHANNEL_FIRST_TOP(ac);
944 
945  /* set blending again, as may not be set in previous step */
947 
948  /* Loop through channels, and set up drawing depending on their type. */
949  for (ale = anim_data.first; ale;
950  ale = ale->next, ymax -= NLACHANNEL_STEP(snla), channel_index++) {
951  float ymin = ymax - NLACHANNEL_HEIGHT(snla);
952 
953  /* check if visible */
954  if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) ||
955  IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) {
956  /* draw all channels using standard channel-drawing API */
957  rctf channel_rect;
958  BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax, ymin, ymax);
959  ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index);
960  }
961  }
962 
963  UI_block_end(C, block);
964  UI_block_draw(C, block);
965 
967  }
968 
969  /* free temporary channels */
970  ANIM_animdata_freelist(&anim_data);
971 }
972 
973 /* *********************************************** */
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2135
struct FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
Definition: fcurve.c:249
@ NLATIME_CONVERT_MAP
Definition: BKE_nla.h:360
bool BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max)
Definition: nla.c:1308
#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
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float min_ff(float a, float b)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition: rct.c:407
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
size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:120
size_t BLI_snprintf_rlen(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 IN_RANGE(a, b, c)
#define UNUSED(x)
#define ELEM(...)
#define IS_EQF(a, b)
@ NLASTRIP_FLAG_ACTIVE
@ NLASTRIP_FLAG_USR_INFLUENCE
@ NLASTRIP_FLAG_TEMP_META
@ NLASTRIP_FLAG_MUTED
@ NLASTRIP_FLAG_SELECT
@ NLASTRIP_FLAG_TWEAKUSER
@ ADT_NLA_SOLO_TRACK
@ ADT_NLA_EDIT_ON
@ NLASTRIP_EXTEND_HOLD_FORWARD
@ NLASTRIP_EXTEND_NOTHING
@ NLASTRIP_EXTEND_HOLD
@ NLASTRIP_TYPE_SOUND
@ NLASTRIP_TYPE_META
@ NLASTRIP_TYPE_TRANSITION
@ NLASTRIP_TYPE_CLIP
@ NLATRACK_SOLO
@ NLATRACK_MUTED
@ NLATRACK_DISABLED
@ SNLA_NOSTRIPCURVES
@ SNLA_NOLOCALMARKERS
@ ANIMTYPE_NLAACTION
Definition: ED_anim_api.h:239
@ ANIMTYPE_NLATRACK
Definition: ED_anim_api.h:238
#define NLACHANNEL_STEP(snla)
Definition: ED_anim_api.h:466
#define NLACHANNEL_SKIP
Definition: ED_anim_api.h:465
#define NLACHANNEL_FIRST_TOP(ac)
Definition: ED_anim_api.h:460
#define NLACHANNEL_TOT_HEIGHT(ac, item_amount)
Definition: ED_anim_api.h:468
#define NLACHANNEL_HEIGHT(snla)
Definition: ED_anim_api.h:462
@ ANIMFILTER_DATA_VISIBLE
Definition: ED_anim_api.h:292
@ ANIMFILTER_LIST_VISIBLE
Definition: ED_anim_api.h:295
@ ANIMFILTER_LIST_CHANNELS
Definition: ED_anim_api.h:300
@ ANIMFILTER_FCURVESONLY
Definition: ED_anim_api.h:328
@ KEYFRAME_SHAPE_FRAME
@ KEYFRAME_HANDLE_NONE
@ KEYFRAME_EXTREME_NONE
void immUniform2f(const char *name, float x, float y)
void immUniformColor4f(float r, float g, float b, float a)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immUniformThemeColorShade(int color_id, int offset)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniform1i(const char *name, int x)
void immBeginAtMost(GPUPrimType, uint max_vertex_len)
void immUniform1f(const char *name, float x)
void immUniformColor4fv(const float rgba[4])
GPUVertFormat * immVertexFormat(void)
void immUniformColor3f(float r, float g, float b)
void immBegin(GPUPrimType, uint vertex_len)
void immUniformColor3fvAlpha(const float rgb[3], float a)
void immEnd(void)
void immUniformColor3fv(const float rgb[3])
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_POINTS
Definition: GPU_primitive.h:19
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:22
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:349
@ GPU_SHADER_KEYFRAME_SHAPE
Definition: GPU_shader.h:192
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
void GPU_program_point_size(bool enable)
Definition: gpu_state.cc:172
@ 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_line_smooth(bool enable)
Definition: gpu_state.cc:75
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:259
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
@ GPU_FETCH_INT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_U32
@ GPU_COMP_U8
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
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
#define C
Definition: RandGen.cpp:25
@ UI_EMBOSS
Definition: UI_interface.h:108
void UI_draw_roundbox_4fv(const struct rctf *rect, bool filled, float rad, const float col[4])
void UI_draw_roundbox_corner_set(int type)
void UI_block_end(const struct bContext *C, uiBlock *block)
void UI_block_draw(const struct bContext *C, struct uiBlock *block)
#define UI_DPI_FAC
Definition: UI_interface.h:305
@ UI_CNR_ALL
uiBlock * UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, eUIEmbossType emboss)
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1165
@ TH_NLA_TRANSITION_SEL
Definition: UI_resources.h:286
@ TH_NLA_META
Definition: UI_resources.h:287
@ TH_NLA_META_SEL
Definition: UI_resources.h:288
@ TH_ANIM_ACTIVE
Definition: UI_resources.h:266
@ TH_NLA_TWEAK
Definition: UI_resources.h:281
@ TH_STRIP
Definition: UI_resources.h:138
@ TH_ANIM_INACTIVE
Definition: UI_resources.h:267
@ TH_NLA_TWEAK_DUPLI
Definition: UI_resources.h:282
@ TH_NLA_SOUND
Definition: UI_resources.h:289
@ TH_NLA_TRANSITION
Definition: UI_resources.h:285
@ TH_STRIP_SELECT
Definition: UI_resources.h:139
@ TH_NLA_SOUND_SEL
Definition: UI_resources.h:290
void UI_GetThemeColor4fv(int colorid, float col[4])
Definition: resources.c:1173
char char char char void UI_view2d_text_cache_add(struct View2D *v2d, float x, float y, const char *str, size_t str_len, const unsigned char col[4])
Definition: view2d.cc:2068
#define V2D_LOCK_COPY
Definition: UI_view2d.h:82
void UI_view2d_sync(struct bScreen *screen, struct ScrArea *area, struct View2D *v2dcur, int flag)
Definition: view2d.cc:851
void UI_view2d_text_cache_add_rectf(struct View2D *v2d, const struct rctf *rect_view, const char *str, size_t str_len, const unsigned char col[4])
void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListElem *ale, uiBlock *block, rctf *rect, size_t channel_index)
void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index)
void ANIM_animdata_freelist(ListBase *anim_data)
Definition: anim_deps.c:397
void ANIM_draw_action_framerange(AnimData *adt, bAction *action, View2D *v2d, float ymin, float ymax)
Definition: anim_draw.c:149
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_Flags filter_mode, void *data, eAnimCont_Types datatype)
Definition: anim_filter.c:3447
#define str(s)
uint pos
uint col
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha, const KeyframeShaderBindings *sh_bindings, short handle_type, short extreme_type)
AnimKeylist * ED_keylist_create()
bool ED_keylist_is_empty(const struct AnimKeylist *keylist)
void ED_keylist_free(AnimKeylist *keylist)
bool ED_keylist_all_keys_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range)
void action_to_keylist(AnimData *adt, bAction *act, AnimKeylist *keylist, const int saction_flag)
const struct ListBase * ED_keylist_listbase(const AnimKeylist *keylist)
format
Definition: logImageCore.h:38
#define floorf(x)
Definition: metal/compat.h:224
T abs(const T &a)
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode)
Definition: nla.c:628
static void nla_draw_strip_text(AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float xminc, float xmaxc, float yminc, float ymaxc)
Definition: nla_draw.c:621
static bool is_nlastrip_enabled(AnimData *adt, NlaTrack *nlt, NlaStrip *strip)
Definition: nla_draw.c:409
static void nla_strip_draw_markers(NlaStrip *strip, float yminc, float ymaxc)
Definition: nla_draw.c:213
void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region)
Definition: nla_draw.c:895
static void nla_action_draw_keyframes(View2D *v2d, AnimData *adt, bAction *act, float y, float ymin, float ymax)
Definition: nla_draw.c:77
static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uint pos)
Definition: nla_draw.c:303
static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, View2D *v2d, float UNUSED(yminc), float ymaxc)
Definition: nla_draw.c:679
static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float color[3])
Definition: nla_draw.c:241
static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc)
Definition: nla_draw.c:426
static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymaxc, int shade, const bool dashed)
Definition: nla_draw.c:169
static uint nla_draw_use_dashed_outlines(const float color[4], bool muted)
Definition: nla_draw.c:375
static ListBase get_visible_nla_strips(NlaTrack *nlt, View2D *v2d)
Definition: nla_draw.c:709
void nla_action_get_color(AnimData *adt, bAction *act, float color[4])
Definition: nla_draw.c:52
void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
Definition: nla_draw.c:787
NlaStrip * actstrip
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
float actstart
struct NlaStrip * next
float blendout
ListBase fcurves
char name[64]
ListBase strips
float actend
float repeat
struct NlaStrip * prev
float blendin
short extendmode
bAction * act
ListBase strips
float min
Definition: BLI_range.h:14
float max
Definition: BLI_range.h:15
ListBase markers
short datatype
Definition: ED_anim_api.h:62
void * data
Definition: ED_anim_api.h:60
struct ScrArea * area
Definition: ED_anim_api.h:72
struct SpaceLink * sl
Definition: ED_anim_api.h:74
struct bAnimListElem * next
Definition: ED_anim_api.h:127
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