Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_convert_sequencer.c
| Show All 27 Lines | |||||
| #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" | ||||
| #define SEQ_EDGE_PAN_INSIDE_PAD 2 | |||||
| #define SEQ_EDGE_PAN_OUTSIDE_PAD 0 /* Disable clamping for panning, use whole screen. */ | |||||
| #define SEQ_EDGE_PAN_SPEED_RAMP 1 | |||||
| #define SEQ_EDGE_PAN_MAX_SPEED 10 /* In UI units per second, slower than default. */ | |||||
| #define SEQ_EDGE_PAN_DELAY 1.0f | |||||
| #define SEQ_EDGE_PAN_ZOOM_INFLUENCE 0.5f | |||||
| /** 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 selection_channel_range_min; | int selection_channel_range_min; | ||||
| int selection_channel_range_max; | int selection_channel_range_max; | ||||
| /* Initial rect of the view2d, used for computing offset during edge panning */ | |||||
| rctf initial_v2d_cur; | |||||
| View2DEdgePanData edge_pan; | |||||
| } TransSeq; | } TransSeq; | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Sequencer Transform Creation | /** \name Sequencer Transform Creation | ||||
| * \{ */ | * \{ */ | ||||
| /* This function applies the rules for transforming a strip so duplicate | /* This function applies the rules for transforming a strip so duplicate | ||||
| * checks don't need to be added in multiple places. | * checks don't need to be added in multiple places. | ||||
| ▲ Show 20 Lines • Show All 561 Lines • ▼ Show 20 Lines | #define XXX_DURIAN_ANIM_TX_HACK | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| if (ed == NULL) { | if (ed == NULL) { | ||||
| tc->data_len = 0; | tc->data_len = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| tc->custom.type.free_cb = freeSeqData; | tc->custom.type.free_cb = freeSeqData; | ||||
| t->frame_side = transform_convert_frame_side_dir_get(t, (float)CFRA); | t->frame_side = transform_convert_frame_side_dir_get(t, (float)CFRA); | ||||
| #ifdef XXX_DURIAN_ANIM_TX_HACK | #ifdef XXX_DURIAN_ANIM_TX_HACK | ||||
Severin: Other code only sets this based on `CTX_VIEW2D_EDGE_PAN` here: https://developer.blender. | |||||
Done Inline ActionsI think I have copied this from original diff. ISS: I think I have copied this from original diff. | |||||
| { | { | ||||
| Sequence *seq; | Sequence *seq; | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = ed->seqbasep->first; seq; seq = seq->next) { | ||||
| /* hack */ | /* hack */ | ||||
| if ((seq->flag & SELECT) == 0 && seq->type & SEQ_TYPE_EFFECT) { | if ((seq->flag & SELECT) == 0 && seq->type & SEQ_TYPE_EFFECT) { | ||||
| Sequence *seq_user; | Sequence *seq_user; | ||||
| int i; | int i; | ||||
| for (i = 0; i < 3; i++) { | for (i = 0; i < 3; i++) { | ||||
| Show All 19 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"); | ||||
| /* Custom data to enable edge panning during transformation. */ | |||||
| UI_view2d_edge_pan_init(t->context, | |||||
| &ts->edge_pan, | |||||
| SEQ_EDGE_PAN_INSIDE_PAD, | |||||
| SEQ_EDGE_PAN_OUTSIDE_PAD, | |||||
| SEQ_EDGE_PAN_SPEED_RAMP, | |||||
| SEQ_EDGE_PAN_MAX_SPEED, | |||||
| SEQ_EDGE_PAN_DELAY, | |||||
| SEQ_EDGE_PAN_ZOOM_INFLUENCE); | |||||
| UI_view2d_edge_pan_set_limits(&ts->edge_pan, -FLT_MAX, FLT_MAX, 1, MAXSEQ + 1); | |||||
| ts->initial_v2d_cur = t->region->v2d.cur; | |||||
| /* 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); | ||||
| 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 All 21 Lines | BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag) | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(sce)); | ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(sce)); | ||||
| SEQ_time_update_sequence(sce, seqbase, seq); | SEQ_time_update_sequence(sce, seqbase, seq); | ||||
| if (sel_flag == SELECT) { | if (sel_flag == SELECT) { | ||||
| SEQ_offset_animdata(sce, seq, seq->start - old_start); | SEQ_offset_animdata(sce, seq, seq->start - old_start); | ||||
| } | } | ||||
| } | } | ||||
| static void view2d_edge_pan_loc_compensate(TransInfo *t, float loc_in[2], float r_loc[2]) | |||||
Done Inline ActionsThis is also something that the node editor doesn't seem to do. Could you explain why this is needed? Best in a code comment. Severin: This is also something that the node editor doesn't seem to do. Could you explain why this is… | |||||
Done Inline ActionsI wanted to extract specific math to own function, but shouldn't include edge pan handling there, so fixed that. ISS: They do here https://developer.blender.org/diffusion/B/browse/master/source/blender/editors/tra… | |||||
| { | |||||
| TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data; | |||||
| /* Initial and current view2D rects for additional transform due to view panning and zooming */ | |||||
| const rctf *rect_src = &ts->initial_v2d_cur; | |||||
| const rctf *rect_dst = &t->region->v2d.cur; | |||||
| copy_v2_v2(r_loc, loc_in); | |||||
| /* Additional offset due to change in view2D rect. */ | |||||
| BLI_rctf_transform_pt_v(rect_dst, rect_src, r_loc, r_loc); | |||||
| } | |||||
| static void flushTransSeq(TransInfo *t) | static void flushTransSeq(TransInfo *t) | ||||
| { | { | ||||
| TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data; | |||||
| if (t->options & CTX_VIEW2D_EDGE_PAN) { | |||||
| if (t->state == TRANS_CANCEL) { | |||||
| UI_view2d_edge_pan_cancel(t->context, &ts->edge_pan); | |||||
| } | |||||
| else { | |||||
| /* Edge panning functions expect window coordinates, mval is relative to region */ | |||||
| const int xy[2] = { | |||||
| t->region->winrct.xmin + t->mval[0], | |||||
| t->region->winrct.ymin + t->mval[1], | |||||
| }; | |||||
| UI_view2d_edge_pan_apply(t->context, &ts->edge_pan, xy); | |||||
| } | |||||
| } | |||||
| /* Editing null check already done */ | /* Editing null check already done */ | ||||
| ListBase *seqbasep = seqbase_active_get(t); | ListBase *seqbasep = seqbase_active_get(t); | ||||
| int a, new_frame; | int a, new_frame; | ||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransData2D *td2d = NULL; | TransData2D *td2d = NULL; | ||||
| TransDataSeq *tdsq = NULL; | TransDataSeq *tdsq = NULL; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| /* Flush to 2D vector from internally used 3D vector. */ | /* Flush to 2D vector from internally used 3D vector. */ | ||||
| for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) { | for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) { | ||||
| tdsq = (TransDataSeq *)td->extra; | tdsq = (TransDataSeq *)td->extra; | ||||
| seq = tdsq->seq; | seq = tdsq->seq; | ||||
| new_frame = round_fl_to_int(td2d->loc[0]); | float loc[2]; | ||||
| view2d_edge_pan_loc_compensate(t, td->loc, loc); | |||||
| new_frame = round_fl_to_int(loc[0]); | |||||
| switch (tdsq->sel_flag) { | switch (tdsq->sel_flag) { | ||||
| case SELECT: | case SELECT: | ||||
| if (SEQ_transform_sequence_can_be_translated(seq)) { | if (SEQ_transform_sequence_can_be_translated(seq)) { | ||||
| const int offset = new_frame - tdsq->start_offset - seq->start; | const int offset = new_frame - tdsq->start_offset - seq->start; | ||||
| SEQ_transform_translate_sequence(t->scene, seq, offset); | SEQ_transform_translate_sequence(t->scene, seq, offset); | ||||
| } | } | ||||
| seq->machine = round_fl_to_int(td2d->loc[1]); | seq->machine = round_fl_to_int(loc[1]); | ||||
| CLAMP(seq->machine, 1, MAXSEQ); | CLAMP(seq->machine, 1, MAXSEQ); | ||||
| break; | break; | ||||
| case SEQ_LEFTSEL: /* No vertical transform. */ | case SEQ_LEFTSEL: /* No vertical transform. */ | ||||
| SEQ_transform_set_left_handle_frame(seq, new_frame); | SEQ_transform_set_left_handle_frame(seq, new_frame); | ||||
| SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); | SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); | ||||
| SEQ_transform_fix_single_image_seq_offsets(seq); | SEQ_transform_fix_single_image_seq_offsets(seq); | ||||
| SEQ_time_update_sequence(t->scene, seqbasep, seq); | SEQ_time_update_sequence(t->scene, seqbasep, seq); | ||||
| ▲ Show 20 Lines • Show All 109 Lines • Show Last 20 Lines | |||||
Other code only sets this based on CTX_VIEW2D_EDGE_PAN here: https://developer.blender.org/diffusion/B/browse/master/source/blender/editors/transform/transform_generics.c$673-676
What's the reason behind this special case?