4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Blender Foundation, 2003-2009
25 * ***** END GPL LICENSE BLOCK *****
31 #include "MEM_guardedalloc.h"
33 #include "BLI_blenlib.h"
34 #include "BLI_arithb.h"
36 #include "IMB_imbuf_types.h"
38 #include "DNA_gpencil_types.h"
39 #include "DNA_sequence_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_screen_types.h"
42 #include "DNA_space_types.h"
43 #include "DNA_view2d_types.h"
44 #include "DNA_userdef_types.h"
46 #include "BKE_context.h"
47 #include "BKE_global.h"
48 #include "BKE_plugin_types.h"
49 #include "BKE_sequence.h"
50 #include "BKE_scene.h"
51 #include "BKE_utildefines.h"
53 #include "IMB_imbuf_types.h"
54 #include "IMB_imbuf.h"
57 #include "BIF_glutil.h"
59 #include "ED_anim_api.h"
60 #include "ED_space_api.h"
61 #include "ED_sequencer.h"
64 #include "UI_interface.h"
65 #include "UI_resources.h"
66 #include "UI_view2d.h"
69 #include "sequencer_intern.h"
71 #define SEQ_LEFTHANDLE 1
72 #define SEQ_RIGHTHANDLE 2
75 /* Note, Dont use WHILE_SEQ while drawing! - it messes up transform, - Campbell */
77 int no_rightbox=0, no_leftbox= 0;
78 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2);
81 static void draw_cfra_seq(View2D *v2d, int cfra)
83 glColor3ub(0x30, 0x90, 0x50);
86 glVertex2f(cfra, v2d->cur.ymin);
87 glVertex2f(cfra, v2d->cur.ymax);
92 static void get_seq_color3ubv(Scene *curscene, Sequence *seq, char *col)
96 SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
100 UI_GetThemeColor3ubv(TH_SEQ_IMAGE, col);
103 UI_GetThemeColor3ubv(TH_SEQ_META, col);
106 UI_GetThemeColor3ubv(TH_SEQ_MOVIE, col);
109 UI_GetThemeColor3ubv(TH_SEQ_SCENE, col);
111 if(seq->scene==curscene) {
112 UI_GetColorPtrBlendShade3ubv(col, col, col, 1.0, 20);
120 /* slightly offset hue to distinguish different effects */
121 UI_GetThemeColor3ubv(TH_SEQ_TRANSITION, col);
123 rgb[0] = col[0]/255.0; rgb[1] = col[1]/255.0; rgb[2] = col[2]/255.0;
124 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
126 if (seq->type == SEQ_CROSS) hsv[0]+= 0.04;
127 if (seq->type == SEQ_GAMCROSS) hsv[0]+= 0.08;
128 if (seq->type == SEQ_WIPE) hsv[0]+= 0.12;
130 if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
131 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
132 col[0] = (char)(rgb[0]*255); col[1] = (char)(rgb[1]*255); col[2] = (char)(rgb[2]*255);
145 /* slightly offset hue to distinguish different effects */
146 UI_GetThemeColor3ubv(TH_SEQ_EFFECT, col);
148 rgb[0] = col[0]/255.0; rgb[1] = col[1]/255.0; rgb[2] = col[2]/255.0;
149 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
151 if (seq->type == SEQ_ADD) hsv[0]+= 0.04;
152 if (seq->type == SEQ_SUB) hsv[0]+= 0.08;
153 if (seq->type == SEQ_MUL) hsv[0]+= 0.12;
154 if (seq->type == SEQ_ALPHAOVER) hsv[0]+= 0.16;
155 if (seq->type == SEQ_ALPHAUNDER) hsv[0]+= 0.20;
156 if (seq->type == SEQ_OVERDROP) hsv[0]+= 0.24;
157 if (seq->type == SEQ_GLOW) hsv[0]+= 0.28;
158 if (seq->type == SEQ_TRANSFORM) hsv[0]+= 0.36;
160 if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
161 hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
162 col[0] = (char)(rgb[0]*255); col[1] = (char)(rgb[1]*255); col[2] = (char)(rgb[2]*255);
166 col[0]= (char)(colvars->col[0]*255);
167 col[1]= (char)(colvars->col[1]*255);
168 col[2]= (char)(colvars->col[2]*255);
170 col[0] = col[1] = col[2] = 128;
174 UI_GetThemeColor3ubv(TH_SEQ_PLUGIN, col);
178 UI_GetThemeColor3ubv(TH_SEQ_AUDIO, col);
179 blendcol[0] = blendcol[1] = blendcol[2] = 128;
180 if(seq->flag & SEQ_MUTE) UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20);
183 col[0] = 10; col[1] = 255; col[2] = 40;
187 static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
189 /* Note, this used to use WHILE_SEQ, but it messes up the seq->depth value, (needed by transform when doing overlap checks)
190 * so for now, just use the meta's immediate children, could be fixed but its only drawing - Campbell */
196 nr= BLI_countlist(&seqm->seqbase);
200 if (seqm->flag & SEQ_MUTE) {
201 glEnable(GL_POLYGON_STIPPLE);
202 glPolygonStipple(stipple_halftone);
204 glEnable(GL_LINE_STIPPLE);
205 glLineStipple(1, 0x8888);
208 for (seq= seqm->seqbase.first; seq; seq= seq->next) {
209 get_seq_color3ubv(scene, seq, col);
211 glColor3ubv((GLubyte *)col);
213 glRectf(x1, y1, x1+0.9*dx, y2);
215 UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -30);
216 glColor3ubv((GLubyte *)col);
218 fdrawbox(x1, y1, x1+0.9*dx, y2);
223 if (seqm->flag & SEQ_MUTE) {
224 glDisable(GL_POLYGON_STIPPLE);
225 glDisable(GL_LINE_STIPPLE);
229 static void drawseqwave(Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, int winx)
232 x1 is the starting x value to draw the wave,
233 x2 the end x value, same for y1 and y2
234 winx is the zoom level.
238 f, /* floating point value used to store the X draw location for the wave lines when openGL drawing*/
239 midy, /* fast access to the middle location (y1+y2)/2 */
240 clipxmin, /* the minimum X value, clip this with the window */
241 clipxmax, /* the maximum X value, clip this with the window */
242 sample_step, /* steps to move per sample, floating value must later translate into an int */
243 fsofs, /* steps to move per sample, floating value must later translate into an int */
245 sound_width, /* convenience: x2-x1 */
246 wavemulti; /* scale the samples by this value when GL_LINE drawing so it renders the right height */
249 offset, /* initial offset value for the wave drawing */
250 offset_next, /* when in the wave drawing loop this value is the samples intil the next vert */
251 sofs, /* Constrained offset value (~3) for the wave, start */
252 eofs, /* ditto, end */
253 wavesample, /* inner loop storage if the current wave sample value, used to make the 2 values below */
254 wavesamplemin, /* used for finding the min and max wave peaks */
255 wavesamplemax, /* ditto */
256 subsample_step=4; /* when the sample step is 4 every sample of
257 the wave is evaluated for min and max values used to draw the wave,
258 however this is slow ehrn zoomed out so when the sample step is above
259 1 (the larger the further out the zoom is) so not evaluate all samples, only some. */
265 // XXX audio_makestream(seq->sound);
266 if(seq->sound==NULL || seq->sound->stream==NULL) return;
268 if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0);
270 sofs = ((int)( FRA2TIME(seq->startdisp-seq->start+seq->anim_startofs)*(float)scene->r.audio.mixrate*4.0 )) & (~3);
271 eofs = ((int)( FRA2TIME(seq->enddisp-seq->start+seq->anim_startofs)*(float)scene->r.audio.mixrate*4.0 )) & (~3);
273 /* clip the drawing area to the screen bounds to save time */
274 sample_step= (v2d->cur.xmax - v2d->cur.xmin)/winx;
275 clipxmin= MAX2(x1, v2d->cur.xmin);
276 clipxmax= MIN2(x2, v2d->cur.xmax);
279 subsample_step= ((int)(subsample_step*sample_step*8)) & (~3);
281 /* for speedy access */
284 feofs_sofs= (float)(eofs-sofs);
287 stream = sound->stream;
288 wavemulti = (y2-y1)/196605; /*y2-y1 is the height*/
291 /* we need to get the starting offset value, excuse the duplicate code */
293 offset= (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3);
295 /* start the loop, draw a line per sample_step -sample_step is about 1 line drawn per pixel */
297 for (f=x1+sample_step; f<=clipxmax; f+=sample_step) {
299 offset_next = (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3);
300 if (f > v2d->cur.xmin) {
301 /* if this is close to the last sample just exit */
302 if (offset_next >= sound->streamlen) break;
304 wavesamplemin = 131070;
305 wavesamplemax = -131070;
307 /*find with high and low of the waveform for this draw,
308 evaluate small samples to find this range */
309 while (offset < offset_next) {
310 s = (signed short*)(stream+offset);
312 wavesample = s[0]*2 + s[1];
313 if (wavesamplemin>wavesample)
314 wavesamplemin=wavesample;
315 if (wavesamplemax<wavesample)
316 wavesamplemax=wavesample;
317 offset+=subsample_step;
319 /* draw the wave line, looks good up close and zoomed out */
320 glVertex2f(f, midy-(wavemulti*wavesamplemin) );
321 glVertex2f(f, midy-(wavemulti*wavesamplemax) );
323 while (offset < offset_next) offset+=subsample_step;
331 /* draw a handle, for each end of a sequence strip */
332 static void draw_seq_handle(View2D *v2d, Sequence *seq, float pixelx, short direction)
334 float v1[2], v2[2], v3[2], rx1=0, rx2=0; //for triangles and rect
335 float x1, x2, y1, y2;
337 float minhandle, maxhandle;
339 unsigned int whichsel=0;
344 y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
345 y2= seq->machine+SEQ_STRIP_OFSTOP;
347 /* clamp handles to defined size in pixel space */
348 handsize = seq->handsize;
351 CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
353 /* set up co-ordinates/dimensions for either left or right handle */
354 if (direction == SEQ_LEFTHANDLE) {
356 rx2 = x1+handsize*0.75;
358 v1[0]= x1+handsize/4; v1[1]= y1+( ((y1+y2)/2.0 - y1)/2);
359 v2[0]= x1+handsize/4; v2[1]= y2-( ((y1+y2)/2.0 - y1)/2);
360 v3[0]= v2[0] + handsize/4; v3[1]= (y1+y2)/2.0;
362 whichsel = SEQ_LEFTSEL;
363 } else if (direction == SEQ_RIGHTHANDLE) {
364 rx1 = x2-handsize*0.75;
367 v1[0]= x2-handsize/4; v1[1]= y1+( ((y1+y2)/2.0 - y1)/2);
368 v2[0]= x2-handsize/4; v2[1]= y2-( ((y1+y2)/2.0 - y1)/2);
369 v3[0]= v2[0] - handsize/4; v3[1]= (y1+y2)/2.0;
371 whichsel = SEQ_RIGHTSEL;
375 if(seq->type < SEQ_EFFECT ||
376 get_sequence_effect_num_inputs(seq->type) == 0) {
377 glEnable( GL_BLEND );
379 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
381 if(seq->flag & whichsel) glColor4ub(0, 0, 0, 80);
382 else if (seq->flag & SELECT) glColor4ub(255, 255, 255, 30);
383 else glColor4ub(0, 0, 0, 22);
385 glRectf(rx1, y1, rx2, y2);
387 if(seq->flag & whichsel) glColor4ub(255, 255, 255, 200);
388 else glColor4ub(0, 0, 0, 50);
390 glEnable( GL_POLYGON_SMOOTH );
391 glBegin(GL_TRIANGLES);
392 glVertex2fv(v1); glVertex2fv(v2); glVertex2fv(v3);
395 glDisable( GL_POLYGON_SMOOTH );
396 glDisable( GL_BLEND );
399 if(G.moving || (seq->flag & whichsel)) {
401 if (direction == SEQ_LEFTHANDLE) {
402 sprintf(str, "%d", seq->startdisp);
406 sprintf(str, "%d", seq->enddisp - 1);
407 x1= x2 - handsize*0.75;
410 UI_view2d_text_cache_add(v2d, x1, y1, str);
414 static void draw_seq_extensions(Scene *scene, SpaceSeq *sseq, Sequence *seq)
416 float x1, x2, y1, y2, pixely, a;
417 char col[3], blendcol[3];
420 if(seq->type >= SEQ_EFFECT) return;
425 y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
426 y2= seq->machine+SEQ_STRIP_OFSTOP;
429 pixely = (v2d->cur.ymax - v2d->cur.ymin)/(v2d->mask.ymax - v2d->mask.ymin);
431 blendcol[0] = blendcol[1] = blendcol[2] = 120;
434 glEnable( GL_BLEND );
435 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
437 get_seq_color3ubv(scene, seq, col);
439 if (seq->flag & SELECT) {
440 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
441 glColor4ub(col[0], col[1], col[2], 170);
443 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
444 glColor4ub(col[0], col[1], col[2], 110);
447 glRectf((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1);
449 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
450 else glColor4ub(col[0], col[1], col[2], 160);
452 fdrawbox((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1); //outline
454 glDisable( GL_BLEND );
457 glEnable( GL_BLEND );
458 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
460 get_seq_color3ubv(scene, seq, col);
462 if (seq->flag & SELECT) {
463 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
464 glColor4ub(col[0], col[1], col[2], 170);
466 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
467 glColor4ub(col[0], col[1], col[2], 110);
470 glRectf(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM);
472 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
473 else glColor4ub(col[0], col[1], col[2], 160);
475 fdrawbox(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM); //outline
477 glDisable( GL_BLEND );
479 if(seq->startstill) {
480 get_seq_color3ubv(scene, seq, col);
481 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
482 glColor3ubv((GLubyte *)col);
484 draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
486 /* feint pinstripes, helps see exactly which is extended and which isn't,
487 * especially when the extension is very small */
488 if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
489 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
491 glColor3ubv((GLubyte *)col);
493 for(a=y1; a< y2; a+= pixely*2.0 ) {
494 fdrawline(x1, a, (float)(seq->start), a);
498 get_seq_color3ubv(scene, seq, col);
499 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
500 glColor3ubv((GLubyte *)col);
502 draw_shadedstrip(seq, col, (float)(seq->start+seq->len), y1, x2, y2);
504 /* feint pinstripes, helps see exactly which is extended and which isn't,
505 * especially when the extension is very small */
506 if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
507 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
509 glColor3ubv((GLubyte *)col);
511 for(a=y1; a< y2; a+= pixely*2.0 ) {
512 fdrawline((float)(seq->start+seq->len), a, x2, a);
517 /* draw info text on a sequence strip */
518 static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, char *background_col)
520 char str[32 + FILE_MAXDIR+FILE_MAXFILE];
523 sprintf(str, "%d | %s: %s", seq->len, give_seqname(seq), seq->name+2);
526 if(seq->type == SEQ_META) {
527 sprintf(str, "%d | %s", seq->len, give_seqname(seq));
529 else if(seq->type == SEQ_SCENE) {
530 if(seq->scene) sprintf(str, "%d | %s: %s", seq->len, give_seqname(seq), seq->scene->id.name+2);
531 else sprintf(str, "%d | %s", seq->len, give_seqname(seq));
534 else if(seq->type == SEQ_IMAGE) {
535 sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
537 else if(seq->type & SEQ_EFFECT) {
538 int can_float = (seq->type != SEQ_PLUGIN)
539 || (seq->plugin && seq->plugin->version >= 4);
541 if(seq->seq3!=seq->seq2 && seq->seq1!=seq->seq3)
542 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!");
543 else if (seq->seq1 && seq->seq2)
544 sprintf(str, "%d | %s: %d>%d%s", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, can_float ? "" : " No float, upgrade plugin!");
546 sprintf(str, "%d | %s", seq->len, give_seqname(seq));
548 else if (seq->type == SEQ_RAM_SOUND) {
549 sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
551 else if (seq->type == SEQ_HD_SOUND) {
552 sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
554 else if (seq->type == SEQ_MOVIE) {
555 sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
559 if(seq->flag & SELECT){
561 }else if ((((int)background_col[0] + (int)background_col[1] + (int)background_col[2]) / 3) < 50){
562 cpack(0x505050); /* use lighter text colour for dark background */
567 UI_view2d_text_cache_add(v2d, x1, y1+SEQ_STRIP_OFSBOTTOM, str);
570 /* draws a shaded strip, made from gradient + flat color + gradient */
571 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2)
575 if (seq->flag & SEQ_MUTE) {
576 glEnable(GL_POLYGON_STIPPLE);
577 glPolygonStipple(stipple_halftone);
580 ymid1 = (y2-y1)*0.25 + y1;
581 ymid2 = (y2-y1)*0.65 + y1;
583 glShadeModel(GL_SMOOTH);
586 if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
587 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0);
589 glColor3ubv((GLubyte *)col);
594 if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
595 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5);
597 glColor3ubv((GLubyte *)col);
599 glVertex2f(x2,ymid1);
600 glVertex2f(x1,ymid1);
604 glRectf(x1, ymid1, x2, ymid2);
608 glVertex2f(x1,ymid2);
609 glVertex2f(x2,ymid2);
611 if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -15);
612 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 25);
614 glColor3ubv((GLubyte *)col);
621 if (seq->flag & SEQ_MUTE) {
622 glDisable(GL_POLYGON_STIPPLE);
627 Draw a sequence strip, bounds check alredy made
628 ARegion is currently only used to get the windows width in pixels
629 so wave file sample drawing precission is zoom adjusted
631 static void draw_seq_strip(Scene *scene, ARegion *ar, SpaceSeq *sseq, Sequence *seq, int outline_tint, float pixelx)
634 extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
635 View2D *v2d= &ar->v2d;
636 float x1, x2, y1, y2;
637 char col[3], background_col[3], is_single_image;
639 /* we need to know if this is a single image/color or not for drawing */
640 is_single_image = (char)check_single_seq(seq);
643 if(seq->startstill) x1= seq->start;
644 else x1= seq->startdisp;
645 y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
646 if(seq->endstill) x2= seq->start+seq->len;
647 else x2= seq->enddisp;
648 y2= seq->machine+SEQ_STRIP_OFSTOP;
651 /* get the correct color per strip type*/
652 //get_seq_color3ubv(scene, seq, col);
653 get_seq_color3ubv(scene, seq, background_col);
655 /* draw the main strip body */
656 if (is_single_image) /* single image */
657 draw_shadedstrip(seq, background_col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2);
658 else /* normal operation */
659 draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
661 /* draw additional info and controls */
662 if (seq->type == SEQ_RAM_SOUND)
663 drawseqwave(scene, v2d, seq, x1, y1, x2, y2, ar->winx);
665 if (!is_single_image)
666 draw_seq_extensions(scene, sseq, seq);
668 draw_seq_handle(v2d, seq, pixelx, SEQ_LEFTHANDLE);
669 draw_seq_handle(v2d, seq, pixelx, SEQ_RIGHTHANDLE);
671 /* draw the strip outline */
675 get_seq_color3ubv(scene, seq, col);
676 if (G.moving && (seq->flag & SELECT)) {
677 if(seq->flag & SEQ_OVERLAP) {
678 col[0]= 255; col[1]= col[2]= 40;
679 } else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
682 UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, outline_tint);
684 glColor3ubv((GLubyte *)col);
686 if (seq->flag & SEQ_MUTE) {
687 glEnable(GL_LINE_STIPPLE);
688 glLineStipple(1, 0x8888);
691 gl_round_box_shade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
693 if (seq->flag & SEQ_MUTE) {
694 glDisable(GL_LINE_STIPPLE);
697 /* calculate if seq is long enough to print a name */
698 x1= seq->startdisp+seq->handsize;
699 x2= seq->enddisp-seq->handsize;
701 /* but first the contents of a meta */
702 if(seq->type==SEQ_META) drawmeta_contents(scene, seq, x1, y1+0.15, x2, y2-0.15);
704 /* info text on the strip */
705 if(x1<v2d->cur.xmin) x1= v2d->cur.xmin;
706 else if(x1>v2d->cur.xmax) x1= v2d->cur.xmax;
707 if(x2<v2d->cur.xmin) x2= v2d->cur.xmin;
708 else if(x2>v2d->cur.xmax) x2= v2d->cur.xmax;
710 /* nice text here would require changing the view matrix for texture text */
711 if( (x2-x1) / pixelx > 32) {
712 draw_seq_text(v2d, seq, x1, x2, y1, y2, background_col);
716 static Sequence *special_seq_update= 0;
718 void set_special_seq_update(int val)
722 /* if mouse over a sequence && LEFTMOUSE */
724 // XXX special_seq_update= find_nearest_seq(&x);
726 else special_seq_update= 0;
730 static void draw_image_seq(Scene *scene, ARegion *ar, SpaceSeq *sseq)
732 extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
734 int x1, y1, rectx, recty;
736 static int recursive= 0;
740 glClearColor(0.0, 0.0, 0.0, 0.0);
741 glClear(GL_COLOR_BUFFER_BIT);
743 rectx= (scene->r.size*scene->r.xsch)/100;
744 recty= (scene->r.size*scene->r.ysch)/100;
746 /* BIG PROBLEM: the give_ibuf_seq() can call a rendering, which in turn calls redraws...
747 this shouldn't belong in a window drawing....
748 So: solve this once event based.
749 Now we check for recursion, space type and active area again (ton) */
755 if (special_seq_update) {
756 ibuf= give_ibuf_seq_direct(scene, rectx, recty, (scene->r.cfra), special_seq_update);
758 else if (!U.prefetchframes) { // XXX || (G.f & G_PLAYANIM) == 0) {
759 ibuf= (ImBuf *)give_ibuf_seq(scene, rectx, recty, (scene->r.cfra), sseq->chanshown);
762 ibuf= (ImBuf *)give_ibuf_seq_threaded(scene, rectx, recty, (scene->r.cfra), sseq->chanshown);
766 /* XXX HURMF! the give_ibuf_seq can call image display in this window */
767 // if(sa->spacetype!=SPACE_SEQ)
770 // areawinset(sa->win);
777 if(ibuf->rect==NULL && ibuf->rect_float == NULL)
780 switch(sseq->mainb != SEQ_DRAW_SEQUENCE) {
781 case SEQ_DRAW_IMG_IMBUF:
782 if (sseq->zebra != 0) {
783 ibuf = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
787 case SEQ_DRAW_IMG_WAVEFORM:
788 if ((sseq->flag & SEQ_DRAW_COLOR_SEPERATED) != 0) {
789 ibuf = make_sep_waveform_view_from_ibuf(ibuf);
791 ibuf = make_waveform_view_from_ibuf(ibuf);
795 case SEQ_DRAW_IMG_VECTORSCOPE:
796 ibuf = make_vectorscope_view_from_ibuf(ibuf);
799 case SEQ_DRAW_IMG_HISTOGRAM:
800 ibuf = make_histogram_view_from_ibuf(ibuf);
805 if(ibuf->rect_float && ibuf->rect==NULL)
806 IMB_rect_from_float(ibuf);
808 /* needed for gla draw */
809 glaDefine2DArea(&ar->winrct);
811 zoom= SEQ_ZOOM_FAC(sseq->zoom);
812 if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
813 zoomx = zoom * ((float)scene->r.xasp / (float)scene->r.yasp);
816 zoomx = zoomy = zoom;
820 x1= (ar->winx-zoomx*ibuf->x)/2 + sseq->xof;
821 y1= (ar->winy-zoomy*ibuf->y)/2 + sseq->yof;
823 glPixelZoom(zoomx, zoomy);
825 glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
827 glPixelZoom(1.0, 1.0);
830 if (sseq->mainb == SEQ_DRAW_IMG_IMBUF &&
831 (sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
833 float x2 = x1 + ibuf->x * zoomx;
834 float y2 = y1 + ibuf->y * zoomy;
836 float a= fac*(x2-x1);
844 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
847 UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
850 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
853 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
856 /* draw grease-pencil (image aligned) */
857 // if (sseq->flag & SEQ_DRAW_GPENCIL)
858 // XXX draw_gpencil_2dimage(sa, ibuf);
864 /* draw grease-pencil (screen aligned) */
865 // if (sseq->flag & SEQ_DRAW_GPENCIL)
866 // XXX draw_gpencil_2dview(sa, 0);
868 /* ortho at pixel level sa */
869 // XXX myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
873 void seq_reset_imageofs(SpaceSeq *sseq)
875 sseq->xof = sseq->yof = sseq->zoom = 0;
880 /* XXX - these should really be made to use View2D instead of so wacko private system - Aligorith */
882 void seq_viewzoom(SpaceSeq *sseq, unsigned short event, int invert)
888 sseq->zoom= (invert)? 2.0: 0.5;
890 sseq->zoom= (invert)? 4.0: 0.25;
892 sseq->zoom= (invert)? 8.0: 0.125;
894 /* ensure pixel exact locations for draw */
895 sseq->xof= (int)sseq->xof;
896 sseq->yof= (int)sseq->yof;
899 void seq_viewmove(Scene *scene, ARegion *ar, SpaceSeq *sseq)
901 short mval[2], mvalo[2];
902 short rectx, recty, xmin, xmax, ymin, ymax, pad;
907 rectx= (scene->r.size*scene->r.xsch)/100;
908 recty= (scene->r.size*scene->r.ysch)/100;
911 xmin = -(ar->winx/2) - rectx/2 + pad;
912 xmax = ar->winx/2 + rectx/2 - pad;
913 ymin = -(ar->winy/2) - recty/2 + pad;
914 ymax = ar->winy/2 + recty/2 - pad;
916 getmouseco_sc(mvalo);
918 oldcursor=get_cursor();
919 win=winlay_get_active_window();
921 SetBlenderCursor(BC_NSEW_SCROLLCURSOR);
923 while(get_mbut()&(L_MOUSE|M_MOUSE)) {
927 if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) {
929 sseq->xof -= (mvalo[0]-mval[0]);
930 sseq->yof -= (mvalo[1]-mval[1]);
932 /* prevent dragging image outside of the window and losing it! */
933 CLAMP(sseq->xof, xmin, xmax);
934 CLAMP(sseq->yof, ymin, ymax);
944 void drawprefetchseqspace(Scene *scene, ARegion *ar, SpaceSeq *sseq)
948 rectx= (scene->r.size*scene->r.xsch)/100;
949 recty= (scene->r.size*scene->r.ysch)/100;
951 if(sseq->mainb != SEQ_DRAW_SEQUENCE) {
952 give_ibuf_prefetch_request(
953 rectx, recty, (scene->r.cfra), sseq->chanshown);
957 void drawseqspace(const bContext *C, ARegion *ar)
959 ScrArea *sa= CTX_wm_area(C);
960 SpaceSeq *sseq= sa->spacedata.first;
961 Scene *scene= CTX_data_scene(C);
962 View2D *v2d= &ar->v2d;
963 View2DScrollers *scrollers;
964 Editing *ed= seq_give_editing(scene, FALSE);
969 if(sseq->mainb != SEQ_DRAW_SEQUENCE) {
970 draw_image_seq(scene, ar, sseq);
974 UI_GetThemeColor3fv(TH_BACK, col);
975 if(ed && ed->metastack.first) glClearColor(col[0], col[1], col[2]-0.1, 0.0);
976 else glClearColor(col[0], col[1], col[2], 0.0);
978 glClear(GL_COLOR_BUFFER_BIT);
980 UI_view2d_view_ortho(C, v2d);
982 UI_ThemeColorShade(TH_BACK, -20);
983 glRectf(v2d->cur.xmin, 0.0, v2d->cur.xmax, 1.0);
985 boundbox_seq(scene, &v2d->tot);
987 /* Alternating horizontal stripes */
988 i= MAX2(1, ((int)v2d->cur.ymin)-1);
991 while (i<v2d->cur.ymax) {
993 UI_ThemeColorShade(TH_BACK, -15);
995 UI_ThemeColorShade(TH_BACK, -25);
997 glVertex2f(v2d->cur.xmax, i);
998 glVertex2f(v2d->cur.xmin, i);
999 glVertex2f(v2d->cur.xmin, i+1);
1000 glVertex2f(v2d->cur.xmax, i+1);
1005 /* Force grid lines */
1006 i= MAX2(1, ((int)v2d->cur.ymin)-1);
1009 while (i<v2d->cur.ymax) {
1010 UI_ThemeColor(TH_GRID);
1011 glVertex2f(v2d->cur.xmax, i);
1012 glVertex2f(v2d->cur.xmin, i);
1017 UI_view2d_constant_grid_draw(C, v2d);
1019 draw_cfra_seq(v2d, scene->r.cfra);
1021 /* sequences: first deselect */
1023 Sequence *last_seq = get_last_seq(scene);
1026 float pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
1027 /* loop through twice, first unselected, then selected */
1028 for (j=0; j<2; j++) {
1029 seq= ed->seqbasep->first;
1030 if (j==0) outline_tint = -150;
1031 else outline_tint = -60;
1033 while(seq) { /* bound box test, dont draw outside the view */
1034 if ( ((seq->flag & SELECT) == sel) ||
1036 MIN2(seq->startdisp, seq->start) > v2d->cur.xmax ||
1037 MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin ||
1038 seq->machine+1.0 < v2d->cur.ymin ||
1039 seq->machine > v2d->cur.ymax)
1043 draw_seq_strip(scene, ar, sseq, seq, outline_tint, pixelx);
1047 sel= SELECT; /* draw selected next time round */
1049 /* draw the last selected last, removes some overlapping error */
1051 draw_seq_strip(scene, ar, sseq, last_seq, 120, pixelx);
1055 /* text draw cached, in pixelspace now */
1056 UI_view2d_text_cache_draw(ar);
1059 // draw_markers_timespace(SCE_MARKERS, DRAW_MARKERS_LINES);
1061 /* reset view matrix */
1062 UI_view2d_view_restore(C);
1065 scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_SECONDSSEQ, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
1066 UI_view2d_scrollers_draw(C, v2d, scrollers);
1067 UI_view2d_scrollers_free(scrollers);