==Sequencer==
[blender.git] / source / blender / src / drawseq.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include <string.h>
38 #include <math.h>
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BMF_Api.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_arithb.h"
46
47 #include "IMB_imbuf_types.h"
48
49 #include "DNA_sequence_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_space_types.h"
53 #include "DNA_view2d_types.h"
54
55 #include "BKE_global.h"
56 #include "BKE_plugin_types.h"
57 #include "BKE_scene.h"
58 #include "BKE_utildefines.h"
59
60 #include "BIF_gl.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
77 #include "IMB_imbuf_types.h"
78 #include "IMB_imbuf.h"
79
80 #include "blendef.h"    /* CFRA */
81 #include "mydevice.h"   /* REDRAWSEQ */
82 #include "interface.h"
83
84 #define SEQ_LEFTHANDLE          1
85 #define SEQ_RIGHTHANDLE 2
86
87 #define SEQ_STRIP_OFSBOTTOM             0.2
88 #define SEQ_STRIP_OFSTOP                0.8
89
90 int no_rightbox=0, no_leftbox= 0;
91 static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction);
92 static void draw_seq_extensions(Sequence *seq, SpaceSeq *sseq);
93 static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2);
94 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2);
95 static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq);
96
97 static char *give_seqname(Sequence *seq)
98 {
99         if(seq->type==SEQ_META) return "Meta";
100         else if(seq->type==SEQ_IMAGE) return "Image";
101         else if(seq->type==SEQ_SCENE) return "Scene";
102         else if(seq->type==SEQ_MOVIE) return "Movie";
103         else if(seq->type==SEQ_RAM_SOUND) return "Audio (RAM)";
104         else if(seq->type==SEQ_HD_SOUND) return "Audio (HD)";
105         else if(seq->type<SEQ_EFFECT) return seq->strip->dir;
106         else if(seq->type==SEQ_CROSS) return "Cross";
107         else if(seq->type==SEQ_GAMCROSS) return "Gamma Cross";
108         else if(seq->type==SEQ_ADD) return "Add";
109         else if(seq->type==SEQ_SUB) return "Sub";
110         else if(seq->type==SEQ_MUL) return "Mul";
111         else if(seq->type==SEQ_ALPHAOVER) return "Alpha Over";
112         else if(seq->type==SEQ_ALPHAUNDER) return "Alpha Under";
113         else if(seq->type==SEQ_OVERDROP) return "Over Drop";
114         else if(seq->type==SEQ_WIPE) return "Wipe";
115         else if(seq->type==SEQ_GLOW) return "Glow";
116         else if(seq->type==SEQ_PLUGIN) {
117                 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
118                    seq->plugin && seq->plugin->doit) return seq->plugin->pname;
119                 return "Plugin";
120         }
121         else return "Effect";
122
123 }
124 static void draw_cfra_seq(void)
125 {
126         glColor3ub(0x30, 0x90, 0x50);
127         glLineWidth(2.0);
128         glBegin(GL_LINES);
129         glVertex2f(G.scene->r.cfra, G.v2d->cur.ymin);
130         glVertex2f(G.scene->r.cfra, G.v2d->cur.ymax);
131         glEnd();
132         glLineWidth(1.0);
133 }
134
135 static void get_seq_color3ubv(Sequence *seq, char *col)
136 {
137         char blendcol[3];
138         float hsv[3], rgb[3];
139         
140         switch(seq->type) {
141         case SEQ_IMAGE:
142                 BIF_GetThemeColor3ubv(TH_SEQ_IMAGE, col);
143                 break;
144         case SEQ_META:
145                 BIF_GetThemeColor3ubv(TH_SEQ_META, col);
146                 break;
147         case SEQ_MOVIE:
148                 BIF_GetThemeColor3ubv(TH_SEQ_MOVIE, col);
149                 break;
150         case SEQ_SCENE:
151                 BIF_GetThemeColor3ubv(TH_SEQ_SCENE, col);
152                 
153                 if(seq->scene==G.scene) {
154                         BIF_GetColorPtrBlendShade3ubv(col, col, col, 1.0, 20);
155                 }
156                 break;
157
158         /* transitions */
159         case SEQ_CROSS:
160         case SEQ_GAMCROSS:
161         case SEQ_WIPE:
162                 /* slightly offset hue to distinguish different effects */
163                 BIF_GetThemeColor3ubv(TH_SEQ_TRANSITION, col);
164                 
165                 rgb[0] = col[0]/255.0; rgb[1] = col[1]/255.0; rgb[2] = col[2]/255.0; 
166                 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
167                 
168                 if (seq->type == SEQ_CROSS)             hsv[0]+= 0.04;
169                 if (seq->type == SEQ_GAMCROSS)  hsv[0]+= 0.08;
170                 if (seq->type == SEQ_WIPE)              hsv[0]+= 0.12;
171                 
172                 if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
173                 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
174                 col[0] = (char)(rgb[0]*255); col[1] = (char)(rgb[1]*255); col[2] = (char)(rgb[2]*255); 
175                 break;
176                 
177         /* effects */
178         case SEQ_ADD:
179         case SEQ_SUB:
180         case SEQ_MUL:
181         case SEQ_ALPHAOVER:
182         case SEQ_ALPHAUNDER:
183         case SEQ_OVERDROP:
184         case SEQ_GLOW:
185                 /* slightly offset hue to distinguish different effects */
186                 BIF_GetThemeColor3ubv(TH_SEQ_EFFECT, col);
187                 
188                 rgb[0] = col[0]/255.0; rgb[1] = col[1]/255.0; rgb[2] = col[2]/255.0; 
189                 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
190                 
191                 if (seq->type == SEQ_ADD)               hsv[0]+= 0.04;
192                 if (seq->type == SEQ_SUB)               hsv[0]+= 0.08;
193                 if (seq->type == SEQ_MUL)               hsv[0]+= 0.12;
194                 if (seq->type == SEQ_ALPHAOVER) hsv[0]+= 0.16;
195                 if (seq->type == SEQ_ALPHAUNDER)        hsv[0]+= 0.20;
196                 if (seq->type == SEQ_OVERDROP)  hsv[0]+= 0.24;
197                 if (seq->type == SEQ_GLOW)              hsv[0]+= 0.28;
198                 
199                 if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
200                 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
201                 col[0] = (char)(rgb[0]*255); col[1] = (char)(rgb[1]*255); col[2] = (char)(rgb[2]*255); 
202                 break;
203                 
204         case SEQ_PLUGIN:
205                 BIF_GetThemeColor3ubv(TH_SEQ_PLUGIN, col);
206                 break;
207         case SEQ_HD_SOUND:
208         case SEQ_RAM_SOUND:
209                 BIF_GetThemeColor3ubv(TH_SEQ_AUDIO, col);
210                 blendcol[0] = blendcol[1] = blendcol[2] = 128;
211                 if(seq->flag & SEQ_MUTE) BIF_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20);
212                 break;
213         default:
214                 col[0] = 10; col[1] = 255; col[2] = 40;
215         }
216 }
217
218 static void drawmeta_contents(Sequence *seqm, float x1, float y1, float x2, float y2)
219 {
220         Sequence *seq;
221         float dx;
222         int nr;
223         char col[3];
224         
225         nr= 0;
226         WHILE_SEQ(&seqm->seqbase) {
227                 nr++;
228         }
229         END_SEQ
230
231         dx= (x2-x1)/nr;
232
233         WHILE_SEQ(&seqm->seqbase) {
234                 get_seq_color3ubv(seq, col);
235                 
236                 glColor3ubv(col);
237
238                 glRectf(x1,  y1,  x1+0.9*dx,  y2);
239                 
240                 BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -30);
241                 glColor3ubv(col);
242
243                 fdrawbox(x1,  y1,  x1+0.9*dx,  y2);
244                 
245                 x1+= dx;
246         }
247         END_SEQ
248 }
249
250 static void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2, int winx)
251 {
252         float f, height, midy, clipxmin, clipxmax, sample_step;
253         int offset, offset_next, sofs, eofs, i=0;
254         signed short* s;
255         bSound *sound;
256         int wavesample, wavesamplemin, wavesamplemax, subsample_step=4; /* used for finding the min and max wave peaks */
257         Uint8 *stream;
258         float fsofs, feofs_sofs, sound_width, wavemulti; /* for faster access in the loop */
259         
260         audio_makestream(seq->sound);
261         if(seq->sound->stream==NULL) return;    
262         
263         if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0);
264         
265         sofs = ((int)( (((float)(seq->startdisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
266         eofs = ((int)( (((float)(seq->enddisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
267         
268         /* clip the drawing area to the screen bounds to save time */
269         sample_step= (G.v2d->cur.xmax-G.v2d->cur.xmin)/winx;
270         clipxmin= MAX2(x1, G.v2d->cur.xmin);
271         clipxmax= MIN2(x2, G.v2d->cur.xmax);
272         
273         /* Stops dithering on redraw when clipxmin is offset. */
274         if (clipxmin != x1) {
275                 clipxmin = (float) ((int)((clipxmin*sample_step)+(i*sample_step))) / sample_step;
276                 while (clipxmin < x1) {
277                         clipxmin = (float) ((int)((clipxmin*sample_step)+(i*sample_step))) / sample_step;
278                         i+=1;
279                 }
280                 clipxmin = (float)((int)clipxmin); /* snap to int */    
281         }
282         
283         /* when the sample step is 4 every sample of the wave is evaluated for min and max
284         values used to draw the wave, however this is slow ehrn zoomed out
285         so when the sample step is above 1 (the larger the further out the zoom is)
286         so not evaluate all samples, only some.*/
287         if (sample_step > 1)
288                 subsample_step= ((int)(subsample_step*sample_step*8)) & (~3);
289         
290         /* for speedy access */
291         midy = (y1+y2)/2;
292         fsofs= (float)sofs;
293         feofs_sofs= (float)(eofs-sofs);
294         sound_width= x2-x1;
295         height= y2-y1;
296         sound = seq->sound;
297         stream = sound->stream;
298         wavemulti = height/196605;
299         wavesample=0;
300         
301         
302         /* we need to get the starting offset value, excuse the duplicate code */
303         f=clipxmin;
304         offset = (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3);
305         
306         /* start the loop, draw a line per sample_step -sample_step is about 1 line drawn per pixel */
307         glBegin(GL_LINES);
308         for (f=clipxmin+sample_step; f<=clipxmax; f+=sample_step) {
309                 
310                 offset_next = (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3);
311                 
312                 /* if this is close to the last sample just exit */
313                 if (offset_next >= sound->streamlen) break;
314                 
315                 wavesamplemin = 131070;
316                 wavesamplemax = -131070;
317                 
318                 /*find with high and low of the waveform for this draw,
319                 evaluate small samples to find this range */
320                 while (offset < offset_next) {
321                         s = (signed short*)(stream+offset);
322                         
323                         wavesample = s[0]*2 + s[1];
324                         if (wavesamplemin>wavesample)
325                                 wavesamplemin=wavesample;
326                         if (wavesamplemax<wavesample)
327                                 wavesamplemax=wavesample;
328                         offset+=subsample_step;
329                 }
330                 /* draw the wave line, looks good up close and zoomed out */
331                 glVertex2f(f,  midy-(wavemulti*wavesamplemin) );
332                 glVertex2f(f,  midy-(wavemulti*wavesamplemax) );
333                 offset=offset_next;
334         }
335         glEnd();
336 }
337
338 /* draw a handle, for each end of a sequence strip */
339 static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction)
340 {
341         float v1[2], v2[2], v3[2], rx1=0, rx2=0; //for triangles and rect
342         float x1, x2, y1, y2;
343         float pixelx;
344         float handsize;
345         float minhandle, maxhandle;
346         char str[120];
347         unsigned int whichsel=0;
348         View2D *v2d;
349         
350         x1= seq->startdisp;
351         x2= seq->enddisp;
352         
353         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
354         y2= seq->machine+SEQ_STRIP_OFSTOP;
355         
356         v2d = &sseq->v2d;
357         pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
358         
359         /* clamp handles to defined size in pixel space */
360         handsize = seq->handsize;
361         minhandle = 7;
362         maxhandle = 28;
363         CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
364         
365         /* set up co-ordinates/dimensions for either left or right handle */
366         if (direction == SEQ_LEFTHANDLE) {      
367                 rx1 = x1;
368                 rx2 = x1+handsize*0.75;
369                 
370                 v1[0]= x1+handsize/4; v1[1]= y1+( ((y1+y2)/2.0 - y1)/2);
371                 v2[0]= x1+handsize/4; v2[1]= y2-( ((y1+y2)/2.0 - y1)/2);
372                 v3[0]= v2[0] + handsize/4; v3[1]= (y1+y2)/2.0;
373                 
374                 whichsel = SEQ_LEFTSEL;
375         } else if (direction == SEQ_RIGHTHANDLE) {      
376                 rx1 = x2-handsize*0.75;
377                 rx2 = x2;
378                 
379                 v1[0]= x2-handsize/4; v1[1]= y1+( ((y1+y2)/2.0 - y1)/2);
380                 v2[0]= x2-handsize/4; v2[1]= y2-( ((y1+y2)/2.0 - y1)/2);
381                 v3[0]= v2[0] - handsize/4; v3[1]= (y1+y2)/2.0;
382                 
383                 whichsel = SEQ_RIGHTSEL;
384         }
385         
386         /* draw! */
387         if(seq->type < SEQ_EFFECT) {
388                 glEnable( GL_BLEND );
389                 
390                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
391                 
392                 if(seq->flag & whichsel) glColor4ub(0, 0, 0, 80);
393                 else if (seq->flag & SELECT) glColor4ub(255, 255, 255, 30);
394                 else glColor4ub(0, 0, 0, 22);
395                 
396                 glRectf(rx1, y1, rx2, y2);
397                 
398                 if(seq->flag & whichsel) glColor4ub(255, 255, 255, 200);
399                 else glColor4ub(0, 0, 0, 50);
400                 
401                 glEnable( GL_POLYGON_SMOOTH );
402                 glBegin(GL_TRIANGLES);
403                 glVertex2fv(v1); glVertex2fv(v2); glVertex2fv(v3);
404                 glEnd();
405                 
406                 glDisable( GL_POLYGON_SMOOTH );
407                 glDisable( GL_BLEND );
408         }
409         
410         if(G.moving || (seq->flag & whichsel)) {
411                 cpack(0xFFFFFF);
412                 if (direction == SEQ_LEFTHANDLE) {
413                         sprintf(str, "%d", seq->startdisp);
414                         glRasterPos3f(rx1,  y1-0.15, 0.0);
415                 } else {
416                         sprintf(str, "%d", seq->enddisp - 1);
417                         glRasterPos3f((x2-BMF_GetStringWidth(G.font, str)*pixelx),  y2+0.05, 0.0);
418                 }
419                 BMF_DrawString(G.font, str);
420         }       
421 }
422
423 static void draw_seq_extensions(Sequence *seq, SpaceSeq *sseq)
424 {
425         float x1, x2, y1, y2, pixely, a;
426         char col[3], blendcol[3];
427         View2D *v2d;
428         
429         if(seq->type >= SEQ_EFFECT) return;
430
431         x1= seq->startdisp;
432         x2= seq->enddisp;
433         
434         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
435         y2= seq->machine+SEQ_STRIP_OFSTOP;
436         
437         v2d = &sseq->v2d;
438         pixely = (v2d->cur.ymax - v2d->cur.ymin)/(v2d->mask.ymax - v2d->mask.ymin);
439         
440         blendcol[0] = blendcol[1] = blendcol[2] = 120;
441
442         if(seq->startofs) {
443                 glEnable( GL_BLEND );
444                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
445                 
446                 get_seq_color3ubv(seq, col);
447                 
448                 if (seq->flag & SELECT) {
449                         BIF_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
450                         glColor4ub(col[0], col[1], col[2], 170);
451                 } else {
452                         BIF_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
453                         glColor4ub(col[0], col[1], col[2], 110);
454                 }
455                 
456                 glRectf((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1);
457                 
458                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
459                 else glColor4ub(col[0], col[1], col[2], 160);
460
461                 fdrawbox((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1);  //outline
462                 
463                 glDisable( GL_BLEND );
464         }
465         if(seq->endofs) {
466                 glEnable( GL_BLEND );
467                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
468                 
469                 get_seq_color3ubv(seq, col);
470                 
471                 if (seq->flag & SELECT) {
472                         BIF_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
473                         glColor4ub(col[0], col[1], col[2], 170);
474                 } else {
475                         BIF_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
476                         glColor4ub(col[0], col[1], col[2], 110);
477                 }
478                 
479                 glRectf(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM);
480                 
481                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
482                 else glColor4ub(col[0], col[1], col[2], 160);
483
484                 fdrawbox(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM); //outline
485                 
486                 glDisable( GL_BLEND );
487         }
488         if(seq->startstill) {
489                 get_seq_color3ubv(seq, col);
490                 BIF_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
491                 glColor3ubv(col);
492                 
493                 draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
494                 
495                 /* feint pinstripes, helps see exactly which is extended and which isn't,
496                 * especially when the extension is very small */ 
497                 if (seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
498                 else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
499                 
500                 glColor3ubv(col);
501                 
502                 for(a=y1; a< y2; a+= pixely*2.0 ) {
503                         fdrawline(x1,  a,  (float)(seq->start),  a);
504                 }
505         }
506         if(seq->endstill) {
507                 get_seq_color3ubv(seq, col);
508                 BIF_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
509                 glColor3ubv(col);
510                 
511                 draw_shadedstrip(seq, col, (float)(seq->start+seq->len), y1, x2, y2);
512                 
513                 /* feint pinstripes, helps see exactly which is extended and which isn't,
514                 * especially when the extension is very small */ 
515                 if (seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
516                 else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
517                 
518                 glColor3ubv(col);
519                 
520                 for(a=y1; a< y2; a+= pixely*2.0 ) {
521                         fdrawline((float)(seq->start+seq->len),  a,  x2,  a);
522                 }
523         }
524 }
525
526 /* draw info text on a sequence strip */
527 static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2)
528 {
529         float v1[2], v2[2];
530         int len, size;
531         char str[120], *strp;
532         short mval[2];
533         
534         v1[1]= y1;
535         v2[1]= y2;
536         
537         v1[0]= x1;
538         ipoco_to_areaco_noclip(G.v2d, v1, mval);
539         x1= mval[0];
540         v2[0]= x2;
541         ipoco_to_areaco_noclip(G.v2d, v2, mval);
542         x2= mval[0];
543         size= x2-x1;
544         
545         if(seq->name[2]) {
546                 sprintf(str, "%d | %s: %s", seq->len, give_seqname(seq), seq->name+2);
547         }else{
548                 if(seq->type == SEQ_META) {
549                         sprintf(str, "%d | %s", seq->len, give_seqname(seq));
550                 }
551                 else if(seq->type == SEQ_SCENE) {
552                         if(seq->scene) sprintf(str, "%d | %s: %s", seq->len, give_seqname(seq), seq->scene->id.name+2);
553                         else sprintf(str, "%d | %s", seq->len, give_seqname(seq));
554                         
555                 }
556                 else if(seq->type == SEQ_IMAGE) {
557                         sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
558                 }
559                 else if(seq->type & SEQ_EFFECT) {
560                         int can_float = (seq->type != SEQ_PLUGIN)
561                                 || (seq->plugin && seq->plugin->version >= 4);
562
563                         if(seq->seq3!=seq->seq2 && seq->seq1!=seq->seq3)
564                                 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!");
565                         else
566                                 sprintf(str, "%d | %s: %d>%d%s", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, can_float ? "" : " No float, upgrade plugin!");
567                 }
568                 else if (seq->type == SEQ_RAM_SOUND) {
569                         sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
570                 }
571                 else if (seq->type == SEQ_HD_SOUND) {
572                         sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
573                 }
574                 else if (seq->type == SEQ_MOVIE) {
575                         sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
576                 }
577         }
578         
579         strp= str;
580         
581         while( (len= BMF_GetStringWidth(G.font, strp)) > size) {
582                 if(len < 10) break;
583                 if(strp[1]==0) break;
584                 strp++;
585         }
586         
587         mval[0]= (x1+x2-len+1)/2;
588         mval[1]= 1;
589         areamouseco_to_ipoco(G.v2d, mval, &x1, &x2);
590         
591         if(seq->flag & SELECT) cpack(0xFFFFFF);
592         else cpack(0);
593         glRasterPos3f(x1,  y1+SEQ_STRIP_OFSBOTTOM, 0.0);
594         BMF_DrawString(G.font, strp);
595 }
596
597 /* draws a shaded strip, made from gradient + flat colour + gradient */
598 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2)
599 {
600         float ymid1, ymid2;
601         
602         ymid1 = (y2-y1)*0.25 + y1;
603         ymid2 = (y2-y1)*0.65 + y1;
604         
605         glShadeModel(GL_SMOOTH);
606         glBegin(GL_QUADS);
607         
608         if(seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
609         else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0);
610         
611         glColor3ubv(col);
612         
613         glVertex2f(x1,y1);
614         glVertex2f(x2,y1);
615         
616         if(seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
617         else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5);
618
619         glColor3ubv(col);
620         
621         glVertex2f(x2,ymid1);
622         glVertex2f(x1,ymid1);
623         
624         glEnd();
625         
626         glRectf(x1,  ymid1,  x2,  ymid2);
627         
628         glBegin(GL_QUADS);
629         
630         glVertex2f(x1,ymid2);
631         glVertex2f(x2,ymid2);
632         
633         if(seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -15);
634         else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 25);
635         
636         glColor3ubv(col);
637         
638         glVertex2f(x2,y2);
639         glVertex2f(x1,y2);
640         
641         glEnd();
642         
643 }
644
645 /*
646 Draw a sequence strip, bounds check alredy made
647 ScrArea is currently only used to get the windows width in pixels
648 so wave file sample drawing precission is zoom adjusted
649 */
650 static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
651 {
652         float x1, x2, y1, y2;
653         char col[3];
654
655         /* body */
656         if(seq->startstill) x1= seq->start;
657         else x1= seq->startdisp;
658         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
659         if(seq->endstill) x2= seq->start+seq->len;
660         else x2= seq->enddisp;
661         y2= seq->machine+SEQ_STRIP_OFSTOP;
662         
663         
664         /* get the correct colour per strip type*/
665         get_seq_color3ubv(seq, col);
666         
667         /* draw the main strip body */
668         draw_shadedstrip(seq, col, x1, y1, x2, y2);
669         
670         /* draw additional info and controls */
671         if (seq->type == SEQ_RAM_SOUND) drawseqwave(seq, x1, y1, x2, y2, sa->winx);
672         draw_seq_extensions(seq, sseq);
673         draw_seq_handle(seq, sseq, SEQ_LEFTHANDLE);
674         draw_seq_handle(seq, sseq, SEQ_RIGHTHANDLE);
675         
676         /* draw the strip outline */
677         x1= seq->startdisp;
678         x2= seq->enddisp;
679         
680         get_seq_color3ubv(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 BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
685         }
686         else if (seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -150);
687         else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -60);
688
689         glColor3ubv(col);
690         gl_round_box_shade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
691
692         
693         /* calculate if seq is long enough to print a name */
694         x1= seq->startdisp+seq->handsize;
695         x2= seq->enddisp-seq->handsize;
696
697         /* but first the contents of a meta */
698         if(seq->type==SEQ_META) drawmeta_contents(seq, x1, y1+0.15, x2, y2-0.15);
699
700         /* info text on the strip */
701         if(x1<G.v2d->cur.xmin) x1= G.v2d->cur.xmin;
702         else if(x1>G.v2d->cur.xmax) x1= G.v2d->cur.xmax;
703         if(x2<G.v2d->cur.xmin) x2= G.v2d->cur.xmin;
704         else if(x2>G.v2d->cur.xmax) x2= G.v2d->cur.xmax;
705
706         if(x1 != x2) {
707                 draw_seq_text(seq, x1, x2, y1, y2);
708         }
709                 
710 }
711
712 static Sequence *special_seq_update= 0;
713
714 void set_special_seq_update(int val)
715 {
716         int x;
717
718         /* if mouse over a sequence && LEFTMOUSE */
719         if(val) {
720                 special_seq_update= find_nearest_seq(&x);
721         }
722         else special_seq_update= 0;
723 }
724
725
726 static void draw_image_seq(ScrArea *sa)
727 {
728         SpaceSeq *sseq;
729         StripElem *se;
730         struct ImBuf *ibuf;
731         int x1, y1, rectx, recty;
732         int free_ibuf = 0;
733         float zoom;
734
735         glClearColor(0.0, 0.0, 0.0, 0.0);
736         glClear(GL_COLOR_BUFFER_BIT);
737
738         sseq= sa->spacedata.first;
739         if(sseq==0) return;
740
741         rectx= (G.scene->r.size*G.scene->r.xsch)/100;
742         recty= (G.scene->r.size*G.scene->r.ysch)/100;
743
744         ibuf= (ImBuf *)give_ibuf_seq(rectx, recty,
745                                      (G.scene->r.cfra), sseq->chanshown);
746
747         if(special_seq_update) {
748                 se = special_seq_update->curelem;
749                 if(se) {
750                         if(se->ok==2) {
751                                 if(se->se1)
752                                         ibuf= se->se1->ibuf;
753                         }
754                         else ibuf= se->ibuf;
755                 }
756         }
757         if(ibuf==NULL) 
758                 return;
759         if(ibuf->rect_float && ibuf->rect==NULL)
760                 IMB_rect_from_float(ibuf);
761         if(ibuf->rect==NULL) 
762                 return;
763
764         if (sseq->mainb == SEQ_DRAW_IMG_WAVEFORM) {
765                 ibuf = make_waveform_view_from_ibuf(ibuf);
766                 free_ibuf = 1;
767         } else if (sseq->mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
768                 ibuf = make_vectorscope_view_from_ibuf(ibuf);
769                 free_ibuf = 1;
770         }
771
772         if (sseq->zoom > 0) {
773                 zoom = sseq->zoom;
774         } else if (sseq->zoom == 0) {
775                 zoom = 1.0;
776         } else {
777                 zoom = -1.0/sseq->zoom;
778         }
779
780         /* calc location */
781         x1= (sa->winx-zoom*ibuf->x)/2 + sseq->xof;
782         y1= (sa->winy-zoom*ibuf->y)/2 + sseq->yof;
783
784         /* needed for gla draw */
785         glaDefine2DArea(&curarea->winrct);
786         glPixelZoom(zoom, zoom);
787         
788         glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
789         
790         glPixelZoom(1.0, 1.0);
791
792         if (free_ibuf) {
793                 IMB_freeImBuf(ibuf);
794         }
795
796         sa->win_swap= WIN_BACK_OK;
797 }
798
799 static void draw_extra_seqinfo(void)
800 {
801         Sequence *last_seq = get_last_seq();
802         StripElem *se, *last;
803         float xco, xfac;
804         int sta, end;
805         char str[256];
806
807         if(last_seq==0) return;
808
809         /* xfac: size of 1 pixel */
810         xfac= G.v2d->cur.xmax - G.v2d->cur.xmin;
811         xfac/= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
812         xco= G.v2d->cur.xmin+40*xfac;
813
814         BIF_ThemeColor(TH_TEXT);
815
816         /* NAME */
817         glRasterPos3f(xco,  0.3, 0.0);
818         strncpy(str, give_seqname(last_seq), 255);
819         BMF_DrawString(G.font, str);
820         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
821
822         if(last_seq->type==SEQ_SCENE && last_seq->scene) {
823                 glRasterPos3f(xco,  0.3, 0.0);
824                 BMF_DrawString(G.font, last_seq->scene->id.name+2);
825                 xco += xfac*BMF_GetStringWidth(G.font, last_seq->scene->id.name+2) +30.0*xfac;
826         }
827
828         /* LEN */
829         if(last_seq->type & SEQ_EFFECT)
830                 sprintf(str, "len: %d   From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1);
831         else
832                 sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len);
833
834         glRasterPos3f(xco,  0.3, 0.0);
835         BMF_DrawString(G.font, str);
836         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
837
838         if(last_seq->type==SEQ_IMAGE) {
839
840                 /* CURRENT */
841                 se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
842                 if(se) {
843                         sprintf(str, "Cur: %s", se->name);
844                         glRasterPos3f(xco,  0.3, 0.0);
845                         BMF_DrawString(G.font, str);
846                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
847                 }
848
849                 /* FIRST AND LAST */
850
851                 if(last_seq->strip) {
852                         se= last_seq->strip->stripdata;
853                         last= se+last_seq->len-1;
854                         if(last_seq->startofs) se+= last_seq->startofs;
855                         if(last_seq->endofs) last-= last_seq->endofs;
856
857                         sprintf(str, "First: %s at %d   Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1);
858                         glRasterPos3f(xco,  0.3, 0.0);
859                         BMF_DrawString(G.font, str);
860                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
861
862                         /* orig size */
863                         sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory);
864                         glRasterPos3f(xco,  0.3, 0.0);
865                         BMF_DrawString(G.font, str);
866                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
867                 }
868         }
869         else if(last_seq->type==SEQ_MOVIE) {
870
871                 sta= last_seq->startofs;
872                 end= last_seq->len-1-last_seq->endofs;
873
874                 sprintf(str, "%s   %s%s  First: %d at %d   Last: %d at %d   Cur: %d",
875                                 last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
876                                 sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp);
877
878                 glRasterPos3f(xco,  0.3, 0.0);
879                 BMF_DrawString(G.font, str);
880         }
881         else if(last_seq->type==SEQ_RAM_SOUND
882                 || last_seq->type == SEQ_HD_SOUND) {
883
884                 sta= last_seq->startofs;
885                 end= last_seq->len-1-last_seq->endofs;
886
887                 sprintf(str, "%s   %s%s  First: %d at %d   Last: %d at %d   Cur: %d   Gain: %.2f dB   Pan: %.2f",
888                                 last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
889                                 sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp,
890                                 last_seq->level, last_seq->pan);
891
892                 glRasterPos3f(xco,  0.3, 0.0);
893                 BMF_DrawString(G.font, str);
894         }
895 }
896
897 void seq_reset_imageofs(SpaceSeq *sseq)
898 {
899         sseq->xof = sseq->yof = sseq->zoom = 0;
900 }
901
902 void seq_viewmove(SpaceSeq *sseq)
903 {       
904         ScrArea *sa;
905         short mval[2], mvalo[2];
906         short rectx, recty, xmin, xmax, ymin, ymax, pad;
907         
908         sa = sseq->area;
909         rectx= (G.scene->r.size*G.scene->r.xsch)/100;
910         recty= (G.scene->r.size*G.scene->r.ysch)/100;
911         
912         pad = 10;
913         xmin = -(sa->winx/2) - rectx/2 + pad;
914         xmax = sa->winx/2 + rectx/2 - pad;
915         ymin = -(sa->winy/2) - recty/2 + pad;
916         ymax = sa->winy/2 + recty/2 - pad;
917         
918         getmouseco_sc(mvalo);
919
920         while(get_mbut()&(L_MOUSE|M_MOUSE)) {
921                 
922                 getmouseco_sc(mval);
923                 
924                 if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) {
925
926                         sseq->xof -= (mvalo[0]-mval[0]);
927                         sseq->yof -= (mvalo[1]-mval[1]);
928                         
929                         /* prevent dragging image outside of the window and losing it! */
930                         CLAMP(sseq->xof, xmin, xmax);
931                         CLAMP(sseq->yof, ymin, ymax);
932                         
933                         mvalo[0]= mval[0];
934                         mvalo[1]= mval[1];
935                         
936                         scrarea_do_windraw(curarea);
937                         screen_swapbuffers();
938                 }
939                 else BIF_wait_for_statechange();
940         }
941 }
942
943 #define SEQ_BUT_PLUGIN  1
944 #define SEQ_BUT_RELOAD  2
945 #define SEQ_BUT_EFFECT  3
946
947 void do_seqbuttons(short val)
948 {
949         Sequence *last_seq = get_last_seq();
950
951         switch(val) {
952         case SEQ_BUT_PLUGIN:
953                 new_stripdata(last_seq);
954                 free_imbuf_effect_spec(CFRA);
955                 break;
956
957         case SEQ_BUT_RELOAD:
958                 free_imbuf_seq();       // frees all
959                 break;
960         case SEQ_BUT_EFFECT:
961                 new_stripdata(last_seq);
962                 calc_sequence(last_seq);
963                 break;
964         }
965
966         allqueue(REDRAWSEQ, 0);
967 }
968
969 static void seq_panel_properties(short cntrl)   // SEQ_HANDLER_PROPERTIES
970 {
971         Sequence *last_seq = get_last_seq();
972         uiBlock *block;
973
974         block= uiNewBlock(&curarea->uiblocks, "seq_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
975         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
976         uiSetPanelHandler(SEQ_HANDLER_PROPERTIES);  // for close and esc
977         if(uiNewPanel(curarea, block, "Strip Properties", "Seq", 10, 230, 318, 204)==0) return;
978
979         if(last_seq==NULL) return;
980
981         if(last_seq->type==SEQ_PLUGIN) {
982                 PluginSeq *pis;
983                 VarStruct *varstr;
984                 int a, xco, yco;
985
986                 uiDefBut(block, LABEL, 0, "Type: Plugin", 10,50,70,20, 0, 0, 0, 0, 0, "");
987
988                 pis= last_seq->plugin;
989                 if(pis->vars==0) return;
990
991                 varstr= pis->varstr;
992                 if(varstr) {
993                         for(a=0; a<pis->vars; a++, varstr++) {
994                                 xco= 150*(a/6)+10;
995                                 yco= 125 - 20*(a % 6)+1;
996                                 uiDefBut(block, varstr->type, SEQ_BUT_PLUGIN, varstr->name, xco,yco,150,19, &(pis->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
997
998                         }
999                 }
1000                 uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED,
1001                              SEQ_BUT_RELOAD, "IPO Frame locked",
1002                              10,-40,150,19, &last_seq->flag,
1003                              0.0, 1.0, 0, 0,
1004                              "Lock the IPO coordinates to the "
1005                              "global frame counter.");
1006
1007         }
1008         else if(last_seq->type==SEQ_IMAGE) {
1009
1010                 uiDefBut(block, LABEL, 0, "Type: Image", 10,140,150,20, 0, 0, 0, 0, 0, "");
1011                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
1012                 
1013                 uiBlockBeginAlign(block);
1014                 uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Convert to Premul", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha");
1015                 uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY",        10,70,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields");
1016                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:",                   10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
1017                 uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,30,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order");
1018                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:",                        10,10,150,19, &last_seq->strobe, 1.0, 30.0, 100, 0, "Only display every nth frame");
1019                 uiBlockEndAlign(block);
1020         }
1021         else if(last_seq->type==SEQ_META) {
1022
1023                 uiDefBut(block, LABEL, 0, "Type: Meta", 10,140,150,20, 0, 0, 0, 0, 0, "");
1024                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
1025
1026         }
1027         else if(last_seq->type==SEQ_SCENE) {
1028
1029                 uiDefBut(block, LABEL, 0, "Type: Scene", 10,140,150,20, 0, 0, 0, 0, 0, "");
1030                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
1031                 uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order");
1032         }
1033         else if(last_seq->type==SEQ_MOVIE) {
1034
1035                 if(last_seq->mul==0.0) last_seq->mul= 1.0;
1036
1037                 uiDefBut(block, LABEL, 0, "Type: Movie", 10,140,150,20, 0, 0, 0, 0, 0, "");
1038                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
1039                 
1040                 uiBlockBeginAlign(block);
1041                 uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Make Premul Alpha ", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha");
1042                 uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY ",       10,70,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields");
1043                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:",                   10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
1044                 
1045                 uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,30,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order");
1046                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:",                        10,10,150,19, &last_seq->strobe, 1.0, 30.0, 100, 0, "Only display every nth frame");
1047                 uiDefButI(block, NUM, SEQ_BUT_RELOAD, "Preseek:",                       10,-10,150,19, &last_seq->anim_preseek, 0.0, 50.0, 100, 0, "On MPEG-seeking preseek this many frames");
1048                 uiBlockEndAlign(block);
1049         }
1050         else if(last_seq->type==SEQ_RAM_SOUND || 
1051                 last_seq->type==SEQ_HD_SOUND) {
1052
1053                 uiDefBut(block, LABEL, 0, "Type: Audio", 10,140,150,20, 0, 0, 0, 0, 0, "");
1054                 uiDefBut(block, TEX, 0, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
1055                 
1056                 uiBlockBeginAlign(block);
1057                 uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED,
1058                              SEQ_BUT_RELOAD, "IPO Frame locked",
1059                              10,90,150,19, &last_seq->flag, 
1060                              0.0, 1.0, 0, 0, 
1061                              "Lock the IPO coordinates to the "
1062                              "global frame counter.");
1063
1064                 uiDefButBitS(block, TOG, SEQ_MUTE, B_NOP, "Mute", 10,70,120,19, &last_seq->flag, 0.0, 21.0, 100, 0, "");
1065                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Gain (dB):", 10,50,150,19, &last_seq->level, -96.0, 6.0, 100, 0, "");
1066                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Pan:",   10,30,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, "");
1067                 uiBlockEndAlign(block);
1068         }
1069         else if(last_seq->type>=SEQ_EFFECT) {
1070                 uiDefBut(block, LABEL, 0, "Type: Effect", 10,140,150,20, 0, 0, 0, 0, 0, "");
1071                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
1072                 
1073                 uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED,
1074                              SEQ_BUT_RELOAD, "IPO Frame locked",
1075                              10,90,150,19, &last_seq->flag, 
1076                              0.0, 1.0, 0, 0, 
1077                              "Lock the IPO coordinates to the "
1078                              "global frame counter.");
1079                 
1080                 uiBlockBeginAlign(block);
1081                 if(last_seq->type==SEQ_WIPE){
1082                         WipeVars *wipe = (WipeVars *)last_seq->effectdata;
1083                         char formatstring[256];
1084                         
1085                         strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255);
1086                         uiDefButS(block, MENU,SEQ_BUT_EFFECT, formatstring,     10,65,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed");
1087                         uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Blur:",    10,40,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge");
1088                         switch(wipe->wipetype){ /*Skip Types that do not require angle*/
1089                                 case DO_IRIS_WIPE:
1090                                 case DO_CLOCK_WIPE:
1091                                 break;
1092                                 
1093                                 default:
1094                                         uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Angle:",   10,15,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge");
1095                         }
1096                         uiDefButS(block, TOG,SEQ_BUT_EFFECT,"Wipe In",  10,-10,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe");                         
1097                 }
1098                 else if(last_seq->type==SEQ_GLOW){
1099                         GlowVars *glow = (GlowVars *)last_seq->effectdata;
1100
1101                         uiBlockBeginAlign(block);
1102                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Threshold:",     10,70,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity");
1103                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Clamp:",                 10,50,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity");
1104                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Boost factor:",  10,30,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier");
1105                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Blur distance:",         10,10,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect");
1106                         uiDefButI(block, NUM, B_NOP, "Quality:", 10,-5,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect");
1107                         uiDefButI(block, TOG, B_NOP, "Only boost", 10,-25,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only");
1108                 }
1109                 uiBlockEndAlign(block);
1110         }
1111 }
1112
1113 static void seq_blockhandlers(ScrArea *sa)
1114 {
1115         SpaceSeq *sseq= sa->spacedata.first;
1116         short a;
1117
1118         /* warning; blocks need to be freed each time, handlers dont remove (for ipo moved to drawipospace) */
1119         uiFreeBlocksWin(&sa->uiblocks, sa->win);
1120
1121         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
1122                 switch(sseq->blockhandler[a]) {
1123
1124                 case SEQ_HANDLER_PROPERTIES:
1125                         seq_panel_properties(sseq->blockhandler[a+1]);
1126                         break;
1127
1128                 }
1129                 /* clear action value for event */
1130                 sseq->blockhandler[a+1]= 0;
1131         }
1132         uiDrawBlocksPanels(sa, 0);
1133
1134 }
1135
1136 void drawseqspace(ScrArea *sa, void *spacedata)
1137 {
1138         SpaceSeq *sseq= sa->spacedata.first;
1139         View2D *v2d= &sseq->v2d;
1140         Editing *ed;
1141         Sequence *seq;
1142         float col[3];
1143         int ofsx, ofsy;
1144         int i;
1145
1146         ed= G.scene->ed;
1147
1148         if(sseq->mainb) {
1149                 draw_image_seq(sa);
1150                 return;
1151         }
1152
1153         bwin_clear_viewmat(sa->win);    /* clear buttons view */
1154         glLoadIdentity();
1155
1156         BIF_GetThemeColor3fv(TH_BACK, col);
1157         if(ed && ed->metastack.first) glClearColor(col[0], col[1], col[2]-0.1, 0.0);
1158         else glClearColor(col[0], col[1], col[2], 0.0);
1159
1160         glClear(GL_COLOR_BUFFER_BIT);
1161
1162         calc_scrollrcts(sa, v2d, sa->winx, sa->winy);
1163
1164         if(sa->winx>SCROLLB+10 && sa->winy>SCROLLH+10) {
1165                 if(v2d->scroll) {
1166                         ofsx= sa->winrct.xmin;  /* because of mywin */
1167                         ofsy= sa->winrct.ymin;
1168                         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);
1169                         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);
1170                 }
1171         }
1172
1173
1174         myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax);
1175
1176         BIF_ThemeColorShade(TH_BACK, -20);
1177         glRectf(v2d->cur.xmin,  0.0,  v2d->cur.xmax,  1.0);
1178
1179         
1180         boundbox_seq();
1181         calc_ipogrid();
1182         
1183         i= MAX2(1, ((int)G.v2d->cur.ymin)-1);
1184
1185         glBegin(GL_QUADS);
1186         while (i<v2d->cur.ymax) {
1187                 if (((int)i) & 1)
1188                         BIF_ThemeColorShade(TH_BACK, -15);
1189                 else
1190                         BIF_ThemeColorShade(TH_BACK, -25);
1191                 
1192                 glVertex2f(v2d->cur.xmax, i);
1193                 glVertex2f(v2d->cur.xmin, i);
1194                 glVertex2f(v2d->cur.xmin, i+1);
1195                 glVertex2f(v2d->cur.xmax, i+1);
1196                 i+=1.0;
1197         }
1198         glEnd();
1199         
1200         /* Force grid lines */
1201         i= MAX2(1, ((int)G.v2d->cur.ymin)-1);
1202         glBegin(GL_LINES);
1203
1204         while (i<G.v2d->cur.ymax) {
1205                 BIF_ThemeColor(TH_GRID);
1206                 glVertex2f(G.v2d->cur.xmax, i);
1207                 glVertex2f(G.v2d->cur.xmin, i);
1208                 i+=1.0;
1209         }
1210         glEnd();
1211         
1212         
1213         draw_ipogrid();
1214         draw_cfra_seq();
1215
1216
1217         /* sequences: first deselect */
1218         if(ed) {
1219                 seq= ed->seqbasep->first;
1220                 while(seq) { /* bound box test, dont draw outside the view */
1221                         if (seq->flag & SELECT ||
1222                                         seq->startdisp > v2d->cur.xmax ||
1223                                         seq->enddisp < v2d->cur.xmin ||
1224                                         seq->machine+1.0 < v2d->cur.ymin ||
1225                                         seq->machine > v2d->cur.ymax)
1226                         {
1227                                 /* dont draw */
1228                         } else {
1229                                 draw_seq_strip(seq, sa, sseq);
1230                         }
1231                         seq= seq->next;
1232                 }
1233         }
1234         ed= G.scene->ed;
1235         if(ed) {
1236                 seq= ed->seqbasep->first;
1237                 while(seq) { /* bound box test, dont draw outside the view */
1238                         if (!(seq->flag & SELECT) ||
1239                                         seq->startdisp > v2d->cur.xmax ||
1240                                         seq->enddisp < v2d->cur.xmin ||
1241                                         seq->machine+1.0 < v2d->cur.ymin ||
1242                                         seq->machine > v2d->cur.ymax)
1243                         {
1244                                 /* dont draw */
1245                         } else {
1246                                 draw_seq_strip(seq, sa, sseq);
1247                         }
1248                         seq= seq->next;
1249                 }
1250         }
1251
1252         draw_extra_seqinfo();
1253
1254         /* restore viewport */
1255         mywinset(sa->win);
1256
1257         /* ortho at pixel level sa */
1258         myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
1259
1260         if(sa->winx>SCROLLB+10 && sa->winy>SCROLLH+10) {
1261                 if(v2d->scroll) {
1262                         drawscroll(0);
1263                 }
1264         }
1265
1266         draw_area_emboss(sa);
1267
1268         if(sseq->mainb==0) {
1269                 /* it is important to end a view in a transform compatible with buttons */
1270                 bwin_scalematrix(sa->win, sseq->blockscale, sseq->blockscale, sseq->blockscale);
1271                 seq_blockhandlers(sa);
1272         }
1273
1274         sa->win_swap= WIN_BACK_OK;
1275 }
1276
1277