Sequencer: support basic selection & delete from previews
Expose select & strip menus and shortcuts for sequencer preview.
This commit is contained in:
parent
e1fb7740f8
commit
f0d20198b2
Notes:
blender-bot
2023-02-13 17:29:55 +01:00
Referenced by commit 1ef8ef4941
, Cleanup: Remove seq->tmp_flag DNA member
Referenced by issue #91998, Sequencer: preview TODO's
|
@ -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),
|
||||
])
|
||||
|
||||
|
|
|
@ -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 has_sequencer:
|
||||
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 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")
|
||||
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):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue