Fix: VSE: Overlap after moving a retiming key was not handled
Moving a strip retiming key at the end of a strip, so that a strip overlaps another one would leave them overlapped. The expected behavior is that it acts according to the Overlap Mode, like it does when moving a strip. Co-authored-by: Richard Antalik <richardantalik@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/124424
This commit is contained in:
parent
b2e3b6c393
commit
e13b2f3774
@ -1242,36 +1242,21 @@ static void draw_seq_timeline_channels(TimelineDrawContext *ctx)
|
||||
* sure that visually selected are always "on top" of others. It matters
|
||||
* while selection is being dragged over other strips. */
|
||||
static void visible_strips_ordered_get(TimelineDrawContext *timeline_ctx,
|
||||
Vector<StripDrawContext> &r_unselected,
|
||||
Vector<StripDrawContext> &r_selected)
|
||||
Vector<StripDrawContext> &r_bottom_layer,
|
||||
Vector<StripDrawContext> &r_top_layer)
|
||||
{
|
||||
Sequence *act_seq = SEQ_select_active_get(timeline_ctx->scene);
|
||||
r_bottom_layer.clear();
|
||||
r_top_layer.clear();
|
||||
|
||||
Vector<Sequence *> strips = sequencer_visible_strips_get(timeline_ctx->C);
|
||||
r_unselected.clear();
|
||||
r_selected.clear();
|
||||
|
||||
for (Sequence *seq : strips) {
|
||||
/* Active will be added last. */
|
||||
if (seq == act_seq) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StripDrawContext strip_ctx = strip_draw_context_get(timeline_ctx, seq);
|
||||
if ((seq->flag & SELECT) == 0) {
|
||||
r_unselected.append(strip_ctx);
|
||||
if ((seq->flag & SEQ_OVERLAP) == 0) {
|
||||
r_bottom_layer.append(strip_ctx);
|
||||
}
|
||||
else {
|
||||
r_selected.append(strip_ctx);
|
||||
}
|
||||
}
|
||||
/* Add active, if any. */
|
||||
if (act_seq) {
|
||||
StripDrawContext strip_ctx = strip_draw_context_get(timeline_ctx, act_seq);
|
||||
if ((act_seq->flag & SELECT) == 0) {
|
||||
r_unselected.append(strip_ctx);
|
||||
}
|
||||
else {
|
||||
r_selected.append(strip_ctx);
|
||||
r_top_layer.append(strip_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1407,18 +1392,26 @@ static void draw_strips_foreground(TimelineDrawContext *timeline_ctx,
|
||||
* - Slightly lighter.
|
||||
* - Red when overlapping with other strips. */
|
||||
const eSeqOverlapMode overlap_mode = SEQ_tool_settings_overlap_mode_get(timeline_ctx->scene);
|
||||
if ((G.moving & G_TRANSFORM_SEQ) && selected) {
|
||||
if (G.moving & G_TRANSFORM_SEQ) {
|
||||
if ((strip.seq->flag & SEQ_OVERLAP) && (overlap_mode != SEQ_OVERLAP_OVERWRITE)) {
|
||||
col[0] = 255;
|
||||
col[1] = col[2] = 33;
|
||||
}
|
||||
else {
|
||||
else if (selected) {
|
||||
UI_GetColorPtrShade3ubv(col, col, 70);
|
||||
}
|
||||
}
|
||||
if (selected)
|
||||
|
||||
const bool overlaps = (strip.seq->flag & SEQ_OVERLAP) && (G.moving & G_TRANSFORM_SEQ);
|
||||
if (overlaps) {
|
||||
data.flags |= GPU_SEQ_FLAG_OVERLAP;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
data.flags |= GPU_SEQ_FLAG_SELECTED;
|
||||
else if (active) {
|
||||
}
|
||||
else if (active && !overlaps) {
|
||||
/* If the strips overlap when retiming, don't replace the red outline. */
|
||||
/* A subtle highlight outline when active but not selected. */
|
||||
UI_GetThemeColorShade3ubv(TH_SEQ_ACTIVE, -40, col);
|
||||
data.flags |= GPU_SEQ_FLAG_ACTIVE;
|
||||
@ -1525,10 +1518,10 @@ static void draw_seq_strips(TimelineDrawContext *timeline_ctx, StripsDrawBatch &
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<StripDrawContext> unselected, selected;
|
||||
visible_strips_ordered_get(timeline_ctx, unselected, selected);
|
||||
draw_seq_strips(timeline_ctx, strips_batch, unselected);
|
||||
draw_seq_strips(timeline_ctx, strips_batch, selected);
|
||||
Vector<StripDrawContext> bottom_layer, top_layer;
|
||||
visible_strips_ordered_get(timeline_ctx, bottom_layer, top_layer);
|
||||
draw_seq_strips(timeline_ctx, strips_batch, bottom_layer);
|
||||
draw_seq_strips(timeline_ctx, strips_batch, top_layer);
|
||||
}
|
||||
|
||||
static void draw_timeline_sfra_efra(TimelineDrawContext *ctx)
|
||||
|
@ -24,6 +24,7 @@ struct TransData;
|
||||
struct TransDataCurveHandleFlags;
|
||||
struct TransInfo;
|
||||
struct bContext;
|
||||
struct Sequence;
|
||||
|
||||
struct TransConvertTypeInfo {
|
||||
int flags; /* #eTFlag. */
|
||||
@ -366,6 +367,8 @@ extern TransConvertTypeInfo TransConvertType_Sculpt;
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_Sequencer;
|
||||
|
||||
bool seq_transform_check_overlap(blender::Span<Sequence *> transformed_strips);
|
||||
|
||||
/* `transform_convert_sequencer_image.cc` */
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_SequencerImage;
|
||||
|
@ -286,7 +286,7 @@ static ListBase *seqbase_active_get(const TransInfo *t)
|
||||
return SEQ_active_seqbase_get(ed);
|
||||
}
|
||||
|
||||
static bool seq_transform_check_overlap(blender::Span<Sequence *> transformed_strips)
|
||||
bool seq_transform_check_overlap(blender::Span<Sequence *> transformed_strips)
|
||||
{
|
||||
for (Sequence *seq : transformed_strips) {
|
||||
if (seq->flag & SEQ_OVERLAP) {
|
||||
|
@ -8,16 +8,20 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
|
||||
#include "SEQ_iterator.hh"
|
||||
#include "SEQ_relations.hh"
|
||||
#include "SEQ_retiming.hh"
|
||||
#include "SEQ_sequencer.hh"
|
||||
#include "SEQ_transform.hh"
|
||||
|
||||
#include "transform.hh"
|
||||
#include "transform_convert.hh"
|
||||
@ -60,11 +64,34 @@ static TransData *SeqToTransData(const Scene *scene,
|
||||
return td;
|
||||
}
|
||||
|
||||
static void freeSeqData(TransInfo * /*t*/,
|
||||
TransDataContainer *tc,
|
||||
TransCustomData * /*custom_data*/)
|
||||
static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData * /*custom_data*/)
|
||||
{
|
||||
TransData *td = (TransData *)tc->data;
|
||||
const TransData *const td = (TransData *)tc->data;
|
||||
Scene *scene = t->scene;
|
||||
const Editing *ed = SEQ_editing_get(t->scene);
|
||||
|
||||
/* Handle overlapping strips. */
|
||||
|
||||
blender::VectorSet<Sequence *> transformed_strips;
|
||||
for (int i = 0; i < tc->data_len; i++) {
|
||||
Sequence *seq = ((TransDataSeq *)(td + i)->extra)->seq;
|
||||
transformed_strips.add(seq);
|
||||
}
|
||||
|
||||
ListBase *seqbasep = SEQ_active_seqbase_get(ed);
|
||||
SEQ_iterator_set_expand(scene, seqbasep, transformed_strips, SEQ_query_strip_effect_chain);
|
||||
|
||||
blender::VectorSet<Sequence *> dependant;
|
||||
dependant.add_multiple(transformed_strips);
|
||||
dependant.remove_if(
|
||||
[&](Sequence *seq) { return SEQ_transform_sequence_can_be_translated(seq); });
|
||||
|
||||
if (seq_transform_check_overlap(transformed_strips)) {
|
||||
const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
|
||||
SEQ_MARKER_TRANS) != 0;
|
||||
SEQ_transform_handle_overlap(scene, seqbasep, transformed_strips, dependant, use_sync_markers);
|
||||
}
|
||||
|
||||
MEM_freeN(td->extra);
|
||||
}
|
||||
|
||||
@ -103,10 +130,14 @@ static void recalcData_sequencer_retiming(TransInfo *t)
|
||||
const TransData2D *td2d = nullptr;
|
||||
int i;
|
||||
|
||||
blender::VectorSet<Sequence *> transformed_strips;
|
||||
|
||||
for (i = 0, td = tc->data, td2d = tc->data_2d; i < tc->data_len; i++, td++, td2d++) {
|
||||
const TransDataSeq *tdseq = static_cast<TransDataSeq *>(td->extra);
|
||||
Sequence *seq = tdseq->seq;
|
||||
|
||||
transformed_strips.add(seq);
|
||||
|
||||
/* Calculate translation. */
|
||||
|
||||
const blender::MutableSpan keys = SEQ_retiming_keys_get(seq);
|
||||
@ -123,6 +154,17 @@ static void recalcData_sequencer_retiming(TransInfo *t)
|
||||
|
||||
SEQ_relations_invalidate_cache_preprocessed(t->scene, seq);
|
||||
}
|
||||
|
||||
/* Test overlap, displays red outline. */
|
||||
Editing *ed = SEQ_editing_get(t->scene);
|
||||
SEQ_iterator_set_expand(
|
||||
t->scene, SEQ_active_seqbase_get(ed), transformed_strips, SEQ_query_strip_effect_chain);
|
||||
for (Sequence *seq : transformed_strips) {
|
||||
seq->flag &= ~SEQ_OVERLAP;
|
||||
if (SEQ_transform_test_overlap(t->scene, SEQ_active_seqbase_get(ed), seq)) {
|
||||
seq->flag |= SEQ_OVERLAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TransConvertTypeInfo TransConvertType_SequencerRetiming = {
|
||||
|
@ -108,6 +108,7 @@ enum eGPUSeqFlags : uint32_t {
|
||||
GPU_SEQ_FLAG_SELECTED_RH = (1u << 12u),
|
||||
GPU_SEQ_FLAG_DRAW_LH = (1u << 13u),
|
||||
GPU_SEQ_FLAG_DRAW_RH = (1u << 14u),
|
||||
GPU_SEQ_FLAG_OVERLAP = (1u << 15u),
|
||||
|
||||
GPU_SEQ_FLAG_ANY_HANDLE = GPU_SEQ_FLAG_SELECTED_LH | GPU_SEQ_FLAG_SELECTED_RH |
|
||||
GPU_SEQ_FLAG_DRAW_LH | GPU_SEQ_FLAG_DRAW_RH
|
||||
|
@ -193,7 +193,9 @@ void main()
|
||||
|
||||
/* Active, but not selected strips get a thin inner line. */
|
||||
bool active_strip = (strip.flags & GPU_SEQ_FLAG_ACTIVE) != 0;
|
||||
if (active_strip && !selected) {
|
||||
/* When moving the retiming keys, the strip might overlap even if it isn't selected. */
|
||||
bool overlaps = (strip.flags & GPU_SEQ_FLAG_OVERLAP) != 0;
|
||||
if ((active_strip && !selected) || overlaps) {
|
||||
col = add_outline(sdf, 1.0, 2.0, col, col_outline);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user