Final merge of HEAD (bf-blender) into the orange branch.
[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, rectx, recty;
474         float zoom;
475
476         glClearColor(0.0, 0.0, 0.0, 0.0);
477         glClear(GL_COLOR_BUFFER_BIT);
478         
479         rectx= (G.scene->r.size*G.scene->r.xsch)/100;
480         recty= (G.scene->r.size*G.scene->r.ysch)/100;
481         
482         ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra));
483
484         if(special_seq_update) {
485        se = special_seq_update->curelem;
486        if(se) {
487            if(se->ok==2) {
488                if(se->se1)
489                    ibuf= se->se1->ibuf;
490            }
491            else ibuf= se->ibuf;
492        }
493         }
494         if(ibuf==0 || ibuf->rect==0) return;
495
496         sseq= sa->spacedata.first;
497         if(sseq==0) return;
498
499         if (sseq->zoom > 0) zoom = sseq->zoom;
500         else zoom = -1.0/sseq->zoom;
501         /* calc location */
502         x1= (sa->winx-zoom*ibuf->x)/2;
503         y1= (sa->winy-zoom*ibuf->y)/2;
504
505         /* needed for gla draw */
506         glaDefine2DArea(&curarea->winrct);
507         glPixelZoom(zoom, zoom);
508         
509         glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
510         
511         glPixelZoom(1.0, 1.0);
512
513         sa->win_swap= WIN_BACK_OK;
514 }
515
516 static void draw_extra_seqinfo(void)
517 {
518         extern Sequence *last_seq;
519         StripElem *se, *last;
520         float xco, xfac;
521         int sta, end;
522         char str[256];
523
524         if(last_seq==0) return;
525
526         /* xfac: size of 1 pixel */
527         xfac= G.v2d->cur.xmax - G.v2d->cur.xmin;
528         xfac/= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
529         xco= G.v2d->cur.xmin+40*xfac;
530
531         BIF_ThemeColor(TH_TEXT);
532
533         /* NAME */
534         glRasterPos3f(xco,  0.3, 0.0);
535         strncpy(str, give_seqname(last_seq), 255);
536         BMF_DrawString(G.font, str);
537         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
538
539         if(last_seq->type==SEQ_SCENE && last_seq->scene) {
540                 glRasterPos3f(xco,  0.3, 0.0);
541                 BMF_DrawString(G.font, last_seq->scene->id.name+2);
542                 xco += xfac*BMF_GetStringWidth(G.font, last_seq->scene->id.name+2) +30.0*xfac;
543         }
544
545         /* LEN */
546         if(last_seq->type & SEQ_EFFECT)
547                 sprintf(str, "len: %d   From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1);
548         else
549                 sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len);
550
551         glRasterPos3f(xco,  0.3, 0.0);
552         BMF_DrawString(G.font, str);
553         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
554
555         if(last_seq->type==SEQ_IMAGE) {
556
557                 /* CURRENT */
558                 se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
559                 if(se) {
560                         sprintf(str, "cur: %s", se->name);
561                         glRasterPos3f(xco,  0.3, 0.0);
562                         BMF_DrawString(G.font, str);
563                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
564                 }
565
566                 /* FIRST AND LAST */
567
568                 if(last_seq->strip) {
569                         se= last_seq->strip->stripdata;
570                         last= se+last_seq->len-1;
571                         if(last_seq->startofs) se+= last_seq->startofs;
572                         if(last_seq->endofs) last-= last_seq->endofs;
573
574                         sprintf(str, "First: %s at %d     Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1);
575                         glRasterPos3f(xco,  0.3, 0.0);
576                         BMF_DrawString(G.font, str);
577                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
578
579                         /* orig size */
580                         sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory);
581                         glRasterPos3f(xco,  0.3, 0.0);
582                         BMF_DrawString(G.font, str);
583                         xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
584                 }
585         }
586         else if(last_seq->type==SEQ_MOVIE) {
587
588                 sta= last_seq->startofs;
589                 end= last_seq->len-1-last_seq->endofs;
590
591                 sprintf(str, "%s   %s%s  First: %d at %d     Last: %d at %d     Cur: %d",
592                                 last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
593                                 sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp);
594
595                 glRasterPos3f(xco,  0.3, 0.0);
596                 BMF_DrawString(G.font, str);
597         }
598         else if(last_seq->type==SEQ_SOUND) {
599
600                 sta= last_seq->startofs;
601                 end= last_seq->len-1-last_seq->endofs;
602
603                 sprintf(str, "%s   %s%s  First: %d at %d     Last: %d at %d     Cur: %d     Gain: %.2f dB     Pan: %.2f",
604                                 last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
605                                 sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp,
606                                 last_seq->level, last_seq->pan);
607
608                 glRasterPos3f(xco,  0.3, 0.0);
609                 BMF_DrawString(G.font, str);
610         }
611 }
612
613 #define SEQ_BUT_PLUGIN  1
614 #define SEQ_BUT_RELOAD  2
615 #define SEQ_BUT_EFFECT  3
616
617 void do_seqbuttons(short val)
618 {
619         extern Sequence *last_seq;
620
621         switch(val) {
622         case SEQ_BUT_PLUGIN:
623                 new_stripdata(last_seq);
624                 free_imbuf_effect_spec(CFRA);
625                 break;
626
627         case SEQ_BUT_RELOAD:
628                 free_imbuf_seq();       // frees all
629                 break;
630         case SEQ_BUT_EFFECT:
631                 new_stripdata(last_seq);
632                 calc_sequence(last_seq);
633                 break;
634         }
635
636         allqueue(REDRAWSEQ, 0);
637 }
638
639 static void seq_panel_properties(short cntrl)   // SEQ_HANDLER_PROPERTIES
640 {
641         extern Sequence *last_seq;
642         uiBlock *block;
643
644         block= uiNewBlock(&curarea->uiblocks, "seq_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
645         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
646         uiSetPanelHandler(SEQ_HANDLER_PROPERTIES);  // for close and esc
647         if(uiNewPanel(curarea, block, "Strip Properties", "Seq", 10, 230, 318, 204)==0) return;
648
649         if(last_seq==NULL) return;
650
651         if(last_seq->type==SEQ_PLUGIN) {
652                 PluginSeq *pis;
653                 VarStruct *varstr;
654                 int a, xco, yco;
655
656                 uiDefBut(block, LABEL, 0, "Type: Plugin", 10,50,70,20, 0, 0, 0, 0, 0, "");
657
658                 pis= last_seq->plugin;
659                 if(pis->vars==0) return;
660
661                 varstr= pis->varstr;
662                 if(varstr) {
663                         for(a=0; a<pis->vars; a++, varstr++) {
664                                 xco= 150*(a/6)+10;
665                                 yco= 125 - 20*(a % 6)+1;
666                                 uiDefBut(block, varstr->type, SEQ_BUT_PLUGIN, varstr->name, xco,yco,150,19, &(pis->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
667
668                         }
669                 }
670         }
671         else if(last_seq->type==SEQ_IMAGE) {
672
673                 uiDefBut(block, LABEL, 0, "Type: Image", 10,140,150,20, 0, 0, 0, 0, 0, "");
674                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
675
676                 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");
677                 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");
678                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:",                   10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
679                 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");
680                 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");
681         }
682         else if(last_seq->type==SEQ_META) {
683
684                 uiDefBut(block, LABEL, 0, "Type: Meta", 10,140,150,20, 0, 0, 0, 0, 0, "");
685                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
686
687         }
688         else if(last_seq->type==SEQ_SCENE) {
689
690                 uiDefBut(block, LABEL, 0, "Type: Scene", 10,140,150,20, 0, 0, 0, 0, 0, "");
691                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
692                 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");
693         }
694         else if(last_seq->type==SEQ_MOVIE) {
695
696                 if(last_seq->mul==0.0) last_seq->mul= 1.0;
697
698                 uiDefBut(block, LABEL, 0, "Type: Movie", 10,140,150,20, 0, 0, 0, 0, 0, "");
699                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
700
701                 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");
702                 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");
703                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:",                   10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
704                 
705                 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");
706                 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");
707
708         }
709         else if(last_seq->type==SEQ_SOUND) {
710
711                 uiDefBut(block, LABEL, 0, "Type: Audio", 10,140,150,20, 0, 0, 0, 0, 0, "");
712                 uiDefBut(block, TEX, 0, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
713
714                 uiDefButBitS(block, TOG, SEQ_MUTE, B_NOP, "Mute", 10,90,120,19, &last_seq->flag, 0.0, 21.0, 100, 0, "");
715                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Gain (dB):", 10,70,150,19, &last_seq->level, -96.0, 6.0, 100, 0, "");
716                 uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Pan:",   10,50,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, "");
717         }
718         else if(last_seq->type>=SEQ_EFFECT) {
719                 uiDefBut(block, LABEL, 0, "Type: Effect", 10,140,150,20, 0, 0, 0, 0, 0, "");
720                 uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
721
722                 if(last_seq->type==SEQ_WIPE){
723                         WipeVars *wipe = (WipeVars *)last_seq->effectdata;
724                         char formatstring[256];
725                         strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255);
726                         uiDefButS(block, MENU,SEQ_BUT_EFFECT, formatstring,     10,90,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed");
727                         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");
728                         switch(wipe->wipetype){ /*Skip Types that do not require angle*/
729                                 case DO_IRIS_WIPE:
730                                 case DO_CLOCK_WIPE:
731                                 break;
732                                 
733                                 default:
734                                         uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Angle:",   10,40,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge");
735                         }
736                         uiDefButS(block, TOG,SEQ_BUT_EFFECT,"Wipe In",  10,15,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe");                          
737                 }
738                 else if(last_seq->type==SEQ_GLOW){
739                         GlowVars *glow = (GlowVars *)last_seq->effectdata;
740
741                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Threshold:",     10,90,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity");
742                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Clamp:",         10,70,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity");
743                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Boost factor:",  10,50,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier");
744                         uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Blur distance:",         10,30,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect");
745                         uiDefButI(block, NUM, B_NOP, "Quality:", 10,10,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect");
746                         uiDefButI(block, TOG, B_NOP, "Only boost", 10,-10,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only");
747                 }
748
749         }
750
751
752 }
753
754 static void seq_blockhandlers(ScrArea *sa)
755 {
756         SpaceSeq *sseq= sa->spacedata.first;
757         short a;
758
759         /* warning; blocks need to be freed each time, handlers dont remove (for ipo moved to drawipospace) */
760         uiFreeBlocksWin(&sa->uiblocks, sa->win);
761
762         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
763                 switch(sseq->blockhandler[a]) {
764
765                 case SEQ_HANDLER_PROPERTIES:
766                         seq_panel_properties(sseq->blockhandler[a+1]);
767                         break;
768
769                 }
770                 /* clear action value for event */
771                 sseq->blockhandler[a+1]= 0;
772         }
773         uiDrawBlocksPanels(sa, 0);
774
775 }
776
777 void drawseqspace(ScrArea *sa, void *spacedata)
778 {
779         SpaceSeq *sseq;
780         Editing *ed;
781         Sequence *seq;
782         float col[3];
783         int ofsx, ofsy;
784
785         ed= G.scene->ed;
786
787         sseq= curarea->spacedata.first;
788         if(sseq->mainb==1) {
789                 draw_image_seq(curarea);
790                 return;
791         }
792
793         bwin_clear_viewmat(sa->win);    /* clear buttons view */
794         glLoadIdentity();
795
796         BIF_GetThemeColor3fv(TH_BACK, col);
797         if(ed && ed->metastack.first) glClearColor(col[0], col[1], col[2]-0.1, 0.0);
798         else glClearColor(col[0], col[1], col[2], 0.0);
799
800         glClear(GL_COLOR_BUFFER_BIT);
801
802         calc_scrollrcts(sa, G.v2d, curarea->winx, curarea->winy);
803
804         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
805                 if(G.v2d->scroll) {
806                         ofsx= curarea->winrct.xmin;     /* because of mywin */
807                         ofsy= curarea->winrct.ymin;
808                         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);
809                         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);
810                 }
811         }
812
813
814         myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
815
816         BIF_ThemeColorShade(TH_BACK, -20);
817         glRectf(G.v2d->cur.xmin,  0.0,  G.v2d->cur.xmax,  1.0);
818
819         boundbox_seq();
820         calc_ipogrid();
821         draw_ipogrid();
822         draw_cfra_seq();
823
824         /* sequences: first deselect */
825
826         if(ed) {
827                 seq= ed->seqbasep->first;
828                 while(seq) { /* bound box test, dont draw outside the view */
829                         if (seq->flag & SELECT ||
830                                         seq->start > G.v2d->cur.xmax ||
831                                         seq->start+seq->len < G.v2d->cur.xmin ||
832                                         seq->machine+1.0 < G.v2d->cur.ymin ||
833                                         seq->machine > G.v2d->cur.ymax)
834                         {
835                                 /* dont draw */
836                         } else {
837                                 drawseq(seq);
838                         }
839                         seq= seq->next;
840                 }
841         }
842         ed= G.scene->ed;
843         if(ed) {
844                 seq= ed->seqbasep->first;
845                 while(seq) { /* bound box test, dont draw outside the view */
846                         if (!(seq->flag & SELECT) ||
847                                         seq->start > G.v2d->cur.xmax ||
848                                         seq->start+seq->len < G.v2d->cur.xmin ||
849                                         seq->machine+1.0 < G.v2d->cur.ymin ||
850                                         seq->machine > G.v2d->cur.ymax)
851                         {
852                                 /* dont draw */
853                         } else {
854                                 drawseq(seq);
855                         }
856                         seq= seq->next;
857                 }
858         }
859
860         draw_extra_seqinfo();
861
862         /* restore viewport */
863         mywinset(curarea->win);
864
865         /* ortho at pixel level curarea */
866         myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
867
868         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
869                 if(G.v2d->scroll) {
870                         drawscroll(0);
871                 }
872         }
873
874         draw_area_emboss(sa);
875
876         if(sseq->mainb==0) {
877                 /* it is important to end a view in a transform compatible with buttons */
878                 bwin_scalematrix(sa->win, sseq->blockscale, sseq->blockscale, sseq->blockscale);
879                 seq_blockhandlers(sa);
880         }
881
882         curarea->win_swap= WIN_BACK_OK;
883 }
884
885