a0b27cede054aa5daefafe337c23d0361d9c2b67
[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         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_RAM_SOUND) {
549                         sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
550                 }
551                 else if (seq->type == SEQ_HD_SOUND) {
552                         sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
553                 }
554                 else if (seq->type == SEQ_MOVIE) {
555                         sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
556                 }
557         }
558         
559         if(seq->flag & SELECT){
560                 cpack(0xFFFFFF);
561         }else if ((((int)background_col[0] + (int)background_col[1] + (int)background_col[2]) / 3) < 50){
562                 cpack(0x505050); /* use lighter text colour for dark background */
563         }else{
564                 cpack(0);
565         }
566         
567         UI_view2d_text_cache_add(v2d, x1, y1+SEQ_STRIP_OFSBOTTOM, str);
568 }
569
570 /* draws a shaded strip, made from gradient + flat color + gradient */
571 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2)
572 {
573         float ymid1, ymid2;
574         
575         if (seq->flag & SEQ_MUTE) {
576                 glEnable(GL_POLYGON_STIPPLE);
577                 glPolygonStipple(stipple_halftone);
578         }
579         
580         ymid1 = (y2-y1)*0.25 + y1;
581         ymid2 = (y2-y1)*0.65 + y1;
582         
583         glShadeModel(GL_SMOOTH);
584         glBegin(GL_QUADS);
585         
586         if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
587         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0);
588         
589         glColor3ubv((GLubyte *)col);
590         
591         glVertex2f(x1,y1);
592         glVertex2f(x2,y1);
593         
594         if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
595         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5);
596
597         glColor3ubv((GLubyte *)col);
598         
599         glVertex2f(x2,ymid1);
600         glVertex2f(x1,ymid1);
601         
602         glEnd();
603         
604         glRectf(x1,  ymid1,  x2,  ymid2);
605         
606         glBegin(GL_QUADS);
607         
608         glVertex2f(x1,ymid2);
609         glVertex2f(x2,ymid2);
610         
611         if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -15);
612         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 25);
613         
614         glColor3ubv((GLubyte *)col);
615         
616         glVertex2f(x2,y2);
617         glVertex2f(x1,y2);
618         
619         glEnd();
620         
621         if (seq->flag & SEQ_MUTE) {
622                 glDisable(GL_POLYGON_STIPPLE);
623         }
624 }
625
626 /*
627 Draw a sequence strip, bounds check alredy made
628 ARegion is currently only used to get the windows width in pixels
629 so wave file sample drawing precission is zoom adjusted
630 */
631 static void draw_seq_strip(Scene *scene, ARegion *ar, SpaceSeq *sseq, Sequence *seq, int outline_tint, float pixelx)
632 {
633         // XXX
634         extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
635         View2D *v2d= &ar->v2d;
636         float x1, x2, y1, y2;
637         char col[3], background_col[3], is_single_image;
638
639         /* we need to know if this is a single image/color or not for drawing */
640         is_single_image = (char)check_single_seq(seq);
641         
642         /* body */
643         if(seq->startstill) x1= seq->start;
644         else x1= seq->startdisp;
645         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
646         if(seq->endstill) x2= seq->start+seq->len;
647         else x2= seq->enddisp;
648         y2= seq->machine+SEQ_STRIP_OFSTOP;
649         
650         
651         /* get the correct color per strip type*/
652         //get_seq_color3ubv(scene, seq, col);
653         get_seq_color3ubv(scene, seq, background_col);
654         
655         /* draw the main strip body */
656         if (is_single_image) /* single image */
657                 draw_shadedstrip(seq, background_col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2);
658         else /* normal operation */
659                 draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
660         
661         /* draw additional info and controls */
662         if (seq->type == SEQ_RAM_SOUND)
663                 drawseqwave(scene, v2d, seq, x1, y1, x2, y2, ar->winx);
664         
665         if (!is_single_image)
666                 draw_seq_extensions(scene, sseq, seq);
667         
668         draw_seq_handle(v2d, seq, pixelx, SEQ_LEFTHANDLE);
669         draw_seq_handle(v2d, seq, pixelx, SEQ_RIGHTHANDLE);
670         
671         /* draw the strip outline */
672         x1= seq->startdisp;
673         x2= seq->enddisp;
674         
675         get_seq_color3ubv(scene, seq, col);
676         if (G.moving && (seq->flag & SELECT)) {
677                 if(seq->flag & SEQ_OVERLAP) {
678                         col[0]= 255; col[1]= col[2]= 40;
679                 } else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
680         }
681
682         UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, outline_tint);
683         
684         glColor3ubv((GLubyte *)col);
685         
686         if (seq->flag & SEQ_MUTE) {
687                 glEnable(GL_LINE_STIPPLE);
688                 glLineStipple(1, 0x8888);
689         }
690         
691         gl_round_box_shade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
692         
693         if (seq->flag & SEQ_MUTE) {
694                 glDisable(GL_LINE_STIPPLE);
695         }
696         
697         /* calculate if seq is long enough to print a name */
698         x1= seq->startdisp+seq->handsize;
699         x2= seq->enddisp-seq->handsize;
700
701         /* but first the contents of a meta */
702         if(seq->type==SEQ_META) drawmeta_contents(scene, seq, x1, y1+0.15, x2, y2-0.15);
703
704         /* info text on the strip */
705         if(x1<v2d->cur.xmin) x1= v2d->cur.xmin;
706         else if(x1>v2d->cur.xmax) x1= v2d->cur.xmax;
707         if(x2<v2d->cur.xmin) x2= v2d->cur.xmin;
708         else if(x2>v2d->cur.xmax) x2= v2d->cur.xmax;
709
710         /* nice text here would require changing the view matrix for texture text */
711         if( (x2-x1) / pixelx > 32) {
712                 draw_seq_text(v2d, seq, x1, x2, y1, y2, background_col);
713         }
714 }
715
716 static Sequence *special_seq_update= 0;
717
718 void set_special_seq_update(int val)
719 {
720 //      int x;
721
722         /* if mouse over a sequence && LEFTMOUSE */
723         if(val) {
724 // XXX          special_seq_update= find_nearest_seq(&x);
725         }
726         else special_seq_update= 0;
727 }
728
729
730 static void draw_image_seq(Scene *scene, ARegion *ar, SpaceSeq *sseq)
731 {
732         extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
733         struct ImBuf *ibuf;
734         int x1, y1, rectx, recty;
735         int free_ibuf = 0;
736         static int recursive= 0;
737         float zoom;
738         float zoomx, zoomy;
739
740         glClearColor(0.0, 0.0, 0.0, 0.0);
741         glClear(GL_COLOR_BUFFER_BIT);
742
743         rectx= (scene->r.size*scene->r.xsch)/100;
744         recty= (scene->r.size*scene->r.ysch)/100;
745
746         /* BIG PROBLEM: the give_ibuf_seq() can call a rendering, which in turn calls redraws...
747            this shouldn't belong in a window drawing....
748            So: solve this once event based. 
749            Now we check for recursion, space type and active area again (ton) */
750         
751         if(recursive)
752                 return;
753         else {
754                 recursive= 1;
755                 if (special_seq_update) {
756                         ibuf= give_ibuf_seq_direct(scene, rectx, recty, (scene->r.cfra), special_seq_update);
757                 } 
758                 else if (!U.prefetchframes) { // XXX || (G.f & G_PLAYANIM) == 0) {
759                         ibuf= (ImBuf *)give_ibuf_seq(scene, rectx, recty, (scene->r.cfra), sseq->chanshown);
760                 } 
761                 else {
762                         ibuf= (ImBuf *)give_ibuf_seq_threaded(scene, rectx, recty, (scene->r.cfra), sseq->chanshown);
763                 }
764                 recursive= 0;
765                 
766                 /* XXX HURMF! the give_ibuf_seq can call image display in this window */
767 //              if(sa->spacetype!=SPACE_SEQ)
768 //                      return;
769 //              if(sa!=curarea) {
770 //                      areawinset(sa->win);
771 //              }
772         }
773         
774         if(ibuf==NULL) 
775                 return;
776
777         if(ibuf->rect==NULL && ibuf->rect_float == NULL) 
778                 return;
779
780         switch(sseq->mainb != SEQ_DRAW_SEQUENCE) {
781         case SEQ_DRAW_IMG_IMBUF:
782                 if (sseq->zebra != 0) {
783                         ibuf = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
784                         free_ibuf = 1;
785                 }
786                 break;
787         case SEQ_DRAW_IMG_WAVEFORM:
788                 if ((sseq->flag & SEQ_DRAW_COLOR_SEPERATED) != 0) {
789                         ibuf = make_sep_waveform_view_from_ibuf(ibuf);
790                 } else {
791                         ibuf = make_waveform_view_from_ibuf(ibuf);
792                 }
793                 free_ibuf = 1;
794                 break;
795         case SEQ_DRAW_IMG_VECTORSCOPE:
796                 ibuf = make_vectorscope_view_from_ibuf(ibuf);
797                 free_ibuf = 1;
798                 break;
799         case SEQ_DRAW_IMG_HISTOGRAM:
800                 ibuf = make_histogram_view_from_ibuf(ibuf);
801                 free_ibuf = 1;
802                 break;
803         }
804
805         if(ibuf->rect_float && ibuf->rect==NULL)
806                 IMB_rect_from_float(ibuf);
807         
808         /* needed for gla draw */
809         glaDefine2DArea(&ar->winrct);
810         
811         zoom= SEQ_ZOOM_FAC(sseq->zoom);
812         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
813                 zoomx = zoom * ((float)scene->r.xasp / (float)scene->r.yasp);
814                 zoomy = zoom;
815         } else {
816                 zoomx = zoomy = zoom;
817         }
818
819         /* calc location */
820         x1= (ar->winx-zoomx*ibuf->x)/2 + sseq->xof;
821         y1= (ar->winy-zoomy*ibuf->y)/2 + sseq->yof;
822         
823         glPixelZoom(zoomx, zoomy);
824         
825         glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
826         
827         glPixelZoom(1.0, 1.0);
828
829         /* safety border */
830         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && 
831             (sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
832                 float fac= 0.1;
833                 float x2 = x1 + ibuf->x * zoomx;
834                 float y2 = y1 + ibuf->y * zoomy;
835                 
836                 float a= fac*(x2-x1);
837                 x1+= a; 
838                 x2-= a;
839         
840                 a= fac*(y2-y1);
841                 y1+= a;
842                 y2-= a;
843         
844                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
845                 setlinestyle(3);
846
847                 UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
848                 
849                 uiSetRoundBox(15);
850                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
851
852                 setlinestyle(0);
853                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
854         }
855         
856         /* draw grease-pencil (image aligned) */
857 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
858 // XXX          draw_gpencil_2dimage(sa, ibuf);
859
860         if (free_ibuf) {
861                 IMB_freeImBuf(ibuf);
862         } 
863         
864         /* draw grease-pencil (screen aligned) */
865 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
866 // XXX          draw_gpencil_2dview(sa, 0);
867         
868         /* ortho at pixel level sa */
869 // XXX  myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
870         
871 }
872
873 void seq_reset_imageofs(SpaceSeq *sseq)
874 {
875         sseq->xof = sseq->yof = sseq->zoom = 0;
876 }
877
878
879 #if 0
880 /* XXX - these should really be made to use View2D instead of so wacko private system - Aligorith */
881
882 void seq_viewzoom(SpaceSeq *sseq, unsigned short event, int invert)
883 {
884
885         if(event==PAD1)
886                 sseq->zoom= 1.0;
887         else if(event==PAD2)
888                 sseq->zoom= (invert)? 2.0: 0.5;
889         else if(event==PAD4)
890                 sseq->zoom= (invert)? 4.0: 0.25;
891         else if(event==PAD8)
892                 sseq->zoom= (invert)? 8.0: 0.125;
893         
894         /* ensure pixel exact locations for draw */
895         sseq->xof= (int)sseq->xof;
896         sseq->yof= (int)sseq->yof;
897 }
898
899 void seq_viewmove(Scene *scene, ARegion *ar, SpaceSeq *sseq)
900 {       
901         short mval[2], mvalo[2];
902         short rectx, recty, xmin, xmax, ymin, ymax, pad;
903         int oldcursor;
904         Window *win;
905         
906         sa = sseq->area;
907         rectx= (scene->r.size*scene->r.xsch)/100;
908         recty= (scene->r.size*scene->r.ysch)/100;
909         
910         pad = 10;
911         xmin = -(ar->winx/2) - rectx/2 + pad;
912         xmax = ar->winx/2 + rectx/2 - pad;
913         ymin = -(ar->winy/2) - recty/2 + pad;
914         ymax = ar->winy/2 + recty/2 - pad;
915         
916         getmouseco_sc(mvalo);
917
918         oldcursor=get_cursor();
919         win=winlay_get_active_window();
920         
921         SetBlenderCursor(BC_NSEW_SCROLLCURSOR);
922         
923         while(get_mbut()&(L_MOUSE|M_MOUSE)) {
924                 
925                 getmouseco_sc(mval);
926                 
927                 if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) {
928
929                         sseq->xof -= (mvalo[0]-mval[0]);
930                         sseq->yof -= (mvalo[1]-mval[1]);
931                         
932                         /* prevent dragging image outside of the window and losing it! */
933                         CLAMP(sseq->xof, xmin, xmax);
934                         CLAMP(sseq->yof, ymin, ymax);
935                         
936                         mvalo[0]= mval[0];
937                         mvalo[1]= mval[1];
938                         
939                 }
940         }
941 }
942 #endif
943
944 void drawprefetchseqspace(Scene *scene, ARegion *ar, SpaceSeq *sseq)
945 {
946         int rectx, recty;
947
948         rectx= (scene->r.size*scene->r.xsch)/100;
949         recty= (scene->r.size*scene->r.ysch)/100;
950
951         if(sseq->mainb != SEQ_DRAW_SEQUENCE) {
952                 give_ibuf_prefetch_request(
953                         rectx, recty, (scene->r.cfra), sseq->chanshown);
954         }
955 }
956
957 void drawseqspace(const bContext *C, ARegion *ar)
958 {
959         ScrArea *sa= CTX_wm_area(C);
960         SpaceSeq *sseq= sa->spacedata.first;
961         Scene *scene= CTX_data_scene(C);
962         View2D *v2d= &ar->v2d;
963         View2DScrollers *scrollers;
964         Editing *ed= seq_give_editing(scene, FALSE);
965         Sequence *seq;
966         float col[3];
967         int i;
968
969         if(sseq->mainb != SEQ_DRAW_SEQUENCE) {
970                 draw_image_seq(scene, ar, sseq);
971                 return;
972         }
973
974         UI_GetThemeColor3fv(TH_BACK, col);
975         if(ed && ed->metastack.first) glClearColor(col[0], col[1], col[2]-0.1, 0.0);
976         else glClearColor(col[0], col[1], col[2], 0.0);
977
978         glClear(GL_COLOR_BUFFER_BIT);
979
980         UI_view2d_view_ortho(C, v2d);
981         
982         UI_ThemeColorShade(TH_BACK, -20);
983         glRectf(v2d->cur.xmin,  0.0,  v2d->cur.xmax,  1.0);
984
985         boundbox_seq(scene, &v2d->tot);
986         
987         /* Alternating horizontal stripes */
988         i= MAX2(1, ((int)v2d->cur.ymin)-1);
989
990         glBegin(GL_QUADS);
991         while (i<v2d->cur.ymax) {
992                 if (((int)i) & 1)
993                         UI_ThemeColorShade(TH_BACK, -15);
994                 else
995                         UI_ThemeColorShade(TH_BACK, -25);
996                 
997                 glVertex2f(v2d->cur.xmax, i);
998                 glVertex2f(v2d->cur.xmin, i);
999                 glVertex2f(v2d->cur.xmin, i+1);
1000                 glVertex2f(v2d->cur.xmax, i+1);
1001                 i+=1.0;
1002         }
1003         glEnd();
1004         
1005         /* Force grid lines */
1006         i= MAX2(1, ((int)v2d->cur.ymin)-1);
1007         glBegin(GL_LINES);
1008
1009         while (i<v2d->cur.ymax) {
1010                 UI_ThemeColor(TH_GRID);
1011                 glVertex2f(v2d->cur.xmax, i);
1012                 glVertex2f(v2d->cur.xmin, i);
1013                 i+=1.0;
1014         }
1015         glEnd();
1016         
1017         UI_view2d_constant_grid_draw(C, v2d);
1018
1019         draw_cfra_seq(v2d, scene->r.cfra);
1020
1021         /* sequences: first deselect */
1022         if(ed) {
1023                 Sequence *last_seq = get_last_seq(scene);
1024                 int sel = 0, j;
1025                 int outline_tint;
1026                 float pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
1027                 /* loop through twice, first unselected, then selected */
1028                 for (j=0; j<2; j++) {
1029                         seq= ed->seqbasep->first;
1030                         if (j==0)       outline_tint = -150;
1031                         else            outline_tint = -60;
1032                         
1033                         while(seq) { /* bound box test, dont draw outside the view */
1034                                 if (  ((seq->flag & SELECT) == sel) ||
1035                                                 seq == last_seq ||
1036                                                 MIN2(seq->startdisp, seq->start) > v2d->cur.xmax ||
1037                                                 MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin ||
1038                                                 seq->machine+1.0 < v2d->cur.ymin ||
1039                                                 seq->machine > v2d->cur.ymax)
1040                                 {
1041                                         /* dont draw */
1042                                 } else {
1043                                         draw_seq_strip(scene, ar, sseq, seq, outline_tint, pixelx);
1044                                 }
1045                                 seq= seq->next;
1046                         }
1047                         sel= SELECT; /* draw selected next time round */
1048                 }
1049                 /* draw the last selected last, removes some overlapping error */
1050                 if (last_seq) {
1051                         draw_seq_strip(scene, ar, sseq, last_seq, 120, pixelx);
1052                 }
1053         }
1054
1055         /* text draw cached, in pixelspace now */
1056         UI_view2d_text_cache_draw(ar);
1057
1058         /* Draw markers */
1059 //      draw_markers_timespace(SCE_MARKERS, DRAW_MARKERS_LINES);
1060         
1061         /* reset view matrix */
1062         UI_view2d_view_restore(C);
1063
1064         /* scrollers */
1065         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_SECONDSSEQ, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
1066         UI_view2d_scrollers_draw(C, v2d, scrollers);
1067         UI_view2d_scrollers_free(scrollers);
1068 }
1069
1070