Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_convert_sequencer.c
| Show All 38 Lines | |||||
| #include "SEQ_time.h" | #include "SEQ_time.h" | ||||
| #include "SEQ_transform.h" | #include "SEQ_transform.h" | ||||
| #include "SEQ_utils.h" | #include "SEQ_utils.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| #include "transform.h" | #include "transform.h" | ||||
| #include "transform_convert.h" | #include "transform_convert.h" | ||||
| #include "transform_snap.h" | |||||
| /** Used for sequencer transform. */ | /** Used for sequencer transform. */ | ||||
| typedef struct TransDataSeq { | typedef struct TransDataSeq { | ||||
| struct Sequence *seq; | struct Sequence *seq; | ||||
| /** A copy of #Sequence.flag that may be modified for nested strips. */ | /** A copy of #Sequence.flag that may be modified for nested strips. */ | ||||
| int flag; | int flag; | ||||
| /** Use this so we can have transform data at the strips start, | /** Use this so we can have transform data at the strips start, | ||||
| * but apply correctly to the start frame. */ | * but apply correctly to the start frame. */ | ||||
| int start_offset; | int start_offset; | ||||
| /** one of #SELECT, #SEQ_LEFTSEL and #SEQ_RIGHTSEL. */ | /** one of #SELECT, #SEQ_LEFTSEL and #SEQ_RIGHTSEL. */ | ||||
| short sel_flag; | short sel_flag; | ||||
| } TransDataSeq; | } TransDataSeq; | ||||
| /** | /** | ||||
| * Sequencer transform customdata (stored in #TransCustomDataContainer). | * Sequencer transform customdata (stored in #TransCustomDataContainer). | ||||
| */ | */ | ||||
| typedef struct TransSeq { | typedef struct TransSeq { | ||||
| TransDataSeq *tdseq; | TransDataSeq *tdseq; | ||||
| int min; | |||||
| int max; | |||||
| bool snap_left; | |||||
| int selection_channel_range_min; | int selection_channel_range_min; | ||||
| int selection_channel_range_max; | int selection_channel_range_max; | ||||
| } TransSeq; | } TransSeq; | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Sequencer Transform Creation | /** \name Sequencer Transform Creation | ||||
| * \{ */ | * \{ */ | ||||
| ▲ Show 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | if (flag & SELECT) { | ||||
| SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT); | SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT); | ||||
| tot++; | tot++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return tot; | return tot; | ||||
| } | } | ||||
| static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts) | |||||
| { | |||||
| Sequence *seq; | |||||
| int count, flag; | |||||
| int max = INT32_MIN, min = INT32_MAX; | |||||
| for (seq = seqbase->first; seq; seq = seq->next) { | |||||
| /* just to get the flag since there are corner cases where this isn't totally obvious */ | |||||
| SeqTransInfo(t, seq, &count, &flag); | |||||
| /* use 'flag' which is derived from seq->flag but modified for special cases */ | |||||
| if (flag & SELECT) { | |||||
| if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) { | |||||
| if (flag & SEQ_LEFTSEL) { | |||||
| min = min_ii(seq->startdisp, min); | |||||
| max = max_ii(seq->startdisp, max); | |||||
| } | |||||
| if (flag & SEQ_RIGHTSEL) { | |||||
| min = min_ii(seq->enddisp, min); | |||||
| max = max_ii(seq->enddisp, max); | |||||
| } | |||||
| } | |||||
| else { | |||||
| min = min_ii(seq->startdisp, min); | |||||
| max = max_ii(seq->enddisp, max); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (ts) { | |||||
| ts->max = max; | |||||
| ts->min = min; | |||||
| } | |||||
| } | |||||
| static void free_transform_custom_data(TransCustomData *custom_data) | static void free_transform_custom_data(TransCustomData *custom_data) | ||||
| { | { | ||||
| if ((custom_data->data != NULL) && custom_data->use_free) { | if ((custom_data->data != NULL) && custom_data->use_free) { | ||||
| TransSeq *ts = custom_data->data; | TransSeq *ts = custom_data->data; | ||||
| MEM_freeN(ts->tdseq); | MEM_freeN(ts->tdseq); | ||||
| MEM_freeN(custom_data->data); | MEM_freeN(custom_data->data); | ||||
| custom_data->data = NULL; | custom_data->data = NULL; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 240 Lines • ▼ Show 20 Lines | #endif | ||||
| tc->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq"); | tc->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq"); | ||||
| tc->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData"); | ||||
| td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D"); | td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D"); | ||||
| ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq"); | ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq"); | ||||
| /* loop 2: build transdata array */ | /* loop 2: build transdata array */ | ||||
| SeqToTransData_build(t, ed->seqbasep, td, td2d, tdsq); | SeqToTransData_build(t, ed->seqbasep, td, td2d, tdsq); | ||||
| SeqTransDataBounds(t, ed->seqbasep, ts); | |||||
| if (t->flag & T_MODAL) { | |||||
| /* set the snap mode based on how close the mouse is at the end/start points */ | |||||
| int xmouse = (int)UI_view2d_region_to_view_x((View2D *)t->view, t->mouse.imval[0]); | |||||
| if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) { | |||||
| ts->snap_left = true; | |||||
| } | |||||
| } | |||||
| ts->selection_channel_range_min = MAXSEQ + 1; | ts->selection_channel_range_min = MAXSEQ + 1; | ||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | ||||
| if ((seq->flag & SELECT) != 0) { | if ((seq->flag & SELECT) != 0) { | ||||
| ts->selection_channel_range_min = min_ii(ts->selection_channel_range_min, seq->machine); | ts->selection_channel_range_min = min_ii(ts->selection_channel_range_min, seq->machine); | ||||
| ts->selection_channel_range_max = max_ii(ts->selection_channel_range_max, seq->machine); | ts->selection_channel_range_max = max_ii(ts->selection_channel_range_max, seq->machine); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | void transform_convert_sequencer_channel_clamp(TransInfo *t) | ||||
| if (max_channel_after_transform > MAXSEQ) { | if (max_channel_after_transform > MAXSEQ) { | ||||
| t->values[1] -= max_channel_after_transform - MAXSEQ; | t->values[1] -= max_channel_after_transform - MAXSEQ; | ||||
| } | } | ||||
| if (min_channel_after_transform < 1) { | if (min_channel_after_transform < 1) { | ||||
| t->values[1] -= min_channel_after_transform - 1; | t->values[1] -= min_channel_after_transform - 1; | ||||
| } | } | ||||
| } | } | ||||
| int transform_convert_sequencer_get_snap_bound(TransInfo *t) | |||||
| { | |||||
| TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data; | |||||
| return ts->snap_left ? ts->min : ts->max; | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||