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