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