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