diff options
Diffstat (limited to 'source/blender/editors/space_sequencer')
7 files changed, 281 insertions, 269 deletions
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index a6e7903d1b1..ac31e0e7c37 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -95,6 +95,7 @@ typedef struct SequencerAddData { #define SEQPROP_NOPATHS (1 << 2) #define SEQPROP_NOCHAN (1 << 3) #define SEQPROP_FIT_METHOD (1 << 4) +#define SEQPROP_VIEW_TRANSFORM (1 << 5) static const EnumPropertyItem scale_fit_methods[] = { {SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image to fit within the canvas"}, @@ -152,6 +153,14 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag) "Fit Method", "Scale fit method"); } + + if (flag & SEQPROP_VIEW_TRANSFORM) { + ot->prop = RNA_def_boolean(ot->srna, + "set_view_transform", + true, + "Set View Transform", + "Set appropriate view transform based on media colorspace"); + } } static void sequencer_generic_invoke_path__internal(bContext *C, @@ -228,7 +237,6 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm PropertyRNA *prop; const bool relative = (prop = RNA_struct_find_property(op->ptr, "relative_path")) && RNA_property_boolean_get(op->ptr, prop); - int is_file = -1; memset(load_data, 0, sizeof(SeqLoadData)); load_data->start_frame = RNA_int_get(op->ptr, "frame_start"); @@ -242,17 +250,26 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm } if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) { - /* Full path, file is set by the caller. */ RNA_property_string_get(op->ptr, prop, load_data->path); - is_file = 1; + BLI_strncpy(load_data->name, BLI_path_basename(load_data->path), sizeof(load_data->name)); } else if ((prop = RNA_struct_find_property(op->ptr, "directory"))) { - /* Full path, file is set by the caller. */ - RNA_property_string_get(op->ptr, prop, load_data->path); - is_file = 0; + char *directory = RNA_string_get_alloc(op->ptr, "directory", NULL, 0); + + if ((prop = RNA_struct_find_property(op->ptr, "files"))) { + RNA_PROP_BEGIN (op->ptr, itemptr, prop) { + char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0); + BLI_strncpy(load_data->name, filename, sizeof(load_data->name)); + BLI_snprintf(load_data->path, sizeof(load_data->path), "%s%s", directory, filename); + MEM_freeN(filename); + break; + } + RNA_PROP_END; + } + MEM_freeN(directory); } - if ((is_file != -1) && relative) { + if (relative) { BLI_path_rel(load_data->path, BKE_main_blendfile_path(bmain)); } @@ -276,17 +293,9 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm load_data->flags |= SEQ_LOAD_MOVIE_SYNC_FPS; } - if (is_file == 1) { - BLI_strncpy(load_data->name, BLI_path_basename(load_data->path), sizeof(load_data->name)); - } - else if ((prop = RNA_struct_find_property(op->ptr, "files"))) { - RNA_PROP_BEGIN (op->ptr, itemptr, prop) { - char *name = RNA_string_get_alloc(&itemptr, "name", NULL, 0); - BLI_strncpy(load_data->name, name, sizeof(load_data->name)); - MEM_freeN(name); - break; - } - RNA_PROP_END; + if ((prop = RNA_struct_find_property(op->ptr, "set_view_transform")) && + RNA_property_boolean_get(op->ptr, prop)) { + load_data->flags |= SEQ_LOAD_SET_VIEW_TRANSFORM; } if ((prop = RNA_struct_find_property(op->ptr, "use_multiview")) && @@ -373,8 +382,23 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static void sequencer_disable_one_time_properties(bContext *C, wmOperator *op) +{ + Editing *ed = SEQ_editing_get(CTX_data_scene(C), false); + /* Disable following properties if there are any existing strips, unless overridden by user. */ + if (ed && ed->seqbasep && ed->seqbasep->first) { + if (RNA_struct_find_property(op->ptr, "use_framerate")) { + RNA_boolean_set(op->ptr, "use_framerate", false); + } + if (RNA_struct_find_property(op->ptr, "set_view_transform")) { + RNA_boolean_set(op->ptr, "set_view_transform", false); + } + } +} + static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + sequencer_disable_one_time_properties(C, op); if (!RNA_struct_property_is_set(op->ptr, "scene")) { return WM_enum_search_invoke(C, op, event); } @@ -707,13 +731,9 @@ static int sequencer_add_movie_strip_invoke(bContext *C, { PropertyRNA *prop; Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); - /* Only enable "use_framerate" if there aren't any existing strips, unless overridden by user. - */ - if (ed && ed->seqbasep && ed->seqbasep->first) { - RNA_boolean_set(op->ptr, "use_framerate", false); - } + sequencer_disable_one_time_properties(C, op); + RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene)); /* This is for drag and drop. */ @@ -739,12 +759,11 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op) uiLayout *layout = op->layout; SequencerAddData *sad = op->customdata; ImageFormatData *imf = &sad->im_format; - PointerRNA imf_ptr, ptr; + PointerRNA imf_ptr; /* Main draw call. */ - RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); uiDefAutoButsRNA( - layout, &ptr, sequencer_add_draw_check_fn, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false); + layout, op->ptr, sequencer_add_draw_check_fn, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false); /* Image template. */ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr); @@ -781,7 +800,8 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); - sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD); + sequencer_generic_props__internal( + ot, SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD | SEQPROP_VIEW_TRANSFORM); RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie"); RNA_def_boolean(ot->srna, "use_framerate", @@ -990,8 +1010,10 @@ static void sequencer_add_image_strip_load_files( wmOperator *op, Sequence *seq, SeqLoadData *load_data, const int minframe, const int numdigits) { const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); - - SEQ_add_image_set_directory(seq, load_data->path); + /* size of Strip->dir. */ + char directory[768]; + BLI_split_dir_part(load_data->path, directory, sizeof(directory)); + SEQ_add_image_set_directory(seq, directory); if (use_placeholders) { sequencer_image_seq_reserve_frames( @@ -1057,8 +1079,9 @@ static int sequencer_add_image_strip_invoke(bContext *C, PropertyRNA *prop; Scene *scene = CTX_data_scene(C); - const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings; - RNA_enum_set(op->ptr, "fit_method", tool_settings->fit_method); + sequencer_disable_one_time_properties(C, op); + + RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene)); /* Name set already by drag and drop. */ if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) { @@ -1104,8 +1127,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); - sequencer_generic_props__internal(ot, - SEQPROP_STARTFRAME | SEQPROP_ENDFRAME | SEQPROP_FIT_METHOD); + sequencer_generic_props__internal( + ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME | SEQPROP_FIT_METHOD | SEQPROP_VIEW_TRANSFORM); RNA_def_boolean(ot->srna, "use_placeholders", diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index 11614d94862..1e0ecfd890e 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -111,10 +111,10 @@ void sequencer_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel metadata"); strcpy(pt->idname, "SEQUENCER_PT_metadata"); strcpy(pt->label, N_("Metadata")); + strcpy(pt->category, "Metadata"); strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); pt->poll = metadata_panel_context_poll; pt->draw = metadata_panel_context_draw; - pt->flag |= PANEL_TYPE_DEFAULT_CLOSED; pt->order = 10; BLI_addtail(&art->paneltypes, pt); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index e4afb27dd2e..5f831cbf535 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -105,8 +105,6 @@ * it messes up transform. */ #undef SEQ_ALL_BEGIN #undef SEQ_ALL_END -#undef SEQ_CURRENT_BEGIN -#undef SEQ_CURRENT_END static Sequence *special_seq_update = NULL; @@ -872,9 +870,9 @@ static void draw_seq_background(Scene *scene, /* Draw the main strip body. */ if (is_single_image) { immRectf(pos, - SEQ_transform_get_left_handle_frame(seq, false), + SEQ_transform_get_left_handle_frame(seq), y1, - SEQ_transform_get_right_handle_frame(seq, false), + SEQ_transform_get_right_handle_frame(seq), y2); } else { @@ -887,10 +885,12 @@ static void draw_seq_background(Scene *scene, immUniformColor4ubv(col); if (seq->startstill) { - immRectf(pos, seq->startdisp, y1, (float)(seq->start), y2); + const float content_start = min_ff(seq->enddisp, seq->start); + immRectf(pos, seq->startdisp, y1, content_start, y2); } if (seq->endstill) { - immRectf(pos, (float)(seq->start + seq->len), y1, seq->enddisp, y2); + const float content_end = max_ff(seq->startdisp, seq->start + seq->len); + immRectf(pos, content_end, y1, seq->enddisp, y2); } } @@ -1107,6 +1107,10 @@ static void draw_seq_strip(const bContext *C, x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp; y2 = seq->machine + SEQ_STRIP_OFSTOP; + /* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */ + x1 = min_ff(x1, seq->enddisp); + x2 = max_ff(x2, seq->startdisp); + float text_margin_y; bool y_threshold; if ((sseq->flag & SEQ_SHOW_STRIP_NAME) || (sseq->flag & SEQ_SHOW_STRIP_SOURCE) || @@ -1524,10 +1528,10 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C, ImBuf *ibuf, bool *r_glsl_used, eGPUTextureFormat *r_format, - eGPUDataFormat *r_data) + eGPUDataFormat *r_data, + void **r_buffer_cache_handle) { void *display_buffer; - void *cache_handle = NULL; bool force_fallback = false; *r_glsl_used = false; force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL); @@ -1580,13 +1584,10 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C, /* There is data to be displayed, but GLSL is not initialized * properly, in this case we fallback to CPU-based display transform. */ if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) { - display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle); *r_format = GPU_RGBA8; *r_data = GPU_DATA_UBYTE; } - if (cache_handle) { - IMB_display_buffer_release(cache_handle); - } return display_buffer; } @@ -1660,6 +1661,7 @@ static void sequencer_draw_display_buffer(const bContext *C, bool draw_backdrop) { void *display_buffer; + void *buffer_cache_handle = NULL; if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) { GPU_blend(GPU_BLEND_ALPHA); @@ -1687,7 +1689,8 @@ static void sequencer_draw_display_buffer(const bContext *C, data = GPU_DATA_UBYTE; } else { - display_buffer = sequencer_OCIO_transform_ibuf(C, ibuf, &glsl_used, &format, &data); + display_buffer = sequencer_OCIO_transform_ibuf( + C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle); } if (draw_backdrop) { @@ -1747,6 +1750,10 @@ static void sequencer_draw_display_buffer(const bContext *C, IMB_colormanagement_finish_glsl_draw(); } + if (buffer_cache_handle) { + IMB_display_buffer_release(buffer_cache_handle); + } + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) { GPU_blend(GPU_BLEND_NONE); } @@ -2358,6 +2365,31 @@ static void draw_cache_view(const bContext *C) } /* Draw sequencer timeline. */ +static void draw_overlap_frame_indicator(const struct Scene *scene, const View2D *v2d) +{ + int overlap_frame = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ? + scene->ed->over_cfra : + scene->r.cfra + scene->ed->over_ofs; + + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + float viewport_size[4]; + GPU_viewport_size_get_f(viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + /* Shader may have color set from past usage - reset it. */ + immUniform1i("colors_len", 0); + immUniform1f("dash_width", 20.0f * U.pixelsize); + immUniform1f("dash_factor", 0.5f); + immUniformThemeColor(TH_CFRAME); + + immBegin(GPU_PRIM_LINES, 2); + immVertex2f(pos, overlap_frame, v2d->cur.ymin); + immVertex2f(pos, overlap_frame, v2d->cur.ymax); + immEnd(); + + immUnbindProgram(); +} + void draw_timeline_seq(const bContext *C, ARegion *region) { Scene *scene = CTX_data_scene(C); @@ -2417,31 +2449,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region) cfra_flag |= DRAWCFRA_UNIT_SECONDS; } - /* Draw overlap frame frame indicator. */ - if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) { - int overlap_frame = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ? - scene->ed->over_cfra : - scene->r.cfra + scene->ed->over_ofs; - - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); - float viewport_size[4]; - GPU_viewport_size_get_f(viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - /* Shader may have color set from past usage - reset it. */ - immUniform1i("colors_len", 0); - immUniform1f("dash_width", 20.0f * U.pixelsize); - immUniform1f("dash_factor", 0.5f); - immUniformThemeColor(TH_CFRAME); - - immBegin(GPU_PRIM_LINES, 2); - immVertex2f(pos, overlap_frame, v2d->cur.ymin); - immVertex2f(pos, overlap_frame, v2d->cur.ymax); - immEnd(); - - immUnbindProgram(); - } - UI_view2d_view_orthoSpecial(region, v2d, 1); int marker_draw_flag = DRAW_MARKERS_MARGIN; if (sseq->flag & SEQ_SHOW_MARKERS) { @@ -2449,11 +2456,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region) } UI_view2d_view_ortho(v2d); - - if (ed) { - draw_cache_view(C); - } - ANIM_draw_previewrange(C, v2d, 1); /* Draw registered callbacks. */ @@ -2479,6 +2481,13 @@ void draw_timeline_seq_display(const bContext *C, ARegion *region) const SpaceSeq *sseq = CTX_wm_space_seq(C); View2D *v2d = ®ion->v2d; + if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) { + UI_view2d_view_ortho(v2d); + draw_cache_view(C); + draw_overlap_frame_indicator(scene, v2d); + UI_view2d_view_restore(C); + } + ED_time_scrub_draw_current_frame(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true); UI_view2d_scrollers_draw(v2d, NULL); } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 78d263dffad..1c9b3676b19 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -34,6 +34,7 @@ #include "BLT_translation.h" +#include "DNA_anim_types.h" #include "DNA_scene_types.h" #include "DNA_sound_types.h" @@ -138,6 +139,42 @@ bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq) ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF)); } +static bool sequencer_fcurves_targets_color_strip(const FCurve *fcurve) +{ + if (!BLI_str_startswith(fcurve->rna_path, "sequence_editor.sequences_all[\"")) { + return false; + } + + if (!BLI_str_endswith(fcurve->rna_path, "\"].color")) { + return false; + } + + return true; +} + +/* + * Check if there is animation attached to a strip, that is shown on the strip in the UI. + * + * - Colors of color strips are displayed on the strip itself. + */ +bool ED_space_sequencer_has_visible_animation_on_strip(const struct Scene *scene) +{ + if (!scene->adt) { + return false; + } + if (!scene->adt->action) { + return false; + } + + LISTBASE_FOREACH (FCurve *, fcurve, &scene->adt->action->curves) { + if (sequencer_fcurves_targets_color_strip(fcurve)) { + return true; + } + } + + return false; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -290,7 +327,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) snap_frame = RNA_int_get(op->ptr, "frame"); - /* Check metas. */ + /* Check meta-strips. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) && SEQ_transform_sequence_can_be_translated(seq)) { @@ -312,8 +349,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) } } - /* Test for effects and overlap. - * Don't use SEQ_CURRENT_BEGIN since that would be recursive. */ + /* Test for effects and overlap. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) { seq->flag &= ~SEQ_OVERLAP; @@ -349,7 +385,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) } } - SEQ_sort(scene); + SEQ_sort(SEQ_active_seqbase_get(ed)); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -558,7 +594,7 @@ static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) seq->endofs = endframe - seq->enddisp; changed = true; } - else if (endframe <= seq->enddisp) { + else { seq->endstill = seq->enddisp - endframe; seq->endofs = 0; changed = true; @@ -569,7 +605,7 @@ static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) seq->startofs = 0; changed = true; } - else if (seq->start <= seq->startdisp) { + else { seq->startstill = 0; seq->startofs = seq->startdisp - seq->start; changed = true; @@ -1411,28 +1447,25 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) } if (changed) { /* Got new strips? */ - Sequence *seq; if (ignore_selection) { if (use_cursor_position) { - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (seq->enddisp == split_frame && seq->machine == split_channel) { seq_selected = seq->flag & SEQ_ALLSEL; } } - SEQ_CURRENT_END; if (!seq_selected) { - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (seq->startdisp == split_frame && seq->machine == split_channel) { seq->flag &= ~SEQ_ALLSEL; } } - SEQ_CURRENT_END; } } } else { if (split_side != SEQ_SIDE_BOTH) { - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (split_side == SEQ_SIDE_LEFT) { if (seq->startdisp >= split_frame) { seq->flag &= ~SEQ_ALLSEL; @@ -1444,11 +1477,10 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) } } } - SEQ_CURRENT_END; } } - SEQ_sort(scene); + SEQ_sort(SEQ_active_seqbase_get(ed)); } if (changed) { WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1496,19 +1528,16 @@ static void sequencer_split_ui(bContext *UNUSED(C), wmOperator *op) uiLayoutSetPropSep(layout, true); uiLayoutSetPropDecorate(layout, false); - PointerRNA ptr; - RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiLayout *row = uiLayoutRow(layout, false); - uiItemR(row, &ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); - uiItemR(layout, &ptr, "frame", 0, NULL, ICON_NONE); - uiItemR(layout, &ptr, "side", 0, NULL, ICON_NONE); + uiItemR(row, op->ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, op->ptr, "frame", 0, NULL, ICON_NONE); + uiItemR(layout, op->ptr, "side", 0, NULL, ICON_NONE); uiItemS(layout); - uiItemR(layout, &ptr, "use_cursor_position", 0, NULL, ICON_NONE); - if (RNA_boolean_get(&ptr, "use_cursor_position")) { - uiItemR(layout, &ptr, "channel", 0, NULL, ICON_NONE); + uiItemR(layout, op->ptr, "use_cursor_position", 0, NULL, ICON_NONE); + if (RNA_boolean_get(op->ptr, "use_cursor_position")) { + uiItemR(layout, op->ptr, "channel", 0, NULL, ICON_NONE); } } @@ -1585,38 +1614,35 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot) /** \name Duplicate Strips Operator * \{ */ -static int apply_unique_name_fn(Sequence *seq, void *arg_pt) -{ - Scene *scene = (Scene *)arg_pt; - char name[sizeof(seq->name) - 2]; - - BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); - SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); - SEQ_dupe_animdata(scene, name, seq->name + 2); - return 1; -} - static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene, false); - ListBase nseqbase = {NULL, NULL}; - if (ed == NULL) { return OPERATOR_CANCELLED; } - SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0); + Sequence *active_seq = SEQ_select_active_get(scene); + ListBase duplicated = {NULL, NULL}; - if (nseqbase.first) { - Sequence *seq = nseqbase.first; + SEQ_sequence_base_dupli_recursive(scene, scene, &duplicated, ed->seqbasep, 0, 0); + ED_sequencer_deselect_all(scene); + + if (duplicated.first) { + Sequence *seq = duplicated.first; /* Rely on the nseqbase list being added at the end. * Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */ - BLI_movelisttolist(ed->seqbasep, &nseqbase); + BLI_movelisttolist(ed->seqbasep, &duplicated); + /* Handle duplicated strips: set active, select, ensure unique name and duplicate animation + * data. */ for (; seq; seq = seq->next) { - SEQ_iterator_recursive_apply(seq, apply_unique_name_fn, scene); + if (active_seq != NULL && STREQ(seq->name, active_seq->name)) { + SEQ_select_active_set(scene, seq); + } + seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); + SEQ_ensure_unique_name(seq, scene); } WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1652,16 +1678,14 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene, false); - Sequence *seq; SEQ_prefetch_stop(scene); - SEQ_CURRENT_BEGIN (scene->ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (seq->flag & SELECT) { SEQ_edit_flag_for_removal(scene, ed->seqbasep, seq); } } - SEQ_CURRENT_END; SEQ_edit_remove_flagged_sequences(scene, ed->seqbasep); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); @@ -1789,8 +1813,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) /* if (seq->ipo) id_us_min(&seq->ipo->id); */ /* XXX, remove fcurve and assign to split image strips */ - start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq, false); - frame_end = SEQ_transform_get_right_handle_frame(seq, false); + start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq); + frame_end = SEQ_transform_get_right_handle_frame(seq); while (timeline_frame < frame_end) { /* New seq. */ @@ -1839,7 +1863,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) } } - SEQ_sort(scene); + SEQ_sort(SEQ_active_seqbase_get(ed)); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1877,13 +1901,13 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) Sequence *active_seq = SEQ_select_active_get(scene); if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) { - /* Enter metastrip. */ + /* Enter meta-strip. */ SEQ_meta_stack_alloc(ed, active_seq); SEQ_seqbase_active_set(ed, &active_seq->seqbase); SEQ_select_active_set(scene, NULL); } else { - /* Exit metastrip if possible. */ + /* Exit meta-strip if possible. */ if (BLI_listbase_is_empty(&ed->metastack)) { return OPERATOR_CANCELLED; } @@ -1905,7 +1929,7 @@ void SEQUENCER_OT_meta_toggle(wmOperatorType *ot) /* Identifiers. */ ot->name = "Toggle Meta Strip"; ot->idname = "SEQUENCER_OT_meta_toggle"; - ot->description = "Toggle a metastrip (to edit enclosed strips)"; + ot->description = "Toggle a meta-strip (to edit enclosed strips)"; /* Api callbacks. */ ot->exec = sequencer_meta_toggle_exec; @@ -1973,7 +1997,7 @@ void SEQUENCER_OT_meta_make(wmOperatorType *ot) /* Identifiers. */ ot->name = "Make Meta Strip"; ot->idname = "SEQUENCER_OT_meta_make"; - ot->description = "Group selected strips into a metastrip"; + ot->description = "Group selected strips into a meta-strip"; /* Api callbacks. */ ot->exec = sequencer_meta_make_exec; @@ -2024,7 +2048,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) } } - SEQ_sort(scene); + SEQ_sort(active_seqbase); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2036,7 +2060,7 @@ void SEQUENCER_OT_meta_separate(wmOperatorType *ot) /* Identifiers. */ ot->name = "UnMeta Strip"; ot->idname = "SEQUENCER_OT_meta_separate"; - ot->description = "Put the contents of a metastrip back in the sequencer"; + ot->description = "Put the contents of a meta-strip back in the sequencer"; /* Api callbacks. */ ot->exec = sequencer_meta_separate_exec; @@ -2247,7 +2271,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) } } - SEQ_sort(scene); + SEQ_sort(SEQ_active_seqbase_get(ed)); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2284,43 +2308,45 @@ void SEQUENCER_OT_swap(wmOperatorType *ot) static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) { - int retval = OPERATOR_CANCELLED; Scene *scene = CTX_data_scene(C); Sequence *active_seq = SEQ_select_active_get(scene); StripElem *se = NULL; - if (active_seq == NULL) { + if (active_seq == NULL || active_seq->strip == NULL) { return OPERATOR_CANCELLED; } - if (active_seq->strip) { - switch (active_seq->type) { - case SEQ_TYPE_IMAGE: - se = SEQ_render_give_stripelem(active_seq, scene->r.cfra); - break; - case SEQ_TYPE_MOVIE: - se = active_seq->strip->stripdata; - break; - case SEQ_TYPE_SCENE: - case SEQ_TYPE_META: - case SEQ_TYPE_SOUND_RAM: - case SEQ_TYPE_SOUND_HD: - default: - break; - } + switch (active_seq->type) { + case SEQ_TYPE_IMAGE: + se = SEQ_render_give_stripelem(active_seq, scene->r.cfra); + break; + case SEQ_TYPE_MOVIE: + se = active_seq->strip->stripdata; + break; + default: + return OPERATOR_CANCELLED; } - if (se) { - /* Prevent setting the render size if sequence values aren't initialized. */ - if ((se->orig_width > 0) && (se->orig_height > 0)) { - scene->r.xsch = se->orig_width; - scene->r.ysch = se->orig_height; - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); - retval = OPERATOR_FINISHED; - } + if (se == NULL) { + return OPERATOR_CANCELLED; + } + + /* Prevent setting the render size if sequence values aren't initialized. */ + if (se->orig_width <= 0 || se->orig_height <= 0) { + return OPERATOR_CANCELLED; } - return retval; + scene->r.xsch = se->orig_width; + scene->r.ysch = se->orig_height; + + active_seq->strip->transform->scale_x = active_seq->strip->transform->scale_y = 1.0f; + active_seq->strip->transform->xofs = active_seq->strip->transform->yofs = 0.0f; + + SEQ_relations_invalidate_cache_preprocessed(scene, active_seq); + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + + return OPERATOR_FINISHED; } void SEQUENCER_OT_rendersize(wmOperatorType *ot) @@ -2418,17 +2444,15 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) void ED_sequencer_deselect_all(Scene *scene) { - Sequence *seq; Editing *ed = SEQ_editing_get(scene, false); if (ed == NULL) { return; } - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { seq->flag &= ~SEQ_ALLSEL; } - SEQ_CURRENT_END; } static int sequencer_paste_exec(bContext *C, wmOperator *op) @@ -2475,7 +2499,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) for (iseq = iseq_first; iseq; iseq = iseq->next) { /* Make sure, that pasted strips have unique names. */ - SEQ_iterator_recursive_apply(iseq, apply_unique_name_fn, scene); + SEQ_ensure_unique_name(iseq, scene); /* Translate after name has been changed, otherwise this will affect animdata of original * strip. */ SEQ_transform_translate_sequence(scene, iseq, ofs); @@ -3074,7 +3098,7 @@ static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op) scene->r.efra = efra; } - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME_RANGE, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index f11a879912c..9b3ecacceb9 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -230,14 +230,13 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Editing *ed = scene->ed; Sequence *seq = SEQ_select_active_get(scene); - Sequence *seq_iter; const int type = RNA_enum_get(op->ptr, "type"); if (!seq || !seq->modifiers.first) { return OPERATOR_CANCELLED; } - SEQ_CURRENT_BEGIN (ed, seq_iter) { + LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) { if (seq_iter->flag & SELECT) { if (seq_iter == seq) { continue; @@ -259,7 +258,6 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op) SEQ_modifier_list_copy(seq_iter, seq); } } - SEQ_CURRENT_END; SEQ_relations_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c index e44afde371a..2dcc2d389d9 100644 --- a/source/blender/editors/space_sequencer/sequencer_proxy.c +++ b/source/blender/editors/space_sequencer/sequencer_proxy.c @@ -58,7 +58,6 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene, false); ScrArea *area = CTX_wm_area(C); - Sequence *seq; if (ed == NULL) { return; @@ -70,7 +69,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) GSet *file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); bool selected = false; /* Check for no selected strips */ - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE) || (seq->flag & SELECT) == 0) { continue; } @@ -92,7 +91,6 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) BKE_reportf(reports, RPT_WARNING, "Overwrite is not checked for %s, skipping", seq->name); } } - SEQ_CURRENT_END; BLI_gset_free(file_list, MEM_freeN); @@ -101,7 +99,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) return; } - if (selected && !WM_jobs_is_running(wm_job)) { + if (!WM_jobs_is_running(wm_job)) { G.is_break = false; WM_jobs_start(CTX_wm_manager(C), wm_job); } @@ -124,7 +122,6 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene, false); - Sequence *seq; GSet *file_list; if (ed == NULL) { @@ -133,7 +130,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if ((seq->flag & SELECT)) { ListBase queue = {NULL, NULL}; LinkData *link; @@ -150,7 +147,6 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) SEQ_relations_free_imbuf(scene, &ed->seqbase, false); } } - SEQ_CURRENT_END; BLI_gset_free(file_list, MEM_freeN); @@ -189,7 +185,6 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene, false); - Sequence *seq; bool proxy_25 = RNA_boolean_get(op->ptr, "proxy_25"); bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50"); bool proxy_75 = RNA_boolean_get(op->ptr, "proxy_75"); @@ -201,7 +196,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) turnon = false; } - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if ((seq->flag & SELECT)) { if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) { SEQ_proxy_set(seq, turnon); @@ -246,7 +241,6 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) } } } - SEQ_CURRENT_END; WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 5f0a18fbd0b..7e515271b13 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -26,7 +26,6 @@ #include <string.h> #include "BLI_blenlib.h" -#include "BLI_ghash.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -43,6 +42,7 @@ #include "SEQ_iterator.h" #include "SEQ_select.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "SEQ_transform.h" /* For menu, popup, icons, etc. */ @@ -548,14 +548,14 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) const float x = UI_view2d_region_to_view_x(v2d, mval[0]); - SEQ_CURRENT_BEGIN (ed, seq) { - if (((x < CFRA) && (seq->enddisp <= CFRA)) || ((x >= CFRA) && (seq->startdisp >= CFRA))) { + LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) { + if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) || + ((x >= CFRA) && (seq_iter->startdisp >= CFRA))) { /* Select left or right. */ - seq->flag |= SELECT; - recurs_sel_seq(seq); + seq_iter->flag |= SELECT; + recurs_sel_seq(seq_iter); } } - SEQ_CURRENT_END; { SpaceSeq *sseq = CTX_wm_space_seq(C); @@ -808,7 +808,7 @@ static bool select_linked_internal(Scene *scene) bool changed = false; LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { - if ((seq->flag & SELECT) != 0) { + if ((seq->flag & SELECT) == 0) { continue; } /* Only get unselected neighbors. */ @@ -1170,7 +1170,6 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) Editing *ed = SEQ_editing_get(scene, false); const bool extend = RNA_boolean_get(op->ptr, "extend"); const int side = RNA_enum_get(op->ptr, "side"); - Sequence *seq; if (ed == NULL) { return OPERATOR_CANCELLED; @@ -1179,7 +1178,7 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) ED_sequencer_deselect_all(scene); } const int timeline_frame = CFRA; - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { bool test = false; switch (side) { case -1: @@ -1188,8 +1187,8 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) case 1: test = (timeline_frame <= seq->startdisp); break; - case 0: - test = (timeline_frame <= seq->enddisp) && (timeline_frame >= seq->startdisp); + case 2: + test = SEQ_time_strip_intersects_frame(seq, timeline_frame); break; } @@ -1198,7 +1197,6 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) recurs_sel_seq(seq); } } - SEQ_CURRENT_END; ED_outliner_select_sync_from_sequence_tag(C); @@ -1212,6 +1210,7 @@ void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot) static const EnumPropertyItem sequencer_select_left_right_types[] = { {-1, "LEFT", 0, "Left", "Select to the left of the current frame"}, {1, "RIGHT", 0, "Right", "Select to the right of the current frame"}, + {2, "CURRENT", 0, "Current Frame", "Select intersecting with the current frame"}, {0, NULL, 0, NULL, NULL}, }; @@ -1483,58 +1482,51 @@ static const EnumPropertyItem sequencer_prop_select_grouped_types[] = { static bool select_grouped_type(Editing *ed, Sequence *actseq, const int channel) { - Sequence *seq; bool changed = false; - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == actseq->type) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; return changed; } static bool select_grouped_type_basic(Editing *ed, Sequence *actseq, const int channel) { - Sequence *seq; bool changed = false; const bool is_sound = SEQ_IS_SOUND(actseq); - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && (is_sound ? SEQ_IS_SOUND(seq) : !SEQ_IS_SOUND(seq))) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; return changed; } static bool select_grouped_type_effect(Editing *ed, Sequence *actseq, const int channel) { - Sequence *seq; bool changed = false; const bool is_effect = SEQ_IS_EFFECT(actseq); - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && (is_effect ? SEQ_IS_EFFECT(seq) : !SEQ_IS_EFFECT(seq))) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; return changed; } static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel) { - Sequence *seq; bool changed = false; const char *dir = actseq->strip ? actseq->strip->dir : NULL; @@ -1543,45 +1535,41 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel } if (SEQ_HAS_PATH(actseq) && dir) { - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && SEQ_HAS_PATH(seq) && seq->strip && STREQ(seq->strip->dir, dir)) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; } else if (actseq->type == SEQ_TYPE_SCENE) { Scene *sce = actseq->scene; - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_SCENE && seq->scene == sce) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; } else if (actseq->type == SEQ_TYPE_MOVIECLIP) { MovieClip *clip = actseq->clip; - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MOVIECLIP && seq->clip == clip) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; } else if (actseq->type == SEQ_TYPE_MASK) { struct Mask *mask = actseq->mask; - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MASK && seq->mask == mask) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; } return changed; @@ -1589,7 +1577,6 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int channel) { - Sequence *seq; bool changed = false; bool effects[SEQ_TYPE_MAX + 1]; @@ -1597,15 +1584,14 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann effects[i] = false; } - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && (seq->type & SEQ_TYPE_EFFECT) && ELEM(actseq, seq->seq1, seq->seq2, seq->seq3)) { effects[seq->type] = true; } } - SEQ_CURRENT_END; - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (SEQ_CHANNEL_CHECK(seq, channel) && effects[seq->type]) { if (seq->seq1) { seq->seq1->flag |= SELECT; @@ -1619,86 +1605,65 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann changed = true; } } - SEQ_CURRENT_END; return changed; } static bool select_grouped_time_overlap(Editing *ed, Sequence *actseq) { - Sequence *seq; bool changed = false; - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { if (seq->startdisp < actseq->enddisp && seq->enddisp > actseq->startdisp) { seq->flag |= SELECT; changed = true; } } - SEQ_CURRENT_END; return changed; } -static bool select_grouped_effect_link(Editing *ed, Sequence *actseq, const int channel) +/* Query strips that are in lower channel and intersect in time with seq_reference. */ +static void query_lower_channel_strips(Sequence *seq_reference, + ListBase *seqbase, + SeqCollection *collection) { - Sequence *seq = NULL; - bool changed = false; - const bool is_audio = ((actseq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(actseq)); - int startdisp = actseq->startdisp; - int enddisp = actseq->enddisp; - int machine = actseq->machine; - SeqIterator iter; - - SEQ_CURRENT_BEGIN (ed, seq) { - seq->tmp = NULL; - } - SEQ_CURRENT_END; - - actseq->tmp = POINTER_FROM_INT(true); - - for (SEQ_iterator_begin(ed, &iter, true); iter.valid; SEQ_iterator_next(&iter)) { - seq = iter.seq; - - /* Ignore all seqs already selected. */ - /* Ignore all seqs not sharing some time with active one. */ - /* Ignore all seqs of incompatible types (audio vs video). */ - if (!SEQ_CHANNEL_CHECK(seq, channel) || (seq->flag & SELECT) || (seq->startdisp >= enddisp) || - (seq->enddisp < startdisp) || (!is_audio && SEQ_IS_SOUND(seq)) || - (is_audio && !((seq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(seq)))) { - continue; + LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { + if (seq_test->machine > seq_reference->machine) { + continue; /* Not lower channel. */ } + if (seq_test->enddisp <= seq_reference->startdisp || + seq_test->startdisp >= seq_reference->enddisp) { + continue; /* Not intersecting in time. */ + } + SEQ_collection_append_strip(seq_test, collection); + } +} - /* If the seq is an effect one, we need extra checking. */ - if (SEQ_IS_EFFECT(seq) && ((seq->seq1 && seq->seq1->tmp) || (seq->seq2 && seq->seq2->tmp) || - (seq->seq3 && seq->seq3->tmp))) { - if (startdisp > seq->startdisp) { - startdisp = seq->startdisp; - } - if (enddisp < seq->enddisp) { - enddisp = seq->enddisp; - } - if (machine < seq->machine) { - machine = seq->machine; - } - - seq->tmp = POINTER_FROM_INT(true); +/* Select all strips within time range and with lower channel of initial selection. Then select + * effect chains of these strips. */ +static bool select_grouped_effect_link(Editing *ed, + Sequence *UNUSED(actseq), + const int UNUSED(channel)) +{ + ListBase *seqbase = SEQ_active_seqbase_get(ed); - seq->flag |= SELECT; - changed = true; + /* Get collection of strips. */ + SeqCollection *collection = SEQ_query_selected_strips(seqbase); + const int selected_strip_count = BLI_gset_len(collection->set); + SEQ_collection_expand(seqbase, collection, query_lower_channel_strips); + SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain); - /* Unfortunately, we must restart checks from the beginning. */ - SEQ_iterator_end(&iter); - SEQ_iterator_begin(ed, &iter, true); - } + /* Check if other strips will be affected. */ + const bool changed = BLI_gset_len(collection->set) > selected_strip_count; - /* Video strips below active one, or any strip for audio (order doesn't matter here). */ - else if (seq->machine < machine || is_audio) { - seq->flag |= SELECT; - changed = true; - } + /* Actual logic. */ + Sequence *seq; + SEQ_ITERATOR_FOREACH (seq, collection) { + seq->flag |= SELECT; } - SEQ_iterator_end(&iter); + + SEQ_collection_free(collection); return changed; } @@ -1711,7 +1676,7 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene, false); - Sequence *seq, *actseq = SEQ_select_active_get(scene); + Sequence *actseq = SEQ_select_active_get(scene); if (actseq == NULL) { BKE_report(op->reports, RPT_ERROR, "No active sequence!"); @@ -1725,11 +1690,10 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) bool changed = false; if (!extend) { - SEQ_CURRENT_BEGIN (ed, seq) { + LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { seq->flag &= ~SELECT; changed = true; } - SEQ_CURRENT_END; } switch (type) { |