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