diff options
Diffstat (limited to 'source/blender/editors')
14 files changed, 595 insertions, 50 deletions
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index c0b94c46631..d718c8b0d95 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -43,8 +43,10 @@ #include "ED_clip.h" #include "ED_gpencil.h" +#include "SEQ_channels.h" #include "SEQ_select.h" #include "SEQ_sequencer.h" +#include "SEQ_transform.h" #include "UI_interface.h" #include "WM_api.h" @@ -645,9 +647,10 @@ static eContextResult screen_ctx_selected_editable_sequences(const bContext *C, wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); if (ed) { LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { - if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { + if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq)) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } } diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt index 07d696283cb..2d1785523d7 100644 --- a/source/blender/editors/space_sequencer/CMakeLists.txt +++ b/source/blender/editors/space_sequencer/CMakeLists.txt @@ -26,6 +26,8 @@ set(SRC sequencer_add.c sequencer_buttons.c sequencer_draw.c + sequencer_channels_draw.c + sequencer_channels_edit.c sequencer_edit.c sequencer_modifier.c sequencer_ops.c diff --git a/source/blender/editors/space_sequencer/sequencer_channels_draw.c b/source/blender/editors/space_sequencer/sequencer_channels_draw.c new file mode 100644 index 00000000000..5a43eade999 --- /dev/null +++ b/source/blender/editors/space_sequencer/sequencer_channels_draw.c @@ -0,0 +1,359 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup sequencer + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BKE_context.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "ED_screen.h" + +#include "GPU_framebuffer.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_matrix.h" +#include "GPU_state.h" +#include "GPU_vertex_buffer.h" +#include "GPU_viewport.h" + +#include "RNA_access.h" +#include "RNA_prototypes.h" + +#include "SEQ_channels.h" +#include "SEQ_sequencer.h" +#include "SEQ_time.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "WM_api.h" + +/* Own include. */ +#include "sequencer_intern.h" + +static ARegion *timeline_region_get(const ScrArea *area) +{ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (region->regiontype == RGN_TYPE_WINDOW) { + return region; + } + } + + BLI_assert_unreachable(); + return NULL; +} + +static float draw_offset_get(const View2D *timeline_region_v2d) +{ + return timeline_region_v2d->cur.ymin; +} + +static float channel_height_pixelspace_get(const View2D *timeline_region_v2d) +{ + return UI_view2d_view_to_region_y(timeline_region_v2d, 1.0f) - + UI_view2d_view_to_region_y(timeline_region_v2d, 0.0f); +} + +static float frame_width_pixelspace_get(const View2D *timeline_region_v2d) +{ + + return UI_view2d_view_to_region_x(timeline_region_v2d, 1.0f) - + UI_view2d_view_to_region_x(timeline_region_v2d, 0.0f); +} + +static float icon_width_get(const SeqChannelDrawContext *context) +{ + return (U.widget_unit * 0.8 * context->scale); +} + +static float widget_y_offset(const SeqChannelDrawContext *context) +{ + return (((context->channel_height / context->scale) - icon_width_get(context))) / 2; +} + +static float channel_index_y_min(const SeqChannelDrawContext *context, const int index) +{ + float y = (index - context->draw_offset) * context->channel_height; + y /= context->scale; + return y; +} + +static void displayed_channel_range_get(const SeqChannelDrawContext *context, + int r_channel_range[2]) +{ + /* Channel 0 is not usable, so should never be drawn. */ + r_channel_range[0] = max_ii(1, floor(context->timeline_region_v2d->cur.ymin)); + r_channel_range[1] = ceil(context->timeline_region_v2d->cur.ymax); + + rctf strip_boundbox; + BLI_rctf_init(&strip_boundbox, 0.0f, 0.0f, 1.0f, r_channel_range[1]); + SEQ_timeline_expand_boundbox(context->seqbase, &strip_boundbox); + CLAMP(r_channel_range[0], strip_boundbox.ymin, strip_boundbox.ymax); + CLAMP(r_channel_range[1], strip_boundbox.ymin, MAXSEQ); +} + +static char *draw_channel_widget_tooltip(bContext *UNUSED(C), void *argN, const char *UNUSED(tip)) +{ + char *dyn_tooltip = argN; + return BLI_strdup(dyn_tooltip); +} + +static float draw_channel_widget_mute(const SeqChannelDrawContext *context, + uiBlock *block, + const int channel_index, + const float offset) +{ + float y = channel_index_y_min(context, channel_index) + widget_y_offset(context); + + const float width = icon_width_get(context); + SeqTimelineChannel *channel = SEQ_channel_get_by_index(context->channels, channel_index); + const int icon = SEQ_channel_is_muted(channel) ? ICON_CHECKBOX_DEHLT : ICON_CHECKBOX_HLT; + + PointerRNA ptr; + RNA_pointer_create(&context->scene->id, &RNA_SequenceTimelineChannel, channel, &ptr); + PropertyRNA *hide_prop = RNA_struct_type_find_property(&RNA_SequenceTimelineChannel, "mute"); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + uiBut *but = uiDefIconButR_prop(block, + UI_BTYPE_TOGGLE, + 1, + icon, + context->v2d->cur.xmax / context->scale - offset, + y, + width, + width, + &ptr, + hide_prop, + 0, + 0, + 0, + 0, + 0, + NULL); + + char *tooltip = BLI_sprintfN( + "%s channel %d", SEQ_channel_is_muted(channel) ? "Unmute" : "Mute", channel_index); + UI_but_func_tooltip_set(but, draw_channel_widget_tooltip, tooltip, MEM_freeN); + + return width; +} + +static float draw_channel_widget_lock(const SeqChannelDrawContext *context, + uiBlock *block, + const int channel_index, + const float offset) +{ + + float y = channel_index_y_min(context, channel_index) + widget_y_offset(context); + const float width = icon_width_get(context); + + SeqTimelineChannel *channel = SEQ_channel_get_by_index(context->channels, channel_index); + const int icon = SEQ_channel_is_locked(channel) ? ICON_LOCKED : ICON_UNLOCKED; + + PointerRNA ptr; + RNA_pointer_create(&context->scene->id, &RNA_SequenceTimelineChannel, channel, &ptr); + PropertyRNA *hide_prop = RNA_struct_type_find_property(&RNA_SequenceTimelineChannel, "lock"); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + uiBut *but = uiDefIconButR_prop(block, + UI_BTYPE_TOGGLE, + 1, + icon, + context->v2d->cur.xmax / context->scale - offset, + y, + width, + width, + &ptr, + hide_prop, + 0, + 0, + 0, + 0, + 0, + ""); + + char *tooltip = BLI_sprintfN( + "%s channel %d", SEQ_channel_is_locked(channel) ? "Unlock" : "Lock", channel_index); + UI_but_func_tooltip_set(but, draw_channel_widget_tooltip, tooltip, MEM_freeN); + + return width; +} + +static bool channel_is_being_renamed(const SpaceSeq *sseq, const int channel_index) +{ + return sseq->runtime.rename_channel_index == channel_index; +} + +static float text_size_get(const SeqChannelDrawContext *context) +{ + const uiStyle *style = UI_style_get_dpi(); + return UI_fontstyle_height_max(&style->widget) * 1.5f * context->scale; +} + +/* Todo: decide what gets priority - label or buttons */ +static rctf label_rect_init(const SeqChannelDrawContext *context, + const int channel_index, + const float used_width) +{ + float text_size = text_size_get(context); + float margin = (context->channel_height / context->scale - text_size) / 2.0f; + float y = channel_index_y_min(context, channel_index) + margin; + + float margin_x = icon_width_get(context) * 0.65; + float width = max_ff(0.0f, context->v2d->cur.xmax / context->scale - used_width); + + /* Text input has own margin. Prevent text jumping around and use as much space as possible. */ + if (channel_is_being_renamed(CTX_wm_space_seq(context->C), channel_index)) { + float input_box_margin = icon_width_get(context) * 0.5f; + margin_x -= input_box_margin; + width += input_box_margin; + } + + rctf rect; + BLI_rctf_init(&rect, margin_x, margin_x + width, y, y + text_size); + return rect; +} + +static void draw_channel_labels(const SeqChannelDrawContext *context, + uiBlock *block, + const int channel_index, + const float used_width) +{ + SpaceSeq *sseq = CTX_wm_space_seq(context->C); + rctf rect = label_rect_init(context, channel_index, used_width); + + if (BLI_rctf_size_y(&rect) <= 1.0f || BLI_rctf_size_x(&rect) <= 1.0f) { + return; + } + + if (channel_is_being_renamed(sseq, channel_index)) { + SeqTimelineChannel *channel = SEQ_channel_get_by_index(context->channels, channel_index); + PointerRNA ptr = {NULL}; + RNA_pointer_create(&context->scene->id, &RNA_SequenceTimelineChannel, channel, &ptr); + PropertyRNA *prop = RNA_struct_name_property(ptr.type); + + UI_block_emboss_set(block, UI_EMBOSS); + uiBut *but = uiDefButR(block, + UI_BTYPE_TEXT, + 1, + "", + rect.xmin, + rect.ymin, + BLI_rctf_size_x(&rect), + BLI_rctf_size_y(&rect), + &ptr, + RNA_property_identifier(prop), + -1, + 0, + 0, + 0, + 0, + NULL); + UI_block_emboss_set(block, UI_EMBOSS_NONE); + + if (UI_but_active_only(context->C, context->region, block, but) == false) { + sseq->runtime.rename_channel_index = 0; + } + + WM_event_add_notifier(context->C, NC_SCENE | ND_SEQUENCER, context->scene); + } + else { + const char *label = SEQ_channel_name_get(context->channels, channel_index); + uiDefBut(block, + UI_BTYPE_LABEL, + 0, + label, + rect.xmin, + rect.ymin, + rect.xmax - rect.xmin, + (rect.ymax - rect.ymin), + NULL, + 0, + 0, + 0, + 0, + NULL); + } +} + +/* Todo: different text/buttons alignment */ +static void draw_channel_header(const SeqChannelDrawContext *context, + uiBlock *block, + const int channel_index) +{ + float offset = icon_width_get(context) * 1.5f; + offset += draw_channel_widget_lock(context, block, channel_index, offset); + offset += draw_channel_widget_mute(context, block, channel_index, offset); + + draw_channel_labels(context, block, channel_index, offset); +} + +static void draw_channel_headers(const SeqChannelDrawContext *context) +{ + GPU_matrix_push(); + wmOrtho2_pixelspace(context->region->winx / context->scale, + context->region->winy / context->scale); + uiBlock *block = UI_block_begin(context->C, context->region, __func__, UI_EMBOSS); + + int channel_range[2]; + displayed_channel_range_get(context, channel_range); + + for (int channel = channel_range[0]; channel <= channel_range[1]; channel++) { + draw_channel_header(context, block, channel); + } + + UI_block_end(context->C, block); + UI_block_draw(context->C, block); + + GPU_matrix_pop(); +} + +static void draw_background(void) +{ + UI_ThemeClearColor(TH_BACK); +} + +void channel_draw_context_init(const bContext *C, + ARegion *region, + SeqChannelDrawContext *r_context) +{ + r_context->C = C; + r_context->area = CTX_wm_area(C); + r_context->region = region; + r_context->v2d = ®ion->v2d; + r_context->scene = CTX_data_scene(C); + r_context->ed = SEQ_editing_get(r_context->scene); + r_context->seqbase = SEQ_active_seqbase_get(r_context->ed); + r_context->channels = SEQ_channels_displayed_get(r_context->ed); + r_context->timeline_region = timeline_region_get(CTX_wm_area(C)); + r_context->timeline_region_v2d = &r_context->timeline_region->v2d; + + r_context->channel_height = channel_height_pixelspace_get(r_context->timeline_region_v2d); + r_context->frame_width = frame_width_pixelspace_get(r_context->timeline_region_v2d); + r_context->draw_offset = draw_offset_get(r_context->timeline_region_v2d); + + r_context->scale = min_ff(r_context->channel_height / (U.widget_unit * 0.6), 1); +} + +void draw_channels(const bContext *C, ARegion *region) +{ + SeqChannelDrawContext context; + channel_draw_context_init(C, region, &context); + + UI_view2d_view_ortho(context.v2d); + + draw_background(); + draw_channel_headers(&context); + + UI_view2d_view_restore(C); +} diff --git a/source/blender/editors/space_sequencer/sequencer_channels_edit.c b/source/blender/editors/space_sequencer/sequencer_channels_edit.c new file mode 100644 index 00000000000..5a9189f74a8 --- /dev/null +++ b/source/blender/editors/space_sequencer/sequencer_channels_edit.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup sequencer + */ + +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_windowmanager_types.h" + +#include "BKE_context.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "ED_screen.h" + +#include "UI_view2d.h" + +#include "SEQ_channels.h" +#include "SEQ_sequencer.h" +#include "SEQ_time.h" + +#include "WM_api.h" + +#include "RNA_define.h" +#include "RNA_enum_types.h" + +/* Own include. */ +#include "sequencer_intern.h" + +static int sequencer_rename_channel_invoke(bContext *C, + wmOperator *UNUSED(op), + const wmEvent *event) +{ + SeqChannelDrawContext context; + SpaceSeq *sseq = CTX_wm_space_seq(C); + channel_draw_context_init(C, CTX_wm_region(C), &context); + float mouse_y = UI_view2d_region_to_view_y(context.timeline_region_v2d, event->mval[1]); + + sseq->runtime.rename_channel_index = mouse_y; + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, CTX_data_scene(C)); + return OPERATOR_FINISHED; +} + +void SEQUENCER_OT_rename_channel(struct wmOperatorType *ot) +{ + /* Identifiers. */ + ot->name = "Rename Channel"; + ot->idname = "SEQUENCER_OT_rename_channel"; + + /* Api callbacks. */ + ot->invoke = sequencer_rename_channel_invoke; + ot->poll = sequencer_edit_poll; + + /* Flags. */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 0ed366209f6..31e885d16f2 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -56,6 +56,7 @@ #include "RNA_prototypes.h" +#include "SEQ_channels.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" #include "SEQ_prefetch.h" @@ -95,6 +96,9 @@ void color3ubv_from_seq(const Scene *curscene, const bool show_strip_color_tag, uchar r_col[3]) { + Editing *ed = SEQ_editing_get(curscene); + ListBase *channels = SEQ_channels_displayed_get(ed); + if (show_strip_color_tag && (uint)seq->color_tag < SEQUENCE_COLOR_TOT && seq->color_tag != SEQUENCE_COLOR_NONE) { bTheme *btheme = UI_GetTheme(); @@ -214,7 +218,7 @@ void color3ubv_from_seq(const Scene *curscene, case SEQ_TYPE_SOUND_RAM: UI_GetThemeColor3ubv(TH_SEQ_AUDIO, r_col); blendcol[0] = blendcol[1] = blendcol[2] = 128; - if (seq->flag & SEQ_MUTE) { + if (SEQ_render_is_muted(channels, seq)) { UI_GetColorPtrBlendShade3ubv(r_col, blendcol, r_col, 0.5, 20); } break; @@ -568,6 +572,8 @@ static void drawmeta_contents(Scene *scene, float y2, const bool show_strip_color_tag) { + Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); Sequence *seq; uchar col[4]; @@ -625,7 +631,7 @@ static void drawmeta_contents(Scene *scene, color3ubv_from_seq(scene, seq, show_strip_color_tag, col); } - if ((seqm->flag & SEQ_MUTE) || (seq->flag & SEQ_MUTE)) { + if (SEQ_render_is_muted(channels, seqm) || SEQ_render_is_muted(channels, seq)) { col[3] = 64; } else { @@ -919,7 +925,8 @@ static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq, } /* Draw info text on a sequence strip. */ -static void draw_seq_text_overlay(View2D *v2d, +static void draw_seq_text_overlay(Scene *scene, + View2D *v2d, Sequence *seq, SpaceSeq *sseq, float x1, @@ -928,6 +935,8 @@ static void draw_seq_text_overlay(View2D *v2d, float y2, bool seq_active) { + Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); char overlay_string[FILE_MAX]; size_t overlay_string_len = draw_seq_text_get_overlay_string( sseq, seq, overlay_string, sizeof(overlay_string)); @@ -942,7 +951,7 @@ static void draw_seq_text_overlay(View2D *v2d, col[3] = 255; /* Make the text duller when the strip is muted. */ - if (seq->flag & SEQ_MUTE) { + if (SEQ_render_is_muted(channels, seq)) { if (seq_active) { UI_GetColorPtrShade3ubv(col, col, -70); } @@ -963,6 +972,8 @@ static void draw_seq_text_overlay(View2D *v2d, static void draw_sequence_extensions_overlay( Scene *scene, Sequence *seq, uint pos, float pixely, const bool show_strip_color_tag) { + Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); float x1, x2, y1, y2; uchar col[4], blend_col[3]; @@ -978,7 +989,7 @@ static void draw_sequence_extensions_overlay( if (seq->flag & SELECT) { UI_GetColorPtrShade3ubv(col, col, 50); } - col[3] = seq->flag & SEQ_MUTE ? MUTE_ALPHA : 200; + col[3] = SEQ_render_is_muted(channels, seq) ? MUTE_ALPHA : 200; UI_GetColorPtrShade3ubv(col, blend_col, 10); if (seq->startofs) { @@ -1001,7 +1012,8 @@ static void draw_sequence_extensions_overlay( GPU_blend(GPU_BLEND_NONE); } -static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, float y1) +static void draw_color_strip_band( + ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1) { uchar col[4]; SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; @@ -1010,7 +1022,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, rgb_float_to_uchar(col, colvars->col); /* Draw muted strips semi-transparent. */ - if (seq->flag & SEQ_MUTE) { + if (SEQ_render_is_muted(channels, seq)) { col[3] = MUTE_ALPHA; } /* Draw background semi-transparent when overlapping strips. */ @@ -1047,6 +1059,8 @@ static void draw_seq_background(Scene *scene, bool is_single_image, bool show_strip_color_tag) { + Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); uchar col[4]; GPU_blend(GPU_BLEND_ALPHA); @@ -1066,7 +1080,7 @@ static void draw_seq_background(Scene *scene, } /* Draw muted strips semi-transparent. */ - if (seq->flag & SEQ_MUTE) { + if (SEQ_render_is_muted(channels, seq)) { col[3] = MUTE_ALPHA; } /* Draw background semi-transparent when overlapping strips. */ @@ -1303,6 +1317,9 @@ static void draw_seq_strip(const bContext *C, float pixelx, bool seq_active) { + Editing *ed = SEQ_editing_get(CTX_data_scene(C)); + ListBase *channels = SEQ_channels_displayed_get(ed); + View2D *v2d = ®ion->v2d; float x1, x2, y1, y2; const float handsize_clamped = sequence_handle_size_get_clamped(seq, pixelx); @@ -1349,7 +1366,7 @@ static void draw_seq_strip(const bContext *C, /* Draw a color band inside color strip. */ if (seq->type == SEQ_TYPE_COLOR && y_threshold) { - draw_color_strip_band(seq, pos, text_margin_y, y1); + draw_color_strip_band(channels, seq, pos, text_margin_y, y1); } /* Draw strip offsets when flag is enabled or during "solo preview". */ @@ -1398,7 +1415,7 @@ static void draw_seq_strip(const bContext *C, BLI_rctf_size_x(®ion->v2d.cur) / region->winx); } /* Draw locked state. */ - if (seq->flag & SEQ_LOCK) { + if (SEQ_transform_is_locked(channels, seq)) { draw_seq_locked(x1, y1, x2, y2); } @@ -1410,7 +1427,7 @@ static void draw_seq_strip(const bContext *C, pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - if ((seq->flag & SEQ_LOCK) == 0) { + if (!SEQ_transform_is_locked(channels, seq)) { draw_seq_handle( v2d, seq, handsize_clamped, SEQ_LEFTHANDLE, pos, seq_active, pixelx, y_threshold); draw_seq_handle( @@ -1437,7 +1454,7 @@ static void draw_seq_strip(const bContext *C, if (((x2 - x1) > 32 * pixelx * U.dpi_fac) && ((y2 - y1) > 8 * pixely * U.dpi_fac)) { /* Depending on the vertical space, draw text on top or in the center of strip. */ draw_seq_text_overlay( - v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active); + scene, v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active); } } } @@ -2218,7 +2235,10 @@ void sequencer_draw_preview(const bContext *C, } if (!draw_backdrop && scene->ed != NULL) { - SeqCollection *collection = SEQ_query_rendered_strips(scene->ed->seqbasep, timeline_frame, 0); + Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); + SeqCollection *collection = SEQ_query_rendered_strips( + channels, ed->seqbasep, timeline_frame, 0); Sequence *seq; Sequence *active_seq = SEQ_select_active_get(scene); SEQ_ITERATOR_FOREACH (seq, collection) { @@ -2269,14 +2289,6 @@ static void draw_seq_timeline_channels(View2D *v2d) immUnbindProgram(); } -static void draw_seq_timeline_channel_numbers(ARegion *region) -{ - View2D *v2d = ®ion->v2d; - rcti rect; - BLI_rcti_init(&rect, 0, 15 * UI_DPI_FAC, 15 * UI_DPI_FAC, region->winy - UI_TIME_SCRUB_MARGIN_Y); - UI_view2d_draw_scale_y__block(region, v2d, &rect, TH_SCROLL_TEXT); -} - static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) { Scene *scene = CTX_data_scene(C); @@ -2695,6 +2707,7 @@ void draw_timeline_seq(const bContext *C, ARegion *region) UI_view2d_view_ortho(v2d); draw_seq_timeline_channels(v2d); + if ((sseq->flag & SEQ_SHOW_OVERLAY) && (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_GRID)) { U.v2d_min_gridsize *= 3; UI_view2d_draw_lines_x__discrete_frames_or_seconds( @@ -2748,8 +2761,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region) UI_view2d_view_restore(C); ED_time_scrub_draw(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true); - - draw_seq_timeline_channel_numbers(region); } void draw_timeline_seq_display(const bContext *C, ARegion *region) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 283bd99cd5d..b77f780e413 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -32,6 +32,7 @@ #include "SEQ_add.h" #include "SEQ_animation.h" +#include "SEQ_channels.h" #include "SEQ_clipboard.h" #include "SEQ_edit.h" #include "SEQ_effects.h" @@ -345,6 +346,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); Sequence *seq; int snap_frame; @@ -352,7 +354,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) /* Check meta-strips. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK) && + if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq) && SEQ_transform_sequence_can_be_translated(seq)) { if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) { SEQ_transform_translate_sequence( @@ -374,7 +376,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) /* Test for effects and overlap. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { + if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq)) { seq->flag &= ~SEQ_OVERLAP; if (SEQ_transform_test_overlap(ed->seqbasep, seq)) { SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); @@ -918,13 +920,14 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); Sequence *seq; bool selected; selected = !RNA_boolean_get(op->ptr, "unselected"); for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((seq->flag & SEQ_LOCK) == 0) { + if (!SEQ_transform_is_locked(channels, seq)) { if (selected) { if (seq->flag & SELECT) { seq->flag |= SEQ_MUTE; @@ -974,13 +977,14 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); + ListBase *channels = SEQ_channels_displayed_get(ed); Sequence *seq; bool selected; selected = !RNA_boolean_get(op->ptr, "unselected"); for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((seq->flag & SEQ_LOCK) == 0) { + if (!SEQ_transform_is_locked(channels, seq)) { if (selected) { if (seq->flag & SELECT) { seq->flag &= ~SEQ_MUTE; @@ -1958,6 +1962,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* Enter meta-strip. */ SEQ_meta_stack_alloc(ed, active_seq); SEQ_seqbase_active_set(ed, &active_seq->seqbase); + SEQ_channels_displayed_set(ed, &active_seq->channels); SEQ_select_active_set(scene, NULL); } else { @@ -1968,6 +1973,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) MetaStack *ms = SEQ_meta_stack_active_get(ed); SEQ_seqbase_active_set(ed, ms->oldbasep); + SEQ_channels_displayed_set(ed, ms->old_channels); SEQ_select_active_set(scene, ms->parseq); SEQ_meta_stack_free(ed, ms); } @@ -3082,8 +3088,10 @@ typedef struct Seq_get_text_cb_data { static bool seq_get_text_strip_cb(Sequence *seq, void *user_data) { Seq_get_text_cb_data *cd = (Seq_get_text_cb_data *)user_data; + Editing *ed = SEQ_editing_get(cd->scene); + ListBase *channels = SEQ_channels_displayed_get(ed); /* Only text strips that are not muted and don't end with negative frame. */ - if ((seq->type == SEQ_TYPE_TEXT) && ((seq->flag & SEQ_MUTE) == 0) && + if ((seq->type == SEQ_TYPE_TEXT) && !SEQ_render_is_muted(channels, seq) && (seq->enddisp > cd->scene->r.sfra)) { BLI_addtail(cd->text_seq, MEM_dupallocN(seq)); } diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 33457103ff8..194aa518cd7 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -25,9 +25,31 @@ struct View2D; struct bContext; struct rctf; struct wmOperator; +struct ScrArea; +struct Editing; +struct ListBase; #define OVERLAP_ALPHA 180 +typedef struct SeqChannelDrawContext { + const struct bContext *C; + struct ScrArea *area; + struct ARegion *region; + struct ARegion *timeline_region; + struct View2D *v2d; + struct View2D *timeline_region_v2d; + + struct Scene *scene; + struct Editing *ed; + struct ListBase *seqbase; /* Displayed seqbase. */ + struct ListBase *channels; /* Displayed channels. */ + + float draw_offset; + float channel_height; + float frame_width; + float scale; +} SeqChannelDrawContext; + /* sequencer_draw.c */ void draw_timeline_seq(const struct bContext *C, struct ARegion *region); @@ -80,6 +102,12 @@ void draw_seq_strip_thumbnail(struct View2D *v2d, float pixelx, float pixely); +/* sequencer_draw_channels.c */ +void draw_channels(const struct bContext *C, struct ARegion *region); +void channel_draw_context_init(const struct bContext *C, + struct ARegion *region, + struct SeqChannelDrawContext *r_context); + /* sequencer_edit.c */ struct View2D; @@ -242,6 +270,9 @@ void SEQUENCER_OT_view_zoom_ratio(struct wmOperatorType *ot); void SEQUENCER_OT_view_selected(struct wmOperatorType *ot); void SEQUENCER_OT_view_ghost_border(struct wmOperatorType *ot); +/* sequencer_channels_edit.c */ +void SEQUENCER_OT_rename_channel(struct wmOperatorType *ot); + /* sequencer_preview.c */ void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index e39fcfbcb24..1aa2991f07a 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -102,6 +102,9 @@ void sequencer_operatortypes(void) WM_operatortype_append(SEQUENCER_OT_view_zoom_ratio); WM_operatortype_append(SEQUENCER_OT_view_selected); WM_operatortype_append(SEQUENCER_OT_view_ghost_border); + + /* sequencer_channels_edit.c */ + WM_operatortype_append(SEQUENCER_OT_rename_channel); } void sequencer_keymap(wmKeyConfig *keyconf) @@ -114,6 +117,9 @@ void sequencer_keymap(wmKeyConfig *keyconf) /* Preview Region ----------------------------------------------------------- */ WM_keymap_ensure(keyconf, "SequencerPreview", SPACE_SEQ, 0); + + /* Channels Region ----------------------------------------------------------- */ + WM_keymap_ensure(keyconf, "Sequencer Channels", SPACE_SEQ, 0); } void ED_operatormacros_sequencer(void) diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index bd6350960f1..66df1309d54 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -25,6 +25,7 @@ #include "RNA_define.h" +#include "SEQ_channels.h" #include "SEQ_iterator.h" #include "SEQ_select.h" #include "SEQ_sequencer.h" @@ -51,11 +52,13 @@ SeqCollection *all_strips_from_context(bContext *C) { Scene *scene = CTX_data_scene(C); - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); + Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); const bool is_preview = sequencer_view_has_preview_poll(C); if (is_preview) { - return SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); + return SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); } return SEQ_query_all_strips(seqbase); @@ -64,11 +67,13 @@ SeqCollection *all_strips_from_context(bContext *C) SeqCollection *selected_strips_from_context(bContext *C) { Scene *scene = CTX_data_scene(C); - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); + Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); const bool is_preview = sequencer_view_has_preview_poll(C); if (is_preview) { - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); + SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); return strips; } @@ -709,6 +714,7 @@ static Sequence *seq_select_seq_from_preview( Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); SpaceSeq *sseq = CTX_wm_space_seq(C); View2D *v2d = UI_view2d_fromcontext(C); @@ -718,7 +724,8 @@ static Sequence *seq_select_seq_from_preview( /* Always update the coordinates (check extended after). */ const bool use_cycle = (!WM_cursor_test_motion_and_update(mval) || extend || toggle); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, sseq->chanshown); + SeqCollection *strips = SEQ_query_rendered_strips( + channels, seqbase, scene->r.cfra, sseq->chanshown); /* Allow strips this far from the closest center to be included. * This allows cycling over center points which are near enough @@ -1574,9 +1581,11 @@ static void seq_box_select_seq_from_preview(const bContext *C, rctf *rect, const Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); SpaceSeq *sseq = CTX_wm_space_seq(C); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, sseq->chanshown); + SeqCollection *strips = SEQ_query_rendered_strips( + channels, seqbase, scene->r.cfra, sseq->chanshown); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, strips) { if (!seq_box_select_rect_image_isect(scene, seq, rect)) { diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index cd4ecd1a714..0a0669e02e4 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -131,6 +131,14 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce region->regiontype = RGN_TYPE_TOOLS; region->alignment = RGN_ALIGN_LEFT; region->flag = RGN_FLAG_HIDDEN; + region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL; + + /* Channels. */ + region = MEM_callocN(sizeof(ARegion), "channels for sequencer"); + + BLI_addtail(&sseq->regionbase, region); + region->regiontype = RGN_TYPE_CHANNELS; + region->alignment = RGN_ALIGN_LEFT; /* Preview region. */ /* NOTE: if you change values here, also change them in sequencer_init_preview_region. */ @@ -182,6 +190,7 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce region->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HANDLES); region->v2d.keepzoom = 0; region->v2d.keeptot = 0; + region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL; region->v2d.align = V2D_ALIGN_NO_NEG_Y; sseq->runtime.last_displayed_thumbnails = NULL; @@ -977,6 +986,24 @@ static void sequencer_id_remap(ScrArea *UNUSED(area), /* ************************************* */ +/* add handlers, stuff you only do once or on area/region changes */ +static void sequencer_channel_region_init(wmWindowManager *wm, ARegion *region) +{ + wmKeyMap *keymap; + + region->alignment = RGN_ALIGN_LEFT; + + UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy); + + keymap = WM_keymap_ensure(wm->defaultconf, "Sequencer Channels", SPACE_SEQ, 0); + WM_event_add_keymap_handler_v2d_mask(®ion->handlers, keymap); +} + +static void sequencer_channel_region_draw(const bContext *C, ARegion *region) +{ + draw_channels(C, region); +} + void ED_spacetype_sequencer(void) { SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype sequencer"); @@ -1048,6 +1075,16 @@ void ED_spacetype_sequencer(void) art->draw = sequencer_tools_region_draw; BLI_addhead(&st->regiontypes, art); + /* Channels. */ + art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer channels"); + art->regionid = RGN_TYPE_CHANNELS; + art->prefsizex = UI_COMPACT_PANEL_WIDTH; + art->keymapflag = ED_KEYMAP_UI; + art->init = sequencer_channel_region_init; + art->draw = sequencer_channel_region_draw; + art->listener = sequencer_main_region_listener; + BLI_addhead(&st->regiontypes, art); + /* Tool header. */ art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer tool header region"); art->regionid = RGN_TYPE_TOOL_HEADER; diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 513d45ef4bf..b355b459c1e 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -17,8 +17,10 @@ #include "BKE_report.h" #include "ED_markers.h" +#include "ED_time_scrub_ui.h" #include "SEQ_animation.h" +#include "SEQ_channels.h" #include "SEQ_edit.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" @@ -66,17 +68,19 @@ typedef struct TransSeq { */ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag) { + Scene *scene = t->scene; + Editing *ed = SEQ_editing_get(t->scene); + ListBase *channels = SEQ_channels_displayed_get(ed); + /* for extend we need to do some tricks */ if (t->mode == TFM_TIME_EXTEND) { /* *** Extend Transform *** */ - - Scene *scene = t->scene; int cfra = CFRA; int left = SEQ_transform_get_left_handle_frame(seq); int right = SEQ_transform_get_right_handle_frame(seq); - if (((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) { + if (((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq))) { *r_count = 0; *r_flag = 0; } @@ -115,7 +119,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag) /* Count */ /* Non nested strips (resect selection and handles) */ - if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) { + if ((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq)) { *r_count = 0; *r_flag = 0; } @@ -771,6 +775,7 @@ static void flushTransSeq(TransInfo *t) seq->flag |= SEQ_OVERLAP; } } + SEQ_collection_free(transformed_strips); } diff --git a/source/blender/editors/transform/transform_convert_sequencer_image.c b/source/blender/editors/transform/transform_convert_sequencer_image.c index 4a7c8d74d8b..cbc2cab0a7a 100644 --- a/source/blender/editors/transform/transform_convert_sequencer_image.c +++ b/source/blender/editors/transform/transform_convert_sequencer_image.c @@ -15,6 +15,7 @@ #include "BKE_context.h" #include "BKE_report.h" +#include "SEQ_channels.h" #include "SEQ_iterator.h" #include "SEQ_relations.h" #include "SEQ_sequencer.h" @@ -121,7 +122,8 @@ void createTransSeqImageData(TransInfo *t) } ListBase *seqbase = SEQ_active_seqbase_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, t->scene->r.cfra, 0); + ListBase *channels = SEQ_channels_displayed_get(ed); + SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, t->scene->r.cfra, 0); SEQ_filter_selected_strips(strips); const int count = SEQ_collection_len(strips); diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index 3b523708872..f2fb5b26305 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -36,6 +36,7 @@ #include "ED_screen.h" #include "ED_uvedit.h" +#include "SEQ_channels.h" #include "SEQ_iterator.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" @@ -243,8 +244,10 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min } else if (area->spacetype == SPACE_SEQ) { Scene *scene = CTX_data_scene(C); - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); + Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); + SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); int selected_strips = SEQ_collection_len(strips); if (selected_strips > 0) { @@ -303,7 +306,8 @@ static int gizmo2d_calc_transform_orientation(const bContext *C) Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); + ListBase *channels = SEQ_channels_displayed_get(ed); + SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); bool use_local_orient = SEQ_collection_len(strips) == 1; @@ -325,7 +329,8 @@ static float gizmo2d_calc_rotation(const bContext *C) Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); ListBase *seqbase = SEQ_active_seqbase_get(ed); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); + ListBase *channels = SEQ_channels_displayed_get(ed); + SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); if (SEQ_collection_len(strips) == 1) { @@ -348,8 +353,10 @@ static bool seq_get_strip_pivot_median(const Scene *scene, float r_pivot[2]) { zero_v2(r_pivot); - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); + Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); + SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); bool has_select = SEQ_collection_len(strips) != 0; @@ -385,8 +392,10 @@ static bool gizmo2d_calc_transform_pivot(const bContext *C, float r_pivot[2]) if (pivot_point == V3D_AROUND_CURSOR) { SEQ_image_preview_unit_to_px(scene, sseq->cursor, r_pivot); - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); - SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); + Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); + SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); has_select = SEQ_collection_len(strips) != 0; SEQ_collection_free(strips); diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c index 85e20d37278..cf229c9e9ec 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.c +++ b/source/blender/editors/transform/transform_snap_sequencer.c @@ -18,8 +18,10 @@ #include "UI_view2d.h" +#include "SEQ_channels.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" +#include "SEQ_render.h" #include "SEQ_sequencer.h" #include "transform.h" @@ -121,14 +123,16 @@ static SeqCollection *seq_collection_extract_effects(SeqCollection *collection) static SeqCollection *query_snap_targets(const TransInfo *t, SeqCollection *snap_sources) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene)); + Editing *ed = SEQ_editing_get(t->scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); const short snap_flag = SEQ_tool_settings_snap_flag_get(t->scene); SeqCollection *snap_targets = SEQ_collection_create(__func__); LISTBASE_FOREACH (Sequence *, seq, seqbase) { if (seq->flag & SELECT) { continue; /* Selected are being transformed. */ } - if ((seq->flag & SEQ_MUTE) && (snap_flag & SEQ_SNAP_IGNORE_MUTED)) { + if (SEQ_render_is_muted(channels, seq) && (snap_flag & SEQ_SNAP_IGNORE_MUTED)) { continue; } if (seq->type == SEQ_TYPE_SOUND_RAM && (snap_flag & SEQ_SNAP_IGNORE_SOUND)) { |