diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-12-23 08:04:03 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-12-23 08:04:03 +0300 |
commit | 9282d305bdc56522543129436db1e8a5d19cf39f (patch) | |
tree | b6d0cdcc7dd3f4113cf9e4f9813c40f44d29746e /source/blender/editors/space_sequencer | |
parent | de724a258eda45d1fed2b2176006c3b2df8abea2 (diff) | |
parent | 646a96bf8edc211a06f3df652101c265ee166e8d (diff) |
Merge branch 'master' into texture_nodes_refactortexture_nodes_refactor
Conflicts:
source/blender/nodes/texture/nodes/node_texture_math.c
Diffstat (limited to 'source/blender/editors/space_sequencer')
11 files changed, 863 insertions, 294 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_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 345988c1d5c..0ab4dcbeae2 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -40,7 +40,6 @@ #include "DNA_scene_types.h" #include "DNA_mask_types.h" -#include "BLF_translation.h" #include "BKE_context.h" #include "BKE_global.h" @@ -61,7 +60,6 @@ #include "ED_screen.h" #include "ED_sequencer.h" -#include "UI_view2d.h" #include "BKE_sound.h" @@ -923,5 +921,6 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type"); - RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); + RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", + "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); } diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index d75eeca2c67..70c6da0bfb3 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -46,12 +46,12 @@ #include "WM_api.h" #include "WM_types.h" -#include "UI_interface.h" #include "sequencer_intern.h" /* **************************** buttons ********************************* */ +#if 0 static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt)) { SpaceSeq *sseq = CTX_wm_space_seq(C); @@ -59,9 +59,11 @@ static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUS /* don't show the gpencil if we are not showing the image */ return ED_space_sequencer_check_show_imbuf(sseq); } +#endif -void sequencer_buttons_register(ARegionType *art) +void sequencer_buttons_register(ARegionType *UNUSED(art)) { +#if 0 PanelType *pt; pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil"); @@ -72,6 +74,7 @@ void sequencer_buttons_register(ARegionType *art) pt->draw = ED_gpencil_panel_standard; pt->poll = sequencer_grease_pencil_panel_poll; BLI_addtail(&art->paneltypes, pt); +#endif } /* **************** operator to open/close properties view ************* */ diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index dab51f752b4..144f7876b5e 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" @@ -69,6 +70,7 @@ #include "WM_api.h" + /* own include */ #include "sequencer_intern.h" @@ -82,9 +84,11 @@ /* Note, Don't use SEQ_BEGIN/SEQ_END while drawing! * it messes up transform, - Campbell */ -static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2); +#undef SEQ_BEGIN +#undef SEQP_BEGIN +#undef SEQ_END -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; @@ -175,14 +179,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; @@ -190,20 +194,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); @@ -299,7 +313,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); @@ -332,7 +346,10 @@ static float draw_seq_handle_size_get_clamped(Sequence *seq, const float pixelx) { const float minhandle = pixelx * SEQ_HANDLE_SIZE_MIN; const float maxhandle = pixelx * SEQ_HANDLE_SIZE_MAX; - return CLAMPIS(seq->handsize, minhandle, maxhandle); + float size = CLAMPIS(seq->handsize, minhandle, maxhandle); + + /* ensure we're not greater than half width */ + return min_ff(size, ((float)(seq->enddisp - seq->startdisp) / 2.0f) / pixelx); } /* draw a handle, for each end of a sequence strip */ @@ -415,112 +432,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]) { @@ -627,7 +538,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; @@ -684,12 +595,117 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa } } +void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq) +{ + float x1, x2, y1, y2, pixely, a; + unsigned char col[3], blendcol[3]; + View2D *v2d = &ar->v2d; + + 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); + } + } +} + + /* * Draw a sequence strip, bounds check already made * 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; @@ -707,8 +723,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 */ @@ -720,10 +736,10 @@ 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); - + if ((sseq->draw_flag & SEQ_DRAW_OFFSET_EXT) && !is_single_image) { + draw_sequence_extensions(scene, ar, seq); + } + draw_seq_handle(v2d, seq, handsize_clamped, SEQ_LEFTHANDLE); draw_seq_handle(v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE); @@ -733,7 +749,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 */ @@ -766,7 +784,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; @@ -784,7 +802,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glLineStipple(1, 0x8888); } - uiDrawBoxShade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0); + UI_draw_roundbox_shade_x(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0); if (seq->flag & SEQ_MUTE) { glDisable(GL_LINE_STIPPLE); @@ -917,7 +935,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; @@ -973,7 +991,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); @@ -1048,23 +1066,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; @@ -1154,6 +1174,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) { @@ -1176,6 +1204,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); @@ -1183,6 +1230,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) @@ -1192,6 +1248,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; @@ -1225,8 +1291,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - uiSetRoundBox(UI_CNR_ALL); - uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_gl_mode(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -1241,9 +1307,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); @@ -1280,9 +1343,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 @@ -1359,6 +1419,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); @@ -1379,7 +1440,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 */ @@ -1388,20 +1449,24 @@ 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) -{ +{ + const Editing *ed = BKE_sequencer_editing_get(scene, false); + const int frame_sta = PSFRA; + const int frame_end = PEFRA + 1; + glEnable(GL_BLEND); /* draw darkened area outside of active timeline * frame range used is preview range or scene range */ UI_ThemeColorShadeAlpha(TH_BACK, -25, -100); - if (PSFRA < PEFRA + 1) { - glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); - glRectf((float)(PEFRA + 1), v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); + if (frame_sta < frame_end) { + glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)frame_sta, v2d->cur.ymax); + glRectf((float)frame_end, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); } else { glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); @@ -1409,9 +1474,21 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) UI_ThemeColorShade(TH_BACK, -60); /* thin lines where the actual frames are */ - fdrawline((float)PSFRA, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); - fdrawline((float)(PEFRA + 1), v2d->cur.ymin, (float)(PEFRA + 1), v2d->cur.ymax); - + fdrawline(frame_sta, v2d->cur.ymin, frame_sta, v2d->cur.ymax); + fdrawline(frame_end, v2d->cur.ymin, frame_end, v2d->cur.ymax); + + if (ed && !BLI_listbase_is_empty(&ed->metastack)) { + MetaStack *ms = ed->metastack.last; + + glColor4ub(255, 255, 255, 8); + glRectf(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax); + + UI_ThemeColorShade(TH_BACK, -40); + + fdrawline(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[0], v2d->cur.ymax); + fdrawline(ms->disp_range[1], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax); + } + glDisable(GL_BLEND); } @@ -1450,6 +1527,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); @@ -1471,7 +1554,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar) /* markers */ UI_view2d_view_orthoSpecial(ar, v2d, 1); - draw_markers_time(C, DRAW_MARKERS_LINES); + ED_markers_draw(C, DRAW_MARKERS_LINES | DRAW_MARKERS_MARGIN); /* preview range */ UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 9c43d22ae2f..c48171826a9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -49,7 +49,6 @@ #include "BKE_report.h" #include "BKE_sound.h" -#include "IMB_imbuf.h" #include "WM_api.h" #include "WM_types.h" @@ -62,9 +61,11 @@ #include "ED_screen.h" #include "ED_transform.h" #include "ED_sequencer.h" +#include "ED_space_api.h" #include "UI_view2d.h" + /* own include */ #include "sequencer_intern.h" @@ -385,7 +386,7 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ displen = (float)abs(seq->startdisp - seq->enddisp); if (displen / pixelx > 16) { /* don't even try to grab the handles of small strips */ - /* Set the max value to handle to 1/3 of the total len when its less then 28. + /* Set the max value to handle to 1/3 of the total len when its less than 28. * This is important because otherwise selecting handles happens even when you click in the middle */ if ((displen / 3) < 30 * pixelx) { @@ -1231,6 +1232,387 @@ 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]; + TransSeq *ts; + Sequence **seq_array; + bool *trim; + 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) +{ + ts->start = seq->start; + ts->machine = seq->machine; + ts->startstill = seq->startstill; + ts->endstill = seq->endstill; + ts->startdisp = seq->startdisp; + ts->enddisp = seq->enddisp; + ts->startofs = seq->startofs; + ts->endofs = seq->endofs; + ts->anim_startofs = seq->anim_startofs; + ts->anim_endofs = seq->anim_endofs; + ts->len = seq->len; +} + + +static void transseq_restore(TransSeq *ts, Sequence *seq) +{ + seq->start = ts->start; + seq->machine = ts->machine; + seq->startstill = ts->startstill; + seq->endstill = ts->endstill; + seq->startdisp = ts->startdisp; + seq->enddisp = ts->enddisp; + seq->startofs = ts->startofs; + seq->endofs = ts->endofs; + seq->anim_startofs = ts->anim_startofs; + seq->anim_endofs = ts->anim_endofs; + seq->len = ts->len; +} + +static void draw_slip_extensions(const bContext *C, ARegion *ar, void *data) +{ + Scene *scene = CTX_data_scene(C); + 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]) { + draw_sequence_extensions(scene, ar, seq); + } + } +} + +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 (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { + seq_array[offset + num_items] = seq; + trim[offset + num_items] = do_trim; + num_items++; + + if (seq->type == SEQ_TYPE_META) { + /* trim the sub-sequences */ + num_items += slip_add_sequences_rec(&seq->seqbase, seq_array, trim, num_items + offset, false); + } + else if (seq->type & SEQ_TYPE_EFFECT) { + trim[offset + num_items] = false; + } + } + } + + return num_items; +} + +static int slip_count_sequences_rec(ListBase *seqbasep, bool first_level) +{ + Sequence *seq; + int trimmed_sequences = 0; + + for (seq = seqbasep->first; seq; seq = seq->next) { + if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { + trimmed_sequences++; + + if (seq->type == SEQ_TYPE_META) { + /* trim the sub-sequences */ + trimmed_sequences += slip_count_sequences_rec(&seq->seqbase, false); + } + } + } + + return trimmed_sequences; +} + +static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + 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); + + /* first recursively cound the trimmed elements */ + num_seq = slip_count_sequences_rec(ed->seqbasep, true); + + if (num_seq == 0) + return OPERATOR_CANCELLED; + + data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); + data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); + data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); + data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); + data->num_seq = num_seq; + + slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); + + for (i = 0; i < num_seq; i++) { + 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); + copy_v2_v2(data->init_mouseloc, mouseloc); + + data->slow = false; + + 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; +} + +static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) +{ + + /* only data types supported for now */ + if (offset != 0) { + Editing *ed = BKE_sequencer_editing_get(scene, false); + int i; + + /* we iterate in reverse so metastrips are iterated after their children */ + for (i = data->num_seq - 1; i >= 0; i--) { + Sequence *seq = data->seq_array[i]; + int endframe; + /* we have the offset, do the terrible math */ + + /* first, do the offset */ + seq->start = data->ts[i].start + offset; + + if (data->trim[i]) { + /* find the endframe */ + endframe = seq->start + seq->len; + + /* now compute the terrible offsets */ + if (endframe > seq->enddisp) { + seq->endstill = 0; + seq->endofs = endframe - seq->enddisp; + } + else if (endframe <= seq->enddisp) { + seq->endstill = seq->enddisp - endframe; + seq->endofs = 0; + } + + if (seq->start > seq->startdisp) { + seq->startstill = seq->start - seq->startdisp; + seq->startofs = 0; + } + else if (seq->start <= seq->startdisp) { + seq->startstill = 0; + seq->startofs = seq->startdisp - seq->start; + } + } + else { + /* if no real trim, don't change the data, rather transform the strips themselves */ + seq->startdisp = data->ts[i].startdisp + offset; + seq->enddisp = data->ts[i].enddisp + offset; + } + + /* effects are only added if we they are in a metastrip. In this case, dependent strips will just be transformed and we can skip calculating for effects + * This way we can avoid an extra loop just for effects*/ + if (!(seq->type & SEQ_TYPE_EFFECT)) + BKE_sequence_calc(scene, seq); + } + BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + + return true; + } + + return false; +} + +static int sequencer_slip_exec(bContext *C, wmOperator *op) +{ + SlipData *data; + Scene *scene = CTX_data_scene(C); + Editing *ed = BKE_sequencer_editing_get(scene, false); + int num_seq, i; + int offset = RNA_int_get(op->ptr, "offset"); + bool success = false; + + /* first recursively cound the trimmed elements */ + num_seq = slip_count_sequences_rec(ed->seqbasep, true); + + if (num_seq == 0) + return OPERATOR_CANCELLED; + + data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); + data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); + data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); + data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); + data->num_seq = num_seq; + + slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); + + for (i = 0; i < num_seq; i++) { + transseq_backup(data->ts + i, data->seq_array[i]); + } + + success = sequencer_slip_recursively(scene, data, offset); + + MEM_freeN(data->seq_array); + MEM_freeN(data->trim); + MEM_freeN(data->ts); + MEM_freeN(data); + + if (success) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + 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: + { + float mouseloc[2]; + int offset; + int mouse_x; + View2D *v2d = UI_view2d_fromcontext(C); + + if (data->slow) { + mouse_x = event->mval[0] - data->slow_offset; + mouse_x *= 0.1f; + mouse_x += data->slow_offset; + } + else { + mouse_x = event->mval[0]; + } + + + /* choose the side based on which side of the playhead the mouse is on */ + UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]); + offset = mouseloc[0] - data->init_mouseloc[0]; + + RNA_int_set(op->ptr, "offset", offset); + + if (sa) { +#define HEADER_LENGTH 40 + char msg[HEADER_LENGTH]; + BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %d", offset); +#undef HEADER_LENGTH + ED_area_headerprint(sa, msg); + } + + if (sequencer_slip_recursively(scene, data, offset)) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + } + break; + } + + 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); + MEM_freeN(data); + op->customdata = NULL; + if (sa) { + ED_area_headerprint(sa, NULL); + } + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; + } + + case ESCKEY: + case RIGHTMOUSE: + { + int i; + Editing *ed = BKE_sequencer_editing_get(scene, false); + + for (i = 0; i < data->num_seq; i++) { + transseq_restore(data->ts + i, data->seq_array[i]); + } + + for (i = 0; i < data->num_seq; i++) { + Sequence *seq = data->seq_array[i]; + BKE_sequence_reload_new_file(scene, seq, false); + 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); + MEM_freeN(data); + op->customdata = NULL; + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + + BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + + if (sa) { + ED_area_headerprint(sa, NULL); + } + + return OPERATOR_CANCELLED; + } + + case RIGHTSHIFTKEY: + case LEFTSHIFTKEY: + if (event->val == KM_PRESS) { + data->slow = true; + data->slow_offset = event->mval[0]; + } + else if (event->val == KM_RELEASE) { + data->slow = false; + } + break; + + default: + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +void SEQUENCER_OT_slip(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Trim Strips"; + ot->idname = "SEQUENCER_OT_slip"; + ot->description = "Trim the contents of the active strip"; + + /* api callbacks */ + ot->invoke = sequencer_slip_invoke; + ot->modal = sequencer_slip_modal; + ot->exec = sequencer_slip_exec; + ot->poll = sequencer_edit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "offset", 0, INT32_MIN, INT32_MAX, "Offset", "Offset to the data of the strip", + INT32_MIN, INT32_MAX); +} + /* mute operator */ static int sequencer_mute_exec(bContext *C, wmOperator *op) { @@ -1993,6 +2375,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) BLI_addtail(&ed->metastack, ms); ms->parseq = last_seq; ms->oldbasep = ed->seqbasep; + copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp); ed->seqbasep = &last_seq->seqbase; @@ -2012,12 +2395,25 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) ed->seqbasep = ms->oldbasep; + /* for old files, update from meta */ + if (ms->disp_range[0] == ms->disp_range[1]) { + copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp); + } + /* recalc all: the meta can have effects connected to it */ for (seq = ed->seqbasep->first; seq; seq = seq->next) BKE_sequence_calc(scene, seq); + /* 2.73+, keeping endpoings is important! + * moving them around means you can't usefully use metas in a complex edit */ +#if 1 + BKE_sequence_tx_set_final_left(ms->parseq, ms->disp_range[0]); + BKE_sequence_tx_set_final_right(ms->parseq, ms->disp_range[1]); + BKE_sequence_calc(scene, ms->parseq); +#else if (BKE_sequence_test_overlap(ed->seqbasep, ms->parseq)) BKE_sequence_base_shuffle(ed->seqbasep, ms->parseq, scene); +#endif BKE_sequencer_active_set(scene, ms->parseq); @@ -2059,8 +2455,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene); int channel_max = 1; - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, false) == false) { - BKE_report(op->reports, RPT_ERROR, "Please select more than one or all related strips"); + if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { + BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } @@ -2439,88 +2835,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, *best_seq = NULL, *frame_seq = NULL; - - int dist, best_dist; - best_dist = MAXFRAME * 2; - - if (ed == NULL) return cfra; - - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - int seq_frame; - - if (do_skip_mute && (seq->flag & SEQ_MUTE)) { - continue; - } - - if (do_center) { - seq_frame = (seq->startdisp + seq->enddisp) / 2; - } - else { - seq_frame = seq->startdisp; - } - - 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; - } - else if (seq_frame == cfra) { - frame_seq = seq; - } - break; - } - - if (dist < best_dist) { - best_dist = dist; - best_seq = seq; - } - } - - /* if no sequence to the right is found and the - * frame is on the start of the last sequence, - * move to the end of the last sequence */ - if (frame_seq) { - if (do_center) { - cfra = (frame_seq->startdisp + frame_seq->enddisp) / 2; - } - else { - cfra = frame_seq->enddisp; - } - } - - if (best_seq) { - if (do_center) { - cfra = (best_seq->startdisp + best_seq->enddisp) / 2; - } - else { - cfra = best_seq->startdisp; - } - } - - return cfra; -} - 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; @@ -2767,7 +3088,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) BKE_sequencer_free_clipboard(); - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, true) == false) { + if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } @@ -2804,9 +3125,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) } /* duplicate pointers */ - for (seq = seqbase_clipboard.first; seq; seq = seq->next) { - BKE_sequence_clipboard_pointers_store(seq); - } + BKE_sequencer_base_clipboard_pointers_store(&seqbase_clipboard); } return OPERATOR_FINISHED; @@ -2850,9 +3169,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) } } - for (iseq = nseqbase.first; iseq; iseq = iseq->next) { - BKE_sequence_clipboard_pointers_restore(iseq, bmain); - } + BKE_sequencer_base_clipboard_pointers_restore(&nseqbase, bmain); for (iseq = nseqbase.first; iseq; iseq = iseq->next) { BKE_sequence_sound_init(scene, iseq); @@ -3270,4 +3587,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 df266b0f546..4e11b4da235 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,10 @@ 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); +void draw_sequence_extensions(struct Scene *scene, struct ARegion *ar, struct Sequence *seq); /* UNUSED */ // void seq_reset_imageofs(struct SpaceSeq *sseq); @@ -84,6 +88,7 @@ struct wmOperatorType; struct wmKeyConfig; void SEQUENCER_OT_cut(struct wmOperatorType *ot); +void SEQUENCER_OT_slip(struct wmOperatorType *ot); void SEQUENCER_OT_mute(struct wmOperatorType *ot); void SEQUENCER_OT_unmute(struct wmOperatorType *ot); void SEQUENCER_OT_lock(struct wmOperatorType *ot); @@ -149,13 +154,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 @@ -198,5 +196,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_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index ff40bf1e638..83f3f9bc961 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -29,24 +29,14 @@ * \ingroup spseq */ -#include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_scene_types.h" -#include "DNA_mask_types.h" -#include "DNA_userdef_types.h" #include "BKE_context.h" -#include "BKE_global.h" -#include "BKE_library.h" -#include "BKE_main.h" #include "BKE_sequencer.h" -#include "BKE_movieclip.h" -#include "BKE_mask.h" -#include "BKE_report.h" #include "WM_api.h" #include "WM_types.h" @@ -54,8 +44,6 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -#include "UI_interface.h" -#include "UI_resources.h" /* own include */ #include "sequencer_intern.h" diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index c5e47c3aa3e..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" @@ -50,6 +52,7 @@ void sequencer_operatortypes(void) { /* sequencer_edit.c */ WM_operatortype_append(SEQUENCER_OT_cut); + WM_operatortype_append(SEQUENCER_OT_slip); WM_operatortype_append(SEQUENCER_OT_mute); WM_operatortype_append(SEQUENCER_OT_unmute); WM_operatortype_append(SEQUENCER_OT_lock); @@ -316,6 +319,8 @@ void sequencer_keymap(wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "SEQUENCER_MT_change", CKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "SEQUENCER_OT_slip", SKEY, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_int", OKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "scene.sequence_editor.overlay_frame"); RNA_int_set(kmi->ptr, "value", 0); 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/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 933daf4adee..6792bbe0577 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -357,25 +357,22 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e case SEQ_SELECT_LR_MOUSE: x = UI_view2d_region_to_view_x(v2d, event->mval[0]); break; - case SEQ_SELECT_LR_LEFT: - x = CFRA - 1; - break; case SEQ_SELECT_LR_RIGHT: - x = CFRA + 1; + x = CFRA; break; } SEQP_BEGIN (ed, seq) { if (x < CFRA) { - if (seq->enddisp < CFRA) { + if (seq->enddisp <= CFRA) { seq->flag |= SELECT; recurs_sel_seq(seq); } } else { - if (seq->startdisp > CFRA) { + if (seq->startdisp >= CFRA) { seq->flag |= SELECT; recurs_sel_seq(seq); } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index c0cfaed7867..6231f02907a 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -328,7 +328,7 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl) SpaceSeq *sseqn = MEM_dupallocN(sl); /* clear or remove stuff from old */ -// XXX sseq->gpd = gpencil_data_duplicate(sseq->gpd); +// XXX sseq->gpd = gpencil_data_duplicate(sseq->gpd, false); memset(&sseqn->scopes, 0, sizeof(sseqn->scopes)); @@ -352,6 +352,10 @@ static void sequencer_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn if (wmn->data == ND_SPACE_SEQUENCER) sequencer_scopes_tag_refresh(sa); break; + case NC_GPENCIL: + if (wmn->data & ND_GPENCIL_EDITMODE) + ED_area_tag_redraw(sa); + break; } } @@ -559,7 +563,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 +574,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)) { @@ -585,7 +589,7 @@ static void sequencer_preview_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED /* context changes */ switch (wmn->category) { case NC_GPENCIL: - if (wmn->action == NA_EDITED) { + if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { ED_region_tag_redraw(ar); } break; @@ -641,7 +645,7 @@ static void sequencer_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED /* context changes */ switch (wmn->category) { case NC_GPENCIL: - if (wmn->data == ND_DATA) { + if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { ED_region_tag_redraw(ar); } break; |