Merging r46495 through r46557 from trunk into soc-2011-tomato
[blender.git] / source / blender / editors / space_sequencer / sequencer_draw.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2003-2009
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_sequencer/sequencer_draw.c
27  *  \ingroup spseq
28  */
29
30
31 #include <string.h>
32 #include <math.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_blenlib.h"
37 #include "BLI_math.h"
38 #include "BLI_utildefines.h"
39
40 #include "IMB_imbuf_types.h"
41
42 #include "DNA_scene_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_userdef_types.h"
46 #include "DNA_sound_types.h"
47
48 #include "BKE_context.h"
49 #include "BKE_global.h"
50 #include "BKE_sequencer.h"
51
52 #include "BKE_sound.h"
53
54 #include "IMB_imbuf.h"
55
56 #include "BIF_gl.h"
57 #include "BIF_glutil.h"
58
59 #include "ED_anim_api.h"
60 #include "ED_markers.h"
61 #include "ED_types.h"
62
63 #include "UI_interface.h"
64 #include "UI_resources.h"
65 #include "UI_view2d.h"
66
67 /* own include */
68 #include "sequencer_intern.h"
69
70
71 #define SEQ_LEFTHANDLE      1
72 #define SEQ_RIGHTHANDLE 2
73
74
75 /* Note, Don't use SEQ_BEGIN/SEQ_END while drawing!
76  * it messes up transform, - Campbell */
77 static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2);
78
79 static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[3])
80 {
81         unsigned char blendcol[3];
82         SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
83
84         switch (seq->type) {
85                 case SEQ_IMAGE:
86                         UI_GetThemeColor3ubv(TH_SEQ_IMAGE, col);
87                         break;
88
89                 case SEQ_META:
90                         UI_GetThemeColor3ubv(TH_SEQ_META, col);
91                         break;
92
93                 case SEQ_MOVIE:
94                         UI_GetThemeColor3ubv(TH_SEQ_MOVIE, col);
95                         break;
96
97                 case SEQ_MOVIECLIP:
98                         UI_GetThemeColor3ubv(TH_SEQ_MOVIECLIP, col);
99                         break;
100                 
101                 case SEQ_SCENE:
102                         UI_GetThemeColor3ubv(TH_SEQ_SCENE, col);
103                 
104                         if (seq->scene == curscene) {
105                                 UI_GetColorPtrShade3ubv(col, col, 20);
106                         }
107                         break;
108                 
109                 /* transitions */
110                 case SEQ_CROSS:
111                 case SEQ_GAMCROSS:
112                 case SEQ_WIPE:
113                         UI_GetThemeColor3ubv(TH_SEQ_TRANSITION, col);
114
115                         /* slightly offset hue to distinguish different effects */
116                         if (seq->type == SEQ_CROSS)    rgb_byte_set_hue_float_offset(col, 0.04);
117                         if (seq->type == SEQ_GAMCROSS) rgb_byte_set_hue_float_offset(col, 0.08);
118                         if (seq->type == SEQ_WIPE)     rgb_byte_set_hue_float_offset(col, 0.12);
119                         break;
120
121                 /* effects */
122                 case SEQ_TRANSFORM:
123                 case SEQ_SPEED:
124                 case SEQ_ADD:
125                 case SEQ_SUB:
126                 case SEQ_MUL:
127                 case SEQ_ALPHAOVER:
128                 case SEQ_ALPHAUNDER:
129                 case SEQ_OVERDROP:
130                 case SEQ_GLOW:
131                 case SEQ_MULTICAM:
132                 case SEQ_ADJUSTMENT:
133                         UI_GetThemeColor3ubv(TH_SEQ_EFFECT, col);
134
135                         /* slightly offset hue to distinguish different effects */
136                         if      (seq->type == SEQ_ADD)        rgb_byte_set_hue_float_offset(col, 0.04);
137                         else if (seq->type == SEQ_SUB)        rgb_byte_set_hue_float_offset(col, 0.08);
138                         else if (seq->type == SEQ_MUL)        rgb_byte_set_hue_float_offset(col, 0.12);
139                         else if (seq->type == SEQ_ALPHAOVER)  rgb_byte_set_hue_float_offset(col, 0.16);
140                         else if (seq->type == SEQ_ALPHAUNDER) rgb_byte_set_hue_float_offset(col, 0.20);
141                         else if (seq->type == SEQ_OVERDROP)   rgb_byte_set_hue_float_offset(col, 0.24);
142                         else if (seq->type == SEQ_GLOW)       rgb_byte_set_hue_float_offset(col, 0.28);
143                         else if (seq->type == SEQ_TRANSFORM)  rgb_byte_set_hue_float_offset(col, 0.36);
144                         else if (seq->type == SEQ_MULTICAM)   rgb_byte_set_hue_float_offset(col, 0.32);
145                         else if (seq->type == SEQ_ADJUSTMENT) rgb_byte_set_hue_float_offset(col, 0.40);
146                         break;
147
148                 case SEQ_COLOR:
149                         if (colvars->col) {
150                                 rgb_float_to_uchar(col, colvars->col);
151                         }
152                         else {
153                                 col[0] = col[1] = col[2] = 128;
154                         }
155                         break;
156                 
157                 case SEQ_PLUGIN:
158                         UI_GetThemeColor3ubv(TH_SEQ_PLUGIN, col);
159                         break;
160
161                 case SEQ_SOUND:
162                         UI_GetThemeColor3ubv(TH_SEQ_AUDIO, col);
163                         blendcol[0] = blendcol[1] = blendcol[2] = 128;
164                         if (seq->flag & SEQ_MUTE) UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20);
165                         break;
166                 
167                 default:
168                         col[0] = 10; col[1] = 255; col[2] = 40;
169         }
170 }
171
172 static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
173 {
174         /*
175          * x1 is the starting x value to draw the wave,
176          * x2 the end x value, same for y1 and y2
177          * stepsize is width of a pixel.
178          */
179         if (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM) {
180                 int i, j, pos;
181                 int length = floor((x2 - x1) / stepsize) + 1;
182                 float ymid = (y1 + y2) / 2;
183                 float yscale = (y2 - y1) / 2;
184                 float samplestep;
185                 float startsample, endsample;
186                 float value;
187
188                 SoundWaveform *waveform;
189
190                 if (!seq->sound->waveform)
191                         sound_read_waveform(seq->sound);
192
193                 if (!seq->sound->waveform)
194                         return;  /* zero length sound */
195
196                 waveform = seq->sound->waveform;
197
198                 if (!waveform)
199                         return;
200
201                 startsample = floor((seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
202                 endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
203                 samplestep = (endsample - startsample) * stepsize / (x2 - x1);
204
205                 if (length > floor((waveform->length - startsample) / samplestep))
206                         length = floor((waveform->length - startsample) / samplestep);
207
208                 glBegin(GL_LINE_STRIP);
209                 for (i = 0; i < length; i++) {
210                         pos = startsample + i * samplestep;
211
212                         value = waveform->data[pos * 3];
213
214                         for (j = pos + 1; (j < waveform->length) && (j < pos + samplestep); j++) {
215                                 if (value > waveform->data[j * 3])
216                                         value = waveform->data[j * 3];
217                         }
218
219                         glVertex2f(x1 + i * stepsize, ymid + value * yscale);
220                 }
221                 glEnd();
222
223                 glBegin(GL_LINE_STRIP);
224                 for (i = 0; i < length; i++) {
225                         pos = startsample + i * samplestep;
226
227                         value = waveform->data[pos * 3 + 1];
228
229                         for (j = pos + 1; (j < waveform->length) && (j < pos + samplestep); j++) {
230                                 if (value < waveform->data[j * 3 + 1])
231                                         value = waveform->data[j * 3 + 1];
232                         }
233
234                         glVertex2f(x1 + i * stepsize, ymid + value * yscale);
235                 }
236                 glEnd();
237         }
238 }
239
240 static void drawmeta_stipple(int value)
241 {
242         if (value) {
243                 glEnable(GL_POLYGON_STIPPLE);
244                 glPolygonStipple(stipple_halftone);
245                 
246                 glEnable(GL_LINE_STIPPLE);
247                 glLineStipple(1, 0x8888);
248         }
249         else {
250                 glDisable(GL_POLYGON_STIPPLE);
251                 glDisable(GL_LINE_STIPPLE);
252         }
253 }
254
255 static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
256 {
257         /* note: this used to use SEQ_BEGIN/SEQ_END, but it messes up the
258          * seq->depth value, (needed by transform when doing overlap checks)
259          * so for now, just use the meta's immediate children, could be fixed but
260          * its only drawing - campbell */
261         Sequence *seq;
262         unsigned char col[4];
263
264         int chan_min = MAXSEQ;
265         int chan_max = 0;
266         int chan_range = 0;
267         float draw_range = y2 - y1;
268         float draw_height;
269
270         glEnable(GL_BLEND);
271         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
272
273         if (seqm->flag & SEQ_MUTE)
274                 drawmeta_stipple(1);
275
276         for (seq = seqm->seqbase.first; seq; seq = seq->next) {
277                 chan_min = MIN2(chan_min, seq->machine);
278                 chan_max = MAX2(chan_max, seq->machine);
279         }
280
281         chan_range = (chan_max - chan_min) + 1;
282         draw_height = draw_range / chan_range;
283
284         col[3] = 196; /* alpha, used for all meta children */
285
286         for (seq = seqm->seqbase.first; seq; seq = seq->next) {
287                 if ((seq->startdisp > x2 || seq->enddisp < x1) == 0) {
288                         float y_chan = (seq->machine - chan_min) / (float)(chan_range) * draw_range;
289                         float x1_chan = seq->startdisp;
290                         float x2_chan = seq->enddisp;
291                         float y1_chan, y2_chan;
292
293                         if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
294                                 drawmeta_stipple(1);
295
296                         get_seq_color3ubv(scene, seq, col);
297
298                         glColor4ubv(col);
299                         
300                         /* clamp within parent sequence strip bounds */
301                         if (x1_chan < x1) x1_chan = x1;
302                         if (x2_chan > x2) x2_chan = x2;
303
304                         y1_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSBOTTOM);
305                         y2_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSTOP);
306
307                         glRectf(x1_chan,  y1_chan, x2_chan,  y2_chan);
308
309                         UI_GetColorPtrShade3ubv(col, col, -30);
310                         glColor4ubv(col);
311                         fdrawbox(x1_chan,  y1_chan, x2_chan,  y2_chan);
312
313                         if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
314                                 drawmeta_stipple(0);
315                 }
316         }
317
318         if (seqm->flag & SEQ_MUTE)
319                 drawmeta_stipple(0);
320         
321         glDisable(GL_BLEND);
322 }
323
324 /* draw a handle, for each end of a sequence strip */
325 static void draw_seq_handle(View2D *v2d, Sequence *seq, float pixelx, short direction)
326 {
327         float v1[2], v2[2], v3[2], rx1 = 0, rx2 = 0; //for triangles and rect
328         float x1, x2, y1, y2;
329         float handsize;
330         float minhandle, maxhandle;
331         char numstr[32];
332         unsigned int whichsel = 0;
333         
334         x1 = seq->startdisp;
335         x2 = seq->enddisp;
336         
337         y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
338         y2 = seq->machine + SEQ_STRIP_OFSTOP;
339         
340         /* clamp handles to defined size in pixel space */
341         handsize = seq->handsize;
342         minhandle = 7;
343         maxhandle = 40;
344         CLAMP(handsize, minhandle * pixelx, maxhandle * pixelx);
345         
346         /* set up co-ordinates/dimensions for either left or right handle */
347         if (direction == SEQ_LEFTHANDLE) {      
348                 rx1 = x1;
349                 rx2 = x1 + handsize * 0.75f;
350                 
351                 v1[0] = x1 + handsize / 4; v1[1] = y1 + ( ((y1 + y2) / 2.0f - y1) / 2);
352                 v2[0] = x1 + handsize / 4; v2[1] = y2 - ( ((y1 + y2) / 2.0f - y1) / 2);
353                 v3[0] = v2[0] + handsize / 4; v3[1] = (y1 + y2) / 2.0f;
354                 
355                 whichsel = SEQ_LEFTSEL;
356         }
357         else if (direction == SEQ_RIGHTHANDLE) {
358                 rx1 = x2 - handsize * 0.75f;
359                 rx2 = x2;
360                 
361                 v1[0] = x2 - handsize / 4; v1[1] = y1 + ( ((y1 + y2) / 2.0f - y1) / 2);
362                 v2[0] = x2 - handsize / 4; v2[1] = y2 - ( ((y1 + y2) / 2.0f - y1) / 2);
363                 v3[0] = v2[0] - handsize / 4; v3[1] = (y1 + y2) / 2.0f;
364                 
365                 whichsel = SEQ_RIGHTSEL;
366         }
367         
368         /* draw! */
369         if (seq->type < SEQ_EFFECT || 
370             get_sequence_effect_num_inputs(seq->type) == 0) {
371                 glEnable(GL_BLEND);
372                 
373                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
374                 
375                 if (seq->flag & whichsel) glColor4ub(0, 0, 0, 80);
376                 else if (seq->flag & SELECT) glColor4ub(255, 255, 255, 30);
377                 else glColor4ub(0, 0, 0, 22);
378                 
379                 glRectf(rx1, y1, rx2, y2);
380                 
381                 if (seq->flag & whichsel) glColor4ub(255, 255, 255, 200);
382                 else glColor4ub(0, 0, 0, 50);
383                 
384                 glEnable(GL_POLYGON_SMOOTH);
385                 glBegin(GL_TRIANGLES);
386                 glVertex2fv(v1); glVertex2fv(v2); glVertex2fv(v3);
387                 glEnd();
388                 
389                 glDisable(GL_POLYGON_SMOOTH);
390                 glDisable(GL_BLEND);
391         }
392         
393         if (G.moving || (seq->flag & whichsel)) {
394                 const char col[4] = {255, 255, 255, 255};
395                 if (direction == SEQ_LEFTHANDLE) {
396                         BLI_snprintf(numstr, sizeof(numstr), "%d", seq->startdisp);
397                         x1 = rx1;
398                         y1 -= 0.45f;
399                 }
400                 else {
401                         BLI_snprintf(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
402                         x1 = x2 - handsize * 0.75f;
403                         y1 = y2 + 0.05f;
404                 }
405                 UI_view2d_text_cache_add(v2d, x1, y1, numstr, col);
406         }       
407 }
408
409 static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq)
410 {
411         float x1, x2, y1, y2, pixely, a;
412         unsigned char col[3], blendcol[3];
413         View2D *v2d = &ar->v2d;
414         
415         if (seq->type >= SEQ_EFFECT) return;
416
417         x1 = seq->startdisp;
418         x2 = seq->enddisp;
419         
420         y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
421         y2 = seq->machine + SEQ_STRIP_OFSTOP;
422
423         pixely = (v2d->cur.ymax - v2d->cur.ymin) / (v2d->mask.ymax - v2d->mask.ymin);
424         
425         if (pixely <= 0) return;  /* can happen when the view is split/resized */
426         
427         blendcol[0] = blendcol[1] = blendcol[2] = 120;
428
429         if (seq->startofs) {
430                 glEnable(GL_BLEND);
431                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
432                 
433                 get_seq_color3ubv(scene, seq, col);
434                 
435                 if (seq->flag & SELECT) {
436                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
437                         glColor4ub(col[0], col[1], col[2], 170);
438                 }
439                 else {
440                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
441                         glColor4ub(col[0], col[1], col[2], 110);
442                 }
443                 
444                 glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
445                 
446                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
447                 else glColor4ub(col[0], col[1], col[2], 160);
448
449                 fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);  //outline
450                 
451                 glDisable(GL_BLEND);
452         }
453         if (seq->endofs) {
454                 glEnable(GL_BLEND);
455                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
456                 
457                 get_seq_color3ubv(scene, seq, col);
458                 
459                 if (seq->flag & SELECT) {
460                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
461                         glColor4ub(col[0], col[1], col[2], 170);
462                 }
463                 else {
464                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
465                         glColor4ub(col[0], col[1], col[2], 110);
466                 }
467                 
468                 glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
469                 
470                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
471                 else glColor4ub(col[0], col[1], col[2], 160);
472
473                 fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline
474                 
475                 glDisable(GL_BLEND);
476         }
477         if (seq->startstill) {
478                 get_seq_color3ubv(scene, seq, col);
479                 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
480                 glColor3ubv((GLubyte *)col);
481                 
482                 draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
483                 
484                 /* feint pinstripes, helps see exactly which is extended and which isn't,
485                  * especially when the extension is very small */ 
486                 if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
487                 else UI_GetColorPtrShade3ubv(col, col, -16);
488                 
489                 glColor3ubv((GLubyte *)col);
490                 
491                 for (a = y1; a < y2; a += pixely * 2.0f) {
492                         fdrawline(x1,  a,  (float)(seq->start),  a);
493                 }
494         }
495         if (seq->endstill) {
496                 get_seq_color3ubv(scene, seq, col);
497                 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
498                 glColor3ubv((GLubyte *)col);
499                 
500                 draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2);
501                 
502                 /* feint pinstripes, helps see exactly which is extended and which isn't,
503                  * especially when the extension is very small */ 
504                 if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24);
505                 else UI_GetColorPtrShade3ubv(col, col, -16);
506                 
507                 glColor3ubv((GLubyte *)col);
508                 
509                 for (a = y1; a < y2; a += pixely * 2.0f) {
510                         fdrawline((float)(seq->start + seq->len),  a,  x2,  a);
511                 }
512         }
513 }
514
515 /* draw info text on a sequence strip */
516 static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, const unsigned char background_col[3])
517 {
518         rctf rect;
519         char str[32 + FILE_MAX];
520         const char *name = seq->name + 2;
521         char col[4];
522
523         /* note, all strings should include 'name' */
524         if (name[0] == '\0')
525                 name = give_seqname(seq);
526
527         if (seq->type == SEQ_META || seq->type == SEQ_ADJUSTMENT) {
528                 BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name);
529         }
530         else if (seq->type == SEQ_SCENE) {
531                 if (seq->scene) {
532                         if (seq->scene_camera) {
533                                 BLI_snprintf(str, sizeof(str), "%d | %s: %s (%s)",
534                                              seq->len, name, seq->scene->id.name + 2, ((ID *)seq->scene_camera)->name + 2);
535                         }
536                         else {
537                                 BLI_snprintf(str, sizeof(str), "%d | %s: %s",
538                                              seq->len, name, seq->scene->id.name + 2);
539                         }
540                 }
541                 else {
542                         BLI_snprintf(str, sizeof(str), "%d | %s",
543                                      seq->len, name);
544                 }
545         }
546         else if (seq->type == SEQ_MOVIECLIP) {
547                 if (seq->clip && strcmp(name, seq->clip->id.name + 2) != 0) {
548                         BLI_snprintf(str, sizeof(str), "%d | %s: %s",
549                                      seq->len, name, seq->clip->id.name + 2);
550                 }
551                 else {
552                         BLI_snprintf(str, sizeof(str), "%d | %s",
553                                      seq->len, name);
554                 }
555         }
556         else if (seq->type == SEQ_MULTICAM) {
557                 BLI_snprintf(str, sizeof(str), "Cam | %s: %d",
558                              name, seq->multicam_source);
559         }
560         else if (seq->type == SEQ_IMAGE) {
561                 BLI_snprintf(str, sizeof(str), "%d | %s: %s%s",
562                              seq->len, name, seq->strip->dir, seq->strip->stripdata->name);
563         }
564         else if (seq->type & SEQ_EFFECT) {
565                 int can_float = (seq->type != SEQ_PLUGIN) || (seq->plugin && seq->plugin->version >= 4);
566
567                 if (seq->seq3 != seq->seq2 && seq->seq1 != seq->seq3) {
568                         BLI_snprintf(str, sizeof(str), "%d | %s: %d>%d (use %d)%s",
569                                      seq->len, name, seq->seq1->machine, seq->seq2->machine, seq->seq3->machine,
570                                      can_float ? "" : " No float, upgrade plugin!");
571                 }
572                 else if (seq->seq1 && seq->seq2) {
573                         BLI_snprintf(str, sizeof(str), "%d | %s: %d>%d%s",
574                                      seq->len, name, seq->seq1->machine, seq->seq2->machine,
575                                      can_float ? "" : " No float, upgrade plugin!");
576                 }
577                 else {
578                         BLI_snprintf(str, sizeof(str), "%d | %s",
579                                      seq->len, name);
580                 }
581         }
582         else if (seq->type == SEQ_SOUND) {
583                 if (seq->sound)
584                         BLI_snprintf(str, sizeof(str), "%d | %s: %s",
585                                      seq->len, name, seq->sound->name);
586                 else
587                         BLI_snprintf(str, sizeof(str), "%d | %s",
588                                      seq->len, name);
589         }
590         else if (seq->type == SEQ_MOVIE) {
591                 BLI_snprintf(str, sizeof(str), "%d | %s: %s%s",
592                              seq->len, name, seq->strip->dir, seq->strip->stripdata->name);
593         }
594         
595         if (seq->flag & SELECT) {
596                 col[0] = col[1] = col[2] = 255;
597         }
598         else if ((((int)background_col[0] + (int)background_col[1] + (int)background_col[2]) / 3) < 50) {
599                 col[0] = col[1] = col[2] = 80; /* use lighter text color for dark background */
600         }
601         else {
602                 col[0] = col[1] = col[2] = 0;
603         }
604         col[3] = 255;
605
606         rect.xmin = x1;
607         rect.ymin = y1;
608         rect.xmax = x2;
609         rect.ymax = y2;
610         UI_view2d_text_cache_rectf(v2d, &rect, str, col);
611 }
612
613 /* draws a shaded strip, made from gradient + flat color + gradient */
614 static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2)
615 {
616         float ymid1, ymid2;
617         
618         if (seq->flag & SEQ_MUTE) {
619                 glEnable(GL_POLYGON_STIPPLE);
620                 glPolygonStipple(stipple_halftone);
621         }
622         
623         ymid1 = (y2 - y1) * 0.25f + y1;
624         ymid2 = (y2 - y1) * 0.65f + y1;
625         
626         glShadeModel(GL_SMOOTH);
627         glBegin(GL_QUADS);
628         
629         if (seq->flag & SEQ_INVALID_EFFECT) { col[0] = 255; col[1] = 0; col[2] = 255; }
630         else if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, -50);
631         /* else UI_GetColorPtrShade3ubv(col, col, 0); */ /* DO NOTHING */
632         
633         glColor3ubv(col);
634         
635         glVertex2f(x1, y1);
636         glVertex2f(x2, y1);
637
638         if (seq->flag & SEQ_INVALID_EFFECT) { col[0] = 255; col[1] = 0; col[2] = 255; }
639         else if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
640         else UI_GetColorPtrShade3ubv(col, col, -5);
641
642         glColor3ubv((GLubyte *)col);
643         
644         glVertex2f(x2, ymid1);
645         glVertex2f(x1, ymid1);
646         
647         glEnd();
648         
649         glRectf(x1,  ymid1,  x2,  ymid2);
650         
651         glBegin(GL_QUADS);
652         
653         glVertex2f(x1, ymid2);
654         glVertex2f(x2, ymid2);
655         
656         if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, -15);
657         else UI_GetColorPtrShade3ubv(col, col, 25);
658         
659         glColor3ubv((GLubyte *)col);
660         
661         glVertex2f(x2, y2);
662         glVertex2f(x1, y2);
663         
664         glEnd();
665         
666         if (seq->flag & SEQ_MUTE) {
667                 glDisable(GL_POLYGON_STIPPLE);
668         }
669 }
670
671 /*
672  * Draw a sequence strip, bounds check already made
673  * ARegion is currently only used to get the windows width in pixels
674  * so wave file sample drawing precision is zoom adjusted
675  */
676 static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx)
677 {
678         View2D *v2d = &ar->v2d;
679         float x1, x2, y1, y2;
680         unsigned char col[3], background_col[3], is_single_image;
681
682         /* we need to know if this is a single image/color or not for drawing */
683         is_single_image = (char)seq_single_check(seq);
684         
685         /* body */
686         x1 = (seq->startstill) ? seq->start : seq->startdisp;
687         y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
688         x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp;
689         y2 = seq->machine + SEQ_STRIP_OFSTOP;
690
691
692         /* get the correct color per strip type*/
693         //get_seq_color3ubv(scene, seq, col);
694         get_seq_color3ubv(scene, seq, background_col);
695         
696         /* draw the main strip body */
697         if (is_single_image) {  /* single image */
698                 draw_shadedstrip(seq, background_col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2);
699         }
700         else {  /* normal operation */
701                 draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
702         }
703         
704         /* draw additional info and controls */
705         if (!is_single_image)
706                 draw_seq_extensions(scene, ar, seq);
707         
708         draw_seq_handle(v2d, seq, pixelx, SEQ_LEFTHANDLE);
709         draw_seq_handle(v2d, seq, pixelx, SEQ_RIGHTHANDLE);
710         
711         /* draw the strip outline */
712         x1 = seq->startdisp;
713         x2 = seq->enddisp;
714         
715         /* draw sound wave */
716         if (seq->type == SEQ_SOUND) {
717                 drawseqwave(scene, seq, x1, y1, x2, y2, (ar->v2d.cur.xmax - ar->v2d.cur.xmin) / ar->winx);
718         }
719
720         /* draw lock */
721         if (seq->flag & SEQ_LOCK) {
722                 glEnable(GL_POLYGON_STIPPLE);
723                 glEnable(GL_BLEND);
724
725                 /* light stripes */
726                 glColor4ub(255, 255, 255, 32);
727                 glPolygonStipple(stipple_diag_stripes_pos);
728                 glRectf(x1, y1, x2, y2);
729
730                 /* dark stripes */
731                 glColor4ub(0, 0, 0, 32);
732                 glPolygonStipple(stipple_diag_stripes_neg);
733                 glRectf(x1, y1, x2, y2);
734
735                 glDisable(GL_POLYGON_STIPPLE);
736                 glDisable(GL_BLEND);
737         }
738
739         get_seq_color3ubv(scene, seq, col);
740         if (G.moving && (seq->flag & SELECT)) {
741                 if (seq->flag & SEQ_OVERLAP) {
742                         col[0] = 255; col[1] = col[2] = 40;
743                 }
744                 else
745                         UI_GetColorPtrShade3ubv(col, col, 120 + outline_tint);
746         }
747         else
748                 UI_GetColorPtrShade3ubv(col, col, outline_tint);
749         
750         glColor3ubv((GLubyte *)col);
751         
752         if (seq->flag & SEQ_MUTE) {
753                 glEnable(GL_LINE_STIPPLE);
754                 glLineStipple(1, 0x8888);
755         }
756         
757         uiDrawBoxShade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
758         
759         if (seq->flag & SEQ_MUTE) {
760                 glDisable(GL_LINE_STIPPLE);
761         }
762         
763         if (seq->type == SEQ_META) {
764                 drawmeta_contents(scene, seq, x1, y1, x2, y2);
765         }
766         
767         /* calculate if seq is long enough to print a name */
768         x1 = seq->startdisp + seq->handsize;
769         x2 = seq->enddisp - seq->handsize;
770
771         /* info text on the strip */
772         if (x1 < v2d->cur.xmin) x1 = v2d->cur.xmin;
773         else if (x1 > v2d->cur.xmax) x1 = v2d->cur.xmax;
774         if (x2 < v2d->cur.xmin) x2 = v2d->cur.xmin;
775         else if (x2 > v2d->cur.xmax) x2 = v2d->cur.xmax;
776
777         /* nice text here would require changing the view matrix for texture text */
778         if ((x2 - x1) / pixelx > 32) {
779                 draw_seq_text(v2d, seq, x1, x2, y1, y2, background_col);
780         }
781 }
782
783 static Sequence *special_seq_update = NULL;
784
785 static void UNUSED_FUNCTION(set_special_seq_update) (int val)
786 {
787 //      int x;
788
789         /* if mouse over a sequence && LEFTMOUSE */
790         if (val) {
791 // XXX          special_seq_update= find_nearest_seq(&x);
792         }
793         else special_seq_update = NULL;
794 }
795
796 void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs)
797 {
798         struct Main *bmain = CTX_data_main(C);
799         struct ImBuf *ibuf = NULL;
800         struct ImBuf *scope = NULL;
801         struct View2D *v2d = &ar->v2d;
802         int rectx, recty;
803         float viewrectx, viewrecty;
804         float render_size = 0.0;
805         float proxy_size = 100.0;
806         float col[3];
807         GLuint texid;
808         GLuint last_texid;
809         SeqRenderData context;
810
811         render_size = sseq->render_size;
812         if (render_size == 0) {
813                 render_size = scene->r.size;
814         }
815         else {
816                 proxy_size = render_size;
817         }
818         if (render_size < 0) {
819                 return;
820         }
821
822         viewrectx = (render_size * (float)scene->r.xsch) / 100.0f;
823         viewrecty = (render_size * (float)scene->r.ysch) / 100.0f;
824
825         rectx = viewrectx + 0.5f;
826         recty = viewrecty + 0.5f;
827
828         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
829                 viewrectx *= scene->r.xasp / scene->r.yasp;
830                 viewrectx /= proxy_size / 100.0f;
831                 viewrecty /= proxy_size / 100.0f;
832         }
833
834         if (frame_ofs == 0) {
835                 UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col);
836                 glClearColor(col[0], col[1], col[2], 0.0);
837                 glClear(GL_COLOR_BUFFER_BIT);
838         }
839
840         /* without this colors can flicker from previous opengl state */
841         glColor4ub(255, 255, 255, 255);
842
843         UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f);
844         UI_view2d_curRect_validate(v2d);
845
846         /* only initialize the preview if a render is in progress */
847         if (G.rendering)
848                 return;
849
850         context = seq_new_render_data(bmain, scene, rectx, recty, proxy_size);
851
852         if (special_seq_update)
853                 ibuf = give_ibuf_seq_direct(context, cfra + frame_ofs, special_seq_update);
854         else if (!U.prefetchframes) // XXX || (G.f & G_PLAYANIM) == 0) {
855                 ibuf = give_ibuf_seq(context, cfra + frame_ofs, sseq->chanshown);
856         else
857                 ibuf = give_ibuf_seq_threaded(context, cfra + frame_ofs, sseq->chanshown);
858         
859         if (ibuf == NULL)
860                 return;
861
862         if (ibuf->rect == NULL && ibuf->rect_float == NULL)
863                 return;
864         
865         switch (sseq->mainb) {
866                 case SEQ_DRAW_IMG_IMBUF:
867                         if (sseq->zebra != 0) {
868                                 scope = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
869                         }
870                         break;
871                 case SEQ_DRAW_IMG_WAVEFORM:
872                         if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) {
873                                 scope = make_sep_waveform_view_from_ibuf(ibuf);
874                         }
875                         else {
876                                 scope = make_waveform_view_from_ibuf(ibuf);
877                         }
878                         break;
879                 case SEQ_DRAW_IMG_VECTORSCOPE:
880                         scope = make_vectorscope_view_from_ibuf(ibuf);
881                         break;
882                 case SEQ_DRAW_IMG_HISTOGRAM:
883                         scope = make_histogram_view_from_ibuf(ibuf);
884                         break;
885         }
886
887         if (scope) {
888                 IMB_freeImBuf(ibuf);
889                 ibuf = scope;
890         }
891
892         if (ibuf->rect_float && ibuf->rect == NULL) {
893                 IMB_rect_from_float(ibuf);      
894         }
895         
896         /* setting up the view - actual drawing starts here */
897         UI_view2d_view_ortho(v2d);
898
899         last_texid = glaGetOneInteger(GL_TEXTURE_2D);
900         glEnable(GL_TEXTURE_2D);
901         glGenTextures(1, (GLuint *)&texid);
902
903         glBindTexture(GL_TEXTURE_2D, texid);
904
905         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
906         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
907
908         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
909         glBegin(GL_QUADS);
910
911         if (frame_ofs) {
912                 rctf tot_clip;
913                 tot_clip.xmin = v2d->tot.xmin + (ABS(v2d->tot.xmax - v2d->tot.xmin) * scene->ed->over_border.xmin);
914                 tot_clip.ymin = v2d->tot.ymin + (ABS(v2d->tot.ymax - v2d->tot.ymin) * scene->ed->over_border.ymin);
915                 tot_clip.xmax = v2d->tot.xmin + (ABS(v2d->tot.xmax - v2d->tot.xmin) * scene->ed->over_border.xmax);
916                 tot_clip.ymax = v2d->tot.ymin + (ABS(v2d->tot.ymax - v2d->tot.ymin) * scene->ed->over_border.ymax);
917
918                 glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymin); glVertex2f(tot_clip.xmin, tot_clip.ymin);
919                 glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymax); glVertex2f(tot_clip.xmin, tot_clip.ymax);
920                 glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymax); glVertex2f(tot_clip.xmax, tot_clip.ymax);
921                 glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymin); glVertex2f(tot_clip.xmax, tot_clip.ymin);
922         }
923         else {
924                 glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin);
925                 glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax);
926                 glTexCoord2f(1.0f, 1.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymax);
927                 glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
928         }
929         glEnd();
930         glBindTexture(GL_TEXTURE_2D, last_texid);
931         glDisable(GL_TEXTURE_2D);
932         glDeleteTextures(1, &texid);
933
934         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
935
936                 float x1 = v2d->tot.xmin;
937                 float y1 = v2d->tot.ymin;
938                 float x2 = v2d->tot.xmax;
939                 float y2 = v2d->tot.ymax;
940
941                 /* border */
942                 setlinestyle(3);
943
944                 UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
945
946                 glBegin(GL_LINE_LOOP);
947                 glVertex2f(x1 - 0.5f, y1 - 0.5f);
948                 glVertex2f(x1 - 0.5f, y2 + 0.5f);
949                 glVertex2f(x2 + 0.5f, y2 + 0.5f);
950                 glVertex2f(x2 + 0.5f, y1 - 0.5f);
951                 glEnd();
952
953                 /* safety border */
954                 if ((sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
955                         float fac = 0.1;
956
957                         float a = fac * (x2 - x1);
958                         x1 += a;
959                         x2 -= a;
960
961                         a = fac * (y2 - y1);
962                         y1 += a;
963                         y2 -= a;
964
965                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
966
967                         uiSetRoundBox(UI_CNR_ALL);
968                         uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
969
970                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
971
972                 }
973
974                 setlinestyle(0);
975         }
976         
977         /* draw grease-pencil (image aligned) */
978 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
979 // XXX          draw_gpencil_2dimage(sa, ibuf);
980
981         IMB_freeImBuf(ibuf);
982         
983         /* draw grease-pencil (screen aligned) */
984 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
985 // XXX          draw_gpencil_view2d(sa, 0);
986         
987         /* ortho at pixel level */
988         UI_view2d_view_restore(C);
989 }
990
991 #if 0
992 void drawprefetchseqspace(Scene *scene, ARegion *UNUSED(ar), SpaceSeq *sseq)
993 {
994         int rectx, recty;
995         int render_size = sseq->render_size;
996         int proxy_size = 100.0; 
997         if (render_size == 0) {
998                 render_size = scene->r.size;
999         }
1000         else {
1001                 proxy_size = render_size;
1002         }
1003         if (render_size < 0) {
1004                 return;
1005         }
1006
1007         rectx = (render_size * scene->r.xsch) / 100;
1008         recty = (render_size * scene->r.ysch) / 100;
1009
1010         if (sseq->mainb != SEQ_DRAW_SEQUENCE) {
1011                 give_ibuf_prefetch_request(
1012                     rectx, recty, (scene->r.cfra), sseq->chanshown,
1013                     proxy_size);
1014         }
1015 }
1016 #endif
1017
1018 /* draw backdrop of the sequencer strips view */
1019 static void draw_seq_backdrop(View2D *v2d)
1020 {
1021         int i;
1022         
1023         /* darker grey overlay over the view backdrop */
1024         UI_ThemeColorShade(TH_BACK, -20);
1025         glRectf(v2d->cur.xmin,  -1.0,  v2d->cur.xmax,  1.0);
1026
1027         /* Alternating horizontal stripes */
1028         i = MAX2(1, ((int)v2d->cur.ymin) - 1);
1029
1030         glBegin(GL_QUADS);
1031         while (i < v2d->cur.ymax) {
1032                 if (((int)i) & 1)
1033                         UI_ThemeColorShade(TH_BACK, -15);
1034                 else
1035                         UI_ThemeColorShade(TH_BACK, -25);
1036                         
1037                 glVertex2f(v2d->cur.xmax, i);
1038                 glVertex2f(v2d->cur.xmin, i);
1039                 glVertex2f(v2d->cur.xmin, i + 1);
1040                 glVertex2f(v2d->cur.xmax, i + 1);
1041
1042                 i += 1.0;
1043         }
1044         glEnd();
1045         
1046         /* Darker lines separating the horizontal bands */
1047         i = MAX2(1, ((int)v2d->cur.ymin) - 1);
1048         UI_ThemeColor(TH_GRID);
1049         
1050         glBegin(GL_LINES);
1051         while (i < v2d->cur.ymax) {
1052                 glVertex2f(v2d->cur.xmax, i);
1053                 glVertex2f(v2d->cur.xmin, i);
1054                         
1055                 i += 1.0;
1056         }
1057         glEnd();
1058 }
1059
1060 /* draw the contents of the sequencer strips view */
1061 static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
1062 {
1063         Scene *scene = CTX_data_scene(C);
1064         View2D *v2d = &ar->v2d;
1065         Sequence *last_seq = BKE_sequencer_active_get(scene);
1066         int sel = 0, j;
1067         float pixelx = (v2d->cur.xmax - v2d->cur.xmin) / (v2d->mask.xmax - v2d->mask.xmin);
1068         
1069         /* loop through twice, first unselected, then selected */
1070         for (j = 0; j < 2; j++) {
1071                 Sequence *seq;
1072                 int outline_tint = (j) ? -60 : -150; /* highlighting around strip edges indicating selection */
1073                 
1074                 /* loop through strips, checking for those that are visible */
1075                 for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1076                         /* boundbox and selection tests for NOT drawing the strip... */
1077                         if ((seq->flag & SELECT) != sel) continue;
1078                         else if (seq == last_seq) continue;
1079                         else if (MIN2(seq->startdisp, seq->start) > v2d->cur.xmax) continue;
1080                         else if (MAX2(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) continue;
1081                         else if (seq->machine + 1.0f < v2d->cur.ymin) continue;
1082                         else if (seq->machine > v2d->cur.ymax) continue;
1083                         
1084                         /* strip passed all tests unscathed... so draw it now */
1085                         draw_seq_strip(scene, ar, seq, outline_tint, pixelx);
1086                 }
1087                 
1088                 /* draw selected next time round */
1089                 sel = SELECT;
1090         }
1091         
1092         /* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */
1093         if (last_seq)
1094                 draw_seq_strip(scene, ar, last_seq, 120, pixelx);
1095 }
1096
1097 static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
1098 {       
1099         glEnable(GL_BLEND);
1100         
1101         /* draw darkened area outside of active timeline 
1102          * frame range used is preview range or scene range */
1103         UI_ThemeColorShadeAlpha(TH_BACK, -25, -100);
1104
1105         if (PSFRA < PEFRA) {
1106                 glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
1107                 glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
1108         }
1109         else {
1110                 glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
1111         }
1112
1113         UI_ThemeColorShade(TH_BACK, -60);
1114         /* thin lines where the actual frames are */
1115         fdrawline((float)PSFRA, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
1116         fdrawline((float)PEFRA, v2d->cur.ymin, (float)PEFRA, v2d->cur.ymax);
1117         
1118         glDisable(GL_BLEND);
1119 }
1120
1121 /* Draw Timeline/Strip Editor Mode for Sequencer */
1122 void draw_timeline_seq(const bContext *C, ARegion *ar)
1123 {
1124         Scene *scene = CTX_data_scene(C);
1125         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1126         SpaceSeq *sseq = CTX_wm_space_seq(C);
1127         View2D *v2d = &ar->v2d;
1128         View2DScrollers *scrollers;
1129         short unit = 0, flag = 0;
1130         float col[3];
1131         
1132         /* clear and setup matrix */
1133         UI_GetThemeColor3fv(TH_BACK, col);
1134         if (ed && ed->metastack.first) 
1135                 glClearColor(col[0], col[1], col[2] - 0.1f, 0.0f);
1136         else 
1137                 glClearColor(col[0], col[1], col[2], 0.0f);
1138         glClear(GL_COLOR_BUFFER_BIT);
1139
1140         UI_view2d_view_ortho(v2d);
1141         
1142         
1143         /* calculate extents of sequencer strips/data 
1144          * NOTE: needed for the scrollers later
1145          */
1146         boundbox_seq(scene, &v2d->tot);
1147         
1148         
1149         /* draw backdrop */
1150         draw_seq_backdrop(v2d);
1151         
1152         /* regular grid-pattern over the rest of the view (i.e. 25-frame grid lines) */
1153         // NOTE: the gridlines are currently spaced every 25 frames, which is only fine for 25 fps, but maybe not for 30...
1154         UI_view2d_constant_grid_draw(v2d);
1155         
1156         seq_draw_sfra_efra(scene, v2d);
1157
1158         /* sequence strips (if there is data available to be drawn) */
1159         if (ed) {
1160                 /* draw the data */
1161                 draw_seq_strips(C, ed, ar);
1162                 
1163                 /* text draw cached (for sequence names), in pixelspace now */
1164                 UI_view2d_text_cache_draw(ar);
1165         }
1166         
1167         /* current frame */
1168         UI_view2d_view_ortho(v2d);
1169         if ((sseq->flag & SEQ_DRAWFRAMES) == 0)      flag |= DRAWCFRA_UNIT_SECONDS;
1170         if ((sseq->flag & SEQ_NO_DRAW_CFRANUM) == 0) flag |= DRAWCFRA_SHOW_NUMBOX;
1171         ANIM_draw_cfra(C, v2d, flag);
1172         
1173         /* markers */
1174         UI_view2d_view_orthoSpecial(ar, v2d, 1);
1175         draw_markers_time(C, DRAW_MARKERS_LINES);
1176         
1177         /* preview range */
1178         UI_view2d_view_ortho(v2d);
1179         ANIM_draw_previewrange(C, v2d);
1180
1181         /* overlap playhead */
1182         if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
1183                 int cfra_over = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ? scene->ed->over_cfra : scene->r.cfra + scene->ed->over_ofs;
1184                 glColor3f(0.2, 0.2, 0.2);
1185                 // glRectf(cfra_over, v2d->cur.ymin, scene->ed->over_ofs + scene->r.cfra + 1, v2d->cur.ymax);
1186
1187                 glBegin(GL_LINES);
1188                 glVertex2f(cfra_over, v2d->cur.ymin);
1189                 glVertex2f(cfra_over, v2d->cur.ymax);
1190                 glEnd();
1191
1192         }
1193         
1194         /* reset view matrix */
1195         UI_view2d_view_restore(C);
1196
1197         /* scrollers */
1198         unit = (sseq->flag & SEQ_DRAWFRAMES) ? V2D_UNIT_FRAMES : V2D_UNIT_SECONDSSEQ;
1199         scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
1200         UI_view2d_scrollers_draw(C, v2d, scrollers);
1201         UI_view2d_scrollers_free(scrollers);
1202 }
1203
1204