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