2.5
[blender.git] / source / blender / editors / space_sequencer / sequencer_draw.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, 2003-2009
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <string.h>
29 #include <math.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "BMF_Api.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_arithb.h"
37
38 #include "IMB_imbuf_types.h"
39
40 #include "DNA_gpencil_types.h"
41 #include "DNA_sequence_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_view2d_types.h"
46 #include "DNA_userdef_types.h"
47
48 #include "BKE_context.h"
49 #include "BKE_global.h"
50 #include "BKE_plugin_types.h"
51 #include "BKE_sequence.h"
52 #include "BKE_scene.h"
53 #include "BKE_utildefines.h"
54  
55 #include "IMB_imbuf_types.h"
56 #include "IMB_imbuf.h"
57
58 #include "BIF_gl.h"
59 #include "BIF_glutil.h"
60
61 #include "ED_anim_api.h"
62 #include "ED_space_api.h"
63 #include "ED_types.h"
64
65 #include "UI_interface.h"
66 #include "UI_resources.h"
67 #include "UI_view2d.h"
68
69 /* own include */
70 #include "sequencer_intern.h"
71
72 #define SEQ_LEFTHANDLE          1
73 #define SEQ_RIGHTHANDLE 2
74
75 #define SEQ_STRIP_OFSBOTTOM             0.2
76 #define SEQ_STRIP_OFSTOP                0.8
77
78 /* Note, Dont use WHILE_SEQ while drawing! - it messes up transform, - Campbell */
79
80 int no_rightbox=0, no_leftbox= 0;
81 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2);
82
83
84 static void draw_cfra_seq(View2D *v2d, int cfra)
85 {
86         glColor3ub(0x30, 0x90, 0x50);
87         glLineWidth(2.0);
88         glBegin(GL_LINES);
89         glVertex2f(cfra, v2d->cur.ymin);
90         glVertex2f(cfra, v2d->cur.ymax);
91         glEnd();
92         glLineWidth(1.0);
93 }
94
95 static void get_seq_color3ubv(Scene *curscene, Sequence *seq, char *col)
96 {
97         char blendcol[3];
98         float hsv[3], rgb[3];
99         SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
100
101         switch(seq->type) {
102         case SEQ_IMAGE:
103                 UI_GetThemeColor3ubv(TH_SEQ_IMAGE, col);
104                 break;
105         case SEQ_META:
106                 UI_GetThemeColor3ubv(TH_SEQ_META, col);
107                 break;
108         case SEQ_MOVIE:
109                 UI_GetThemeColor3ubv(TH_SEQ_MOVIE, col);
110                 break;
111         case SEQ_SCENE:
112                 UI_GetThemeColor3ubv(TH_SEQ_SCENE, col);
113                 
114                 if(seq->scene==curscene) {
115                         UI_GetColorPtrBlendShade3ubv(col, col, col, 1.0, 20);
116                 }
117                 break;
118
119         /* transitions */
120         case SEQ_CROSS:
121         case SEQ_GAMCROSS:
122         case SEQ_WIPE:
123                 /* slightly offset hue to distinguish different effects */
124                 UI_GetThemeColor3ubv(TH_SEQ_TRANSITION, col);
125                 
126                 rgb[0] = col[0]/255.0; rgb[1] = col[1]/255.0; rgb[2] = col[2]/255.0; 
127                 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
128                 
129                 if (seq->type == SEQ_CROSS)             hsv[0]+= 0.04;
130                 if (seq->type == SEQ_GAMCROSS)  hsv[0]+= 0.08;
131                 if (seq->type == SEQ_WIPE)              hsv[0]+= 0.12;
132                 
133                 if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
134                 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
135                 col[0] = (char)(rgb[0]*255); col[1] = (char)(rgb[1]*255); col[2] = (char)(rgb[2]*255); 
136                 break;
137                 
138         /* effects */
139         case SEQ_TRANSFORM:
140         case SEQ_SPEED:
141         case SEQ_ADD:
142         case SEQ_SUB:
143         case SEQ_MUL:
144         case SEQ_ALPHAOVER:
145         case SEQ_ALPHAUNDER:
146         case SEQ_OVERDROP:
147         case SEQ_GLOW:
148                 /* slightly offset hue to distinguish different effects */
149                 UI_GetThemeColor3ubv(TH_SEQ_EFFECT, col);
150                 
151                 rgb[0] = col[0]/255.0; rgb[1] = col[1]/255.0; rgb[2] = col[2]/255.0; 
152                 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
153                 
154                 if (seq->type == SEQ_ADD)               hsv[0]+= 0.04;
155                 if (seq->type == SEQ_SUB)               hsv[0]+= 0.08;
156                 if (seq->type == SEQ_MUL)               hsv[0]+= 0.12;
157                 if (seq->type == SEQ_ALPHAOVER) hsv[0]+= 0.16;
158                 if (seq->type == SEQ_ALPHAUNDER)        hsv[0]+= 0.20;
159                 if (seq->type == SEQ_OVERDROP)  hsv[0]+= 0.24;
160                 if (seq->type == SEQ_GLOW)              hsv[0]+= 0.28;
161                 if (seq->type == SEQ_TRANSFORM)         hsv[0]+= 0.36;
162
163                 if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
164                 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
165                 col[0] = (char)(rgb[0]*255); col[1] = (char)(rgb[1]*255); col[2] = (char)(rgb[2]*255); 
166                 break;
167         case SEQ_COLOR:
168                 if (colvars->col) {
169                         col[0]= (char)(colvars->col[0]*255);
170                         col[1]= (char)(colvars->col[1]*255);
171                         col[2]= (char)(colvars->col[2]*255);
172                 } else {
173                         col[0] = col[1] = col[2] = 128;
174                 }
175                 break;
176         case SEQ_PLUGIN:
177                 UI_GetThemeColor3ubv(TH_SEQ_PLUGIN, col);
178                 break;
179         case SEQ_HD_SOUND:
180         case SEQ_RAM_SOUND:
181                 UI_GetThemeColor3ubv(TH_SEQ_AUDIO, col);
182                 blendcol[0] = blendcol[1] = blendcol[2] = 128;
183                 if(seq->flag & SEQ_MUTE) UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20);
184                 break;
185         default:
186                 col[0] = 10; col[1] = 255; col[2] = 40;
187         }
188 }
189
190 static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
191 {
192         /* Note, this used to use WHILE_SEQ, but it messes up the seq->depth value, (needed by transform when doing overlap checks)
193          * so for now, just use the meta's immediate children, could be fixed but its only drawing - Campbell */
194         Sequence *seq;
195         float dx;
196         int nr;
197         char col[3];
198         
199         nr= BLI_countlist(&seqm->seqbase);
200
201         dx= (x2-x1)/nr;
202
203         if (seqm->flag & SEQ_MUTE) {
204                 glEnable(GL_POLYGON_STIPPLE);
205                 glPolygonStipple(stipple_halftone);
206                 
207                 glEnable(GL_LINE_STIPPLE);
208                 glLineStipple(1, 0x8888);
209         }
210         
211         for (seq= seqm->seqbase.first; seq; seq= seq->next) {
212                 get_seq_color3ubv(scene, seq, col);
213                 
214                 glColor3ubv((GLubyte *)col);
215
216                 glRectf(x1,  y1,  x1+0.9*dx,  y2);
217                 
218                 UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -30);
219                 glColor3ubv((GLubyte *)col);
220
221                 fdrawbox(x1,  y1,  x1+0.9*dx,  y2);
222                 
223                 x1+= dx;
224         }
225         
226         if (seqm->flag & SEQ_MUTE) {
227                 glDisable(GL_POLYGON_STIPPLE);
228                 glDisable(GL_LINE_STIPPLE);
229         }
230 }
231
232 static void drawseqwave(Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, int winx)
233 {
234         /*
235         x1 is the starting x value to draw the wave,
236         x2 the end x value, same for y1 and y2
237         winx is the zoom level.
238         */
239         
240         float
241         f, /* floating point value used to store the X draw location for the wave lines when openGL drawing*/
242         midy, /* fast access to the middle location (y1+y2)/2 */
243         clipxmin, /* the minimum X value, clip this with the window */
244         clipxmax, /* the maximum X value, clip this with the window */
245         sample_step, /* steps to move per sample, floating value must later translate into an int */
246         fsofs, /* steps to move per sample, floating value must later translate into an int */
247         feofs_sofs, /*  */
248         sound_width, /* convenience: x2-x1 */
249         wavemulti; /* scale the samples by this value when GL_LINE drawing so it renders the right height */
250         
251         int
252         offset, /* initial offset value for the wave drawing */
253         offset_next, /* when in the wave drawing loop this value is the samples intil the next vert */
254         sofs, /* Constrained offset value (~3) for the wave, start */
255         eofs, /* ditto, end */
256         wavesample, /* inner loop storage if the current wave sample value, used to make the 2 values below */
257         wavesamplemin, /* used for finding the min and max wave peaks */
258         wavesamplemax, /* ditto */
259         subsample_step=4; /* when the sample step is 4 every sample of
260         the wave is evaluated for min and max values used to draw the wave,
261         however this is slow ehrn zoomed out so when the sample step is above
262         1 (the larger the further out the zoom is) so not evaluate all samples, only some. */
263         
264         signed short* s;
265         bSound *sound;
266         uint8_t *stream;
267         
268 // XXX  audio_makestream(seq->sound);
269 //      if(seq->sound==NULL || seq->sound->stream==NULL) return;
270         
271         if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0);
272         
273         sofs = ((int)( FRA2TIME(seq->startdisp-seq->start+seq->anim_startofs)*(float)scene->r.audio.mixrate*4.0 )) & (~3);
274         eofs = ((int)( FRA2TIME(seq->enddisp-seq->start+seq->anim_startofs)*(float)scene->r.audio.mixrate*4.0 )) & (~3);
275         
276         /* clip the drawing area to the screen bounds to save time */
277         sample_step= (v2d->cur.xmax - v2d->cur.xmin)/winx;
278         clipxmin= MAX2(x1, v2d->cur.xmin);
279         clipxmax= MIN2(x2, v2d->cur.xmax);
280         
281         if (sample_step > 1)
282                 subsample_step= ((int)(subsample_step*sample_step*8)) & (~3);
283         
284         /* for speedy access */
285         midy = (y1+y2)/2;
286         fsofs= (float)sofs;
287         feofs_sofs= (float)(eofs-sofs);
288         sound_width= x2-x1;
289         sound = seq->sound;
290         stream = sound->stream;
291         wavemulti = (y2-y1)/196605; /*y2-y1 is the height*/
292         wavesample=0;
293         
294         /* we need to get the starting offset value, excuse the duplicate code */
295         f=clipxmin;
296         offset= (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3);
297         
298         /* start the loop, draw a line per sample_step -sample_step is about 1 line drawn per pixel */
299         glBegin(GL_LINES);
300         for (f=x1+sample_step; f<=clipxmax; f+=sample_step) {
301                 
302                 offset_next = (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3);
303                 if (f > v2d->cur.xmin) {
304                         /* if this is close to the last sample just exit */
305                         if (offset_next >= sound->streamlen) break;
306                         
307                         wavesamplemin = 131070;
308                         wavesamplemax = -131070;
309                         
310                         /*find with high and low of the waveform for this draw,
311                         evaluate small samples to find this range */
312                         while (offset < offset_next) {
313                                 s = (signed short*)(stream+offset);
314                                 
315                                 wavesample = s[0]*2 + s[1];
316                                 if (wavesamplemin>wavesample)
317                                         wavesamplemin=wavesample;
318                                 if (wavesamplemax<wavesample)
319                                         wavesamplemax=wavesample;
320                                 offset+=subsample_step;
321                         }
322                         /* draw the wave line, looks good up close and zoomed out */
323                         glVertex2f(f,  midy-(wavemulti*wavesamplemin) );
324                         glVertex2f(f,  midy-(wavemulti*wavesamplemax) );
325                 } else {
326                         while (offset < offset_next) offset+=subsample_step;
327                 }
328                 
329                 offset=offset_next;
330         }
331         glEnd();
332 }
333
334 /* draw a handle, for each end of a sequence strip */
335 static void draw_seq_handle(SpaceSeq *sseq, Sequence *seq, float pixelx, short direction)
336 {
337         float v1[2], v2[2], v3[2], rx1=0, rx2=0; //for triangles and rect
338         float x1, x2, y1, y2;
339         float handsize;
340         float minhandle, maxhandle;
341         char str[32];
342         unsigned int whichsel=0;
343         View2D *v2d;
344         
345         x1= seq->startdisp;
346         x2= seq->enddisp;
347         
348         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
349         y2= seq->machine+SEQ_STRIP_OFSTOP;
350         
351         v2d = &sseq->v2d;
352         
353         /* clamp handles to defined size in pixel space */
354         handsize = seq->handsize;
355         minhandle = 7;
356         maxhandle = 40;
357         CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
358         
359         /* set up co-ordinates/dimensions for either left or right handle */
360         if (direction == SEQ_LEFTHANDLE) {      
361                 rx1 = x1;
362                 rx2 = x1+handsize*0.75;
363                 
364                 v1[0]= x1+handsize/4; v1[1]= y1+( ((y1+y2)/2.0 - y1)/2);
365                 v2[0]= x1+handsize/4; v2[1]= y2-( ((y1+y2)/2.0 - y1)/2);
366                 v3[0]= v2[0] + handsize/4; v3[1]= (y1+y2)/2.0;
367                 
368                 whichsel = SEQ_LEFTSEL;
369         } else if (direction == SEQ_RIGHTHANDLE) {      
370                 rx1 = x2-handsize*0.75;
371                 rx2 = x2;
372                 
373                 v1[0]= x2-handsize/4; v1[1]= y1+( ((y1+y2)/2.0 - y1)/2);
374                 v2[0]= x2-handsize/4; v2[1]= y2-( ((y1+y2)/2.0 - y1)/2);
375                 v3[0]= v2[0] - handsize/4; v3[1]= (y1+y2)/2.0;
376                 
377                 whichsel = SEQ_RIGHTSEL;
378         }
379         
380         /* draw! */
381         if(seq->type < SEQ_EFFECT || 
382            get_sequence_effect_num_inputs(seq->type) == 0) {
383                 glEnable( GL_BLEND );
384                 
385                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
386                 
387                 if(seq->flag & whichsel) glColor4ub(0, 0, 0, 80);
388                 else if (seq->flag & SELECT) glColor4ub(255, 255, 255, 30);
389                 else glColor4ub(0, 0, 0, 22);
390                 
391                 glRectf(rx1, y1, rx2, y2);
392                 
393                 if(seq->flag & whichsel) glColor4ub(255, 255, 255, 200);
394                 else glColor4ub(0, 0, 0, 50);
395                 
396                 glEnable( GL_POLYGON_SMOOTH );
397                 glBegin(GL_TRIANGLES);
398                 glVertex2fv(v1); glVertex2fv(v2); glVertex2fv(v3);
399                 glEnd();
400                 
401                 glDisable( GL_POLYGON_SMOOTH );
402                 glDisable( GL_BLEND );
403         }
404         
405         if(G.moving || (seq->flag & whichsel)) {
406                 cpack(0xFFFFFF);
407                 if (direction == SEQ_LEFTHANDLE) {
408                         sprintf(str, "%d", seq->startdisp);
409                         glRasterPos3f(rx1,  y1-0.15, 0.0);
410                 } else {
411                         sprintf(str, "%d", seq->enddisp - 1);
412                         glRasterPos3f((x2-BMF_GetStringWidth(G.fonts, str)*pixelx),  y2+0.05, 0.0);
413                 }
414                 BMF_DrawString(G.fonts, str);
415         }       
416 }
417
418 static void draw_seq_extensions(Scene *scene, SpaceSeq *sseq, Sequence *seq)
419 {
420         float x1, x2, y1, y2, pixely, a;
421         char col[3], blendcol[3];
422         View2D *v2d;
423         
424         if(seq->type >= SEQ_EFFECT) return;
425
426         x1= seq->startdisp;
427         x2= seq->enddisp;
428         
429         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
430         y2= seq->machine+SEQ_STRIP_OFSTOP;
431         
432         v2d = &sseq->v2d;
433         pixely = (v2d->cur.ymax - v2d->cur.ymin)/(v2d->mask.ymax - v2d->mask.ymin);
434         
435         blendcol[0] = blendcol[1] = blendcol[2] = 120;
436
437         if(seq->startofs) {
438                 glEnable( GL_BLEND );
439                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
440                 
441                 get_seq_color3ubv(scene, seq, col);
442                 
443                 if (seq->flag & SELECT) {
444                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
445                         glColor4ub(col[0], col[1], col[2], 170);
446                 } else {
447                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
448                         glColor4ub(col[0], col[1], col[2], 110);
449                 }
450                 
451                 glRectf((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1);
452                 
453                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
454                 else glColor4ub(col[0], col[1], col[2], 160);
455
456                 fdrawbox((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1);  //outline
457                 
458                 glDisable( GL_BLEND );
459         }
460         if(seq->endofs) {
461                 glEnable( GL_BLEND );
462                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
463                 
464                 get_seq_color3ubv(scene, seq, col);
465                 
466                 if (seq->flag & SELECT) {
467                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
468                         glColor4ub(col[0], col[1], col[2], 170);
469                 } else {
470                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
471                         glColor4ub(col[0], col[1], col[2], 110);
472                 }
473                 
474                 glRectf(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM);
475                 
476                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
477                 else glColor4ub(col[0], col[1], col[2], 160);
478
479                 fdrawbox(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM); //outline
480                 
481                 glDisable( GL_BLEND );
482         }
483         if(seq->startstill) {
484                 get_seq_color3ubv(scene, seq, col);
485                 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
486                 glColor3ubv((GLubyte *)col);
487                 
488                 draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
489                 
490                 /* feint pinstripes, helps see exactly which is extended and which isn't,
491                 * especially when the extension is very small */ 
492                 if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
493                 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
494                 
495                 glColor3ubv((GLubyte *)col);
496                 
497                 for(a=y1; a< y2; a+= pixely*2.0 ) {
498                         fdrawline(x1,  a,  (float)(seq->start),  a);
499                 }
500         }
501         if(seq->endstill) {
502                 get_seq_color3ubv(scene, seq, col);
503                 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
504                 glColor3ubv((GLubyte *)col);
505                 
506                 draw_shadedstrip(seq, col, (float)(seq->start+seq->len), y1, x2, y2);
507                 
508                 /* feint pinstripes, helps see exactly which is extended and which isn't,
509                 * especially when the extension is very small */ 
510                 if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
511                 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
512                 
513                 glColor3ubv((GLubyte *)col);
514                 
515                 for(a=y1; a< y2; a+= pixely*2.0 ) {
516                         fdrawline((float)(seq->start+seq->len),  a,  x2,  a);
517                 }
518         }
519 }
520
521 /* draw info text on a sequence strip */
522 static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, char *background_col)
523 {
524         float v1[2], v2[2];
525         int len, size;
526         char str[32 + FILE_MAXDIR+FILE_MAXFILE], *strp;
527         short mval[2];
528         
529         v1[1]= y1;
530         v2[1]= y2;
531         
532         v1[0]= x1;
533         UI_view2d_to_region_no_clip(v2d, v1[0], v1[1], mval, mval+1);
534         x1= mval[0];
535         v2[0]= x2;
536         UI_view2d_to_region_no_clip(v2d, v2[0], v2[1], mval, mval+1);
537         x2= mval[0];
538         size= x2-x1;
539         
540         if(seq->name[2]) {
541                 sprintf(str, "%d | %s: %s", seq->len, give_seqname(seq), seq->name+2);
542         }else{
543                 if(seq->type == SEQ_META) {
544                         sprintf(str, "%d | %s", seq->len, give_seqname(seq));
545                 }
546                 else if(seq->type == SEQ_SCENE) {
547                         if(seq->scene) sprintf(str, "%d | %s: %s", seq->len, give_seqname(seq), seq->scene->id.name+2);
548                         else sprintf(str, "%d | %s", seq->len, give_seqname(seq));
549                         
550                 }
551                 else if(seq->type == SEQ_IMAGE) {
552                         sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
553                 }
554                 else if(seq->type & SEQ_EFFECT) {
555                         int can_float = (seq->type != SEQ_PLUGIN)
556                                 || (seq->plugin && seq->plugin->version >= 4);
557
558                         if(seq->seq3!=seq->seq2 && seq->seq1!=seq->seq3)
559                                 sprintf(str, "%d | %s: %d>%d (use %d)%s", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, seq->seq3->machine, can_float ? "" : " No float, upgrade plugin!");
560                         else if (seq->seq1 && seq->seq2)
561                                 sprintf(str, "%d | %s: %d>%d%s", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, can_float ? "" : " No float, upgrade plugin!");
562                         else 
563                                 sprintf(str, "%d | %s", seq->len, give_seqname(seq));
564                 }
565                 else if (seq->type == SEQ_RAM_SOUND) {
566                         sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
567                 }
568                 else if (seq->type == SEQ_HD_SOUND) {
569                         sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
570                 }
571                 else if (seq->type == SEQ_MOVIE) {
572                         sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
573                 }
574         }
575         
576         strp= str;
577         
578         while( (len= BMF_GetStringWidth(G.font, strp)) > size) {
579                 if(len < 10) break;
580                 if(strp[1]==0) break;
581                 strp++;
582         }
583         
584         mval[0]= (x1+x2-len+1)/2;
585         mval[1]= 1;
586         UI_view2d_region_to_view(v2d, mval[0], mval[1], &x1, &x2);
587         
588         if(seq->flag & SELECT){
589                 cpack(0xFFFFFF);
590         }else if ((((int)background_col[0] + (int)background_col[1] + (int)background_col[2]) / 3) < 50){
591                 cpack(0x505050); /* use lighter text colour for dark background */
592         }else{
593                 cpack(0);
594         }
595         glRasterPos3f(x1,  y1+SEQ_STRIP_OFSBOTTOM, 0.0);
596         BMF_DrawString(G.font, strp);
597 }
598
599 /* draws a shaded strip, made from gradient + flat color + gradient */
600 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2)
601 {
602         float ymid1, ymid2;
603         
604         if (seq->flag & SEQ_MUTE) {
605                 glEnable(GL_POLYGON_STIPPLE);
606                 glPolygonStipple(stipple_halftone);
607         }
608         
609         ymid1 = (y2-y1)*0.25 + y1;
610         ymid2 = (y2-y1)*0.65 + y1;
611         
612         glShadeModel(GL_SMOOTH);
613         glBegin(GL_QUADS);
614         
615         if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
616         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0);
617         
618         glColor3ubv((GLubyte *)col);
619         
620         glVertex2f(x1,y1);
621         glVertex2f(x2,y1);
622         
623         if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
624         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5);
625
626         glColor3ubv((GLubyte *)col);
627         
628         glVertex2f(x2,ymid1);
629         glVertex2f(x1,ymid1);
630         
631         glEnd();
632         
633         glRectf(x1,  ymid1,  x2,  ymid2);
634         
635         glBegin(GL_QUADS);
636         
637         glVertex2f(x1,ymid2);
638         glVertex2f(x2,ymid2);
639         
640         if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -15);
641         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 25);
642         
643         glColor3ubv((GLubyte *)col);
644         
645         glVertex2f(x2,y2);
646         glVertex2f(x1,y2);
647         
648         glEnd();
649         
650         if (seq->flag & SEQ_MUTE) {
651                 glDisable(GL_POLYGON_STIPPLE);
652         }
653 }
654
655 /*
656 Draw a sequence strip, bounds check alredy made
657 ARegion is currently only used to get the windows width in pixels
658 so wave file sample drawing precission is zoom adjusted
659 */
660 static void draw_seq_strip(Scene *scene, ARegion *ar, SpaceSeq *sseq, Sequence *seq, int outline_tint, float pixelx)
661 {
662         // XXX
663         extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
664         View2D *v2d= &ar->v2d;
665         float x1, x2, y1, y2;
666         char col[3], background_col[3], is_single_image;
667
668         /* we need to know if this is a single image/color or not for drawing */
669         is_single_image = (char)check_single_seq(seq);
670         
671         /* body */
672         if(seq->startstill) x1= seq->start;
673         else x1= seq->startdisp;
674         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
675         if(seq->endstill) x2= seq->start+seq->len;
676         else x2= seq->enddisp;
677         y2= seq->machine+SEQ_STRIP_OFSTOP;
678         
679         
680         /* get the correct color per strip type*/
681         //get_seq_color3ubv(scene, seq, col);
682         get_seq_color3ubv(scene, seq, background_col);
683         
684         /* draw the main strip body */
685         if (is_single_image) /* single image */
686                 draw_shadedstrip(seq, background_col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2);
687         else /* normal operation */
688                 draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
689         
690         /* draw additional info and controls */
691         if (seq->type == SEQ_RAM_SOUND)
692                 drawseqwave(scene, v2d, seq, x1, y1, x2, y2, ar->winx);
693         
694         if (!is_single_image)
695                 draw_seq_extensions(scene, sseq, seq);
696         
697         draw_seq_handle(sseq, seq, pixelx, SEQ_LEFTHANDLE);
698         draw_seq_handle(sseq, seq, pixelx, SEQ_RIGHTHANDLE);
699         
700         /* draw the strip outline */
701         x1= seq->startdisp;
702         x2= seq->enddisp;
703         
704         get_seq_color3ubv(scene, seq, col);
705         if (G.moving && (seq->flag & SELECT)) {
706                 if(seq->flag & SEQ_OVERLAP) {
707                         col[0]= 255; col[1]= col[2]= 40;
708                 } else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
709         }
710
711         UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, outline_tint);
712         
713         glColor3ubv((GLubyte *)col);
714         
715         if (seq->flag & SEQ_MUTE) {
716                 glEnable(GL_LINE_STIPPLE);
717                 glLineStipple(1, 0x8888);
718         }
719         
720         gl_round_box_shade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
721         
722         if (seq->flag & SEQ_MUTE) {
723                 glDisable(GL_LINE_STIPPLE);
724         }
725         
726         /* calculate if seq is long enough to print a name */
727         x1= seq->startdisp+seq->handsize;
728         x2= seq->enddisp-seq->handsize;
729
730         /* but first the contents of a meta */
731         if(seq->type==SEQ_META) drawmeta_contents(scene, seq, x1, y1+0.15, x2, y2-0.15);
732
733         /* info text on the strip */
734         if(x1<v2d->cur.xmin) x1= v2d->cur.xmin;
735         else if(x1>v2d->cur.xmax) x1= v2d->cur.xmax;
736         if(x2<v2d->cur.xmin) x2= v2d->cur.xmin;
737         else if(x2>v2d->cur.xmax) x2= v2d->cur.xmax;
738
739         /* nice text here would require changing the view matrix for texture text */
740         if( (x2-x1) / pixelx > 32) {
741                 draw_seq_text(v2d, seq, x1, x2, y1, y2, background_col);
742         }
743 }
744
745 static Sequence *special_seq_update= 0;
746
747 void set_special_seq_update(int val)
748 {
749 //      int x;
750
751         /* if mouse over a sequence && LEFTMOUSE */
752         if(val) {
753 // XXX          special_seq_update= find_nearest_seq(&x);
754         }
755         else special_seq_update= 0;
756 }
757
758
759 static void draw_image_seq(Scene *scene, ARegion *ar, SpaceSeq *sseq)
760 {
761         extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
762         struct ImBuf *ibuf;
763         int x1, y1, rectx, recty;
764         int free_ibuf = 0;
765         static int recursive= 0;
766         float zoom;
767         float zoomx, zoomy;
768
769         glClearColor(0.0, 0.0, 0.0, 0.0);
770         glClear(GL_COLOR_BUFFER_BIT);
771
772         rectx= (scene->r.size*scene->r.xsch)/100;
773         recty= (scene->r.size*scene->r.ysch)/100;
774
775         /* BIG PROBLEM: the give_ibuf_seq() can call a rendering, which in turn calls redraws...
776            this shouldn't belong in a window drawing....
777            So: solve this once event based. 
778            Now we check for recursion, space type and active area again (ton) */
779         
780         if(recursive)
781                 return;
782         else {
783                 recursive= 1;
784                 if (special_seq_update) {
785                         ibuf= give_ibuf_seq_direct(scene, rectx, recty, (scene->r.cfra), special_seq_update);
786                 } 
787                 else if (!U.prefetchframes) { // XXX || (G.f & G_PLAYANIM) == 0) {
788                         ibuf= (ImBuf *)give_ibuf_seq(scene, rectx, recty, (scene->r.cfra), sseq->chanshown);
789                 } 
790                 else {
791                         ibuf= (ImBuf *)give_ibuf_seq_threaded(scene, rectx, recty, (scene->r.cfra), sseq->chanshown);
792                 }
793                 recursive= 0;
794                 
795                 /* XXX HURMF! the give_ibuf_seq can call image display in this window */
796 //              if(sa->spacetype!=SPACE_SEQ)
797 //                      return;
798 //              if(sa!=curarea) {
799 //                      areawinset(sa->win);
800 //              }
801         }
802         
803         if(ibuf==NULL) 
804                 return;
805
806         if(ibuf->rect==NULL && ibuf->rect_float == NULL) 
807                 return;
808
809         switch(sseq->mainb) {
810         case SEQ_DRAW_IMG_IMBUF:
811                 if (sseq->zebra != 0) {
812                         ibuf = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
813                         free_ibuf = 1;
814                 }
815                 break;
816         case SEQ_DRAW_IMG_WAVEFORM:
817                 if ((sseq->flag & SEQ_DRAW_COLOR_SEPERATED) != 0) {
818                         ibuf = make_sep_waveform_view_from_ibuf(ibuf);
819                 } else {
820                         ibuf = make_waveform_view_from_ibuf(ibuf);
821                 }
822                 free_ibuf = 1;
823                 break;
824         case SEQ_DRAW_IMG_VECTORSCOPE:
825                 ibuf = make_vectorscope_view_from_ibuf(ibuf);
826                 free_ibuf = 1;
827                 break;
828         case SEQ_DRAW_IMG_HISTOGRAM:
829                 ibuf = make_histogram_view_from_ibuf(ibuf);
830                 free_ibuf = 1;
831                 break;
832         }
833
834         if(ibuf->rect_float && ibuf->rect==NULL)
835                 IMB_rect_from_float(ibuf);
836         
837         /* needed for gla draw */
838         glaDefine2DArea(&ar->winrct);
839         
840         zoom= SEQ_ZOOM_FAC(sseq->zoom);
841         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
842                 zoomx = zoom * ((float)scene->r.xasp / (float)scene->r.yasp);
843                 zoomy = zoom;
844         } else {
845                 zoomx = zoomy = zoom;
846         }
847
848         /* calc location */
849         x1= (ar->winx-zoomx*ibuf->x)/2 + sseq->xof;
850         y1= (ar->winy-zoomy*ibuf->y)/2 + sseq->yof;
851         
852         glPixelZoom(zoomx, zoomy);
853         
854         glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
855         
856         glPixelZoom(1.0, 1.0);
857
858         /* safety border */
859         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && 
860             (sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
861                 float fac= 0.1;
862                 float x2 = x1 + ibuf->x * zoomx;
863                 float y2 = y1 + ibuf->y * zoomy;
864                 
865                 float a= fac*(x2-x1);
866                 x1+= a; 
867                 x2-= a;
868         
869                 a= fac*(y2-y1);
870                 y1+= a;
871                 y2-= a;
872         
873                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
874                 setlinestyle(3);
875
876                 UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
877                 
878                 uiSetRoundBox(15);
879                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
880
881                 setlinestyle(0);
882                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
883         }
884         
885         /* draw grease-pencil (image aligned) */
886 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
887 // XXX          draw_gpencil_2dimage(sa, ibuf);
888
889         if (free_ibuf) {
890                 IMB_freeImBuf(ibuf);
891         } 
892         
893         /* draw grease-pencil (screen aligned) */
894 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
895 // XXX          draw_gpencil_2dview(sa, 0);
896         
897         /* ortho at pixel level sa */
898 // XXX  myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
899         
900 }
901
902 void seq_reset_imageofs(SpaceSeq *sseq)
903 {
904         sseq->xof = sseq->yof = sseq->zoom = 0;
905 }
906
907 void seq_home(Scene *scene, ARegion *ar, SpaceSeq *sseq)
908 {
909         View2D *v2d= &ar->v2d;
910         
911         if (!sseq->mainb) {
912                 v2d->cur= v2d->tot;
913 //              test_view2d(v2d, ar->winx, ar->winy);
914 //              view2d_do_locks(ar, V2D_LOCK_COPY);
915         } else {
916                 float zoomX, zoomY;
917                 int width, height, imgwidth, imgheight; 
918                 
919                 width = ar->winx;
920                 height = ar->winy;
921                 
922                 seq_reset_imageofs(sseq);
923                 
924                 imgwidth= (scene->r.size*scene->r.xsch)/100;
925                 imgheight= (scene->r.size*scene->r.ysch)/100;
926                 
927                 /* Apply aspect, dosnt need to be that accurate */
928                 imgwidth= (int)(imgwidth * ((float)scene->r.xasp / (float)scene->r.yasp));
929                 
930                 if (((imgwidth >= width) || (imgheight >= height)) && 
931                         ((width > 0) && (height > 0))) {
932                         
933                         /* Find the zoom value that will fit the image in the image space */
934                         zoomX = ((float)width) / ((float)imgwidth);
935                         zoomY = ((float)height) / ((float)imgheight);
936                         sseq->zoom= (zoomX < zoomY) ? zoomX : zoomY;
937         
938                         sseq->zoom = 1.0f / power_of_2(1/ MIN2(zoomX, zoomY) );
939                 }
940                 else {
941                         sseq->zoom= 1.0f;
942                 }
943         }
944 }
945
946 #if 0
947 /* XXX */
948 void seq_viewzoom(SpaceSeq *sseq, unsigned short event, int invert)
949 {
950
951         if(event==PAD1)
952                 sseq->zoom= 1.0;
953         else if(event==PAD2)
954                 sseq->zoom= (invert)? 2.0: 0.5;
955         else if(event==PAD4)
956                 sseq->zoom= (invert)? 4.0: 0.25;
957         else if(event==PAD8)
958                 sseq->zoom= (invert)? 8.0: 0.125;
959         
960         /* ensure pixel exact locations for draw */
961         sseq->xof= (int)sseq->xof;
962         sseq->yof= (int)sseq->yof;
963 }
964
965 void seq_viewmove(Scene *scene, ARegion *ar, SpaceSeq *sseq)
966 {       
967         short mval[2], mvalo[2];
968         short rectx, recty, xmin, xmax, ymin, ymax, pad;
969         int oldcursor;
970         Window *win;
971         
972         sa = sseq->area;
973         rectx= (scene->r.size*scene->r.xsch)/100;
974         recty= (scene->r.size*scene->r.ysch)/100;
975         
976         pad = 10;
977         xmin = -(ar->winx/2) - rectx/2 + pad;
978         xmax = ar->winx/2 + rectx/2 - pad;
979         ymin = -(ar->winy/2) - recty/2 + pad;
980         ymax = ar->winy/2 + recty/2 - pad;
981         
982         getmouseco_sc(mvalo);
983
984         oldcursor=get_cursor();
985         win=winlay_get_active_window();
986         
987         SetBlenderCursor(BC_NSEW_SCROLLCURSOR);
988         
989         while(get_mbut()&(L_MOUSE|M_MOUSE)) {
990                 
991                 getmouseco_sc(mval);
992                 
993                 if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) {
994
995                         sseq->xof -= (mvalo[0]-mval[0]);
996                         sseq->yof -= (mvalo[1]-mval[1]);
997                         
998                         /* prevent dragging image outside of the window and losing it! */
999                         CLAMP(sseq->xof, xmin, xmax);
1000                         CLAMP(sseq->yof, ymin, ymax);
1001                         
1002                         mvalo[0]= mval[0];
1003                         mvalo[1]= mval[1];
1004                         
1005                 }
1006         }
1007 }
1008 #endif
1009
1010 void drawprefetchseqspace(Scene *scene, ARegion *ar, SpaceSeq *sseq)
1011 {
1012         int rectx, recty;
1013
1014         rectx= (scene->r.size*scene->r.xsch)/100;
1015         recty= (scene->r.size*scene->r.ysch)/100;
1016
1017         if(sseq->mainb) {
1018                 give_ibuf_prefetch_request(
1019                         rectx, recty, (scene->r.cfra), sseq->chanshown);
1020         }
1021 }
1022
1023 void drawseqspace(const bContext *C, ARegion *ar)
1024 {
1025         ScrArea *sa= CTX_wm_area(C);
1026         SpaceSeq *sseq= sa->spacedata.first;
1027         Scene *scene= CTX_data_scene(C);
1028         View2D *v2d= &ar->v2d;
1029         View2DScrollers *scrollers;
1030         Editing *ed;
1031         Sequence *seq;
1032         float col[3];
1033         int i;
1034
1035         ed= scene->ed;
1036
1037         if(sseq->mainb) {
1038                 draw_image_seq(scene, ar, sseq);
1039                 return;
1040         }
1041
1042         UI_GetThemeColor3fv(TH_BACK, col);
1043         if(ed && ed->metastack.first) glClearColor(col[0], col[1], col[2]-0.1, 0.0);
1044         else glClearColor(col[0], col[1], col[2], 0.0);
1045
1046         glClear(GL_COLOR_BUFFER_BIT);
1047
1048         UI_view2d_view_ortho(C, v2d);
1049         
1050         UI_ThemeColorShade(TH_BACK, -20);
1051         glRectf(v2d->cur.xmin,  0.0,  v2d->cur.xmax,  1.0);
1052
1053         boundbox_seq(scene, &v2d->tot);
1054         
1055         /* Alternating horizontal stripes */
1056         i= MAX2(1, ((int)v2d->cur.ymin)-1);
1057
1058         glBegin(GL_QUADS);
1059         while (i<v2d->cur.ymax) {
1060                 if (((int)i) & 1)
1061                         UI_ThemeColorShade(TH_BACK, -15);
1062                 else
1063                         UI_ThemeColorShade(TH_BACK, -25);
1064                 
1065                 glVertex2f(v2d->cur.xmax, i);
1066                 glVertex2f(v2d->cur.xmin, i);
1067                 glVertex2f(v2d->cur.xmin, i+1);
1068                 glVertex2f(v2d->cur.xmax, i+1);
1069                 i+=1.0;
1070         }
1071         glEnd();
1072         
1073         /* Force grid lines */
1074         i= MAX2(1, ((int)v2d->cur.ymin)-1);
1075         glBegin(GL_LINES);
1076
1077         while (i<v2d->cur.ymax) {
1078                 UI_ThemeColor(TH_GRID);
1079                 glVertex2f(v2d->cur.xmax, i);
1080                 glVertex2f(v2d->cur.xmin, i);
1081                 i+=1.0;
1082         }
1083         glEnd();
1084         
1085         UI_view2d_constant_grid_draw(C, v2d);
1086
1087         draw_cfra_seq(v2d, scene->r.cfra);
1088
1089         /* sequences: first deselect */
1090         if(ed) {
1091                 Sequence *last_seq = get_last_seq(scene);
1092                 int sel = 0, j;
1093                 int outline_tint;
1094                 float pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
1095                 /* loop through twice, first unselected, then selected */
1096                 for (j=0; j<2; j++) {
1097                         seq= ed->seqbasep->first;
1098                         if (j==0)       outline_tint = -150;
1099                         else            outline_tint = -60;
1100                         
1101                         while(seq) { /* bound box test, dont draw outside the view */
1102                                 if (  ((seq->flag & SELECT) == sel) ||
1103                                                 seq == last_seq ||
1104                                                 MIN2(seq->startdisp, seq->start) > v2d->cur.xmax ||
1105                                                 MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin ||
1106                                                 seq->machine+1.0 < v2d->cur.ymin ||
1107                                                 seq->machine > v2d->cur.ymax)
1108                                 {
1109                                         /* dont draw */
1110                                 } else {
1111                                         draw_seq_strip(scene, ar, sseq, seq, outline_tint, pixelx);
1112                                 }
1113                                 seq= seq->next;
1114                         }
1115                         sel= SELECT; /* draw selected next time round */
1116                 }
1117                 /* draw the last selected last, removes some overlapping error */
1118                 if (last_seq) {
1119                         draw_seq_strip(scene, ar, sseq, last_seq, 120, pixelx);
1120                 }
1121         }
1122
1123         /* Draw markers */
1124 //      draw_markers_timespace(SCE_MARKERS, DRAW_MARKERS_LINES);
1125         
1126         /* reset view matrix */
1127         UI_view2d_view_restore(C);
1128
1129         /* scrollers */
1130         scrollers= UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
1131         UI_view2d_scrollers_draw(C, v2d, scrollers);
1132         UI_view2d_scrollers_free(scrollers);
1133 }
1134
1135