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