Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_sequencer/sequencer_edit.c
| Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
| #include "sequencer_intern.h" | #include "sequencer_intern.h" | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Structs & Enums | /** \name Structs & Enums | ||||
| * \{ */ | * \{ */ | ||||
| typedef struct TransSeq { | typedef struct TransSeq { | ||||
| int start, machine; | int start, machine; | ||||
| int startstill, endstill; | |||||
| int startdisp, enddisp; | int startdisp, enddisp; | ||||
| int startofs, endofs; | int startofs, endofs; | ||||
| int anim_startofs, anim_endofs; | int anim_startofs, anim_endofs; | ||||
| /* int final_left, final_right; */ /* UNUSED */ | /* int final_left, final_right; */ /* UNUSED */ | ||||
| int len; | int len; | ||||
| } TransSeq; | } TransSeq; | ||||
| /** \} */ | /** \} */ | ||||
| ▲ Show 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | static int sequencer_snap_exec(bContext *C, wmOperator *op) | ||||
| snap_frame = RNA_int_get(op->ptr, "frame"); | snap_frame = RNA_int_get(op->ptr, "frame"); | ||||
| /* Check meta-strips. */ | /* Check meta-strips. */ | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = ed->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq) && | if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq) && | ||||
| SEQ_transform_sequence_can_be_translated(seq)) { | SEQ_transform_sequence_can_be_translated(seq)) { | ||||
| if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) { | if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) { | ||||
| SEQ_transform_translate_sequence( | SEQ_transform_translate_sequence(scene, seq, (snap_frame - seq->startofs) - seq->start); | ||||
| scene, seq, (snap_frame - seq->startofs + seq->startstill) - seq->start); | |||||
| } | } | ||||
| else { | else { | ||||
| if (seq->flag & SEQ_LEFTSEL) { | if (seq->flag & SEQ_LEFTSEL) { | ||||
| SEQ_transform_set_left_handle_frame(seq, snap_frame); | SEQ_transform_set_left_handle_frame(seq, snap_frame); | ||||
| } | } | ||||
| else { /* SEQ_RIGHTSEL */ | else { /* SEQ_RIGHTSEL */ | ||||
| SEQ_transform_set_right_handle_frame(seq, snap_frame); | SEQ_transform_set_right_handle_frame(seq, snap_frame); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | typedef struct SlipData { | ||||
| int slow_offset; /* Offset at the point where offset was turned on. */ | int slow_offset; /* Offset at the point where offset was turned on. */ | ||||
| NumInput num_input; | NumInput num_input; | ||||
| } SlipData; | } SlipData; | ||||
| static void transseq_backup(TransSeq *ts, Sequence *seq) | static void transseq_backup(TransSeq *ts, Sequence *seq) | ||||
| { | { | ||||
| ts->start = seq->start; | ts->start = seq->start; | ||||
| ts->machine = seq->machine; | ts->machine = seq->machine; | ||||
| ts->startstill = seq->startstill; | |||||
| ts->endstill = seq->endstill; | |||||
| ts->startdisp = seq->startdisp; | ts->startdisp = seq->startdisp; | ||||
| ts->enddisp = seq->enddisp; | ts->enddisp = seq->enddisp; | ||||
| ts->startofs = seq->startofs; | ts->startofs = seq->startofs; | ||||
| ts->endofs = seq->endofs; | ts->endofs = seq->endofs; | ||||
| ts->anim_startofs = seq->anim_startofs; | ts->anim_startofs = seq->anim_startofs; | ||||
| ts->anim_endofs = seq->anim_endofs; | ts->anim_endofs = seq->anim_endofs; | ||||
| ts->len = seq->len; | ts->len = seq->len; | ||||
| } | } | ||||
| static void transseq_restore(TransSeq *ts, Sequence *seq) | static void transseq_restore(TransSeq *ts, Sequence *seq) | ||||
| { | { | ||||
| seq->start = ts->start; | seq->start = ts->start; | ||||
| seq->machine = ts->machine; | seq->machine = ts->machine; | ||||
| seq->startstill = ts->startstill; | |||||
| seq->endstill = ts->endstill; | |||||
| seq->startdisp = ts->startdisp; | seq->startdisp = ts->startdisp; | ||||
| seq->enddisp = ts->enddisp; | seq->enddisp = ts->enddisp; | ||||
| seq->startofs = ts->startofs; | seq->startofs = ts->startofs; | ||||
| seq->endofs = ts->endofs; | seq->endofs = ts->endofs; | ||||
| seq->anim_startofs = ts->anim_startofs; | seq->anim_startofs = ts->anim_startofs; | ||||
| seq->anim_endofs = ts->anim_endofs; | seq->anim_endofs = ts->anim_endofs; | ||||
| seq->len = ts->len; | seq->len = ts->len; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| WM_event_add_modal_handler(C, op); | WM_event_add_modal_handler(C, op); | ||||
| /* Notify so we draw extensions immediately. */ | /* Notify so we draw extensions immediately. */ | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) | static void sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) | ||||
| { | { | ||||
| /* Only data types supported for now. */ | |||||
| bool changed = false; | |||||
| /* Iterate in reverse so meta-strips are iterated after their children. */ | /* Iterate in reverse so meta-strips are iterated after their children. */ | ||||
| for (int i = data->num_seq - 1; i >= 0; i--) { | for (int i = data->num_seq - 1; i >= 0; i--) { | ||||
| Sequence *seq = data->seq_array[i]; | Sequence *seq = data->seq_array[i]; | ||||
| int endframe; | int endframe; | ||||
| /* Offset seq start. */ | /* Offset seq start. */ | ||||
| seq->start = data->ts[i].start + offset; | seq->start = data->ts[i].start + offset; | ||||
| if (data->trim[i]) { | if (data->trim[i]) { | ||||
| /* Find the end-frame. */ | /* Find the end-frame. */ | ||||
| endframe = seq->start + seq->len; | endframe = seq->start + seq->len; | ||||
| /* Compute the sequence offsets. */ | /* Compute the sequence offsets. */ | ||||
| if (endframe > seq->enddisp) { | |||||
| seq->endstill = 0; | |||||
| seq->endofs = endframe - seq->enddisp; | seq->endofs = endframe - seq->enddisp; | ||||
| changed = true; | |||||
| } | |||||
| else { | |||||
| seq->endstill = seq->enddisp - endframe; | |||||
| seq->endofs = 0; | |||||
| changed = true; | |||||
| } | |||||
| if (seq->start > seq->startdisp) { | |||||
| seq->startstill = seq->start - seq->startdisp; | |||||
| seq->startofs = 0; | |||||
| changed = true; | |||||
| } | |||||
| else { | |||||
| seq->startstill = 0; | |||||
| seq->startofs = seq->startdisp - seq->start; | seq->startofs = seq->startdisp - seq->start; | ||||
| changed = true; | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| /* No transform data (likely effect strip). Only move start and end. */ | /* No transform data (likely effect strip). Only move start and end. */ | ||||
| seq->startdisp = data->ts[i].startdisp + offset; | seq->startdisp = data->ts[i].startdisp + offset; | ||||
| seq->enddisp = data->ts[i].enddisp + offset; | seq->enddisp = data->ts[i].enddisp + offset; | ||||
| changed = true; | |||||
| } | } | ||||
| /* Effects are only added if we they are in a meta-strip. | /* Effects are only added if we they are in a meta-strip. | ||||
| * In this case, dependent strips will just be transformed and | * In this case, dependent strips will just be transformed and | ||||
| * we can skip calculating for effects. | * we can skip calculating for effects. | ||||
| * This way we can avoid an extra loop just for effects. */ | * This way we can avoid an extra loop just for effects. */ | ||||
| if (!(seq->type & SEQ_TYPE_EFFECT)) { | if (!(seq->type & SEQ_TYPE_EFFECT)) { | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | ||||
| SEQ_time_update_sequence(scene, seqbase, seq); | SEQ_time_update_sequence(scene, seqbase, seq); | ||||
| } | } | ||||
| } | } | ||||
| if (changed) { | |||||
| for (int i = data->num_seq - 1; i >= 0; i--) { | for (int i = data->num_seq - 1; i >= 0; i--) { | ||||
| Sequence *seq = data->seq_array[i]; | Sequence *seq = data->seq_array[i]; | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(scene, seq); | ||||
| } | } | ||||
| } | } | ||||
| return changed; | |||||
| } | |||||
| /* Make sure, that each strip contains at least 1 frame of content. */ | /* Make sure, that each strip contains at least 1 frame of content. */ | ||||
| static void sequencer_slip_apply_limits(SlipData *data, int *offset) | static void sequencer_slip_apply_limits(SlipData *data, int *offset) | ||||
| { | { | ||||
| for (int i = 0; i < data->num_seq; i++) { | for (int i = 0; i < data->num_seq; i++) { | ||||
| if (data->trim[i]) { | if (data->trim[i]) { | ||||
| Sequence *seq = data->seq_array[i]; | Sequence *seq = data->seq_array[i]; | ||||
| int seq_content_start = data->ts[i].start + *offset; | int seq_content_start = data->ts[i].start + *offset; | ||||
| Show All 12 Lines | static void sequencer_slip_apply_limits(SlipData *data, int *offset) | ||||
| } | } | ||||
| } | } | ||||
| static int sequencer_slip_exec(bContext *C, wmOperator *op) | static int sequencer_slip_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | Editing *ed = SEQ_editing_get(scene); | ||||
| int offset = RNA_int_get(op->ptr, "offset"); | int offset = RNA_int_get(op->ptr, "offset"); | ||||
| bool success = false; | |||||
| /* Recursively count the trimmed elements. */ | /* Recursively count the trimmed elements. */ | ||||
| int num_seq = slip_count_sequences_recursive(ed->seqbasep, true); | int num_seq = slip_count_sequences_recursive(ed->seqbasep, true); | ||||
| if (num_seq == 0) { | if (num_seq == 0) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| SlipData *data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); | SlipData *data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); | ||||
| data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); | data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); | ||||
| data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); | data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); | ||||
| data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); | data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); | ||||
| data->num_seq = num_seq; | data->num_seq = num_seq; | ||||
| slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true); | slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true); | ||||
| for (int i = 0; i < num_seq; i++) { | for (int i = 0; i < num_seq; i++) { | ||||
| transseq_backup(data->ts + i, data->seq_array[i]); | transseq_backup(data->ts + i, data->seq_array[i]); | ||||
| } | } | ||||
| sequencer_slip_apply_limits(data, &offset); | sequencer_slip_apply_limits(data, &offset); | ||||
| success = sequencer_slip_recursively(scene, data, offset); | sequencer_slip_recursively(scene, data, offset); | ||||
| MEM_freeN(data->seq_array); | MEM_freeN(data->seq_array); | ||||
| MEM_freeN(data->trim); | MEM_freeN(data->trim); | ||||
| MEM_freeN(data->ts); | MEM_freeN(data->ts); | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| if (success) { | |||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| static void sequencer_slip_update_header(Scene *scene, ScrArea *area, SlipData *data, int offset) | static void sequencer_slip_update_header(Scene *scene, ScrArea *area, SlipData *data, int offset) | ||||
| { | { | ||||
| char msg[UI_MAX_DRAW_STR]; | char msg[UI_MAX_DRAW_STR]; | ||||
| if (area) { | if (area) { | ||||
| if (hasNumInput(&data->num_input)) { | if (hasNumInput(&data->num_input)) { | ||||
| char num_str[NUM_STR_REP_LEN]; | char num_str[NUM_STR_REP_LEN]; | ||||
| Show All 23 Lines | if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) { | ||||
| applyNumInput(&data->num_input, &offset_fl); | applyNumInput(&data->num_input, &offset_fl); | ||||
| int offset = round_fl_to_int(offset_fl); | int offset = round_fl_to_int(offset_fl); | ||||
| sequencer_slip_apply_limits(data, &offset); | sequencer_slip_apply_limits(data, &offset); | ||||
| sequencer_slip_update_header(scene, area, data, offset); | sequencer_slip_update_header(scene, area, data, offset); | ||||
| RNA_int_set(op->ptr, "offset", offset); | RNA_int_set(op->ptr, "offset", offset); | ||||
| if (sequencer_slip_recursively(scene, data, offset)) { | sequencer_slip_recursively(scene, data, offset); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | ||||
| } | |||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| switch (event->type) { | switch (event->type) { | ||||
| case MOUSEMOVE: { | case MOUSEMOVE: { | ||||
| if (!has_numInput) { | if (!has_numInput) { | ||||
| float mouseloc[2]; | float mouseloc[2]; | ||||
| Show All 14 Lines | case MOUSEMOVE: { | ||||
| UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]); | UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]); | ||||
| offset = mouseloc[0] - data->init_mouseloc[0]; | offset = mouseloc[0] - data->init_mouseloc[0]; | ||||
| sequencer_slip_apply_limits(data, &offset); | sequencer_slip_apply_limits(data, &offset); | ||||
| sequencer_slip_update_header(scene, area, data, offset); | sequencer_slip_update_header(scene, area, data, offset); | ||||
| RNA_int_set(op->ptr, "offset", offset); | RNA_int_set(op->ptr, "offset", offset); | ||||
| if (sequencer_slip_recursively(scene, data, offset)) { | sequencer_slip_recursively(scene, data, offset); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | ||||
| } | } | ||||
| } | |||||
| break; | break; | ||||
| } | } | ||||
| case LEFTMOUSE: | case LEFTMOUSE: | ||||
| case EVT_RETKEY: | case EVT_RETKEY: | ||||
| case EVT_SPACEKEY: { | case EVT_SPACEKEY: { | ||||
| MEM_freeN(data->seq_array); | MEM_freeN(data->seq_array); | ||||
| MEM_freeN(data->trim); | MEM_freeN(data->trim); | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) { | ||||
| applyNumInput(&data->num_input, &offset_fl); | applyNumInput(&data->num_input, &offset_fl); | ||||
| int offset = round_fl_to_int(offset_fl); | int offset = round_fl_to_int(offset_fl); | ||||
| sequencer_slip_apply_limits(data, &offset); | sequencer_slip_apply_limits(data, &offset); | ||||
| sequencer_slip_update_header(scene, area, data, offset); | sequencer_slip_update_header(scene, area, data, offset); | ||||
| RNA_int_set(op->ptr, "offset", offset); | RNA_int_set(op->ptr, "offset", offset); | ||||
| if (sequencer_slip_recursively(scene, data, offset)) { | sequencer_slip_recursively(scene, data, offset); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | ||||
| } | } | ||||
| } | |||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| void SEQUENCER_OT_slip(struct wmOperatorType *ot) | void SEQUENCER_OT_slip(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Slip Strips"; | ot->name = "Slip Strips"; | ||||
| ▲ Show 20 Lines • Show All 900 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | Editing *ed = SEQ_editing_get(scene); | ||||
| Sequence *seq; | Sequence *seq; | ||||
| /* For effects, try to find a replacement input. */ | /* For effects, try to find a replacement input. */ | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = ed->seqbasep->first; seq; seq = seq->next) { | ||||
| if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) { | if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) { | ||||
| seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0; | seq->startofs = seq->endofs = 0; | ||||
| } | } | ||||
| } | } | ||||
| /* Update lengths, etc. */ | /* Update lengths, etc. */ | ||||
| seq = ed->seqbasep->first; | seq = ed->seqbasep->first; | ||||
| while (seq) { | while (seq) { | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(ed); | ListBase *seqbase = SEQ_active_seqbase_get(ed); | ||||
| SEQ_time_update_sequence(scene, seqbase, seq); | SEQ_time_update_sequence(scene, seqbase, seq); | ||||
| ▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { | ||||
| /* New seq. */ | /* New seq. */ | ||||
| se = SEQ_render_give_stripelem(seq, timeline_frame); | se = SEQ_render_give_stripelem(seq, timeline_frame); | ||||
| seq_new = SEQ_sequence_dupli_recursive(scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME); | seq_new = SEQ_sequence_dupli_recursive(scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME); | ||||
| seq_new->start = start_ofs; | seq_new->start = start_ofs; | ||||
| seq_new->type = SEQ_TYPE_IMAGE; | seq_new->type = SEQ_TYPE_IMAGE; | ||||
| seq_new->len = 1; | seq_new->len = 1; | ||||
| seq_new->endstill = step - 1; | seq_new->endofs = 1 - step; | ||||
| /* New strip. */ | /* New strip. */ | ||||
| strip_new = seq_new->strip; | strip_new = seq_new->strip; | ||||
| strip_new->us = 1; | strip_new->us = 1; | ||||
| /* New stripdata, only one element now. */ | /* New stripdata, only one element now. */ | ||||
| /* Note this assume all elements (images) have the same dimension, | /* Note this assume all elements (images) have the same dimension, | ||||
| * since we only copy the name here. */ | * since we only copy the name here. */ | ||||
| ▲ Show 20 Lines • Show All 1,649 Lines • Show Last 20 Lines | |||||