diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2014-11-24 20:18:35 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2014-11-24 20:23:44 +0300 |
commit | 649a2bcc3d51cfc6f9fc237695015c87bcca7deb (patch) | |
tree | 4bea67033363027c40c3e78b2782d7df00e39558 /source/blender/editors/space_sequencer | |
parent | aa0b268acbf352bdf69644bb11ee3b893008cc40 (diff) |
Politically correct terrible consequencer changes
This patch includes the work done in the terrible consequencer branch
that hasn't been merged to master minus a few controversial and WIP
stuff, like strip parenting, new sequence data structs and cuddly
widgets.
What is included:
* Strip extensions only when slipping. It can very easily be made an
option but with a few strips with overlapping durations it makes view
too crowded and difficult to make out.
* Threaded waveform loading + code that restores waveforms on undo (not
used though, since sound_load recreates everything. There's a patch for
review D876)
* Toggle to enable backdrop in the strip sequence editor
* Toggle to easily turn on/off waveform display
* Snapping during transform on sequence boundaries. Snapping to start or
end of selection depends on position of mouse when invoking the operator
* Snapping of timeline indicator in sequencer to strip boundaries. To
use just press and hold ctrl while dragging.
Reviewers: campbellbarton
Differential Revision: https://developer.blender.org/D904
Diffstat (limited to 'source/blender/editors/space_sequencer')
7 files changed, 430 insertions, 237 deletions
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt index 4cf9c0c95c2..d9aff2781f0 100644 --- a/source/blender/editors/space_sequencer/CMakeLists.txt +++ b/source/blender/editors/space_sequencer/CMakeLists.txt @@ -43,6 +43,7 @@ set(SRC sequencer_edit.c sequencer_modifier.c sequencer_ops.c + sequencer_preview.c sequencer_scopes.c sequencer_select.c sequencer_view.c diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index fa82704c36f..1235ba8a421 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -34,6 +34,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_threads.h" #include "IMB_imbuf_types.h" @@ -62,6 +63,7 @@ #include "ED_mask.h" #include "ED_sequencer.h" #include "ED_space_api.h" +#include "ED_screen.h" #include "UI_interface.h" #include "UI_resources.h" @@ -69,6 +71,8 @@ #include "WM_api.h" +#include "MEM_guardedalloc.h" + /* own include */ #include "sequencer_intern.h" @@ -86,9 +90,7 @@ #undef SEQP_BEGIN #undef SEQ_END -static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2); - -static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[3]) +void color3ubv_from_seq(Scene *curscene, Sequence *seq, unsigned char col[3]) { unsigned char blendcol[3]; SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; @@ -179,14 +181,14 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ } } -static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize) +static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize) { /* * x1 is the starting x value to draw the wave, * x2 the end x value, same for y1 and y2 * stepsize is width of a pixel. */ - if (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM) { + if ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM)) { int i, j, pos; int length = floor((x2 - x1) / stepsize) + 1; float ymid = (y1 + y2) / 2; @@ -194,20 +196,30 @@ static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x float samplestep; float startsample, endsample; float value; - + bSound *sound = seq->sound; + SoundWaveform *waveform; - - if (!seq->sound->waveform) - sound_read_waveform(seq->sound); - - if (!seq->sound->waveform) - return; /* zero length sound */ - + + if (!sound->mutex) + sound->mutex = BLI_mutex_alloc(); + + BLI_mutex_lock(sound->mutex); + if (!seq->sound->waveform) { + if(!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) { + /* prevent sounds from reloading */ + seq->sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING; + BLI_mutex_unlock(sound->mutex); + sequencer_preview_add_sound(C, seq); + } + else { + BLI_mutex_unlock(sound->mutex); + } + return; /* nothing to draw */ + } + BLI_mutex_unlock(sound->mutex); + waveform = seq->sound->waveform; - - if (!waveform) - return; - + startsample = floor((seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND); endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND); samplestep = (endsample - startsample) * stepsize / (x2 - x1); @@ -303,7 +315,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE)) drawmeta_stipple(1); - get_seq_color3ubv(scene, seq, col); + color3ubv_from_seq(scene, seq, col); glColor4ubv(col); @@ -422,112 +434,6 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla } } -static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq) -{ - float x1, x2, y1, y2, pixely, a; - unsigned char col[3], blendcol[3]; - View2D *v2d = &ar->v2d; - - if (seq->type >= SEQ_TYPE_EFFECT) return; - - x1 = seq->startdisp; - x2 = seq->enddisp; - - y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; - y2 = seq->machine + SEQ_STRIP_OFSTOP; - - pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); - - if (pixely <= 0) return; /* can happen when the view is split/resized */ - - blendcol[0] = blendcol[1] = blendcol[2] = 120; - - if (seq->startofs) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - get_seq_color3ubv(scene, seq, col); - - if (seq->flag & SELECT) { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); - glColor4ub(col[0], col[1], col[2], 170); - } - else { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); - glColor4ub(col[0], col[1], col[2], 110); - } - - glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); - - if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); - else glColor4ub(col[0], col[1], col[2], 160); - - fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline - - glDisable(GL_BLEND); - } - if (seq->endofs) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - get_seq_color3ubv(scene, seq, col); - - if (seq->flag & SELECT) { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); - glColor4ub(col[0], col[1], col[2], 170); - } - else { - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); - glColor4ub(col[0], col[1], col[2], 110); - } - - glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); - - if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); - else glColor4ub(col[0], col[1], col[2], 160); - - fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline - - glDisable(GL_BLEND); - } - if (seq->startstill) { - get_seq_color3ubv(scene, seq, col); - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); - glColor3ubv((GLubyte *)col); - - draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2); - - /* feint pinstripes, helps see exactly which is extended and which isn't, - * especially when the extension is very small */ - if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24); - else UI_GetColorPtrShade3ubv(col, col, -16); - - glColor3ubv((GLubyte *)col); - - for (a = y1; a < y2; a += pixely * 2.0f) { - fdrawline(x1, a, (float)(seq->start), a); - } - } - if (seq->endstill) { - get_seq_color3ubv(scene, seq, col); - UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); - glColor3ubv((GLubyte *)col); - - draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2); - - /* feint pinstripes, helps see exactly which is extended and which isn't, - * especially when the extension is very small */ - if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24); - else UI_GetColorPtrShade3ubv(col, col, -16); - - glColor3ubv((GLubyte *)col); - - for (a = y1; a < y2; a += pixely * 2.0f) { - fdrawline((float)(seq->start + seq->len), a, x2, a); - } - } -} - /* draw info text on a sequence strip */ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, const unsigned char background_col[3]) { @@ -634,7 +540,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float } /* draws a shaded strip, made from gradient + flat color + gradient */ -static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2) +void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2) { float ymid1, ymid2; @@ -696,7 +602,7 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa * ARegion is currently only used to get the windows width in pixels * so wave file sample drawing precision is zoom adjusted */ -static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx) +static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx) { View2D *v2d = &ar->v2d; float x1, x2, y1, y2; @@ -714,8 +620,8 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline /* get the correct color per strip type*/ - //get_seq_color3ubv(scene, seq, col); - get_seq_color3ubv(scene, seq, background_col); + //color3ubv_from_seq(scene, seq, col); + color3ubv_from_seq(scene, seq, background_col); /* draw the main strip body */ if (is_single_image) { /* single image */ @@ -727,10 +633,6 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline draw_shadedstrip(seq, background_col, x1, y1, x2, y2); } - /* draw additional info and controls */ - if (!is_single_image) - draw_seq_extensions(scene, ar, seq); - draw_seq_handle(v2d, seq, handsize_clamped, SEQ_LEFTHANDLE); draw_seq_handle(v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE); @@ -740,7 +642,9 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline /* draw sound wave */ if (seq->type == SEQ_TYPE_SOUND_RAM) { - drawseqwave(scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx); + if(!(sseq->flag & SEQ_NO_WAVEFORMS)) { + drawseqwave(C, sseq, scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx); + } } /* draw lock */ @@ -773,7 +677,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glDisable(GL_POLYGON_STIPPLE); } - get_seq_color3ubv(scene, seq, col); + color3ubv_from_seq(scene, seq, col); if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT)) { if (seq->flag & SEQ_OVERLAP) { col[0] = 255; col[1] = col[2] = 40; @@ -924,7 +828,7 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop return scope; } -void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay) +void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_backdrop) { struct Main *bmain = CTX_data_main(C); struct ImBuf *ibuf = NULL; @@ -980,7 +884,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq viewrecty /= proxy_size / 100.0f; } - if (!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) { + if ((!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) && !draw_backdrop) { UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col); glClearColor(col[0], col[1], col[2], 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -1055,23 +959,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* without this colors can flicker from previous opengl state */ glColor4ub(255, 255, 255, 255); - UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f); - UI_view2d_curRect_validate(v2d); - - /* setting up the view - actual drawing starts here */ - UI_view2d_view_ortho(v2d); - - /* only draw alpha for main buffer */ - if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - if (sseq->flag & SEQ_USE_ALPHA) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); - glColor4f(1.0, 1.0, 1.0, 1.0); + if (!draw_backdrop) { + UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f); + UI_view2d_curRect_validate(v2d); + + /* setting up the view - actual drawing starts here */ + UI_view2d_view_ortho(v2d); + + /* only draw alpha for main buffer */ + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + if (sseq->flag & SEQ_USE_ALPHA) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); + glColor4f(1.0, 1.0, 1.0, 1.0); + } } } - + if (scope) { IMB_freeImBuf(ibuf); ibuf = scope; @@ -1161,6 +1067,14 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer); + if (draw_backdrop) { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + } glBegin(GL_QUADS); if (draw_overlay) { @@ -1183,6 +1097,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin); } } + else if (draw_backdrop) { + float aspect = BLI_rcti_size_x(&ar->winrct) / (float)BLI_rcti_size_y(&ar->winrct); + float image_aspect = viewrectx/viewrecty; + float imagex, imagey; + + if (aspect >= image_aspect) { + imagex = image_aspect/aspect; + imagey = 1.0f; + } + else { + imagex = 1.0f; + imagey = aspect/image_aspect; + } + + glTexCoord2f(0.0f, 0.0f); glVertex2f(-imagex, -imagey); + glTexCoord2f(0.0f, 1.0f); glVertex2f(-imagex, imagey); + glTexCoord2f(1.0f, 1.0f); glVertex2f(imagex, imagey); + glTexCoord2f(1.0f, 0.0f); glVertex2f(imagex, -imagey); + } else { glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin); glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax); @@ -1190,6 +1123,15 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin); } glEnd(); + + if (draw_backdrop) { + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + } + glBindTexture(GL_TEXTURE_2D, last_texid); glDisable(GL_TEXTURE_2D); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) @@ -1199,6 +1141,16 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq if (glsl_used) IMB_colormanagement_finish_glsl_draw(); + if (cache_handle) + IMB_display_buffer_release(cache_handle); + + if (!scope) + IMB_freeImBuf(ibuf); + + if (draw_backdrop) { + return; + } + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { float x1 = v2d->tot.xmin; @@ -1248,9 +1200,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq ED_gpencil_draw_2dimage(C); } } - - if (!scope) - IMB_freeImBuf(ibuf); /* ortho at pixel level */ UI_view2d_view_restore(C); @@ -1287,9 +1236,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq NULL, C); } } - - if (cache_handle) - IMB_display_buffer_release(cache_handle); } #if 0 @@ -1366,6 +1312,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) { Scene *scene = CTX_data_scene(C); View2D *v2d = &ar->v2d; + SpaceSeq *sseq = CTX_wm_space_seq(C); Sequence *last_seq = BKE_sequencer_active_get(scene); int sel = 0, j; float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); @@ -1386,7 +1333,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) else if (seq->machine > v2d->cur.ymax) continue; /* strip passed all tests unscathed... so draw it now */ - draw_seq_strip(scene, ar, seq, outline_tint, pixelx); + draw_seq_strip(C, sseq, scene, ar, seq, outline_tint, pixelx); } /* draw selected next time round */ @@ -1395,7 +1342,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) /* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */ if (last_seq) - draw_seq_strip(scene, ar, last_seq, 120, pixelx); + draw_seq_strip(C, sseq, scene, ar, last_seq, 120, pixelx); } static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) @@ -1473,6 +1420,12 @@ void draw_timeline_seq(const bContext *C, ARegion *ar) // NOTE: the gridlines are currently spaced every 25 frames, which is only fine for 25 fps, but maybe not for 30... UI_view2d_constant_grid_draw(v2d); + if (sseq->draw_flag & SEQ_DRAW_BACKDROP) { + draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, true); + UI_SetTheme(SPACE_SEQ, RGN_TYPE_WINDOW); + UI_view2d_view_ortho(v2d); + } + ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); seq_draw_sfra_efra(scene, v2d); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index b9e1fb9c02a..2525b5d13e2 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -62,8 +62,13 @@ #include "ED_screen.h" #include "ED_transform.h" #include "ED_sequencer.h" +#include "ED_space_api.h" #include "UI_view2d.h" +#include "UI_resources.h" + +#include "GL/glew.h" +#include "BIF_glutil.h" /* own include */ #include "sequencer_intern.h" @@ -1231,7 +1236,6 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot) RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX); } - typedef struct SlipData { int init_mouse[2]; float init_mouseloc[2]; @@ -1241,6 +1245,7 @@ typedef struct SlipData { int num_seq; bool slow; int slow_offset; /* offset at the point where offset was turned on */ + void *draw_handle; } SlipData; static void transseq_backup(TransSeq *ts, Sequence *seq) @@ -1274,15 +1279,129 @@ static void transseq_restore(TransSeq *ts, Sequence *seq) seq->len = ts->len; } -static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool first_level) +static void draw_slip_extensions(const bContext *C, ARegion *ar, void *data) +{ + Scene *scene = CTX_data_scene(C); + float x1, x2, y1, y2, pixely, a; + unsigned char col[3], blendcol[3]; + View2D *v2d = &ar->v2d; + SlipData *td = data; + int i; + + for (i = 0; i < td->num_seq; i++) { + Sequence *seq = td->seq_array[i]; + + if ((seq->type != SEQ_TYPE_META) && td->trim[i]) { + + x1 = seq->startdisp; + x2 = seq->enddisp; + + y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; + y2 = seq->machine + SEQ_STRIP_OFSTOP; + + pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); + + if (pixely <= 0) return; /* can happen when the view is split/resized */ + + blendcol[0] = blendcol[1] = blendcol[2] = 120; + + if (seq->startofs) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + color3ubv_from_seq(scene, seq, col); + + if (seq->flag & SELECT) { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); + glColor4ub(col[0], col[1], col[2], 170); + } + else { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); + glColor4ub(col[0], col[1], col[2], 110); + } + + glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); + + if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); + else glColor4ub(col[0], col[1], col[2], 160); + + fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline + + glDisable(GL_BLEND); + } + if (seq->endofs) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + color3ubv_from_seq(scene, seq, col); + + if (seq->flag & SELECT) { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40); + glColor4ub(col[0], col[1], col[2], 170); + } + else { + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0); + glColor4ub(col[0], col[1], col[2], 110); + } + + glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); + + if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255); + else glColor4ub(col[0], col[1], col[2], 160); + + fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline + + glDisable(GL_BLEND); + } + if (seq->startstill) { + color3ubv_from_seq(scene, seq, col); + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); + glColor3ubv((GLubyte *)col); + + draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2); + + /* feint pinstripes, helps see exactly which is extended and which isn't, + * especially when the extension is very small */ + if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24); + else UI_GetColorPtrShade3ubv(col, col, -16); + + glColor3ubv((GLubyte *)col); + + for (a = y1; a < y2; a += pixely * 2.0f) { + fdrawline(x1, a, (float)(seq->start), a); + } + } + if (seq->endstill) { + color3ubv_from_seq(scene, seq, col); + UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40); + glColor3ubv((GLubyte *)col); + + draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2); + + /* feint pinstripes, helps see exactly which is extended and which isn't, + * especially when the extension is very small */ + if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24); + else UI_GetColorPtrShade3ubv(col, col, -16); + + glColor3ubv((GLubyte *)col); + + for (a = y1; a < y2; a += pixely * 2.0f) { + fdrawline((float)(seq->start + seq->len), a, x2, a); + } + } + } + } +} + +static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim) { Sequence *seq; int num_items = 0; for (seq = seqbasep->first; seq; seq = seq->next) { - if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { + if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { seq_array[offset + num_items] = seq; - trim[offset + num_items] = first_level; + trim[offset + num_items] = do_trim; num_items++; if (seq->type == SEQ_TYPE_META) { @@ -1322,6 +1441,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve SlipData *data; Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, false); + ARegion *ar = CTX_wm_region(C); float mouseloc[2]; int num_seq, i; View2D *v2d = UI_view2d_fromcontext(C); @@ -1344,6 +1464,8 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve transseq_backup(data->ts + i, data->seq_array[i]); } + data->draw_handle = ED_region_draw_cb_activate(ar->type, draw_slip_extensions, data, REGION_DRAW_POST_VIEW); + UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]); copy_v2_v2_int(data->init_mouse, event->mval); @@ -1353,6 +1475,9 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve WM_event_add_modal_handler(C, op); + /* notify so we draw extensions immediately */ + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_RUNNING_MODAL; } @@ -1463,6 +1588,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even Scene *scene = CTX_data_scene(C); SlipData *data = (SlipData *)op->customdata; ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); switch (event->type) { case MOUSEMOVE: @@ -1504,6 +1630,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even case LEFTMOUSE: { + ED_region_draw_cb_exit(ar->type, data->draw_handle); MEM_freeN(data->seq_array); MEM_freeN(data->trim); MEM_freeN(data->ts); @@ -1532,6 +1659,8 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even BKE_sequence_calc(scene, seq); } + ED_region_draw_cb_exit(ar->type, data->draw_handle); + MEM_freeN(data->seq_array); MEM_freeN(data->ts); MEM_freeN(data->trim); @@ -1587,7 +1716,6 @@ void SEQUENCER_OT_slip(struct wmOperatorType *ot) INT32_MIN, INT32_MAX); } - /* mute operator */ static int sequencer_mute_exec(bContext *C, wmOperator *op) { @@ -2810,74 +2938,13 @@ void SEQUENCER_OT_view_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; } - -static int find_next_prev_edit(Scene *scene, int cfra, - const short side, - const bool do_skip_mute, const bool do_center) -{ - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq; - - int dist, best_dist, best_frame = cfra; - int seq_frames[2], seq_frames_tot; - - best_dist = MAXFRAME * 2; - - if (ed == NULL) return cfra; - - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - int i; - - if (do_skip_mute && (seq->flag & SEQ_MUTE)) { - continue; - } - - if (do_center) { - seq_frames[0] = (seq->startdisp + seq->enddisp) / 2; - seq_frames_tot = 1; - } - else { - seq_frames[0] = seq->startdisp; - seq_frames[1] = seq->enddisp; - - seq_frames_tot = 2; - } - - for (i = 0; i < seq_frames_tot; i++) { - const int seq_frame = seq_frames[i]; - - dist = MAXFRAME * 2; - - switch (side) { - case SEQ_SIDE_LEFT: - if (seq_frame < cfra) { - dist = cfra - seq_frame; - } - break; - case SEQ_SIDE_RIGHT: - if (seq_frame > cfra) { - dist = seq_frame - cfra; - } - break; - } - - if (dist < best_dist) { - best_frame = seq_frame; - best_dist = dist; - } - } - } - - return best_frame; -} - static bool strip_jump_internal(Scene *scene, const short side, const bool do_skip_mute, const bool do_center) { bool changed = false; int cfra = CFRA; - int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center); + int nfra = BKE_sequencer_find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center, false); if (nfra != cfra) { CFRA = nfra; @@ -3623,4 +3690,3 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot) WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); } - diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 438696d0327..f3723b73865 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -45,6 +45,7 @@ struct ARegion; struct ARegionType; struct Scene; struct Main; +struct SequencePreview; /* space_sequencer.c */ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa); @@ -52,7 +53,9 @@ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa); /* sequencer_draw.c */ void draw_timeline_seq(const struct bContext *C, struct ARegion *ar); -void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay); +void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay, bool draw_backdrop); +void color3ubv_from_seq(struct Scene *curscene, struct Sequence *seq, unsigned char col[3]); +void draw_shadedstrip(struct Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2); /* UNUSED */ // void seq_reset_imageofs(struct SpaceSeq *sseq); @@ -150,13 +153,6 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot); -/* RNA enums, just to be more readable */ -enum { - SEQ_SIDE_NONE = 0, - SEQ_SIDE_LEFT, - SEQ_SIDE_RIGHT, - SEQ_SIDE_BOTH -}; enum { SEQ_CUT_SOFT, SEQ_CUT_HARD @@ -199,5 +195,8 @@ void SEQUENCER_OT_strip_modifier_move(struct wmOperatorType *ot); /* sequencer_view.c */ void SEQUENCER_OT_sample(struct wmOperatorType *ot); +/* sequencer_preview.c */ +void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq); + #endif /* __SEQUENCER_INTERN_H__ */ diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 88646b55e23..9b5ef18f7cd 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -40,6 +40,8 @@ #include "ED_markers.h" #include "ED_transform.h" /* transform keymap */ +#include "BKE_sequencer.h" + #include "sequencer_intern.h" diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c new file mode 100644 index 00000000000..dd6349efb8f --- /dev/null +++ b/source/blender/editors/space_sequencer/sequencer_preview.c @@ -0,0 +1,172 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2003-2009, Antony Riakiotakis + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_sequencer/sequencer_preview.c + * \ingroup spseq + */ + +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" + +#include "BLI_listbase.h" +#include "BLI_threads.h" + +#include "BKE_sound.h" +#include "BKE_context.h" +#include "BKE_global.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" + +#include "MEM_guardedalloc.h" + +#include "sequencer_intern.h" + +typedef struct PreviewJob { + ListBase previews; + ThreadMutex *mutex; + Scene *scene; + int total; + int processed; +} PreviewJob; + +typedef struct PreviewJobAudio { + struct PreviewJobAudio *next, *prev; + bSound *sound; + int lr; /* sample left or right */ + int startframe; + bool waveform; /* reload sound or waveform */ +} PreviewJobAudio; + +static void free_preview_job(void *data) +{ + PreviewJob *pj = (PreviewJob *)data; + + BLI_mutex_free(pj->mutex); + BLI_freelistN(&pj->previews); + MEM_freeN(pj); +} + +/* only this runs inside thread */ +static void preview_startjob(void *data, short *stop, short *do_update, float *progress) +{ + PreviewJob *pj = data; + PreviewJobAudio *previewjb; + + BLI_mutex_lock(pj->mutex); + previewjb = pj->previews.first; + BLI_mutex_unlock(pj->mutex); + + while (previewjb) { + PreviewJobAudio *preview_next; + bSound *sound = previewjb->sound; + + sound_read_waveform(sound, true, stop); + + if (*stop || G.is_break) { + BLI_mutex_lock(pj->mutex); + previewjb = previewjb->next; + BLI_mutex_unlock(pj->mutex); + while (previewjb) { + sound = previewjb->sound; + + /* make sure we cleanup the loading flag! */ + BLI_mutex_lock(sound->mutex); + sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + BLI_mutex_unlock(sound->mutex); + + BLI_mutex_lock(pj->mutex); + previewjb = previewjb->next; + BLI_mutex_unlock(pj->mutex); + } + + BLI_mutex_lock(pj->mutex); + BLI_freelistN(&pj->previews); + pj->total = 0; + pj->processed = 0; + BLI_mutex_unlock(pj->mutex); + break; + } + + BLI_mutex_lock(pj->mutex); + preview_next = previewjb->next; + BLI_freelinkN(&pj->previews, previewjb); + previewjb = preview_next; + pj->processed++; + *progress = (pj->total > 0) ? (float)pj->processed / (float)pj->total : 1.0; + *do_update = true; + BLI_mutex_unlock(pj->mutex); + } +} + +static void preview_endjob(void *data) +{ + PreviewJob *pj = data; + + WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene); +} + + +void sequencer_preview_add_sound(const bContext *C, Sequence *seq) +{ + /* first, get the preview job, if it exists */ + wmJob *wm_job; + PreviewJob *pj; + ScrArea *sa = CTX_wm_area(C); + PreviewJobAudio *audiojob = MEM_callocN(sizeof(PreviewJobAudio), "preview_audio"); + wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Strip Previews", + WM_JOB_PROGRESS, WM_JOB_TYPE_SEQ_BUILD_PREVIEW); + + pj = WM_jobs_customdata_get(wm_job); + + if (!pj) { + pj = MEM_callocN(sizeof(PreviewJob), "preview rebuild job"); + + pj->mutex = BLI_mutex_alloc(); + pj->scene = CTX_data_scene(C); + + WM_jobs_customdata_set(wm_job, pj, free_preview_job); + WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER); + WM_jobs_callbacks(wm_job, preview_startjob, NULL, NULL, preview_endjob); + } + + /* attempt to lock mutex of job here */ + + audiojob->sound = seq->sound; + + BLI_mutex_lock(pj->mutex); + BLI_addtail(&pj->previews, audiojob); + pj->total++; + BLI_mutex_unlock(pj->mutex); + + if (!WM_jobs_is_running(wm_job)) { + G.is_break = false; + WM_jobs_start(CTX_wm_manager(C), wm_job); + } + + ED_area_tag_redraw(sa); +} diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 007d3c44a64..3f9e2f72578 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -559,7 +559,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar) if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF; if (!show_split || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE) - draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false); + draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, false); if (show_split && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) { int over_cfra; @@ -570,7 +570,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar) over_cfra = scene->r.cfra + scene->ed->over_ofs; if (over_cfra != scene->r.cfra || sseq->overlay_type != SEQ_DRAW_OVERLAY_RECT) - draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true); + draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true, false); } if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) { |