Dont draw blocks what are outside the the view. - massive speedup with complex sequence's
[blender.git] / source / blender / src / drawseq.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include <string.h>
38 #include <math.h>
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BMF_Api.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_arithb.h"
46
47 #include "IMB_imbuf_types.h"
48
49 #include "DNA_sequence_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_space_types.h"
53 #include "DNA_view2d_types.h"
54
55 #include "BKE_global.h"
56 #include "BKE_plugin_types.h"
57 #include "BKE_scene.h"
58 #include "BKE_utildefines.h"
59
60 #include "BIF_gl.h"
61 #include "BIF_mywindow.h"
62 #include "BIF_screen.h"
63 #include "BIF_drawseq.h"
64 #include "BIF_editseq.h"
65 #include "BIF_glutil.h"
66 #include "BIF_resources.h"
67 #include "BIF_space.h"
68 #include "BIF_interface.h"
69
70 #include "BSE_view.h"
71 #include "BSE_drawipo.h"
72 #include "BSE_sequence.h"
73 #include "BSE_seqaudio.h"
74
75 #include "IMB_imbuf_types.h"
76 #include "IMB_imbuf.h"
77
78 #include "blendef.h"    /* CFRA */
79 #include "mydevice.h"   /* REDRAWSEQ */
80
81 int no_rightbox=0, no_leftbox= 0;
82
83 static void EmbossBoxf(float x1, float y1, float x2, float y2, int sel, unsigned int dark, unsigned int light)
84 {
85
86         if(sel) cpack(dark);
87         else cpack(light);
88         if(sel) glLineWidth(2.0);
89         fdrawline(x1,  y2,  x2,  y2);   /* top */
90         if(no_leftbox==0) fdrawline(x1,  y1,  x1,  y2); /* left */
91
92         if(sel) glLineWidth(1.0);
93
94         if(sel) cpack(light);
95         else cpack(dark);
96         fdrawline(x1,  y1,  x2,  y1); /* bottom */
97         if(no_rightbox==0) fdrawline(x2,  y1,  x2,  y2);        /* right */
98
99 }
100
101 static char *give_seqname(Sequence *seq)
102 {
103         if(seq->type==SEQ_META) {
104                 if(seq->name[2]) return seq->name+2;
105                 return "META";
106         }
107         else if(seq->type==SEQ_IMAGE) return "IMAGE";
108         else if(seq->type==SEQ_SCENE) return "SCENE";
109         else if(seq->type==SEQ_MOVIE) return "MOVIE";
110         else if(seq->type==SEQ_SOUND) return "AUDIO";
111         else if(seq->type<SEQ_EFFECT) return seq->strip->dir;
112         else if(seq->type==SEQ_CROSS) return "CROSS";
113         else if(seq->type==SEQ_GAMCROSS) return "GAMMA CROSS";
114         else if(seq->type==SEQ_ADD) return "ADD";
115         else if(seq->type==SEQ_SUB) return "SUB";
116         else if(seq->type==SEQ_MUL) return "MUL";
117         else if(seq->type==SEQ_ALPHAOVER) return "ALPHAOVER";
118         else if(seq->type==SEQ_ALPHAUNDER) return "ALPHAUNDER";
119         else if(seq->type==SEQ_OVERDROP) return "OVER DROP";
120         else if(seq->type==SEQ_WIPE) return "WIPE";
121         else if(seq->type==SEQ_GLOW) return "GLOW";
122         else if(seq->type==SEQ_PLUGIN) {
123                 if(seq->plugin && seq->plugin->doit) return seq->plugin->pname;
124                 return "PLUGIN";
125         }
126         else return "EFFECT";
127
128 }
129 static void draw_cfra_seq(void)
130 {
131         glColor3ub(0x30, 0x90, 0x50);
132         glLineWidth(2.0);
133         glBegin(GL_LINES);
134         glVertex2f(G.scene->r.cfra, G.v2d->cur.ymin);
135         glVertex2f(G.scene->r.cfra, G.v2d->cur.ymax);
136         glEnd();
137         glLineWidth(1.0);
138 }
139
140 static unsigned int seq_color(Sequence *seq)
141 {
142         switch(seq->type) {
143         case SEQ_META:
144                 return 0x509090;
145         case SEQ_MOVIE:
146                 return 0x805040;
147         case SEQ_SCENE:
148                 if(seq->scene==G.scene) return 0x709050;
149                 return 0x609060;
150         case SEQ_CROSS:
151                 return 0x505090;
152         case SEQ_GAMCROSS:
153                 return 0x5040A0;
154         case SEQ_ADD:
155                 return 0x6060A0;
156         case SEQ_SUB:
157                 return 0x8060A0;
158         case SEQ_MUL:
159                 return 0x8080A0;
160         case SEQ_ALPHAOVER:
161                 return 0x6080A0;
162         case SEQ_ALPHAUNDER:
163                 return 0x9080A0;
164         case SEQ_OVERDROP:
165                 return 0x5080B0;
166         case SEQ_WIPE:
167                 return 0x2080B0;
168         case SEQ_GLOW:
169                 return 0x0080B0;
170         case SEQ_PLUGIN:
171                 return 0x906000;
172         case SEQ_SOUND:
173                 if(seq->flag & SEQ_MUTE) return 0x707060; else return 0x787850;
174         default:
175                 return 0x906060;
176         }
177
178 }
179 static void drawmeta_contents(Sequence *seqm, float x1, float y1, float x2, float y2)
180 {
181         Sequence *seq;
182         float dx;
183         int nr;
184
185         nr= 0;
186         WHILE_SEQ(&seqm->seqbase) {
187                 nr++;
188         }
189         END_SEQ
190
191         dx= (x2-x1)/nr;
192
193         WHILE_SEQ(&seqm->seqbase) {
194                 cpack(seq_color(seq));
195                 glRectf(x1,  y1,  x1+0.9*dx,  y2);
196                 EmbossBoxf(x1, y1, x1+0.9*dx, y2, 0, 0x404040, 0xB0B0B0);
197                 x1+= dx;
198         }
199         END_SEQ
200 }
201
202 static void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2)
203 {
204         float f, height, midy;
205         int offset, sofs, eofs;
206         signed short* s;
207         bSound *sound;
208
209         audio_makestream(seq->sound);
210         if(seq->sound->stream==NULL) return;
211
212         if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0);
213         sound = seq->sound;
214         sofs = ((int)( (((float)(seq->startdisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
215         eofs = ((int)( (((float)(seq->enddisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
216
217         for (f=x1; f<=x2; f+=0.2) {
218                 offset = (int) ((float)sofs + ((f-x1)/(x2-x1)) * (float)(eofs-sofs)) & (~3);
219                 if (offset >= sound->streamlen) offset = sound->streamlen-1;
220                 s = (signed short*)(((Uint8*)sound->stream) + offset);
221                 midy = (y1+y2)/2;
222                 height = ( ( ((float)s[0]/32768 + (float)s[1]/32768)/2 ) * (y2-y1) )/2;
223                 glBegin(GL_LINES);
224                 glVertex2f(f, midy-height);
225                 glVertex2f(f, midy+height);
226                 glEnd();
227         }
228 }
229
230 void drawseq(Sequence *seq)
231 {
232         float v1[2], v2[2], x1, x2, y1, y2;
233         unsigned int body, dark, light;
234         int len, size;
235         short mval[2];
236         char str[120], *strp;
237
238
239         if(seq->startdisp > seq->enddisp) body= 0x707070;
240
241         body= seq_color(seq);
242         dark= 0x202020;
243         light= 0xB0B0B0;
244
245         if(G.moving && (seq->flag & SELECT)) {
246                 if(seq->flag & SEQ_OVERLAP) dark= light= 0x4040FF;
247                 else {
248                         if(seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL));
249                         else dark= light= 0xFFFFFF;
250                 }
251         }
252
253         /* body */
254         if(seq->startstill) x1= seq->start;
255         else x1= seq->startdisp;
256         y1= seq->machine+0.2;
257         if(seq->endstill) x2= seq->start+seq->len;
258         else x2= seq->enddisp;
259         y2= seq->machine+0.8;
260
261         cpack(body);
262         glRectf(x1,  y1,  x2,  y2);
263         if (seq->type == SEQ_SOUND) drawseqwave(seq, x1, y1, x2, y2);
264         EmbossBoxf(x1, y1, x2, y2, seq->flag & 1, dark, light);
265
266         v1[1]= y1;
267         v2[1]= y2;
268         if(seq->type < SEQ_EFFECT) {
269
270                 /* decoration: the bars */
271                 x1= seq->startdisp;
272                 x2= seq->enddisp;
273
274                 if(seq->startofs) {
275                         cpack(0x707070);
276                         glRectf((float)(seq->start),  y1-0.2,  x1,  y1);
277                         EmbossBoxf((float)(seq->start), y1-0.2, x1, y1, seq->flag & 1, dark, light);
278                 }
279                 if(seq->endofs) {
280                         cpack(0x707070);
281                         glRectf(x2,  y2,  (float)(seq->start+seq->len),  y2+0.2);
282                         EmbossBoxf(x2, y2, (float)(seq->start+seq->len), y2+0.2, seq->flag & 1, dark, light);
283                 }
284
285                 if(seq->startstill) {
286                         cpack(body);
287                         glRectf(x1,  y1+0.1,  (float)(seq->start),  y1+0.5);
288                         no_rightbox= 1;
289                         EmbossBoxf(x1, y1+0.1, (float)(seq->start), y1+0.5, seq->flag & 1, dark, light);
290                         no_rightbox= 0;
291                 }
292                 if(seq->endstill) {
293                         cpack(body);
294                         glRectf((float)(seq->start+seq->len),  y1+0.1,  x2,  y1+0.5);
295                         no_leftbox= 1;
296                         EmbossBoxf((float)(seq->start+seq->len), y1+0.1, x2, y1+0.5, seq->flag & 1, dark, light);
297                         no_leftbox= 0;
298                 }
299
300         }
301
302         /* calculate if seq is long enough to print a name */
303         x1= seq->startdisp+seq->handsize;
304         x2= seq->enddisp-seq->handsize;
305
306         /* but first the contents of a meta */
307         if(seq->type==SEQ_META) drawmeta_contents(seq, x1, y1+0.15, x2, y2-0.15);
308
309         if(x1<G.v2d->cur.xmin) x1= G.v2d->cur.xmin;
310         else if(x1>G.v2d->cur.xmax) x1= G.v2d->cur.xmax;
311         if(x2<G.v2d->cur.xmin) x2= G.v2d->cur.xmin;
312         else if(x2>G.v2d->cur.xmax) x2= G.v2d->cur.xmax;
313
314         if(x1 != x2) {
315                 v1[0]= x1;
316                 ipoco_to_areaco_noclip(G.v2d, v1, mval);
317                 x1= mval[0];
318                 v2[0]= x2;
319                 ipoco_to_areaco_noclip(G.v2d, v2, mval);
320                 x2= mval[0];
321                 size= x2-x1;
322
323                 if(seq->name[2]) {
324                         sprintf(str, "%s: %s (%d)", give_seqname(seq), seq->name+2, seq->len);
325                 }else{
326                         if(seq->type == SEQ_META) {
327                                 sprintf(str, "%d %s", seq->len, give_seqname(seq));
328                         }
329                         else if(seq->type == SEQ_SCENE) {
330                                 if(seq->scene) sprintf(str, "%d %s %s", seq->len, give_seqname(seq), seq->scene->id.name+2);
331                                 else sprintf(str, "%d %s", seq->len, give_seqname(seq));
332
333                         }
334                         else if(seq->type == SEQ_IMAGE) {
335                                 sprintf(str, "%d %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
336                         }
337                         else if(seq->type & SEQ_EFFECT) {
338                                 if(seq->seq3!=seq->seq2 && seq->seq1!=seq->seq3)
339                                         sprintf(str, "%d %s: %d-%d (use %d)", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, seq->seq3->machine);
340                                 else
341                                         sprintf(str, "%d %s: %d-%d", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine);
342                         }
343                         else if (seq->type == SEQ_SOUND) {
344                                 sprintf(str, "%d %s", seq->len, seq->strip->stripdata->name);
345                         }
346                         else if (seq->type == SEQ_MOVIE) {
347                                 sprintf(str, "%d %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
348                         }
349                 }
350
351
352                 strp= str;
353
354                 while( (len= BMF_GetStringWidth(G.font, strp)) > size) {
355                         if(len < 10) break;
356                         if(strp[1]==0) break;
357                         strp++;
358                 }
359
360                 mval[0]= (x1+x2-len+1)/2;
361                 mval[1]= 1;
362                 areamouseco_to_ipoco(G.v2d, mval, &x1, &x2);
363
364                 if(seq->flag & SELECT) cpack(0xFFFFFF);
365                 else cpack(0x0);
366                 glRasterPos3f(x1,  y1+0.2, 0.0);
367                 BMF_DrawString(G.font, strp);
368         }
369
370         if(seq->type < SEQ_EFFECT) {
371                 /* decoration: triangles */
372                 x1= seq->startdisp;
373                 x2= seq->enddisp;
374
375                 body+= 0x101010;
376                 dark= 0x202020;
377                 light= 0xB0B0B0;
378
379                 /* left triangle */
380                 if(seq->flag & SEQ_LEFTSEL) {
381                         cpack(body+0x20);
382                         if(G.moving) {
383                                 if(seq->flag & SEQ_OVERLAP) dark= light= 0x4040FF;
384                                 else dark= light= 0xFFFFFF;
385                         }
386                 }
387                 else {
388                         cpack(body);
389                 }
390
391                 glBegin(GL_TRIANGLES);
392                         v1[0]= x1; glVertex2fv(v1);
393                         v2[0]= x1; glVertex2fv(v2);
394                         v2[0]+= seq->handsize; v2[1]= (y1+y2)/2.0; glVertex2fv(v2); v2[1]= y2;
395                 glEnd();
396
397                 cpack(light);
398
399                 glBegin(GL_LINE_STRIP);
400                         v1[0]= x1; glVertex2fv(v1);
401                         v2[0]= x1; glVertex2fv(v2);
402                         v2[0]+= seq->handsize; v2[1]= (y1+y2)/2.0; glVertex2fv(v2); v2[1]= y2;
403                         cpack(dark);
404                         glVertex2fv(v1);
405                 glEnd();
406         }
407
408         if(G.moving || (seq->flag & SEQ_LEFTSEL)) {
409                 cpack(0xFFFFFF);
410                 glRasterPos3f(x1,  y1+0.2, 0.0);
411                 sprintf(str, "%d", seq->startdisp);
412                 BMF_DrawString(G.font, str);
413         }
414
415                 /* right triangle */
416         if(seq->type < SEQ_EFFECT) {
417                 dark= 0x202020;
418                 light= 0xB0B0B0;
419
420                 if(seq->flag & SEQ_RIGHTSEL) {
421                         cpack(body+0x20);
422                         if(G.moving) {
423                                 if(seq->flag & SEQ_OVERLAP) dark= light= 0x4040FF;
424                                 else dark= light= 0xFFFFFF;
425                         }
426                 }
427                 else {
428                         cpack(body);
429                 }
430                 glBegin(GL_TRIANGLES);
431                         v2[0]= x2; glVertex2fv(v2);
432                         v1[0]= x2; glVertex2fv(v1);
433                         v2[0]-= seq->handsize; v2[1]= (y1+y2)/2.0; glVertex2fv(v2); v2[1]= y2;
434                 glEnd();
435
436                 cpack(dark);
437                 glBegin(GL_LINE_STRIP);
438                         v2[0]= x2; glVertex2fv(v2);
439                         v1[0]= x2; glVertex2fv(v1);
440                         v1[0]-= seq->handsize; v1[1]= (y1+y2)/2.0; glVertex2fv(v1); v1[1]= y2;
441                         cpack(light);
442                         glVertex2fv(v2);
443                 glEnd();
444         }
445
446         if(G.moving || (seq->flag & SEQ_RIGHTSEL)) {
447                 cpack(0xFFFFFF);
448                 glRasterPos3f(x2-seq->handsize/2,  y1+0.2, 0.0);
449                 sprintf(str, "%d", seq->enddisp-1);
450                 BMF_DrawString(G.font, str);
451         }
452 }
453
454 static Sequence *special_seq_update= 0;
455
456 void set_special_seq_update(int val)
457 {
458         int x;
459
460         /* if mouse over a sequence && LEFTMOUSE */
461         if(val) {
462                 special_seq_update= find_nearest_seq(&x);
463         }
464         else special_seq_update= 0;
465 }
466
467
468 static void draw_image_seq(ScrArea *sa)
469 {
470         SpaceSeq *sseq;
471         StripElem *se;
472         struct ImBuf *ibuf;
473         int x1, y1;
474         float zoom;
475
476         glClearColor(0.0, 0.0, 0.0, 0.0);
477         glClear(GL_COLOR_BUFFER_BIT);
478
479         ibuf= (ImBuf *)give_ibuf_seq( (G.scene->r.cfra));
480
481         if(special_seq_update) {
482        se = special_seq_update->curelem;
483        if(se) {
484            if(se->ok==2) {
485                if(se->se1)
486                    ibuf= se->se1->ibuf;
487            }
488            else ibuf= se->ibuf;
489        }
490         }
491         if(ibuf==0 || ibuf->rect==0) return;
492
493         sseq= sa->spacedata.first;
494         if(sseq==0) return;
495
496         if (sseq->zoom > 0) zoom = sseq->zoom;
497         else zoom = -1.0/sseq->zoom;
498         /* calc location */
499         x1= (sa->winx-zoom*ibuf->x)/2;
500         y1= (sa->winy-zoom*ibuf->y)/2;
501
502         /* needed for gla draw */
503         glaDefine2DArea(&curarea->winrct);
504         glPixelZoom(zoom, zoom);
505         
506         glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->rect);
507         
508         glPixelZoom(1.0, 1.0);
509
510         sa->win_swap= WIN_BACK_OK;
511 }
512
513 static void draw_extra_seqinfo(void)
514 {
515         extern Sequence *last_seq;
516         StripElem *se, *last;
517         float xco, xfac;
518         int sta, end;
519         char str[256];
520
521         if(last_seq==0) return;
522
523         /* xfac: size of 1 pixel */
524         xfac= G.v2d->cur.xmax - G.v2d->cur.xmin;
525         xfac/= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
526         xco= G.v2d->cur.xmin+40*xfac;
527
528         BIF_ThemeColor(TH_TEXT);
529
530         /* NAME */
531         glRasterPos3f(xco,  0.3, 0.0);
532         strncpy(str, give_seqname(last_seq), 255);
533         BMF_DrawString(G.font, str);
534         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
535
536         if(last_seq->type==SEQ_SCENE && last_seq->scene) {
537                 glRasterPos3f(xco,  0.3, 0.0);
538                 BMF_DrawString(G.font, last_seq->scene->id.name+2);
539                 xco += xfac*BMF_GetStringWidth(G.font, last_seq->scene->id.name+2) +30.0*xfac;
540         }
541
542         /* LEN */
543         if(last_seq->type & SEQ_EFFECT)
544                 sprintf(str, "len: %d   From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1);
545         else
546                 sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len);
547
548         glRasterPos3f(xco,  0.3, 0.0);
549         BMF_DrawString(G.font, str);
550         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
551
552         if(last_seq->type==SEQ_IMAGE) {
553
554                 /* CURRENT */
555                 se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
556                 if(se) {
557                         sprintf(str, "cur: %s", se->name);
558                         glRasterPos3f(xco,  0.3, 0.0);
559                         BMF_DrawString(G.font, str);
560                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
561                 }
562
563                 /* FIRST AND LAST */
564
565                 if(last_seq->strip) {
566                         se= last_seq->strip->stripdata;
567                         last= se+last_seq->len-1;
568                         if(last_seq->startofs) se+= last_seq->startofs;
569                         if(last_seq->endofs) last-= last_seq->endofs;
570
571                         sprintf(str, "First: %s at %d     Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1);
572                         glRasterPos3f(xco,  0.3, 0.0);
573                         BMF_DrawString(G.font, str);
574                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
575
576                         /* orig size */
577                         sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory);
578                         glRasterPos3f(xco,  0.3, 0.0);
579                         BMF_DrawString(G.font, str);
580                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
581                 }
582         }
583         else if(last_seq->type==SEQ_MOVIE) {
584
585                 sta= last_seq->startofs;
586                 end= last_seq->len-1-last_seq->endofs;
587
588                 sprintf(str, "%s   %s%s  First: %d at %d     Last: %d at %d     Cur: %d",
589                                 last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
590                                 sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp);
591
592                 glRasterPos3f(xco,  0.3, 0.0);
593                 BMF_DrawString(G.font, str);
594         }
595         else if(last_seq->type==SEQ_SOUND) {
596
597                 sta= last_seq->startofs;
598                 end= last_seq->len-1-last_seq->endofs;
599
600                 sprintf(str, "%s   %s%s  First: %d at %d     Last: %d at %d     Cur: %d     Gain: %.2f dB     Pan: %.2f",
601                                 last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
602                                 sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp,
603                                 last_seq->level, last_seq->pan);
604
605                 glRasterPos3f(xco,  0.3, 0.0);
606                 BMF_DrawString(G.font, str);
607         }
608 }
609
610 #define SEQ_BUT_PLUGIN  1
611 #define SEQ_BUT_RELOAD  2
612 #define SEQ_BUT_EFFECT  3
613
614 void do_seqbuttons(short val)
615 {
616         extern Sequence *last_seq;
617
618         switch(val) {
619         case SEQ_BUT_PLUGIN:
620                 new_stripdata(last_seq);
621                 free_imbuf_effect_spec(CFRA);
622                 break;
623
624         case SEQ_BUT_RELOAD:
625                 free_imbuf_seq();       // frees all
626                 break;
627         case SEQ_BUT_EFFECT:
628                 new_stripdata(last_seq);
629                 calc_sequence(last_seq);
630                 break;
631         }
632
633         allqueue(REDRAWSEQ, 0);
634 }
635
636 static void seq_panel_properties(short cntrl)   // SEQ_HANDLER_PROPERTIES
637 {
638         extern Sequence *last_seq;
639         uiBlock *block;
640
641         block= uiNewBlock(&curarea->uiblocks, "seq_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
642         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
643         uiSetPanelHandler(SEQ_HANDLER_PROPERTIES);  // for close and esc
644         if(uiNewPanel(curarea, block, "Strip Properties", "Seq", 10, 230, 318, 204)==0) return;
645
646         if(last_seq==NULL) return;
647
648         if(last_seq->type==SEQ_PLUGIN) {
649                 PluginSeq *pis;
650                 VarStruct *varstr;
651                 int a, xco, yco;
652
653                 uiDefBut(block, LABEL, 0, "Type: Plugin", 10,50,70,20, 0, 0, 0, 0, 0, "");
654
655                 pis= last_seq->plugin;
656                 if(pis->vars==0) return;
657
658                 varstr= pis->varstr;
659                 if(varstr) {
660                         for(a=0; a<pis->vars; a++, varstr++) {
661                                 xco= 150*(a/6)+10;
662                                 yco= 125 - 20*(a % 6)+1;
663                                 uiDefBut(block, varstr->type, SEQ_BUT_PLUGIN, varstr->name, xco,yco,150,19, &(pis->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
664
665                         }
666                 }
667         }
668         else if(last_seq->type==SEQ_IMAGE) {
669
670                 uiDefBut(block, LABEL, 0, "Type: Image", 10,140,150,20, 0, 0, 0, 0, 0, "");
671                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
672
673                 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");
674                 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");
675                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:",                   10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
676                 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");
677                 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");
678         }
679         else if(last_seq->type==SEQ_META) {
680
681                 uiDefBut(block, LABEL, 0, "Type: Meta", 10,140,150,20, 0, 0, 0, 0, 0, "");
682                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
683
684         }
685         else if(last_seq->type==SEQ_SCENE) {
686
687                 uiDefBut(block, LABEL, 0, "Type: Scene", 10,140,150,20, 0, 0, 0, 0, 0, "");
688                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
689                 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");
690         }
691         else if(last_seq->type==SEQ_MOVIE) {
692
693                 if(last_seq->mul==0.0) last_seq->mul= 1.0;
694
695                 uiDefBut(block, LABEL, 0, "Type: Movie", 10,140,150,20, 0, 0, 0, 0, 0, "");
696                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
697
698                 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");
699                 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");
700                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:",                   10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
701                 
702                 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");
703                 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");
704
705         }
706         else if(last_seq->type==SEQ_SOUND) {
707
708                 uiDefBut(block, LABEL, 0, "Type: Audio", 10,140,150,20, 0, 0, 0, 0, 0, "");
709                 uiDefBut(block, TEX, 0, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
710
711                 uiDefButBitS(block, TOG, SEQ_MUTE, B_NOP, "Mute", 10,90,120,19, &last_seq->flag, 0.0, 21.0, 100, 0, "");
712                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Gain (dB):", 10,70,150,19, &last_seq->level, -96.0, 6.0, 100, 0, "");
713                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Pan:",   10,50,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, "");
714         }
715         else if(last_seq->type>=SEQ_EFFECT) {
716                 uiDefBut(block, LABEL, 0, "Type: Effect", 10,140,150,20, 0, 0, 0, 0, 0, "");
717                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
718
719                 if(last_seq->type==SEQ_WIPE){
720                         WipeVars *wipe = (WipeVars *)last_seq->effectdata;
721                         char formatstring[256];
722                         strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255);
723                         uiDefButS(block, MENU,SEQ_BUT_EFFECT, formatstring,     10,90,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed");
724                         uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Blur:",    10,65,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge");
725                         switch(wipe->wipetype){ /*Skip Types that do not require angle*/
726                                 case DO_IRIS_WIPE:
727                                 case DO_CLOCK_WIPE:
728                                 break;
729                                 
730                                 default:
731                                         uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Angle:",   10,40,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge");
732                         }
733                         uiDefButS(block, TOG,SEQ_BUT_EFFECT,"Wipe In",  10,15,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe");                          
734                 }
735                 else if(last_seq->type==SEQ_GLOW){
736                         GlowVars *glow = (GlowVars *)last_seq->effectdata;
737
738                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Threshold:",     10,90,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity");
739                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Clamp:",         10,70,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity");
740                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Boost factor:",  10,50,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier");
741                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Blur distance:",         10,30,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect");
742                         uiDefButI(block, NUM, B_NOP, "Quality:", 10,10,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect");
743                         uiDefButI(block, TOG, B_NOP, "Only boost", 10,-10,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only");
744                 }
745
746         }
747
748
749 }
750
751 static void seq_blockhandlers(ScrArea *sa)
752 {
753         SpaceSeq *sseq= sa->spacedata.first;
754         short a;
755
756         /* warning; blocks need to be freed each time, handlers dont remove (for ipo moved to drawipospace) */
757         uiFreeBlocksWin(&sa->uiblocks, sa->win);
758
759         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
760                 switch(sseq->blockhandler[a]) {
761
762                 case SEQ_HANDLER_PROPERTIES:
763                         seq_panel_properties(sseq->blockhandler[a+1]);
764                         break;
765
766                 }
767                 /* clear action value for event */
768                 sseq->blockhandler[a+1]= 0;
769         }
770         uiDrawBlocksPanels(sa, 0);
771
772 }
773
774 void drawseqspace(ScrArea *sa, void *spacedata)
775 {
776         SpaceSeq *sseq;
777         Editing *ed;
778         Sequence *seq;
779         float col[3];
780         int ofsx, ofsy;
781
782         ed= G.scene->ed;
783
784         sseq= curarea->spacedata.first;
785         if(sseq->mainb==1) {
786                 draw_image_seq(curarea);
787                 return;
788         }
789
790         bwin_clear_viewmat(sa->win);    /* clear buttons view */
791         glLoadIdentity();
792
793         BIF_GetThemeColor3fv(TH_BACK, col);
794         if(ed && ed->metastack.first) glClearColor(col[0], col[1], col[2]-0.1, 0.0);
795         else glClearColor(col[0], col[1], col[2], 0.0);
796
797         glClear(GL_COLOR_BUFFER_BIT);
798
799         calc_scrollrcts(sa, G.v2d, curarea->winx, curarea->winy);
800
801         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
802                 if(G.v2d->scroll) {
803                         ofsx= curarea->winrct.xmin;     /* because of mywin */
804                         ofsy= curarea->winrct.ymin;
805                         glViewport(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
806                         glScissor(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
807                 }
808         }
809
810
811         myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
812
813         BIF_ThemeColorShade(TH_BACK, -20);
814         glRectf(G.v2d->cur.xmin,  0.0,  G.v2d->cur.xmax,  1.0);
815
816         boundbox_seq();
817         calc_ipogrid();
818         draw_ipogrid();
819         draw_cfra_seq();
820
821         /* sequences: first deselect */
822
823         if(ed) {
824                 seq= ed->seqbasep->first;
825                 while(seq) {
826                         if (seq->flag & SELECT ||
827                                         seq->start > G.v2d->cur.xmax ||
828                                         seq->start+seq->len < G.v2d->cur.xmin ||
829                                         seq->machine+1.0 < G.v2d->cur.ymin || seq->machine > G.v2d->cur.ymax)
830                         {
831                                 /* do nothing */
832                         } else {
833                                 drawseq(seq);
834                         }
835                         seq= seq->next;
836                 }
837         }
838         ed= G.scene->ed;
839         if(ed) {
840                 seq= ed->seqbasep->first;
841                 while(seq) {
842                         if (!(seq->flag & SELECT) ||
843                                         seq->start > G.v2d->cur.xmax ||
844                                         seq->start+seq->len < G.v2d->cur.xmin ||
845                                         seq->machine+1.0 < G.v2d->cur.ymin ||
846                                         seq->machine > G.v2d->cur.ymax)
847                         {
848                                 /* do nothing */
849                         } else {
850                                 drawseq(seq);
851                         }
852                         seq= seq->next;
853                 }
854         }
855
856         draw_extra_seqinfo();
857
858         /* restore viewport */
859         mywinset(curarea->win);
860
861         /* ortho at pixel level curarea */
862         myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
863
864         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
865                 if(G.v2d->scroll) {
866                         drawscroll(0);
867                 }
868         }
869
870         draw_area_emboss(sa);
871
872         if(sseq->mainb==0) {
873                 /* it is important to end a view in a transform compatible with buttons */
874                 bwin_scalematrix(sa->win, sseq->blockscale, sseq->blockscale, sseq->blockscale);
875                 seq_blockhandlers(sa);
876         }
877
878         curarea->win_swap= WIN_BACK_OK;
879 }
880
881