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