From f0d20198b290338a9f58392f98ee43957b0bad61 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 28 Oct 2021 14:31:17 +1100 Subject: Sequencer: support basic selection & delete from previews Expose select & strip menus and shortcuts for sequencer preview. --- .../keyconfig/keymap_data/blender_default.py | 9 + release/scripts/startup/bl_ui/space_sequencer.py | 191 +++++++++++++-------- .../editors/space_sequencer/sequencer_edit.c | 16 +- .../editors/space_sequencer/sequencer_select.c | 121 ++++++++++--- source/blender/makesdna/DNA_sequence_types.h | 6 +- source/blender/sequencer/SEQ_iterator.h | 5 + source/blender/sequencer/intern/iterator.c | 26 +++ 7 files changed, 268 insertions(+), 106 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index fbc85b2164b..3a1ba3e22ff 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -2868,7 +2868,10 @@ def km_sequencerpreview(params): value=params.select_mouse_value_fallback, legacy=params.legacy, ), + *_template_items_select_actions(params, "sequencer.select_all"), + ("sequencer.select_box", {"type": 'B', "value": 'PRESS'}, None), + # View. ("sequencer.view_all_preview", {"type": 'HOME', "value": 'PRESS'}, None), ("sequencer.view_all_preview", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("sequencer.view_ghost_border", {"type": 'O', "value": 'PRESS'}, None), @@ -2886,6 +2889,8 @@ def km_sequencerpreview(params): {"properties": [("ratio", 0.25)]}), ("sequencer.view_zoom_ratio", {"type": 'NUMPAD_8', "value": 'PRESS'}, {"properties": [("ratio", 0.125)]}), + + # Edit. ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), op_tool_optional( ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), @@ -2902,6 +2907,10 @@ def km_sequencerpreview(params): {"properties": [("property", 'SCALE')]}), ("sequencer.strip_transform_clear", {"type": 'R', "alt": True, "value": 'PRESS'}, {"properties": [("property", 'ROTATION')]}), + + ("sequencer.delete", {"type": 'X', "value": 'PRESS'}, None), + ("sequencer.delete", {"type": 'DEL', "value": 'PRESS'}, None), + *_template_items_context_menu("SEQUENCER_MT_preview_context_menu", params.context_menu_event), ]) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index cdfe4f4068f..120b2d7c13a 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -37,6 +37,14 @@ from bl_ui.space_toolsystem_common import ( from rna_prop_ui import PropertyPanel +def _space_view_types(st): + view_type = st.view_type + return ( + view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}, + view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}, + ) + + def selected_sequences_len(context): selected_sequences = getattr(context, "selected_sequences", None) if selected_sequences is None: @@ -228,15 +236,17 @@ class SEQUENCER_MT_editor_menus(Menu): def draw(self, context): layout = self.layout st = context.space_data + has_sequencer, _has_preview = _space_view_types(st) layout.menu("SEQUENCER_MT_view") + layout.menu("SEQUENCER_MT_select") - if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}: - layout.menu("SEQUENCER_MT_select") + if has_sequencer: if st.show_markers: layout.menu("SEQUENCER_MT_marker") layout.menu("SEQUENCER_MT_add") - layout.menu("SEQUENCER_MT_strip") + + layout.menu("SEQUENCER_MT_strip") layout.menu("SEQUENCER_MT_image") @@ -561,8 +571,14 @@ class SEQUENCER_MT_select_linked(Menu): class SEQUENCER_MT_select(Menu): bl_label = "Select" - def draw(self, _context): + def draw(self, context): layout = self.layout + st = context.space_data + has_sequencer, has_preview = _space_view_types(st) + + # FIXME: this doesn't work for both preview + window region. + if has_preview: + layout.operator_context = 'INVOKE_REGION_PREVIEW' layout.operator("sequencer.select_all", text="All").action = 'SELECT' layout.operator("sequencer.select_all", text="None").action = 'DESELECT' @@ -571,17 +587,20 @@ class SEQUENCER_MT_select(Menu): layout.separator() layout.operator("sequencer.select_box", text="Box Select") - props = layout.operator("sequencer.select_box", text="Box Select (Include Handles)") - props.include_handles = True + if has_sequencer: + props = layout.operator("sequencer.select_box", text="Box Select (Include Handles)") + props.include_handles = True layout.separator() - layout.operator_menu_enum("sequencer.select_side_of_frame", "side", text="Side of Frame...") - layout.menu("SEQUENCER_MT_select_handle", text="Handle") - layout.menu("SEQUENCER_MT_select_channel", text="Channel") - layout.menu("SEQUENCER_MT_select_linked", text="Linked") + if has_sequencer: + layout.operator_menu_enum("sequencer.select_side_of_frame", "side", text="Side of Frame...") + layout.menu("SEQUENCER_MT_select_handle", text="Handle") + layout.menu("SEQUENCER_MT_select_channel", text="Channel") + layout.menu("SEQUENCER_MT_select_linked", text="Linked") + + layout.separator() - layout.separator() layout.operator_menu_enum("sequencer.select_grouped", "type", text="Grouped") @@ -792,23 +811,40 @@ class SEQUENCER_MT_add_effect(Menu): class SEQUENCER_MT_strip_transform(Menu): bl_label = "Transform" - def draw(self, _context): + def draw(self, context): layout = self.layout + st = context.space_data + has_sequencer, has_preview = _space_view_types(st) - layout.operator("transform.seq_slide", text="Move") - layout.operator("transform.transform", text="Move/Extend from Current Frame").mode = 'TIME_EXTEND' - layout.operator("sequencer.slip", text="Slip Strip Contents") + if has_preview: + layout.operator_context = 'INVOKE_REGION_PREVIEW' + else: + layout.operator_context = 'INVOKE_REGION_WIN' - layout.separator() - layout.operator("sequencer.snap") - layout.operator("sequencer.offset_clear") + # FIXME: mixed preview/sequencer views. + if has_preview: + layout.operator("transform.translate", text="Move") + layout.operator("transform.rotate", text="Rotate") + layout.operator("transform.resize", text="Scale") + else: + layout.operator("transform.seq_slide", text="Move") + layout.operator("transform.transform", text="Move/Extend from Current Frame").mode = 'TIME_EXTEND' + layout.operator("sequencer.slip", text="Slip Strip Contents") - layout.separator() - layout.operator_menu_enum("sequencer.swap", "side") + # TODO (for preview) + if has_sequencer: + layout.separator() + layout.operator("sequencer.snap") + layout.operator("sequencer.offset_clear") - layout.separator() - layout.operator("sequencer.gap_remove").all = False - layout.operator("sequencer.gap_insert") + layout.separator() + + if has_sequencer: + layout.operator_menu_enum("sequencer.swap", "side") + + layout.separator() + layout.operator("sequencer.gap_remove").all = False + layout.operator("sequencer.gap_insert") class SEQUENCER_MT_strip_input(Menu): @@ -878,68 +914,79 @@ class SEQUENCER_MT_strip(Menu): def draw(self, context): layout = self.layout + st = context.space_data + has_sequencer, has_preview = _space_view_types(st) - layout.operator_context = 'INVOKE_REGION_WIN' + # FIXME: this doesn't work for both preview + window region. + if has_preview: + layout.operator_context = 'INVOKE_REGION_PREVIEW' + else: + layout.operator_context = 'INVOKE_REGION_WIN' - layout.separator() layout.menu("SEQUENCER_MT_strip_transform") - layout.separator() - layout.operator("sequencer.split", text="Split").type = 'SOFT' - layout.operator("sequencer.split", text="Hold Split").type = 'HARD' - layout.separator() - layout.operator("sequencer.copy", text="Copy") - layout.operator("sequencer.paste", text="Paste") - layout.operator("sequencer.duplicate_move") + if has_sequencer: + + layout.operator("sequencer.split", text="Split").type = 'SOFT' + layout.operator("sequencer.split", text="Hold Split").type = 'HARD' + layout.separator() + + if has_sequencer: + layout.operator("sequencer.copy", text="Copy") + layout.operator("sequencer.paste", text="Paste") + layout.operator("sequencer.duplicate_move") + layout.operator("sequencer.delete", text="Delete") strip = context.active_sequence_strip - if strip: - strip_type = strip.type - - if strip_type != 'SOUND': - layout.separator() - layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier") - layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection") + if has_sequencer: + if strip: + strip_type = strip.type - if strip_type in { - 'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', - 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW', - 'TRANSFORM', 'COLOR', 'SPEED', 'MULTICAM', 'ADJUSTMENT', - 'GAUSSIAN_BLUR', - }: - layout.separator() - layout.menu("SEQUENCER_MT_strip_effect") - elif strip_type == 'MOVIE': - layout.separator() - layout.menu("SEQUENCER_MT_strip_movie") - elif strip_type == 'IMAGE': - layout.separator() - layout.operator("sequencer.rendersize") - layout.operator("sequencer.images_separate") - elif strip_type == 'TEXT': - layout.separator() - layout.menu("SEQUENCER_MT_strip_effect") - elif strip_type == 'META': - layout.separator() - layout.operator("sequencer.meta_make") - layout.operator("sequencer.meta_separate") - layout.operator("sequencer.meta_toggle", text="Toggle Meta") - if strip_type != 'META': - layout.separator() - layout.operator("sequencer.meta_make") - layout.operator("sequencer.meta_toggle", text="Toggle Meta") + if strip_type != 'SOUND': + layout.separator() + layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier") + layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection") + + if strip_type in { + 'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', + 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW', + 'TRANSFORM', 'COLOR', 'SPEED', 'MULTICAM', 'ADJUSTMENT', + 'GAUSSIAN_BLUR', + }: + layout.separator() + layout.menu("SEQUENCER_MT_strip_effect") + elif strip_type == 'MOVIE': + layout.separator() + layout.menu("SEQUENCER_MT_strip_movie") + elif strip_type == 'IMAGE': + layout.separator() + layout.operator("sequencer.rendersize") + layout.operator("sequencer.images_separate") + elif strip_type == 'TEXT': + layout.separator() + layout.menu("SEQUENCER_MT_strip_effect") + elif strip_type == 'META': + layout.separator() + layout.operator("sequencer.meta_make") + layout.operator("sequencer.meta_separate") + layout.operator("sequencer.meta_toggle", text="Toggle Meta") + if strip_type != 'META': + layout.separator() + layout.operator("sequencer.meta_make") + layout.operator("sequencer.meta_toggle", text="Toggle Meta") - layout.separator() - layout.menu("SEQUENCER_MT_color_tag_picker") + if has_sequencer: + layout.separator() + layout.menu("SEQUENCER_MT_color_tag_picker") - layout.separator() - layout.menu("SEQUENCER_MT_strip_lock_mute") + layout.separator() + layout.menu("SEQUENCER_MT_strip_lock_mute") - layout.separator() - layout.menu("SEQUENCER_MT_strip_input") + layout.separator() + layout.menu("SEQUENCER_MT_strip_input") class SEQUENCER_MT_image(Menu): diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 2a29125af19..8c70f4e3f7a 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1709,16 +1709,24 @@ 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); + ListBase *seqbasep = SEQ_active_seqbase_get(SEQ_editing_get(scene)); SEQ_prefetch_stop(scene); - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + const bool is_preview = sequencer_view_preview_poll(C); + if (is_preview) { + SEQ_query_rendered_strips_to_tag(seqbasep, scene->r.cfra, 0); + } + + LISTBASE_FOREACH (Sequence *, seq, seqbasep) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (seq->flag & SELECT) { - SEQ_edit_flag_for_removal(scene, ed->seqbasep, seq); + SEQ_edit_flag_for_removal(scene, seqbasep, seq); } } - SEQ_edit_remove_flagged_sequences(scene, ed->seqbasep); + SEQ_edit_remove_flagged_sequences(scene, seqbasep); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 1cc7507e5f6..8a8a24f08ff 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -416,9 +416,17 @@ static int sequencer_de_select_all_exec(bContext *C, wmOperator *op) Editing *ed = SEQ_editing_get(scene); Sequence *seq; + const bool is_preview = sequencer_view_preview_poll(C); + if (is_preview) { + SEQ_query_rendered_strips_to_tag(ed->seqbasep, scene->r.cfra, 0); + } + if (action == SEL_TOGGLE) { action = SEL_SELECT; for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (seq->flag & SEQ_ALLSEL) { action = SEL_DESELECT; break; @@ -427,6 +435,9 @@ static int sequencer_de_select_all_exec(bContext *C, wmOperator *op) } for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } switch (action) { case SEL_SELECT: seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL); @@ -483,7 +494,15 @@ static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) Editing *ed = SEQ_editing_get(scene); Sequence *seq; + const bool is_preview = sequencer_view_preview_poll(C); + if (is_preview) { + SEQ_query_rendered_strips_to_tag(ed->seqbasep, scene->r.cfra, 0); + } + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (seq->flag & SELECT) { seq->flag &= ~SEQ_ALLSEL; } @@ -1748,11 +1767,17 @@ static const EnumPropertyItem sequencer_prop_select_grouped_types[] = { #define SEQ_CHANNEL_CHECK(_seq, _chan) (ELEM((_chan), 0, (_seq)->machine)) -static bool select_grouped_type(Editing *ed, Sequence *actseq, const int channel) +static bool select_grouped_type(ListBase *seqbasep, + const bool is_preview, + Sequence *actseq, + const int channel) { bool changed = false; - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbasep) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == actseq->type) { seq->flag |= SELECT; changed = true; @@ -1762,12 +1787,18 @@ static bool select_grouped_type(Editing *ed, Sequence *actseq, const int channel return changed; } -static bool select_grouped_type_basic(Editing *ed, Sequence *actseq, const int channel) +static bool select_grouped_type_basic(ListBase *seqbase, + const bool is_preview, + Sequence *actseq, + const int channel) { bool changed = false; const bool is_sound = SEQ_IS_SOUND(actseq); - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (SEQ_CHANNEL_CHECK(seq, channel) && (is_sound ? SEQ_IS_SOUND(seq) : !SEQ_IS_SOUND(seq))) { seq->flag |= SELECT; changed = true; @@ -1777,12 +1808,18 @@ static bool select_grouped_type_basic(Editing *ed, Sequence *actseq, const int c return changed; } -static bool select_grouped_type_effect(Editing *ed, Sequence *actseq, const int channel) +static bool select_grouped_type_effect(ListBase *seqbase, + const bool is_preview, + Sequence *actseq, + const int channel) { bool changed = false; const bool is_effect = SEQ_IS_EFFECT(actseq); - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (SEQ_CHANNEL_CHECK(seq, channel) && (is_effect ? SEQ_IS_EFFECT(seq) : !SEQ_IS_EFFECT(seq))) { seq->flag |= SELECT; @@ -1793,7 +1830,10 @@ static bool select_grouped_type_effect(Editing *ed, Sequence *actseq, const int return changed; } -static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel) +static bool select_grouped_data(ListBase *seqbase, + const bool is_preview, + Sequence *actseq, + const int channel) { bool changed = false; const char *dir = actseq->strip ? actseq->strip->dir : NULL; @@ -1803,7 +1843,10 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel } if (SEQ_HAS_PATH(actseq) && dir) { - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (SEQ_CHANNEL_CHECK(seq, channel) && SEQ_HAS_PATH(seq) && seq->strip && STREQ(seq->strip->dir, dir)) { seq->flag |= SELECT; @@ -1813,7 +1856,7 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel } else if (actseq->type == SEQ_TYPE_SCENE) { Scene *sce = actseq->scene; - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_SCENE && seq->scene == sce) { seq->flag |= SELECT; changed = true; @@ -1822,7 +1865,7 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel } else if (actseq->type == SEQ_TYPE_MOVIECLIP) { MovieClip *clip = actseq->clip; - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MOVIECLIP && seq->clip == clip) { seq->flag |= SELECT; @@ -1832,7 +1875,7 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel } else if (actseq->type == SEQ_TYPE_MASK) { struct Mask *mask = actseq->mask; - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MASK && seq->mask == mask) { seq->flag |= SELECT; changed = true; @@ -1843,7 +1886,10 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel return changed; } -static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int channel) +static bool select_grouped_effect(ListBase *seqbase, + const bool is_preview, + Sequence *actseq, + const int channel) { bool changed = false; bool effects[SEQ_TYPE_MAX + 1]; @@ -1852,14 +1898,20 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann effects[i] = false; } - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (SEQ_CHANNEL_CHECK(seq, channel) && (seq->type & SEQ_TYPE_EFFECT) && ELEM(actseq, seq->seq1, seq->seq2, seq->seq3)) { effects[seq->type] = true; } } - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (SEQ_CHANNEL_CHECK(seq, channel) && effects[seq->type]) { if (seq->seq1) { seq->seq1->flag |= SELECT; @@ -1877,11 +1929,14 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann return changed; } -static bool select_grouped_time_overlap(Editing *ed, Sequence *actseq) +static bool select_grouped_time_overlap(ListBase *seqbase, const bool is_preview, Sequence *actseq) { bool changed = false; - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } if (seq->startdisp < actseq->enddisp && seq->enddisp > actseq->startdisp) { seq->flag |= SELECT; changed = true; @@ -1910,12 +1965,11 @@ static void query_lower_channel_strips(Sequence *seq_reference, /* 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, +static bool select_grouped_effect_link(ListBase *seqbase, + const bool is_preview, Sequence *UNUSED(actseq), const int UNUSED(channel)) { - ListBase *seqbase = SEQ_active_seqbase_get(ed); - /* Get collection of strips. */ SeqCollection *collection = SEQ_query_selected_strips(seqbase); const int selected_strip_count = BLI_gset_len(collection->set); @@ -1928,6 +1982,9 @@ static bool select_grouped_effect_link(Editing *ed, /* Actual logic. */ Sequence *seq; SEQ_ITERATOR_FOREACH (seq, collection) { + if (is_preview && (seq->tmp_tag == false)) { + continue; + } seq->flag |= SELECT; } @@ -1943,9 +2000,17 @@ static bool select_grouped_effect_link(Editing *ed, static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); Sequence *actseq = SEQ_select_active_get(scene); + const bool is_preview = sequencer_view_preview_poll(C); + if (is_preview) { + SEQ_query_rendered_strips_to_tag(seqbase, scene->r.cfra, 0); + if (actseq && actseq->tmp_tag == false) { + actseq = NULL; + } + } + if (actseq == NULL) { BKE_report(op->reports, RPT_ERROR, "No active sequence!"); return OPERATOR_CANCELLED; @@ -1958,7 +2023,7 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) bool changed = false; if (!extend) { - LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { + LISTBASE_FOREACH (Sequence *, seq, seqbase) { seq->flag &= ~SELECT; changed = true; } @@ -1966,25 +2031,25 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) switch (type) { case SEQ_SELECT_GROUP_TYPE: - changed |= select_grouped_type(ed, actseq, channel); + changed |= select_grouped_type(seqbase, is_preview, actseq, channel); break; case SEQ_SELECT_GROUP_TYPE_BASIC: - changed |= select_grouped_type_basic(ed, actseq, channel); + changed |= select_grouped_type_basic(seqbase, is_preview, actseq, channel); break; case SEQ_SELECT_GROUP_TYPE_EFFECT: - changed |= select_grouped_type_effect(ed, actseq, channel); + changed |= select_grouped_type_effect(seqbase, is_preview, actseq, channel); break; case SEQ_SELECT_GROUP_DATA: - changed |= select_grouped_data(ed, actseq, channel); + changed |= select_grouped_data(seqbase, is_preview, actseq, channel); break; case SEQ_SELECT_GROUP_EFFECT: - changed |= select_grouped_effect(ed, actseq, channel); + changed |= select_grouped_effect(seqbase, is_preview, actseq, channel); break; case SEQ_SELECT_GROUP_EFFECT_LINK: - changed |= select_grouped_effect_link(ed, actseq, channel); + changed |= select_grouped_effect_link(seqbase, is_preview, actseq, channel); break; case SEQ_SELECT_GROUP_OVERLAP: - changed |= select_grouped_time_overlap(ed, actseq); + changed |= select_grouped_time_overlap(seqbase, is_preview, actseq); break; default: BLI_assert(0); diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index af01bb76680..fc23d3c69a3 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -179,7 +179,9 @@ typedef struct Sequence { /** Starting and ending points of the strip in the sequence. */ int startdisp, enddisp; float sat; - float mul, handsize; + float mul; + char tmp_tag; + char _pad[3]; short anim_preseek; /* UNUSED. */ /** Streamindex for movie or sound files with several streams. */ @@ -250,7 +252,7 @@ typedef struct Sequence { /* Multiview */ char views_format; - char _pad[3]; + char _pad1[3]; struct Stereo3dFormat *stereo3d_format; struct IDProperty *prop; diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h index d2a47a13db3..4de7c09640b 100644 --- a/source/blender/sequencer/SEQ_iterator.h +++ b/source/blender/sequencer/SEQ_iterator.h @@ -104,6 +104,11 @@ void SEQ_query_strip_effect_chain(struct Sequence *seq_reference, SeqCollection *collection); void SEQ_filter_selected_strips(SeqCollection *collection); +/* Utilities to access these as tags. */ +int SEQ_query_rendered_strips_to_tag(ListBase *seqbase, + const int timeline_frame, + const int displayed_channel); + #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/iterator.c b/source/blender/sequencer/intern/iterator.c index a12a5cbdc61..68f632ddb28 100644 --- a/source/blender/sequencer/intern/iterator.c +++ b/source/blender/sequencer/intern/iterator.c @@ -520,3 +520,29 @@ void SEQ_filter_selected_strips(SeqCollection *collection) } } } + +static void seq_collection_to_tag(ListBase *seqbase, SeqCollection *collection) +{ + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + seq->tmp_tag = false; + } + Sequence *seq; + SEQ_ITERATOR_FOREACH (seq, collection) { + seq->tmp_tag = true; + } +} + +/* Utilities to access these as tags. */ +int SEQ_query_rendered_strips_to_tag(ListBase *seqbase, + const int timeline_frame, + const int displayed_channel) +{ + SeqCollection *collection = SEQ_query_rendered_strips( + seqbase, timeline_frame, displayed_channel); + + seq_collection_to_tag(seqbase, collection); + + const int len = SEQ_collection_len(collection); + SEQ_collection_free(collection); + return len; +} -- cgit v1.2.3