changes to the sequencer in trunk between 20855:20928, (excluding UI changes)
[blender-staging.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         float render_size = 0.0;
745         float proxy_size = 100.0;
746
747         glClearColor(0.0, 0.0, 0.0, 0.0);
748         glClear(GL_COLOR_BUFFER_BIT);
749
750         render_size = sseq->render_size;
751         if (render_size == 0) {
752                 render_size = scene->r.size;
753         } else {
754                 proxy_size = render_size;
755         }
756         if (render_size < 0) {
757                 return;
758         }
759
760         rectx= (render_size*scene->r.xsch)/100;
761         recty= (render_size*scene->r.ysch)/100;
762
763         /* BIG PROBLEM: the give_ibuf_seq() can call a rendering, which in turn calls redraws...
764            this shouldn't belong in a window drawing....
765            So: solve this once event based. 
766            Now we check for recursion, space type and active area again (ton) */
767         
768         if(recursive)
769                 return;
770         else {
771                 recursive= 1;
772                 if (special_seq_update) {
773                         ibuf= give_ibuf_seq_direct(scene, rectx, recty, (scene->r.cfra), proxy_size, special_seq_update);
774                 } 
775                 else if (!U.prefetchframes) { // XXX || (G.f & G_PLAYANIM) == 0) {
776                         ibuf= (ImBuf *)give_ibuf_seq(scene, rectx, recty, (scene->r.cfra), sseq->chanshown, proxy_size);
777                 } 
778                 else {
779                         ibuf= (ImBuf *)give_ibuf_seq_threaded(scene, rectx, recty, (scene->r.cfra), sseq->chanshown, proxy_size);
780                 }
781                 recursive= 0;
782                 
783                 /* XXX HURMF! the give_ibuf_seq can call image display in this window */
784 //              if(sa->spacetype!=SPACE_SEQ)
785 //                      return;
786 //              if(sa!=curarea) {
787 //                      areawinset(sa->win);
788 //              }
789         }
790         
791         if(ibuf==NULL) 
792                 return;
793
794         if(ibuf->rect==NULL && ibuf->rect_float == NULL) 
795                 return;
796         
797         switch(sseq->mainb) {
798         case SEQ_DRAW_IMG_IMBUF:
799                 if (sseq->zebra != 0) {
800                         ibuf = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
801                         free_ibuf = 1;
802                 }
803                 break;
804         case SEQ_DRAW_IMG_WAVEFORM:
805                 if ((sseq->flag & SEQ_DRAW_COLOR_SEPERATED) != 0) {
806                         ibuf = make_sep_waveform_view_from_ibuf(ibuf);
807                 } else {
808                         ibuf = make_waveform_view_from_ibuf(ibuf);
809                 }
810                 free_ibuf = 1;
811                 break;
812         case SEQ_DRAW_IMG_VECTORSCOPE:
813                 ibuf = make_vectorscope_view_from_ibuf(ibuf);
814                 free_ibuf = 1;
815                 break;
816         case SEQ_DRAW_IMG_HISTOGRAM:
817                 ibuf = make_histogram_view_from_ibuf(ibuf);
818                 free_ibuf = 1;
819                 break;
820         }
821
822         if(ibuf->rect_float && ibuf->rect==NULL)
823                 IMB_rect_from_float(ibuf);
824         
825         /* needed for gla draw */
826         glaDefine2DArea(&ar->winrct);
827         
828         zoom= SEQ_ZOOM_FAC(sseq->zoom);
829         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
830                 zoom /= proxy_size / 100.0;
831                 zoomx = zoom * ((float)scene->r.xasp / (float)scene->r.yasp);
832                 zoomy = zoom;
833         } else {
834                 zoomx = zoomy = zoom;
835         }
836
837         /* calc location */
838         x1= (ar->winx-zoomx*ibuf->x)/2 + sseq->xof;
839         y1= (ar->winy-zoomy*ibuf->y)/2 + sseq->yof;
840         
841         glPixelZoom(zoomx, zoomy);
842         
843         glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
844         
845         glPixelZoom(1.0, 1.0);
846
847         /* safety border */
848         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && 
849             (sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
850                 float fac= 0.1;
851                 float x2 = x1 + ibuf->x * zoomx;
852                 float y2 = y1 + ibuf->y * zoomy;
853                 
854                 float a= fac*(x2-x1);
855                 x1+= a; 
856                 x2-= a;
857         
858                 a= fac*(y2-y1);
859                 y1+= a;
860                 y2-= a;
861         
862                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
863                 setlinestyle(3);
864
865                 UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
866                 
867                 uiSetRoundBox(15);
868                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
869
870                 setlinestyle(0);
871                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
872         }
873         
874         /* draw grease-pencil (image aligned) */
875 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
876 // XXX          draw_gpencil_2dimage(sa, ibuf);
877
878         if (free_ibuf) {
879                 IMB_freeImBuf(ibuf);
880         } 
881         
882         /* draw grease-pencil (screen aligned) */
883 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
884 // XXX          draw_gpencil_2dview(sa, 0);
885         
886         /* ortho at pixel level sa */
887 // XXX  myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
888         
889 }
890
891 void seq_reset_imageofs(SpaceSeq *sseq)
892 {
893         sseq->xof = sseq->yof = sseq->zoom = 0;
894 }
895
896
897 #if 0
898 /* XXX - these should really be made to use View2D instead of so wacko private system - Aligorith */
899
900 void seq_viewzoom(SpaceSeq *sseq, unsigned short event, int invert)
901 {
902
903         if(event==PAD1)
904                 sseq->zoom= 1.0;
905         else if(event==PAD2)
906                 sseq->zoom= (invert)? 2.0: 0.5;
907         else if(event==PAD4)
908                 sseq->zoom= (invert)? 4.0: 0.25;
909         else if(event==PAD8)
910                 sseq->zoom= (invert)? 8.0: 0.125;
911         
912         /* ensure pixel exact locations for draw */
913         sseq->xof= (int)sseq->xof;
914         sseq->yof= (int)sseq->yof;
915 }
916
917 void seq_viewmove(Scene *scene, ARegion *ar, SpaceSeq *sseq)
918 {       
919         short mval[2], mvalo[2];
920         short rectx, recty, xmin, xmax, ymin, ymax, pad;
921         int oldcursor;
922         Window *win;
923         
924         sa = sseq->area;
925         rectx= (scene->r.size*scene->r.xsch)/100;
926         recty= (scene->r.size*scene->r.ysch)/100;
927         
928         pad = 10;
929         xmin = -(ar->winx/2) - rectx/2 + pad;
930         xmax = ar->winx/2 + rectx/2 - pad;
931         ymin = -(ar->winy/2) - recty/2 + pad;
932         ymax = ar->winy/2 + recty/2 - pad;
933         
934         getmouseco_sc(mvalo);
935
936         oldcursor=get_cursor();
937         win=winlay_get_active_window();
938         
939         SetBlenderCursor(BC_NSEW_SCROLLCURSOR);
940         
941         while(get_mbut()&(L_MOUSE|M_MOUSE)) {
942                 
943                 getmouseco_sc(mval);
944                 
945                 if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) {
946
947                         sseq->xof -= (mvalo[0]-mval[0]);
948                         sseq->yof -= (mvalo[1]-mval[1]);
949                         
950                         /* prevent dragging image outside of the window and losing it! */
951                         CLAMP(sseq->xof, xmin, xmax);
952                         CLAMP(sseq->yof, ymin, ymax);
953                         
954                         mvalo[0]= mval[0];
955                         mvalo[1]= mval[1];
956                         
957                 }
958         }
959 }
960 #endif
961
962 void drawprefetchseqspace(Scene *scene, ARegion *ar, SpaceSeq *sseq)
963 {
964         int rectx, recty;
965         int render_size = sseq->render_size;
966         int proxy_size = 100.0; 
967         if (render_size == 0) {
968                 render_size = scene->r.size;
969         } else {
970                 proxy_size = render_size;
971         }
972         if (render_size < 0) {
973                 return;
974         }
975
976         rectx= (render_size*scene->r.xsch)/100;
977         recty= (render_size*scene->r.ysch)/100;
978
979         if(sseq->mainb != SEQ_DRAW_SEQUENCE) {
980                 give_ibuf_prefetch_request(
981                         rectx, recty, (scene->r.cfra), sseq->chanshown,
982                         proxy_size);
983         }
984 }
985
986 void drawseqspace(const bContext *C, ARegion *ar)
987 {
988         ScrArea *sa= CTX_wm_area(C);
989         SpaceSeq *sseq= sa->spacedata.first;
990         Scene *scene= CTX_data_scene(C);
991         View2D *v2d= &ar->v2d;
992         View2DScrollers *scrollers;
993         Editing *ed= seq_give_editing(scene, FALSE);
994         Sequence *seq;
995         float col[3];
996         int i;
997
998         if(sseq->mainb != SEQ_DRAW_SEQUENCE) {
999                 draw_image_seq(scene, ar, sseq);
1000                 return;
1001         }
1002
1003         UI_GetThemeColor3fv(TH_BACK, col);
1004         if(ed && ed->metastack.first) glClearColor(col[0], col[1], col[2]-0.1, 0.0);
1005         else glClearColor(col[0], col[1], col[2], 0.0);
1006
1007         glClear(GL_COLOR_BUFFER_BIT);
1008
1009         UI_view2d_view_ortho(C, v2d);
1010         
1011         UI_ThemeColorShade(TH_BACK, -20);
1012         glRectf(v2d->cur.xmin,  0.0,  v2d->cur.xmax,  1.0);
1013
1014         boundbox_seq(scene, &v2d->tot);
1015         
1016         /* Alternating horizontal stripes */
1017         i= MAX2(1, ((int)v2d->cur.ymin)-1);
1018
1019         glBegin(GL_QUADS);
1020         while (i<v2d->cur.ymax) {
1021                 if (((int)i) & 1)
1022                         UI_ThemeColorShade(TH_BACK, -15);
1023                 else
1024                         UI_ThemeColorShade(TH_BACK, -25);
1025                 
1026                 glVertex2f(v2d->cur.xmax, i);
1027                 glVertex2f(v2d->cur.xmin, i);
1028                 glVertex2f(v2d->cur.xmin, i+1);
1029                 glVertex2f(v2d->cur.xmax, i+1);
1030                 i+=1.0;
1031         }
1032         glEnd();
1033         
1034         /* Force grid lines */
1035         i= MAX2(1, ((int)v2d->cur.ymin)-1);
1036         glBegin(GL_LINES);
1037
1038         while (i<v2d->cur.ymax) {
1039                 UI_ThemeColor(TH_GRID);
1040                 glVertex2f(v2d->cur.xmax, i);
1041                 glVertex2f(v2d->cur.xmin, i);
1042                 i+=1.0;
1043         }
1044         glEnd();
1045         
1046         UI_view2d_constant_grid_draw(C, v2d);
1047
1048         draw_cfra_seq(v2d, scene->r.cfra);
1049
1050         /* sequences: first deselect */
1051         if(ed) {
1052                 Sequence *last_seq = get_last_seq(scene);
1053                 int sel = 0, j;
1054                 int outline_tint;
1055                 float pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
1056                 /* loop through twice, first unselected, then selected */
1057                 for (j=0; j<2; j++) {
1058                         seq= ed->seqbasep->first;
1059                         if (j==0)       outline_tint = -150;
1060                         else            outline_tint = -60;
1061                         
1062                         while(seq) { /* bound box test, dont draw outside the view */
1063                                 if (  ((seq->flag & SELECT) == sel) ||
1064                                                 seq == last_seq ||
1065                                                 MIN2(seq->startdisp, seq->start) > v2d->cur.xmax ||
1066                                                 MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin ||
1067                                                 seq->machine+1.0 < v2d->cur.ymin ||
1068                                                 seq->machine > v2d->cur.ymax)
1069                                 {
1070                                         /* dont draw */
1071                                 } else {
1072                                         draw_seq_strip(scene, ar, sseq, seq, outline_tint, pixelx);
1073                                 }
1074                                 seq= seq->next;
1075                         }
1076                         sel= SELECT; /* draw selected next time round */
1077                 }
1078                 /* draw the last selected last, removes some overlapping error */
1079                 if (last_seq) {
1080                         draw_seq_strip(scene, ar, sseq, last_seq, 120, pixelx);
1081                 }
1082         }
1083
1084         /* text draw cached, in pixelspace now */
1085         UI_view2d_text_cache_draw(ar);
1086
1087         /* Draw markers */
1088 //      draw_markers_timespace(SCE_MARKERS, DRAW_MARKERS_LINES);
1089         
1090         /* reset view matrix */
1091         UI_view2d_view_restore(C);
1092
1093         /* scrollers */
1094         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_SECONDSSEQ, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
1095         UI_view2d_scrollers_draw(C, v2d, scrollers);
1096         UI_view2d_scrollers_free(scrollers);
1097 }
1098
1099