Blender  V2.59
sequencer_draw.c
Go to the documentation of this file.
00001 /*
00002  * $Id: sequencer_draw.c 38978 2011-08-03 09:28:16Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * Contributor(s): Blender Foundation, 2003-2009
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <string.h>
00034 #include <math.h>
00035 
00036 #include "MEM_guardedalloc.h"
00037 
00038 #include "BLI_blenlib.h"
00039 #include "BLI_math.h"
00040 #include "BLI_utildefines.h"
00041 
00042 #include "IMB_imbuf_types.h"
00043 
00044 #include "DNA_scene_types.h"
00045 #include "DNA_screen_types.h"
00046 #include "DNA_space_types.h"
00047 #include "DNA_userdef_types.h"
00048 #include "DNA_sound_types.h"
00049 
00050 #include "BKE_context.h"
00051 #include "BKE_global.h"
00052 #include "BKE_sequencer.h"
00053 
00054 #include "BKE_sound.h"
00055 
00056 #include "IMB_imbuf.h"
00057 
00058 #include "BIF_gl.h"
00059 #include "BIF_glutil.h"
00060 
00061 #include "ED_anim_api.h"
00062 #include "ED_markers.h"
00063 #include "ED_types.h"
00064 
00065 #include "UI_interface.h"
00066 #include "UI_resources.h"
00067 #include "UI_view2d.h"
00068 
00069 /* own include */
00070 #include "sequencer_intern.h"
00071 
00072 
00073 #define SEQ_LEFTHANDLE          1
00074 #define SEQ_RIGHTHANDLE 2
00075 
00076 
00077 /* Note, Dont use WHILE_SEQ while drawing! - it messes up transform, - Campbell */
00078 static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2);
00079 
00080 static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[3])
00081 {
00082         unsigned char blendcol[3];
00083         SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
00084 
00085         switch(seq->type) {
00086         case SEQ_IMAGE:
00087                 UI_GetThemeColor3ubv(TH_SEQ_IMAGE, col);
00088                 break;
00089                 
00090         case SEQ_META:
00091                 UI_GetThemeColor3ubv(TH_SEQ_META, col);
00092                 break;
00093                 
00094         case SEQ_MOVIE:
00095                 UI_GetThemeColor3ubv(TH_SEQ_MOVIE, col);
00096                 break;
00097                 
00098         case SEQ_SCENE:
00099                 UI_GetThemeColor3ubv(TH_SEQ_SCENE, col);
00100                 
00101                 if(seq->scene==curscene) {
00102                         UI_GetColorPtrBlendShade3ubv(col, col, col, 1.0, 20);
00103                 }
00104                 break;
00105                 
00106         /* transitions */
00107         case SEQ_CROSS:
00108         case SEQ_GAMCROSS:
00109         case SEQ_WIPE:
00110                 UI_GetThemeColor3ubv(TH_SEQ_TRANSITION, col);
00111 
00112                 /* slightly offset hue to distinguish different effects */
00113                 if (seq->type == SEQ_CROSS)                     rgb_byte_set_hue_float_offset(col,0.04);
00114                 if (seq->type == SEQ_GAMCROSS)          rgb_byte_set_hue_float_offset(col,0.08);
00115                 if (seq->type == SEQ_WIPE)                      rgb_byte_set_hue_float_offset(col,0.12);
00116                 break;
00117                 
00118         /* effects */
00119         case SEQ_TRANSFORM:
00120         case SEQ_SPEED:
00121         case SEQ_ADD:
00122         case SEQ_SUB:
00123         case SEQ_MUL:
00124         case SEQ_ALPHAOVER:
00125         case SEQ_ALPHAUNDER:
00126         case SEQ_OVERDROP:
00127         case SEQ_GLOW:
00128         case SEQ_MULTICAM:
00129         case SEQ_ADJUSTMENT:
00130                 UI_GetThemeColor3ubv(TH_SEQ_EFFECT, col);
00131                 
00132                 /* slightly offset hue to distinguish different effects */
00133                 if (seq->type == SEQ_ADD)                       rgb_byte_set_hue_float_offset(col,0.04);
00134                 if (seq->type == SEQ_SUB)                       rgb_byte_set_hue_float_offset(col,0.08);
00135                 if (seq->type == SEQ_MUL)                       rgb_byte_set_hue_float_offset(col,0.12);
00136                 if (seq->type == SEQ_ALPHAOVER)         rgb_byte_set_hue_float_offset(col,0.16);
00137                 if (seq->type == SEQ_ALPHAUNDER)        rgb_byte_set_hue_float_offset(col,0.20);
00138                 if (seq->type == SEQ_OVERDROP)          rgb_byte_set_hue_float_offset(col,0.24);
00139                 if (seq->type == SEQ_GLOW)                      rgb_byte_set_hue_float_offset(col,0.28);
00140                 if (seq->type == SEQ_TRANSFORM)         rgb_byte_set_hue_float_offset(col,0.36);
00141                 if (seq->type == SEQ_MULTICAM)          rgb_byte_set_hue_float_offset(col,0.32);
00142                 if (seq->type == SEQ_ADJUSTMENT)                rgb_byte_set_hue_float_offset(col,0.40);
00143                 break;
00144                 
00145         case SEQ_COLOR:
00146                 if (colvars->col) {
00147                         rgb_float_to_byte(colvars->col, col);
00148                 } else {
00149                         col[0] = col[1] = col[2] = 128;
00150                 }
00151                 break;
00152                 
00153         case SEQ_PLUGIN:
00154                 UI_GetThemeColor3ubv(TH_SEQ_PLUGIN, col);
00155                 break;
00156                 
00157         case SEQ_SOUND:
00158                 UI_GetThemeColor3ubv(TH_SEQ_AUDIO, col);
00159                 blendcol[0] = blendcol[1] = blendcol[2] = 128;
00160                 if(seq->flag & SEQ_MUTE) UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20);
00161                 break;
00162                 
00163         default:
00164                 col[0] = 10; col[1] = 255; col[2] = 40;
00165         }
00166 }
00167 
00168 static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
00169 {
00170         /*
00171         x1 is the starting x value to draw the wave,
00172         x2 the end x value, same for y1 and y2
00173         stepsize is width of a pixel.
00174         */
00175         if(seq->sound->cache)
00176         {
00177                 int i;
00178                 int length = floor((x2-x1)/stepsize)+1;
00179                 float ymid = (y1+y2)/2;
00180                 float yscale = (y2-y1)/2;
00181                 float* samples = MEM_mallocN(length * sizeof(float) * 2, "seqwave_samples");
00182                 if(!samples)
00183                         return;
00184                 if(sound_read_sound_buffer(seq->sound, samples, length,
00185                                                                    (seq->startofs + seq->anim_startofs)/FPS,
00186                                                                    (seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp)/FPS) != length)
00187                 {
00188                         MEM_freeN(samples);
00189                         return;
00190                 }
00191                 glBegin(GL_LINES);
00192                 for(i = 0; i < length; i++)
00193                 {
00194                         glVertex2f(x1+i*stepsize, ymid + samples[i * 2] * yscale);
00195                         glVertex2f(x1+i*stepsize, ymid + samples[i * 2 + 1] * yscale);
00196                 }
00197                 glEnd();
00198                 MEM_freeN(samples);
00199         }
00200 }
00201 
00202 static void drawmeta_stipple(int value)
00203 {
00204         if(value) {
00205                 glEnable(GL_POLYGON_STIPPLE);
00206                 glPolygonStipple(stipple_halftone);
00207                 
00208                 glEnable(GL_LINE_STIPPLE);
00209                 glLineStipple(1, 0x8888);
00210         }
00211         else {
00212                 glDisable(GL_POLYGON_STIPPLE);
00213                 glDisable(GL_LINE_STIPPLE);
00214         }
00215 }
00216 
00217 static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
00218 {
00219         /* Note, this used to use WHILE_SEQ, but it messes up the seq->depth value, (needed by transform when doing overlap checks)
00220          * so for now, just use the meta's immediate children, could be fixed but its only drawing - Campbell */
00221         Sequence *seq;
00222         unsigned char col[4];
00223 
00224         int chan_min= MAXSEQ;
00225         int chan_max= 0;
00226         int chan_range= 0;
00227         float draw_range= y2 - y1;
00228         float draw_height;
00229 
00230         glEnable(GL_BLEND);
00231         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00232 
00233         if(seqm->flag & SEQ_MUTE)
00234                 drawmeta_stipple(1);
00235 
00236         for (seq= seqm->seqbase.first; seq; seq= seq->next) {
00237                 chan_min= MIN2(chan_min, seq->machine);
00238                 chan_max= MAX2(chan_max, seq->machine);
00239         }
00240 
00241         chan_range= (chan_max - chan_min) + 1;
00242         draw_height= draw_range / chan_range; 
00243 
00244         col[3]= 196; /* alpha, used for all meta children */
00245 
00246         for (seq= seqm->seqbase.first; seq; seq= seq->next) {
00247                 if((seq->startdisp > x2 || seq->enddisp < x1) == 0) {
00248                         float y_chan= (seq->machine - chan_min) / (float)(chan_range) * draw_range;
00249                         float x1_chan= seq->startdisp;
00250                         float x2_chan= seq->enddisp;
00251                         float y1_chan, y2_chan;
00252 
00253                         if((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
00254                                 drawmeta_stipple(1);
00255 
00256                         get_seq_color3ubv(scene, seq, col);
00257 
00258                         glColor4ubv(col);
00259                         
00260                         /* clamp within parent sequence strip bounds */
00261                         if(x1_chan < x1) x1_chan= x1;
00262                         if(x2_chan > x2) x2_chan= x2;
00263 
00264                         y1_chan= y1 + y_chan + (draw_height * SEQ_STRIP_OFSBOTTOM);
00265                         y2_chan= y1 + y_chan + (draw_height * SEQ_STRIP_OFSTOP);
00266 
00267                         glRectf(x1_chan,  y1_chan, x2_chan,  y2_chan);
00268 
00269                         UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -30);
00270                         glColor4ubv(col);
00271                         fdrawbox(x1_chan,  y1_chan, x2_chan,  y2_chan);
00272 
00273                         if((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
00274                                 drawmeta_stipple(0);
00275                 }
00276         }
00277 
00278         if (seqm->flag & SEQ_MUTE)
00279                 drawmeta_stipple(0);
00280         
00281         glDisable(GL_BLEND);
00282 }
00283 
00284 /* draw a handle, for each end of a sequence strip */
00285 static void draw_seq_handle(View2D *v2d, Sequence *seq, float pixelx, short direction)
00286 {
00287         float v1[2], v2[2], v3[2], rx1=0, rx2=0; //for triangles and rect
00288         float x1, x2, y1, y2;
00289         float handsize;
00290         float minhandle, maxhandle;
00291         char str[32];
00292         unsigned int whichsel=0;
00293         
00294         x1= seq->startdisp;
00295         x2= seq->enddisp;
00296         
00297         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
00298         y2= seq->machine+SEQ_STRIP_OFSTOP;
00299         
00300         /* clamp handles to defined size in pixel space */
00301         handsize = seq->handsize;
00302         minhandle = 7;
00303         maxhandle = 40;
00304         CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
00305         
00306         /* set up co-ordinates/dimensions for either left or right handle */
00307         if (direction == SEQ_LEFTHANDLE) {      
00308                 rx1 = x1;
00309                 rx2 = x1+handsize * 0.75f;
00310                 
00311                 v1[0]= x1+handsize/4; v1[1]= y1+( ((y1+y2)/2.0f - y1)/2);
00312                 v2[0]= x1+handsize/4; v2[1]= y2-( ((y1+y2)/2.0f - y1)/2);
00313                 v3[0]= v2[0] + handsize/4; v3[1]= (y1+y2)/2.0f;
00314                 
00315                 whichsel = SEQ_LEFTSEL;
00316         } else if (direction == SEQ_RIGHTHANDLE) {      
00317                 rx1 = x2-handsize*0.75f;
00318                 rx2 = x2;
00319                 
00320                 v1[0]= x2-handsize/4; v1[1]= y1+( ((y1+y2)/2.0f - y1)/2);
00321                 v2[0]= x2-handsize/4; v2[1]= y2-( ((y1+y2)/2.0f - y1)/2);
00322                 v3[0]= v2[0] - handsize/4; v3[1]= (y1+y2)/2.0f;
00323                 
00324                 whichsel = SEQ_RIGHTSEL;
00325         }
00326         
00327         /* draw! */
00328         if(seq->type < SEQ_EFFECT || 
00329            get_sequence_effect_num_inputs(seq->type) == 0) {
00330                 glEnable( GL_BLEND );
00331                 
00332                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00333                 
00334                 if(seq->flag & whichsel) glColor4ub(0, 0, 0, 80);
00335                 else if (seq->flag & SELECT) glColor4ub(255, 255, 255, 30);
00336                 else glColor4ub(0, 0, 0, 22);
00337                 
00338                 glRectf(rx1, y1, rx2, y2);
00339                 
00340                 if(seq->flag & whichsel) glColor4ub(255, 255, 255, 200);
00341                 else glColor4ub(0, 0, 0, 50);
00342                 
00343                 glEnable( GL_POLYGON_SMOOTH );
00344                 glBegin(GL_TRIANGLES);
00345                 glVertex2fv(v1); glVertex2fv(v2); glVertex2fv(v3);
00346                 glEnd();
00347                 
00348                 glDisable( GL_POLYGON_SMOOTH );
00349                 glDisable( GL_BLEND );
00350         }
00351         
00352         if(G.moving || (seq->flag & whichsel)) {
00353                 const char col[4]= {255, 255, 255, 255};
00354                 if (direction == SEQ_LEFTHANDLE) {
00355                         sprintf(str, "%d", seq->startdisp);
00356                         x1= rx1;
00357                         y1 -= 0.45f;
00358                 } else {
00359                         sprintf(str, "%d", seq->enddisp - 1);
00360                         x1= x2 - handsize*0.75f;
00361                         y1= y2 + 0.05f;
00362                 }
00363                 UI_view2d_text_cache_add(v2d, x1, y1, str, col);
00364         }       
00365 }
00366 
00367 static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq)
00368 {
00369         float x1, x2, y1, y2, pixely, a;
00370         unsigned char col[3], blendcol[3];
00371         View2D *v2d= &ar->v2d;
00372         
00373         if(seq->type >= SEQ_EFFECT) return;
00374 
00375         x1= seq->startdisp;
00376         x2= seq->enddisp;
00377         
00378         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
00379         y2= seq->machine+SEQ_STRIP_OFSTOP;
00380 
00381         pixely = (v2d->cur.ymax - v2d->cur.ymin)/(v2d->mask.ymax - v2d->mask.ymin);
00382         
00383         if(pixely <= 0) return; /* can happen when the view is split/resized */
00384         
00385         blendcol[0] = blendcol[1] = blendcol[2] = 120;
00386 
00387         if(seq->startofs) {
00388                 glEnable( GL_BLEND );
00389                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00390                 
00391                 get_seq_color3ubv(scene, seq, col);
00392                 
00393                 if (seq->flag & SELECT) {
00394                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
00395                         glColor4ub(col[0], col[1], col[2], 170);
00396                 } else {
00397                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
00398                         glColor4ub(col[0], col[1], col[2], 110);
00399                 }
00400                 
00401                 glRectf((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1);
00402                 
00403                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
00404                 else glColor4ub(col[0], col[1], col[2], 160);
00405 
00406                 fdrawbox((float)(seq->start), y1-SEQ_STRIP_OFSBOTTOM, x1, y1);  //outline
00407                 
00408                 glDisable( GL_BLEND );
00409         }
00410         if(seq->endofs) {
00411                 glEnable( GL_BLEND );
00412                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00413                 
00414                 get_seq_color3ubv(scene, seq, col);
00415                 
00416                 if (seq->flag & SELECT) {
00417                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
00418                         glColor4ub(col[0], col[1], col[2], 170);
00419                 } else {
00420                         UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
00421                         glColor4ub(col[0], col[1], col[2], 110);
00422                 }
00423                 
00424                 glRectf(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM);
00425                 
00426                 if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
00427                 else glColor4ub(col[0], col[1], col[2], 160);
00428 
00429                 fdrawbox(x2, y2, (float)(seq->start+seq->len), y2+SEQ_STRIP_OFSBOTTOM); //outline
00430                 
00431                 glDisable( GL_BLEND );
00432         }
00433         if(seq->startstill) {
00434                 get_seq_color3ubv(scene, seq, col);
00435                 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
00436                 glColor3ubv((GLubyte *)col);
00437                 
00438                 draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
00439                 
00440                 /* feint pinstripes, helps see exactly which is extended and which isn't,
00441                 * especially when the extension is very small */ 
00442                 if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
00443                 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
00444                 
00445                 glColor3ubv((GLubyte *)col);
00446                 
00447                 for(a=y1; a< y2; a+= pixely * 2.0f) {
00448                         fdrawline(x1,  a,  (float)(seq->start),  a);
00449                 }
00450         }
00451         if(seq->endstill) {
00452                 get_seq_color3ubv(scene, seq, col);
00453                 UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
00454                 glColor3ubv((GLubyte *)col);
00455                 
00456                 draw_shadedstrip(seq, col, (float)(seq->start+seq->len), y1, x2, y2);
00457                 
00458                 /* feint pinstripes, helps see exactly which is extended and which isn't,
00459                 * especially when the extension is very small */ 
00460                 if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
00461                 else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -16);
00462                 
00463                 glColor3ubv((GLubyte *)col);
00464                 
00465                 for(a=y1; a< y2; a+= pixely * 2.0f) {
00466                         fdrawline((float)(seq->start+seq->len),  a,  x2,  a);
00467                 }
00468         }
00469 }
00470 
00471 /* draw info text on a sequence strip */
00472 static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, const unsigned char background_col[3])
00473 {
00474         rctf rect;
00475         char str[32 + FILE_MAXDIR+FILE_MAXFILE];
00476         const char *name= seq->name+2;
00477         char col[4];
00478         
00479         if(name[0]=='\0')
00480                 name= give_seqname(seq);
00481 
00482         if(seq->type == SEQ_META || seq->type == SEQ_ADJUSTMENT) {
00483                 sprintf(str, "%d | %s", seq->len, name);
00484         }
00485         else if(seq->type == SEQ_SCENE) {
00486                 if(seq->scene) {
00487                         if(seq->scene_camera) {
00488                                 sprintf(str, "%d | %s: %s (%s)", seq->len, name, seq->scene->id.name+2, ((ID *)seq->scene_camera)->name+2);
00489                         } else {
00490                                 sprintf(str, "%d | %s: %s", seq->len, name, seq->scene->id.name+2);
00491                         }
00492                 }
00493                 else {
00494                         sprintf(str, "%d | %s", seq->len, name);
00495                 }
00496         }
00497         else if(seq->type == SEQ_MULTICAM) {
00498                 sprintf(str, "Cam: %d", seq->multicam_source);
00499         }
00500         else if(seq->type == SEQ_IMAGE) {
00501                 sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
00502         }
00503         else if(seq->type & SEQ_EFFECT) {
00504                 int can_float = (seq->type != SEQ_PLUGIN)
00505                         || (seq->plugin && seq->plugin->version >= 4);
00506 
00507                 if(seq->seq3!=seq->seq2 && seq->seq1!=seq->seq3)
00508                         sprintf(str, "%d | %s: %d>%d (use %d)%s", seq->len, name, seq->seq1->machine, seq->seq2->machine, seq->seq3->machine, can_float ? "" : " No float, upgrade plugin!");
00509                 else if (seq->seq1 && seq->seq2)
00510                         sprintf(str, "%d | %s: %d>%d%s", seq->len, name, seq->seq1->machine, seq->seq2->machine, can_float ? "" : " No float, upgrade plugin!");
00511                 else
00512                         sprintf(str, "%d | %s", seq->len, name);
00513         }
00514         else if (seq->type == SEQ_SOUND) {
00515                 sprintf(str, "%d | %s", seq->len, seq->sound->name);
00516         }
00517         else if (seq->type == SEQ_MOVIE) {
00518                 sprintf(str, "%d | %s%s", seq->len, seq->strip->dir, seq->strip->stripdata->name);
00519         }
00520         
00521         if(seq->flag & SELECT){
00522                 col[0]= col[1]= col[2]= 255;
00523         }else if ((((int)background_col[0] + (int)background_col[1] + (int)background_col[2]) / 3) < 50){
00524                 col[0]= col[1]= col[2]= 80; /* use lighter text color for dark background */
00525         }else{
00526                 col[0]= col[1]= col[2]= 0;
00527         }
00528         col[3]= 255;
00529 
00530         rect.xmin= x1;
00531         rect.ymin= y1;
00532         rect.xmax= x2;
00533         rect.ymax= y2;
00534         UI_view2d_text_cache_rectf(v2d, &rect, str, col);
00535 }
00536 
00537 /* draws a shaded strip, made from gradient + flat color + gradient */
00538 static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2)
00539 {
00540         float ymid1, ymid2;
00541         
00542         if (seq->flag & SEQ_MUTE) {
00543                 glEnable(GL_POLYGON_STIPPLE);
00544                 glPolygonStipple(stipple_halftone);
00545         }
00546         
00547         ymid1 = (y2-y1)*0.25f + y1;
00548         ymid2 = (y2-y1)*0.65f + y1;
00549         
00550         glShadeModel(GL_SMOOTH);
00551         glBegin(GL_QUADS);
00552         
00553         if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; }
00554         else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
00555         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0);
00556         
00557         glColor3ubv(col);
00558         
00559         glVertex2f(x1,y1);
00560         glVertex2f(x2,y1);
00561 
00562         if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; }
00563         else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
00564         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5);
00565 
00566         glColor3ubv((GLubyte *)col);
00567         
00568         glVertex2f(x2,ymid1);
00569         glVertex2f(x1,ymid1);
00570         
00571         glEnd();
00572         
00573         glRectf(x1,  ymid1,  x2,  ymid2);
00574         
00575         glBegin(GL_QUADS);
00576         
00577         glVertex2f(x1,ymid2);
00578         glVertex2f(x2,ymid2);
00579         
00580         if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -15);
00581         else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 25);
00582         
00583         glColor3ubv((GLubyte *)col);
00584         
00585         glVertex2f(x2,y2);
00586         glVertex2f(x1,y2);
00587         
00588         glEnd();
00589         
00590         if (seq->flag & SEQ_MUTE) {
00591                 glDisable(GL_POLYGON_STIPPLE);
00592         }
00593 }
00594 
00595 /*
00596 Draw a sequence strip, bounds check already made
00597 ARegion is currently only used to get the windows width in pixels
00598 so wave file sample drawing precision is zoom adjusted
00599 */
00600 static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx)
00601 {
00602         View2D *v2d= &ar->v2d;
00603         float x1, x2, y1, y2;
00604         unsigned char col[3], background_col[3], is_single_image;
00605 
00606         /* we need to know if this is a single image/color or not for drawing */
00607         is_single_image = (char)seq_single_check(seq);
00608         
00609         /* body */
00610         if(seq->startstill) x1= seq->start;
00611         else x1= seq->startdisp;
00612         y1= seq->machine+SEQ_STRIP_OFSBOTTOM;
00613         if(seq->endstill) x2= seq->start+seq->len;
00614         else x2= seq->enddisp;
00615         y2= seq->machine+SEQ_STRIP_OFSTOP;
00616         
00617         
00618         /* get the correct color per strip type*/
00619         //get_seq_color3ubv(scene, seq, col);
00620         get_seq_color3ubv(scene, seq, background_col);
00621         
00622         /* draw the main strip body */
00623         if (is_single_image) /* single image */
00624                 draw_shadedstrip(seq, background_col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2);
00625         else /* normal operation */
00626                 draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
00627         
00628         /* draw additional info and controls */
00629         if (!is_single_image)
00630                 draw_seq_extensions(scene, ar, seq);
00631         
00632         draw_seq_handle(v2d, seq, pixelx, SEQ_LEFTHANDLE);
00633         draw_seq_handle(v2d, seq, pixelx, SEQ_RIGHTHANDLE);
00634         
00635         /* draw the strip outline */
00636         x1= seq->startdisp;
00637         x2= seq->enddisp;
00638         
00639         /* draw sound wave */
00640         if(seq->type == SEQ_SOUND) drawseqwave(scene, seq, x1, y1, x2, y2, (ar->v2d.cur.xmax - ar->v2d.cur.xmin)/ar->winx);
00641 
00642         /* draw lock */
00643         if(seq->flag & SEQ_LOCK) {
00644                 glEnable(GL_POLYGON_STIPPLE);
00645                 glEnable(GL_BLEND);
00646 
00647                 /* light stripes */
00648                 glColor4ub(255, 255, 255, 32);
00649                 glPolygonStipple(stipple_diag_stripes_pos);
00650                 glRectf(x1, y1, x2, y2);
00651 
00652                 /* dark stripes */
00653                 glColor4ub(0, 0, 0, 32);
00654                 glPolygonStipple(stipple_diag_stripes_neg);
00655                 glRectf(x1, y1, x2, y2);
00656 
00657                 glDisable(GL_POLYGON_STIPPLE);
00658                 glDisable(GL_BLEND);
00659         }
00660 
00661         get_seq_color3ubv(scene, seq, col);
00662         if (G.moving && (seq->flag & SELECT)) {
00663                 if(seq->flag & SEQ_OVERLAP) {
00664                         col[0]= 255; col[1]= col[2]= 40;
00665                 }
00666                 else
00667                         UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120+outline_tint);
00668         }
00669         else
00670                 UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, outline_tint);
00671         
00672         glColor3ubv((GLubyte *)col);
00673         
00674         if (seq->flag & SEQ_MUTE) {
00675                 glEnable(GL_LINE_STIPPLE);
00676                 glLineStipple(1, 0x8888);
00677         }
00678         
00679         uiDrawBoxShade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
00680         
00681         if (seq->flag & SEQ_MUTE) {
00682                 glDisable(GL_LINE_STIPPLE);
00683         }
00684         
00685         if(seq->type==SEQ_META) drawmeta_contents(scene, seq, x1, y1, x2, y2);
00686         
00687         /* calculate if seq is long enough to print a name */
00688         x1= seq->startdisp+seq->handsize;
00689         x2= seq->enddisp-seq->handsize;
00690 
00691         /* info text on the strip */
00692         if(x1<v2d->cur.xmin) x1= v2d->cur.xmin;
00693         else if(x1>v2d->cur.xmax) x1= v2d->cur.xmax;
00694         if(x2<v2d->cur.xmin) x2= v2d->cur.xmin;
00695         else if(x2>v2d->cur.xmax) x2= v2d->cur.xmax;
00696 
00697         /* nice text here would require changing the view matrix for texture text */
00698         if( (x2-x1) / pixelx > 32) {
00699                 draw_seq_text(v2d, seq, x1, x2, y1, y2, background_col);
00700         }
00701 }
00702 
00703 static Sequence *special_seq_update= 0;
00704 
00705 static void set_special_seq_update(int val)
00706 {
00707 //      int x;
00708 
00709         /* if mouse over a sequence && LEFTMOUSE */
00710         if(val) {
00711 // XXX          special_seq_update= find_nearest_seq(&x);
00712         }
00713         else special_seq_update= 0;
00714 }
00715 
00716 void draw_image_seq(const bContext* C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs)
00717 {
00718         struct Main *bmain= CTX_data_main(C);
00719         struct ImBuf *ibuf = 0;
00720         struct ImBuf *scope = 0;
00721         struct View2D *v2d = &ar->v2d;
00722         int rectx, recty;
00723         float viewrectx, viewrecty;
00724         float render_size = 0.0;
00725         float proxy_size = 100.0;
00726         GLuint texid;
00727         GLuint last_texid;
00728         SeqRenderData context;
00729 
00730         render_size = sseq->render_size;
00731         if (render_size == 0) {
00732                 render_size = scene->r.size;
00733         } else {
00734                 proxy_size = render_size;
00735         }
00736         if (render_size < 0) {
00737                 return;
00738         }
00739 
00740         viewrectx = (render_size*(float)scene->r.xsch)/100.0f;
00741         viewrecty = (render_size*(float)scene->r.ysch)/100.0f;
00742 
00743         rectx = viewrectx + 0.5f;
00744         recty = viewrecty + 0.5f;
00745 
00746         if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
00747                 viewrectx *= scene->r.xasp / scene->r.yasp;
00748                 viewrectx /= proxy_size / 100.0f;
00749                 viewrecty /= proxy_size / 100.0f;
00750         }
00751 
00752         if(frame_ofs == 0) {
00753                 /* XXX TODO: take color from theme */
00754                 glClearColor(0.0, 0.0, 0.0, 0.0);
00755                 glClear(GL_COLOR_BUFFER_BIT);
00756         }
00757 
00758         /* without this colors can flicker from previous opengl state */
00759         glColor4ub(255, 255, 255, 255);
00760 
00761         UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f);
00762         UI_view2d_curRect_validate(v2d);
00763 
00764         /* only initialize the preview if a render is in progress */
00765         if(G.rendering)
00766                 return;
00767 
00768         context = seq_new_render_data(bmain, scene, rectx, recty, proxy_size);
00769 
00770         if (special_seq_update)
00771                 ibuf= give_ibuf_seq_direct(context, cfra + frame_ofs, special_seq_update);
00772         else if (!U.prefetchframes) // XXX || (G.f & G_PLAYANIM) == 0) {
00773                 ibuf= (ImBuf *)give_ibuf_seq(context, cfra + frame_ofs, sseq->chanshown);
00774         else
00775                 ibuf= (ImBuf *)give_ibuf_seq_threaded(context, cfra + frame_ofs, sseq->chanshown);
00776         
00777         if(ibuf==NULL) 
00778                 return;
00779 
00780         if(ibuf->rect==NULL && ibuf->rect_float == NULL) 
00781                 return;
00782         
00783         switch(sseq->mainb) {
00784         case SEQ_DRAW_IMG_IMBUF:
00785                 if (sseq->zebra != 0) {
00786                         scope = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
00787                 }
00788                 break;
00789         case SEQ_DRAW_IMG_WAVEFORM:
00790                 if ((sseq->flag & SEQ_DRAW_COLOR_SEPERATED) != 0) {
00791                         scope = make_sep_waveform_view_from_ibuf(ibuf);
00792                 } else {
00793                         scope = make_waveform_view_from_ibuf(ibuf);
00794                 }
00795                 break;
00796         case SEQ_DRAW_IMG_VECTORSCOPE:
00797                 scope = make_vectorscope_view_from_ibuf(ibuf);
00798                 break;
00799         case SEQ_DRAW_IMG_HISTOGRAM:
00800                 scope = make_histogram_view_from_ibuf(ibuf);
00801                 break;
00802         }
00803 
00804         if (scope) {
00805                 IMB_freeImBuf(ibuf);
00806                 ibuf = scope;
00807         }
00808 
00809         if(ibuf->rect_float && ibuf->rect==NULL) {
00810                 IMB_rect_from_float(ibuf);      
00811         }
00812         
00813         /* setting up the view - actual drawing starts here */
00814         UI_view2d_view_ortho(v2d);
00815 
00816         last_texid= glaGetOneInteger(GL_TEXTURE_2D);
00817         glEnable(GL_TEXTURE_2D);
00818         glGenTextures(1, (GLuint *)&texid);
00819 
00820         glBindTexture(GL_TEXTURE_2D, texid);
00821 
00822         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00823         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00824 
00825         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
00826         glBegin(GL_QUADS);
00827 
00828         if(frame_ofs) {
00829                 rctf tot_clip;
00830                 tot_clip.xmin= v2d->tot.xmin + (ABS(v2d->tot.xmax - v2d->tot.xmin) * scene->ed->over_border.xmin);
00831                 tot_clip.ymin= v2d->tot.ymin + (ABS(v2d->tot.ymax - v2d->tot.ymin) * scene->ed->over_border.ymin);
00832                 tot_clip.xmax= v2d->tot.xmin + (ABS(v2d->tot.xmax - v2d->tot.xmin) * scene->ed->over_border.xmax);
00833                 tot_clip.ymax= v2d->tot.ymin + (ABS(v2d->tot.ymax - v2d->tot.ymin) * scene->ed->over_border.ymax);
00834 
00835                 glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymin);glVertex2f(tot_clip.xmin, tot_clip.ymin);
00836                 glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymax);glVertex2f(tot_clip.xmin, tot_clip.ymax);
00837                 glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymax);glVertex2f(tot_clip.xmax, tot_clip.ymax);
00838                 glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymin);glVertex2f(tot_clip.xmax, tot_clip.ymin);
00839         }
00840         else {
00841                 glTexCoord2f(0.0f, 0.0f);glVertex2f(v2d->tot.xmin, v2d->tot.ymin);
00842                 glTexCoord2f(0.0f, 1.0f);glVertex2f(v2d->tot.xmin, v2d->tot.ymax);
00843                 glTexCoord2f(1.0f, 1.0f);glVertex2f(v2d->tot.xmax, v2d->tot.ymax);
00844                 glTexCoord2f(1.0f, 0.0f);glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
00845         }
00846         glEnd( );
00847         glBindTexture(GL_TEXTURE_2D, last_texid);
00848         glDisable(GL_TEXTURE_2D);
00849         glDeleteTextures(1, &texid);
00850 
00851         if(sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
00852 
00853                 float x1 = v2d->tot.xmin;
00854                 float y1 = v2d->tot.ymin;
00855                 float x2 = v2d->tot.xmax;
00856                 float y2 = v2d->tot.ymax;
00857 
00858                 /* border */
00859                 setlinestyle(3);
00860 
00861                 UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
00862 
00863                 glBegin(GL_LINE_LOOP);
00864                 glVertex2f(x1-0.5f, y1-0.5f);
00865                 glVertex2f(x1-0.5f, y2+0.5f);
00866                 glVertex2f(x2+0.5f, y2+0.5f);
00867                 glVertex2f(x2+0.5f, y1-0.5f);
00868                 glEnd();
00869 
00870                 /* safety border */
00871                 if ((sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
00872                         float fac= 0.1;
00873 
00874                         float a= fac*(x2-x1);
00875                         x1+= a;
00876                         x2-= a;
00877 
00878                         a= fac*(y2-y1);
00879                         y1+= a;
00880                         y2-= a;
00881 
00882                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00883 
00884                         uiSetRoundBox(15);
00885                         uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
00886 
00887                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00888 
00889                 }
00890 
00891                 setlinestyle(0);
00892         }
00893         
00894         /* draw grease-pencil (image aligned) */
00895 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
00896 // XXX          draw_gpencil_2dimage(sa, ibuf);
00897 
00898         IMB_freeImBuf(ibuf);
00899         
00900         /* draw grease-pencil (screen aligned) */
00901 //      if (sseq->flag & SEQ_DRAW_GPENCIL)
00902 // XXX          draw_gpencil_view2d(sa, 0);
00903         
00904         /* ortho at pixel level */
00905         UI_view2d_view_restore(C);
00906 }
00907 
00908 #if 0
00909 void drawprefetchseqspace(Scene *scene, ARegion *UNUSED(ar), SpaceSeq *sseq)
00910 {
00911         int rectx, recty;
00912         int render_size = sseq->render_size;
00913         int proxy_size = 100.0; 
00914         if (render_size == 0) {
00915                 render_size = scene->r.size;
00916         } else {
00917                 proxy_size = render_size;
00918         }
00919         if (render_size < 0) {
00920                 return;
00921         }
00922 
00923         rectx= (render_size*scene->r.xsch)/100;
00924         recty= (render_size*scene->r.ysch)/100;
00925 
00926         if(sseq->mainb != SEQ_DRAW_SEQUENCE) {
00927                 give_ibuf_prefetch_request(
00928                         rectx, recty, (scene->r.cfra), sseq->chanshown,
00929                         proxy_size);
00930         }
00931 }
00932 #endif
00933 
00934 /* draw backdrop of the sequencer strips view */
00935 static void draw_seq_backdrop(View2D *v2d)
00936 {
00937         int i;
00938         
00939         /* darker grey overlay over the view backdrop */
00940         UI_ThemeColorShade(TH_BACK, -20);
00941         glRectf(v2d->cur.xmin,  -1.0,  v2d->cur.xmax,  1.0);
00942 
00943         /* Alternating horizontal stripes */
00944         i= MAX2(1, ((int)v2d->cur.ymin)-1);
00945 
00946         glBegin(GL_QUADS);
00947                 while (i<v2d->cur.ymax) {
00948                         if (((int)i) & 1)
00949                                 UI_ThemeColorShade(TH_BACK, -15);
00950                         else
00951                                 UI_ThemeColorShade(TH_BACK, -25);
00952                         
00953                         glVertex2f(v2d->cur.xmax, i);
00954                         glVertex2f(v2d->cur.xmin, i);
00955                         glVertex2f(v2d->cur.xmin, i+1);
00956                         glVertex2f(v2d->cur.xmax, i+1);
00957                         
00958                         i+=1.0;
00959                 }
00960         glEnd();
00961         
00962         /* Darker lines separating the horizontal bands */
00963         i= MAX2(1, ((int)v2d->cur.ymin)-1);
00964         UI_ThemeColor(TH_GRID);
00965         
00966         glBegin(GL_LINES);
00967                 while (i < v2d->cur.ymax) {
00968                         glVertex2f(v2d->cur.xmax, i);
00969                         glVertex2f(v2d->cur.xmin, i);
00970                         
00971                         i+=1.0;
00972                 }
00973         glEnd();
00974 }
00975 
00976 /* draw the contents of the sequencer strips view */
00977 static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
00978 {
00979         Scene *scene= CTX_data_scene(C);
00980         View2D *v2d= &ar->v2d;
00981         Sequence *last_seq = seq_active_get(scene);
00982         int sel = 0, j;
00983         float pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
00984         
00985         /* loop through twice, first unselected, then selected */
00986         for (j=0; j<2; j++) {
00987                 Sequence *seq;
00988                 int outline_tint= (j) ? -60 : -150; /* highlighting around strip edges indicating selection */
00989                 
00990                 /* loop through strips, checking for those that are visible */
00991                 for (seq= ed->seqbasep->first; seq; seq= seq->next) {
00992                         /* boundbox and selection tests for NOT drawing the strip... */
00993                         if ((seq->flag & SELECT) != sel) continue;
00994                         else if (seq == last_seq) continue;
00995                         else if (MIN2(seq->startdisp, seq->start) > v2d->cur.xmax) continue;
00996                         else if (MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin) continue;
00997                         else if (seq->machine+1.0f < v2d->cur.ymin) continue;
00998                         else if (seq->machine > v2d->cur.ymax) continue;
00999                         
01000                         /* strip passed all tests unscathed... so draw it now */
01001                         draw_seq_strip(scene, ar, seq, outline_tint, pixelx);
01002                 }
01003                 
01004                 /* draw selected next time round */
01005                 sel= SELECT; 
01006         }
01007         
01008         /* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */
01009         if (last_seq)
01010                 draw_seq_strip(scene, ar, last_seq, 120, pixelx);
01011 }
01012 
01013 static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
01014 {       
01015         glEnable(GL_BLEND);
01016         
01017         /* draw darkened area outside of active timeline 
01018          * frame range used is preview range or scene range */
01019         UI_ThemeColorShadeAlpha(TH_BACK, -25, -100);
01020 
01021         if (PSFRA < PEFRA) {
01022                 glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
01023                 glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
01024         }
01025         else {
01026                 glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
01027         }
01028 
01029         UI_ThemeColorShade(TH_BACK, -60);
01030         /* thin lines where the actual frames are */
01031         fdrawline((float)PSFRA, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
01032         fdrawline((float)PEFRA, v2d->cur.ymin, (float)PEFRA, v2d->cur.ymax);
01033         
01034         glDisable(GL_BLEND);
01035 }
01036 
01037 /* Draw Timeline/Strip Editor Mode for Sequencer */
01038 void draw_timeline_seq(const bContext *C, ARegion *ar)
01039 {
01040         Scene *scene= CTX_data_scene(C);
01041         Editing *ed= seq_give_editing(scene, FALSE);
01042         SpaceSeq *sseq= CTX_wm_space_seq(C);
01043         View2D *v2d= &ar->v2d;
01044         View2DScrollers *scrollers;
01045         float col[3];
01046         int flag=0;
01047         
01048         /* clear and setup matrix */
01049         UI_GetThemeColor3fv(TH_BACK, col);
01050         if (ed && ed->metastack.first) 
01051                 glClearColor(col[0], col[1], col[2]-0.1f, 0.0f);
01052         else 
01053                 glClearColor(col[0], col[1], col[2], 0.0f);
01054         glClear(GL_COLOR_BUFFER_BIT);
01055 
01056         UI_view2d_view_ortho(v2d);
01057         
01058         
01059         /* calculate extents of sequencer strips/data 
01060          * NOTE: needed for the scrollers later
01061          */
01062         boundbox_seq(scene, &v2d->tot);
01063         
01064         
01065         /* draw backdrop */
01066         draw_seq_backdrop(v2d);
01067         
01068         /* regular grid-pattern over the rest of the view (i.e. frame grid lines) */
01069         UI_view2d_constant_grid_draw(v2d);
01070 
01071         seq_draw_sfra_efra(scene, v2d); 
01072 
01073         /* sequence strips (if there is data available to be drawn) */
01074         if (ed) {
01075                 /* draw the data */
01076                 draw_seq_strips(C, ed, ar);
01077                 
01078                 /* text draw cached (for sequence names), in pixelspace now */
01079                 UI_view2d_text_cache_draw(ar);
01080         }
01081         
01082         /* current frame */
01083         UI_view2d_view_ortho(v2d);
01084         if ((sseq->flag & SEQ_DRAWFRAMES)==0)   flag |= DRAWCFRA_UNIT_SECONDS;
01085         if ((sseq->flag & SEQ_NO_DRAW_CFRANUM)==0)  flag |= DRAWCFRA_SHOW_NUMBOX;
01086         ANIM_draw_cfra(C, v2d, flag);
01087         
01088         /* markers */
01089         UI_view2d_view_orthoSpecial(ar, v2d, 1);
01090         draw_markers_time(C, DRAW_MARKERS_LINES);
01091         
01092         /* preview range */
01093         UI_view2d_view_ortho(v2d);
01094         ANIM_draw_previewrange(C, v2d);
01095 
01096         /* overlap playhead */
01097         if(scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
01098                 int cfra_over= (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ? scene->ed->over_cfra : scene->r.cfra + scene->ed->over_ofs;
01099                 glColor3f(0.2, 0.2, 0.2);
01100                 // glRectf(cfra_over, v2d->cur.ymin, scene->ed->over_ofs + scene->r.cfra + 1, v2d->cur.ymax);
01101 
01102                 glBegin(GL_LINES);
01103                         glVertex2f(cfra_over, v2d->cur.ymin);
01104                         glVertex2f(cfra_over, v2d->cur.ymax);
01105                 glEnd();
01106 
01107         }
01108         
01109         /* reset view matrix */
01110         UI_view2d_view_restore(C);
01111 
01112         /* scrollers */
01113         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_SECONDSSEQ, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
01114         UI_view2d_scrollers_draw(C, v2d, scrollers);
01115         UI_view2d_scrollers_free(scrollers);
01116 }
01117 
01118