Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_sequencer/sequencer_edit.c
| Show All 15 Lines | |||||
| #include "BLI_timecode.h" | #include "BLI_timecode.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "DNA_anim_types.h" | #include "DNA_anim_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_sound_types.h" | #include "DNA_sound_types.h" | ||||
| #include "DNA_video_edit_types.h" | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_fcurve.h" | #include "BKE_fcurve.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_sound.h" | #include "BKE_sound.h" | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
| /** \name Public Context Checks | /** \name Public Context Checks | ||||
| * \{ */ | * \{ */ | ||||
| bool ED_space_sequencer_maskedit_mask_poll(bContext *C) | bool ED_space_sequencer_maskedit_mask_poll(bContext *C) | ||||
| { | { | ||||
| return ED_space_sequencer_maskedit_poll(C); | return ED_space_sequencer_maskedit_poll(C); | ||||
| } | } | ||||
| bool ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, Scene *scene) | bool ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, VideoEdit *video_edit) | ||||
| { | { | ||||
| if (sseq && sseq->mainb == SEQ_DRAW_IMG_IMBUF) { | if (sseq && sseq->mainb == SEQ_DRAW_IMG_IMBUF) { | ||||
| return (SEQ_active_mask_get(scene) != NULL); | return (SEQ_active_mask_get(video_edit) != NULL); | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool ED_space_sequencer_maskedit_poll(bContext *C) | bool ED_space_sequencer_maskedit_poll(bContext *C) | ||||
| { | { | ||||
| SpaceSeq *sseq = CTX_wm_space_seq(C); | SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| if (sseq) { | if (sseq) { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| return ED_space_sequencer_check_show_maskedit(sseq, scene); | return ED_space_sequencer_check_show_maskedit(sseq, video_edit); | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq) | bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq) | ||||
| { | { | ||||
| return (sseq->mainb == SEQ_DRAW_IMG_IMBUF) && | return (sseq->mainb == SEQ_DRAW_IMG_IMBUF) && | ||||
| Show All 14 Lines | static bool sequencer_fcurves_targets_color_strip(const FCurve *fcurve) | ||||
| if (!BLI_str_endswith(fcurve->rna_path, "\"].color")) { | if (!BLI_str_endswith(fcurve->rna_path, "\"].color")) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool ED_space_sequencer_has_playback_animation(const struct SpaceSeq *sseq, | bool ED_space_sequencer_has_playback_animation(const struct SpaceSeq *sseq, | ||||
| const struct Scene *scene) | const struct VideoEdit *video_edit) | ||||
| { | { | ||||
| if (sseq->draw_flag & SEQ_DRAW_BACKDROP) { | if (sseq->draw_flag & SEQ_DRAW_BACKDROP) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (!scene->adt) { | if (!video_edit->adt) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (!scene->adt->action) { | if (!video_edit->adt->action) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| LISTBASE_FOREACH (FCurve *, fcurve, &scene->adt->action->curves) { | LISTBASE_FOREACH (FCurve *, fcurve, &video_edit->adt->action->curves) { | ||||
| if (sequencer_fcurves_targets_color_strip(fcurve)) { | if (sequencer_fcurves_targets_color_strip(fcurve)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Shared Poll Functions | /** \name Shared Poll Functions | ||||
| * \{ */ | * \{ */ | ||||
| bool sequencer_edit_poll(bContext *C) | bool sequencer_edit_poll(bContext *C) | ||||
| { | { | ||||
| return (SEQ_editing_get(CTX_data_scene(C)) != NULL); | return (CTX_data_video_edit(C) != NULL); | ||||
| } | } | ||||
| bool sequencer_editing_initialized_and_active(bContext *C) | bool sequencer_editing_initialized_and_active(bContext *C) | ||||
| { | { | ||||
| return ED_operator_sequencer_active(C) && sequencer_edit_poll(C); | return ED_operator_sequencer_active(C) && sequencer_edit_poll(C); | ||||
| } | } | ||||
| #if 0 /* UNUSED */ | #if 0 /* UNUSED */ | ||||
| bool sequencer_strip_poll(bContext *C) | bool sequencer_strip_poll(bContext *C) | ||||
| { | { | ||||
| Editing *ed; | Editing *ed; | ||||
| return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && | return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && | ||||
| (ed->act_seq != NULL)); | (ed->act_seq != NULL)); | ||||
| } | } | ||||
| #endif | #endif | ||||
| bool sequencer_strip_has_path_poll(bContext *C) | bool sequencer_strip_has_path_poll(bContext *C) | ||||
| { | { | ||||
| Editing *ed; | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq; | if (video_edit == NULL) { | ||||
| return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && ((seq = ed->act_seq) != NULL) && | return false; | ||||
| SEQ_HAS_PATH(seq)); | } | ||||
| Sequence *seq = video_edit->act_seq; | |||||
| return (seq != NULL) && SEQ_HAS_PATH(seq); | |||||
| } | } | ||||
| bool sequencer_view_has_preview_poll(bContext *C) | bool sequencer_view_has_preview_poll(bContext *C) | ||||
| { | { | ||||
| SpaceSeq *sseq = CTX_wm_space_seq(C); | SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| if (sseq == NULL) { | if (sseq == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (SEQ_editing_get(CTX_data_scene(C)) == NULL) { | if (CTX_data_video_edit(C) == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (!(ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW) && | if (!(ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW) && | ||||
| (sseq->mainb == SEQ_DRAW_IMG_IMBUF))) { | (sseq->mainb == SEQ_DRAW_IMG_IMBUF))) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| if (!(region && region->regiontype == RGN_TYPE_PREVIEW)) { | if (!(region && region->regiontype == RGN_TYPE_PREVIEW)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool sequencer_view_preview_only_poll(const bContext *C) | bool sequencer_view_preview_only_poll(const bContext *C) | ||||
| { | { | ||||
| SpaceSeq *sseq = CTX_wm_space_seq(C); | SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| if (sseq == NULL) { | if (sseq == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (SEQ_editing_get(CTX_data_scene(C)) == NULL) { | if (CTX_data_video_edit(C) == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (!(ELEM(sseq->view, SEQ_VIEW_PREVIEW) && (sseq->mainb == SEQ_DRAW_IMG_IMBUF))) { | if (!(ELEM(sseq->view, SEQ_VIEW_PREVIEW) && (sseq->mainb == SEQ_DRAW_IMG_IMBUF))) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| if (!(region && region->regiontype == RGN_TYPE_PREVIEW)) { | if (!(region && region->regiontype == RGN_TYPE_PREVIEW)) { | ||||
| return false; | return false; | ||||
| Show All 21 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Remove Gaps Operator | /** \name Remove Gaps Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) | static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| const bool do_all = RNA_boolean_get(op->ptr, "all"); | const bool do_all = RNA_boolean_get(op->ptr, "all"); | ||||
| const Editing *ed = SEQ_editing_get(scene); | |||||
| SEQ_edit_remove_gaps(scene, ed->seqbasep, scene->r.cfra, do_all); | SEQ_edit_remove_gaps(video_edit, video_edit->seqbasep, video_edit->r.cfra, do_all); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot) | void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Remove Gaps"; | ot->name = "Remove Gaps"; | ||||
| Show All 16 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Insert Gaps Operator | /** \name Insert Gaps Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_gap_insert_exec(bContext *C, wmOperator *op) | static int sequencer_gap_insert_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| const int frames = RNA_int_get(op->ptr, "frames"); | const int frames = RNA_int_get(op->ptr, "frames"); | ||||
| const Editing *ed = SEQ_editing_get(scene); | SEQ_transform_offset_after_frame(video_edit, video_edit->seqbasep, frames, video_edit->r.cfra); | ||||
| SEQ_transform_offset_after_frame(scene, ed->seqbasep, frames, scene->r.cfra); | |||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot) | void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Insert Gaps"; | ot->name = "Insert Gaps"; | ||||
| Show All 24 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Snap Strips to the Current Frame Operator | /** \name Snap Strips to the Current Frame Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_snap_exec(bContext *C, wmOperator *op) | static int sequencer_snap_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | ListBase *channels = SEQ_channels_displayed_get(video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| int snap_frame; | int snap_frame; | ||||
| 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 = video_edit->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(scene, seq, (snap_frame - seq->startofs) - seq->start); | SEQ_transform_translate_sequence( | ||||
| video_edit, seq, (snap_frame - seq->startofs) - seq->start); | |||||
| } | } | ||||
| else { | else { | ||||
| if (seq->flag & SEQ_LEFTSEL) { | if (seq->flag & SEQ_LEFTSEL) { | ||||
| SEQ_time_left_handle_frame_set(scene, seq, snap_frame); | SEQ_time_left_handle_frame_set(video_edit, seq, snap_frame); | ||||
| } | } | ||||
| else { /* SEQ_RIGHTSEL */ | else { /* SEQ_RIGHTSEL */ | ||||
| SEQ_time_right_handle_frame_set(scene, seq, snap_frame); | SEQ_time_right_handle_frame_set(video_edit, seq, snap_frame); | ||||
| } | } | ||||
| SEQ_transform_fix_single_image_seq_offsets(scene, seq); | SEQ_transform_fix_single_image_seq_offsets(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Test for effects and overlap. */ | /* Test for effects and overlap. */ | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->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->flag &= ~SEQ_OVERLAP; | seq->flag &= ~SEQ_OVERLAP; | ||||
| if (SEQ_transform_test_overlap(scene, ed->seqbasep, seq)) { | if (SEQ_transform_test_overlap(video_edit, video_edit->seqbasep, seq)) { | ||||
| SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); | SEQ_transform_seqbase_shuffle(video_edit, video_edit->seqbasep, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Recalculate bounds of effect strips, offsetting the keyframes if not snapping any handle. */ | /* Recalculate bounds of effect strips, offsetting the keyframes if not snapping any handle. */ | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->type & SEQ_TYPE_EFFECT) { | if (seq->type & SEQ_TYPE_EFFECT) { | ||||
| const bool either_handle_selected = (seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) != 0; | const bool either_handle_selected = (seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) != 0; | ||||
| if (seq->seq1 && (seq->seq1->flag & SELECT)) { | if (seq->seq1 && (seq->seq1->flag & SELECT)) { | ||||
| if (!either_handle_selected) { | if (!either_handle_selected) { | ||||
| SEQ_offset_animdata( | SEQ_offset_animdata( | ||||
| scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(scene, seq))); | video_edit, seq, (snap_frame - SEQ_time_left_handle_frame_get(video_edit, seq))); | ||||
| } | } | ||||
| } | } | ||||
| else if (seq->seq2 && (seq->seq2->flag & SELECT)) { | else if (seq->seq2 && (seq->seq2->flag & SELECT)) { | ||||
| if (!either_handle_selected) { | if (!either_handle_selected) { | ||||
| SEQ_offset_animdata( | SEQ_offset_animdata( | ||||
| scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(scene, seq))); | video_edit, seq, (snap_frame - SEQ_time_left_handle_frame_get(video_edit, seq))); | ||||
| } | } | ||||
| } | } | ||||
| else if (seq->seq3 && (seq->seq3->flag & SELECT)) { | else if (seq->seq3 && (seq->seq3->flag & SELECT)) { | ||||
| if (!either_handle_selected) { | if (!either_handle_selected) { | ||||
| SEQ_offset_animdata( | SEQ_offset_animdata( | ||||
| scene, seq, (snap_frame - SEQ_time_left_handle_frame_get(scene, seq))); | video_edit, seq, (snap_frame - SEQ_time_left_handle_frame_get(video_edit, seq))); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| int snap_frame; | int snap_frame; | ||||
| snap_frame = scene->r.cfra; | snap_frame = video_edit->r.cfra; | ||||
| RNA_int_set(op->ptr, "frame", snap_frame); | RNA_int_set(op->ptr, "frame", snap_frame); | ||||
| return sequencer_snap_exec(C, op); | return sequencer_snap_exec(C, op); | ||||
| } | } | ||||
| void SEQUENCER_OT_snap(struct wmOperatorType *ot) | void SEQUENCER_OT_snap(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | static int slip_count_sequences_recursive(ListBase *seqbasep, bool first_level) | ||||
| } | } | ||||
| return trimmed_sequences; | return trimmed_sequences; | ||||
| } | } | ||||
| static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| SlipData *data; | SlipData *data; | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| float mouseloc[2]; | float mouseloc[2]; | ||||
| int num_seq; | int num_seq; | ||||
| View2D *v2d = UI_view2d_fromcontext(C); | View2D *v2d = UI_view2d_fromcontext(C); | ||||
| /* Recursively count the trimmed elements. */ | /* Recursively count the trimmed elements. */ | ||||
| num_seq = slip_count_sequences_recursive(ed->seqbasep, true); | num_seq = slip_count_sequences_recursive(video_edit->seqbasep, true); | ||||
| if (num_seq == 0) { | if (num_seq == 0) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); | 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; | ||||
| initNumInput(&data->num_input); | initNumInput(&data->num_input); | ||||
| data->num_input.idx_max = 0; | data->num_input.idx_max = 0; | ||||
| data->num_input.val_flag[0] |= NUM_NO_FRACTION; | data->num_input.val_flag[0] |= NUM_NO_FRACTION; | ||||
| data->num_input.unit_sys = USER_UNIT_NONE; | data->num_input.unit_sys = USER_UNIT_NONE; | ||||
| data->num_input.unit_type[0] = 0; | data->num_input.unit_type[0] = 0; | ||||
| slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true); | slip_add_sequences_recursive(video_edit->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]); | ||||
| } | } | ||||
| UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]); | UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]); | ||||
| copy_v2_v2_int(data->init_mouse, event->mval); | copy_v2_v2_int(data->init_mouse, event->mval); | ||||
| copy_v2_v2(data->init_mouseloc, mouseloc); | copy_v2_v2(data->init_mouseloc, mouseloc); | ||||
| data->slow = false; | data->slow = false; | ||||
| 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_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| static void sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) | static void sequencer_slip_recursively(VideoEdit *video_edit, SlipData *data, int offset) | ||||
| { | { | ||||
| 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->start = data->ts[i].start + offset; | seq->start = data->ts[i].start + offset; | ||||
| if (data->trim[i]) { | if (data->trim[i]) { | ||||
| seq->startofs = data->ts[i].startofs - offset; | seq->startofs = data->ts[i].startofs - offset; | ||||
| seq->endofs = data->ts[i].endofs + offset; | seq->endofs = data->ts[i].endofs + offset; | ||||
| } | } | ||||
| } | } | ||||
| 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(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| /* 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(const Scene *scene, SlipData *data, int *offset) | static void sequencer_slip_apply_limits(const VideoEdit *video_edit, 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; | ||||
| int seq_content_end = seq_content_start + seq->len + seq->anim_startofs + seq->anim_endofs; | int seq_content_end = seq_content_start + seq->len + seq->anim_startofs + seq->anim_endofs; | ||||
| int diff = 0; | int diff = 0; | ||||
| if (seq_content_start >= SEQ_time_right_handle_frame_get(scene, seq)) { | if (seq_content_start >= SEQ_time_right_handle_frame_get(video_edit, seq)) { | ||||
| diff = SEQ_time_right_handle_frame_get(scene, seq) - seq_content_start - 1; | diff = SEQ_time_right_handle_frame_get(video_edit, seq) - seq_content_start - 1; | ||||
| } | } | ||||
| if (seq_content_end <= SEQ_time_left_handle_frame_get(scene, seq)) { | if (seq_content_end <= SEQ_time_left_handle_frame_get(video_edit, seq)) { | ||||
| diff = SEQ_time_left_handle_frame_get(scene, seq) - seq_content_end + 1; | diff = SEQ_time_left_handle_frame_get(video_edit, seq) - seq_content_end + 1; | ||||
| } | } | ||||
| *offset += diff; | *offset += diff; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static int sequencer_slip_exec(bContext *C, wmOperator *op) | static int sequencer_slip_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| int offset = RNA_int_get(op->ptr, "offset"); | int offset = RNA_int_get(op->ptr, "offset"); | ||||
| /* 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(video_edit->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(video_edit->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(scene, data, &offset); | sequencer_slip_apply_limits(video_edit, data, &offset); | ||||
| sequencer_slip_recursively(scene, data, offset); | sequencer_slip_recursively(video_edit, 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); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static void sequencer_slip_update_header(Scene *scene, ScrArea *area, SlipData *data, int offset) | static void sequencer_slip_update_header(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]; | ||||
| outputNumInput(&data->num_input, num_str, &scene->unit); | outputNumInput(&data->num_input, num_str, NULL); | ||||
| BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %s"), num_str); | BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %s"), num_str); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %d"), offset); | BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %d"), offset); | ||||
| } | } | ||||
| } | } | ||||
| ED_area_status_text(area, msg); | ED_area_status_text(area, msg); | ||||
| } | } | ||||
| static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| SlipData *data = (SlipData *)op->customdata; | SlipData *data = (SlipData *)op->customdata; | ||||
| ScrArea *area = CTX_wm_area(C); | ScrArea *area = CTX_wm_area(C); | ||||
| const bool has_numInput = hasNumInput(&data->num_input); | const bool has_numInput = hasNumInput(&data->num_input); | ||||
| bool handled = true; | bool handled = true; | ||||
| /* Modal numinput active, try to handle numeric inputs. */ | /* Modal numinput active, try to handle numeric inputs. */ | ||||
| if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) { | if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) { | ||||
| float offset_fl; | float offset_fl; | ||||
| 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(scene, data, &offset); | sequencer_slip_apply_limits(video_edit, data, &offset); | ||||
| sequencer_slip_update_header(scene, area, data, offset); | sequencer_slip_update_header(area, data, offset); | ||||
| RNA_int_set(op->ptr, "offset", offset); | RNA_int_set(op->ptr, "offset", offset); | ||||
| sequencer_slip_recursively(scene, data, offset); | sequencer_slip_recursively(video_edit, data, offset); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| 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 9 Lines | case MOUSEMOVE: { | ||||
| else { | else { | ||||
| mouse_x = event->mval[0]; | mouse_x = event->mval[0]; | ||||
| } | } | ||||
| /* Choose the side based on which side of the current frame the mouse is. */ | /* Choose the side based on which side of the current frame the mouse is. */ | ||||
| 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(scene, data, &offset); | sequencer_slip_apply_limits(video_edit, data, &offset); | ||||
| sequencer_slip_update_header(scene, area, data, offset); | sequencer_slip_update_header(area, data, offset); | ||||
| RNA_int_set(op->ptr, "offset", offset); | RNA_int_set(op->ptr, "offset", offset); | ||||
| sequencer_slip_recursively(scene, data, offset); | sequencer_slip_recursively(video_edit, data, offset); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| } | } | ||||
| 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); | ||||
| MEM_freeN(data->ts); | MEM_freeN(data->ts); | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| op->customdata = NULL; | op->customdata = NULL; | ||||
| if (area) { | if (area) { | ||||
| ED_area_status_text(area, NULL); | ED_area_status_text(area, NULL); | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| case EVT_ESCKEY: | case EVT_ESCKEY: | ||||
| case RIGHTMOUSE: { | case RIGHTMOUSE: { | ||||
| for (int i = 0; i < data->num_seq; i++) { | for (int i = 0; i < data->num_seq; i++) { | ||||
| transseq_restore(data->ts + i, data->seq_array[i]); | transseq_restore(data->ts + i, data->seq_array[i]); | ||||
| } | } | ||||
| for (int i = 0; i < data->num_seq; i++) { | for (int i = 0; i < data->num_seq; i++) { | ||||
| Sequence *seq = data->seq_array[i]; | Sequence *seq = data->seq_array[i]; | ||||
| SEQ_add_reload_new_file(bmain, scene, seq, false); | SEQ_add_reload_new_file(bmain, video_edit, seq, false); | ||||
| } | } | ||||
| MEM_freeN(data->seq_array); | MEM_freeN(data->seq_array); | ||||
| MEM_freeN(data->ts); | MEM_freeN(data->ts); | ||||
| MEM_freeN(data->trim); | MEM_freeN(data->trim); | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| op->customdata = NULL; | op->customdata = NULL; | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| if (area) { | if (area) { | ||||
| ED_area_status_text(area, NULL); | ED_area_status_text(area, NULL); | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| Show All 16 Lines | static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| } | } | ||||
| /* Modal numinput inactive, try to handle numeric inputs. */ | /* Modal numinput inactive, try to handle numeric inputs. */ | ||||
| if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) { | if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) { | ||||
| float offset_fl; | float offset_fl; | ||||
| 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(scene, data, &offset); | sequencer_slip_apply_limits(video_edit, data, &offset); | ||||
| sequencer_slip_update_header(scene, area, data, offset); | sequencer_slip_update_header(area, data, offset); | ||||
| RNA_int_set(op->ptr, "offset", offset); | RNA_int_set(op->ptr, "offset", offset); | ||||
| sequencer_slip_recursively(scene, data, offset); | sequencer_slip_recursively(video_edit, data, offset); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| } | } | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| void SEQUENCER_OT_slip(struct wmOperatorType *ot) | void SEQUENCER_OT_slip(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| Show All 24 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Mute Strips Operator | /** \name Mute Strips Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_mute_exec(bContext *C, wmOperator *op) | static int sequencer_mute_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | ListBase *channels = SEQ_channels_displayed_get(video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| bool selected; | bool selected; | ||||
| selected = !RNA_boolean_get(op->ptr, "unselected"); | selected = !RNA_boolean_get(op->ptr, "unselected"); | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (!SEQ_transform_is_locked(channels, seq)) { | if (!SEQ_transform_is_locked(channels, seq)) { | ||||
| if (selected) { | if (selected) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| seq->flag |= SEQ_MUTE; | seq->flag |= SEQ_MUTE; | ||||
| SEQ_relations_invalidate_dependent(scene, seq); | SEQ_relations_invalidate_dependent(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if ((seq->flag & SELECT) == 0) { | if ((seq->flag & SELECT) == 0) { | ||||
| seq->flag |= SEQ_MUTE; | seq->flag |= SEQ_MUTE; | ||||
| SEQ_relations_invalidate_dependent(scene, seq); | SEQ_relations_invalidate_dependent(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_mute(struct wmOperatorType *ot) | void SEQUENCER_OT_mute(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Mute Strips"; | ot->name = "Mute Strips"; | ||||
| Show All 14 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Unmute Strips Operator | /** \name Unmute Strips Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_unmute_exec(bContext *C, wmOperator *op) | static int sequencer_unmute_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | ListBase *channels = SEQ_channels_displayed_get(video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| bool selected; | bool selected; | ||||
| selected = !RNA_boolean_get(op->ptr, "unselected"); | selected = !RNA_boolean_get(op->ptr, "unselected"); | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (!SEQ_transform_is_locked(channels, seq)) { | if (!SEQ_transform_is_locked(channels, seq)) { | ||||
| if (selected) { | if (selected) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| seq->flag &= ~SEQ_MUTE; | seq->flag &= ~SEQ_MUTE; | ||||
| SEQ_relations_invalidate_dependent(scene, seq); | SEQ_relations_invalidate_dependent(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if ((seq->flag & SELECT) == 0) { | if ((seq->flag & SELECT) == 0) { | ||||
| seq->flag &= ~SEQ_MUTE; | seq->flag &= ~SEQ_MUTE; | ||||
| SEQ_relations_invalidate_dependent(scene, seq); | SEQ_relations_invalidate_dependent(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_unmute(struct wmOperatorType *ot) | void SEQUENCER_OT_unmute(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Unmute Strips"; | ot->name = "Unmute Strips"; | ||||
| Show All 14 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Lock Strips Operator | /** \name Lock Strips Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| seq->flag |= SEQ_LOCK; | seq->flag |= SEQ_LOCK; | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_lock(struct wmOperatorType *ot) | void SEQUENCER_OT_lock(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Lock Strips"; | ot->name = "Lock Strips"; | ||||
| Show All 11 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Unlock Strips Operator | /** \name Unlock Strips Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| seq->flag &= ~SEQ_LOCK; | seq->flag &= ~SEQ_LOCK; | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_unlock(struct wmOperatorType *ot) | void SEQUENCER_OT_unlock(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Unlock Strips"; | ot->name = "Unlock Strips"; | ||||
| Show All 12 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Reload Strips Operator | /** \name Reload Strips Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_reload_exec(bContext *C, wmOperator *op) | static int sequencer_reload_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length"); | const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length"); | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| SEQ_add_reload_new_file(bmain, scene, seq, !adjust_length); | SEQ_add_reload_new_file(bmain, video_edit, seq, !adjust_length); | ||||
| if (adjust_length) { | if (adjust_length) { | ||||
| if (SEQ_transform_test_overlap(scene, ed->seqbasep, seq)) { | if (SEQ_transform_test_overlap(video_edit, video_edit->seqbasep, seq)) { | ||||
| SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); | SEQ_transform_seqbase_shuffle(video_edit, video_edit->seqbasep, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_reload(struct wmOperatorType *ot) | void SEQUENCER_OT_reload(struct wmOperatorType *ot) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| Show All 28 Lines | static bool sequencer_refresh_all_poll(bContext *C) | ||||
| if (G.is_rendering) { | if (G.is_rendering) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| return sequencer_edit_poll(C); | return sequencer_edit_poll(C); | ||||
| } | } | ||||
| static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| SEQ_relations_free_imbuf(scene, &ed->seqbase, false); | SEQ_relations_free_imbuf(video_edit, &video_edit->seqbase, false); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot) | void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Refresh Sequencer"; | ot->name = "Refresh Sequencer"; | ||||
| ot->idname = "SEQUENCER_OT_refresh_all"; | ot->idname = "SEQUENCER_OT_refresh_all"; | ||||
| ot->description = "Refresh the sequencer editor"; | ot->description = "Refresh the sequencer editor"; | ||||
| /* Api callbacks. */ | /* Api callbacks. */ | ||||
| ot->exec = sequencer_refresh_all_exec; | ot->exec = sequencer_refresh_all_exec; | ||||
| ot->poll = sequencer_refresh_all_poll; | ot->poll = sequencer_refresh_all_poll; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Reassign Inputs Operator | /** \name Reassign Inputs Operator | ||||
| * \{ */ | * \{ */ | ||||
| int seq_effect_find_selected(Scene *scene, | int seq_effect_find_selected(VideoEdit *video_edit, | ||||
| Sequence *activeseq, | Sequence *activeseq, | ||||
| int type, | int type, | ||||
| Sequence **r_selseq1, | Sequence **r_selseq1, | ||||
| Sequence **r_selseq2, | Sequence **r_selseq2, | ||||
| Sequence **r_selseq3, | Sequence **r_selseq3, | ||||
| const char **r_error_str) | const char **r_error_str) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq; | Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq; | ||||
| *r_error_str = NULL; | *r_error_str = NULL; | ||||
| if (!activeseq) { | if (!activeseq) { | ||||
| seq2 = SEQ_select_active_get(scene); | seq2 = SEQ_select_active_get(video_edit); | ||||
| } | } | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| if (seq->type == SEQ_TYPE_SOUND_RAM && SEQ_effect_get_num_inputs(type) != 0) { | if (seq->type == SEQ_TYPE_SOUND_RAM && SEQ_effect_get_num_inputs(type) != 0) { | ||||
| *r_error_str = N_("Cannot apply effects to audio sequence strips"); | *r_error_str = N_("Cannot apply effects to audio sequence strips"); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| if (!ELEM(seq, activeseq, seq2)) { | if (!ELEM(seq, activeseq, seq2)) { | ||||
| if (seq2 == NULL) { | if (seq2 == NULL) { | ||||
| seq2 = seq; | seq2 = seq; | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | if (SEQ_effect_get_num_inputs(type) < 2) { | ||||
| *r_selseq2 = NULL; | *r_selseq2 = NULL; | ||||
| } | } | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) | static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq1, *seq2, *seq3, *last_seq = SEQ_select_active_get(scene); | Sequence *seq1, *seq2, *seq3, *last_seq = SEQ_select_active_get(video_edit); | ||||
| const char *error_msg; | const char *error_msg; | ||||
| if (SEQ_effect_get_num_inputs(last_seq->type) == 0) { | if (SEQ_effect_get_num_inputs(last_seq->type) == 0) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: strip has no inputs"); | BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: strip has no inputs"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (!seq_effect_find_selected( | if (!seq_effect_find_selected( | ||||
| scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg) || | video_edit, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg) || | ||||
| SEQ_effect_get_num_inputs(last_seq->type) == 0) { | SEQ_effect_get_num_inputs(last_seq->type) == 0) { | ||||
| BKE_report(op->reports, RPT_ERROR, error_msg); | BKE_report(op->reports, RPT_ERROR, error_msg); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* Check if reassigning would create recursivity. */ | /* Check if reassigning would create recursivity. */ | ||||
| if (SEQ_relations_render_loop_check(seq1, last_seq) || | if (SEQ_relations_render_loop_check(seq1, last_seq) || | ||||
| SEQ_relations_render_loop_check(seq2, last_seq) || | SEQ_relations_render_loop_check(seq2, last_seq) || | ||||
| SEQ_relations_render_loop_check(seq3, last_seq)) { | SEQ_relations_render_loop_check(seq3, last_seq)) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: recursion detected"); | BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: recursion detected"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| last_seq->seq1 = seq1; | last_seq->seq1 = seq1; | ||||
| last_seq->seq2 = seq2; | last_seq->seq2 = seq2; | ||||
| last_seq->seq3 = seq3; | last_seq->seq3 = seq3; | ||||
| int old_start = last_seq->start; | int old_start = last_seq->start; | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, last_seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, last_seq); | ||||
| SEQ_offset_animdata(scene, last_seq, (last_seq->start - old_start)); | SEQ_offset_animdata(video_edit, last_seq, (last_seq->start - old_start)); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static bool sequencer_effect_poll(bContext *C) | static bool sequencer_effect_poll(bContext *C) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| if (ed) { | Sequence *last_seq = SEQ_select_active_get(video_edit); | ||||
| Sequence *last_seq = SEQ_select_active_get(scene); | |||||
| if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) { | if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) { | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| } | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot) | void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Reassign Inputs"; | ot->name = "Reassign Inputs"; | ||||
| Show All 11 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Swap Inputs Operator | /** \name Swap Inputs Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op) | static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq, *last_seq = SEQ_select_active_get(scene); | Sequence *seq, *last_seq = SEQ_select_active_get(video_edit); | ||||
| if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) { | if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) { | ||||
| BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap"); | BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| seq = last_seq->seq1; | seq = last_seq->seq1; | ||||
| last_seq->seq1 = last_seq->seq2; | last_seq->seq1 = last_seq->seq2; | ||||
| last_seq->seq2 = seq; | last_seq->seq2 = seq; | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, last_seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, last_seq); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot) | void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Swap Inputs"; | ot->name = "Swap Inputs"; | ||||
| ot->idname = "SEQUENCER_OT_swap_inputs"; | ot->idname = "SEQUENCER_OT_swap_inputs"; | ||||
| Show All 40 Lines | EnumPropertyItem prop_side_types[] = { | ||||
| {SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""}, | {SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""}, | ||||
| {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No Change", ""}, | {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No Change", ""}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static int sequencer_split_exec(bContext *C, wmOperator *op) | static int sequencer_split_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| bool changed = false; | bool changed = false; | ||||
| bool seq_selected = false; | bool seq_selected = false; | ||||
| const int split_frame = RNA_int_get(op->ptr, "frame"); | const int split_frame = RNA_int_get(op->ptr, "frame"); | ||||
| const int split_channel = RNA_int_get(op->ptr, "channel"); | const int split_channel = RNA_int_get(op->ptr, "channel"); | ||||
| const bool use_cursor_position = RNA_boolean_get(op->ptr, "use_cursor_position"); | const bool use_cursor_position = RNA_boolean_get(op->ptr, "use_cursor_position"); | ||||
| const eSeqSplitMethod method = RNA_enum_get(op->ptr, "type"); | const eSeqSplitMethod method = RNA_enum_get(op->ptr, "type"); | ||||
| const int split_side = RNA_enum_get(op->ptr, "side"); | const int split_side = RNA_enum_get(op->ptr, "side"); | ||||
| const bool ignore_selection = RNA_boolean_get(op->ptr, "ignore_selection"); | const bool ignore_selection = RNA_boolean_get(op->ptr, "ignore_selection"); | ||||
| SEQ_prefetch_stop(scene); | SEQ_prefetch_stop(video_edit); | ||||
| LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { | LISTBASE_FOREACH (Sequence *, seq, video_edit->seqbasep) { | ||||
| seq->tmp = NULL; | seq->tmp = NULL; | ||||
| } | } | ||||
| LISTBASE_FOREACH_BACKWARD (Sequence *, seq, ed->seqbasep) { | LISTBASE_FOREACH_BACKWARD (Sequence *, seq, video_edit->seqbasep) { | ||||
| if (use_cursor_position && seq->machine != split_channel) { | if (use_cursor_position && seq->machine != split_channel) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (ignore_selection || seq->flag & SELECT) { | if (ignore_selection || seq->flag & SELECT) { | ||||
| const char *error_msg = NULL; | const char *error_msg = NULL; | ||||
| if (SEQ_edit_strip_split(bmain, scene, ed->seqbasep, seq, split_frame, method, &error_msg) != | if (SEQ_edit_strip_split( | ||||
| bmain, video_edit, video_edit->seqbasep, seq, split_frame, method, &error_msg) != | |||||
| NULL) { | NULL) { | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| if (error_msg != NULL) { | if (error_msg != NULL) { | ||||
| BKE_report(op->reports, RPT_ERROR, error_msg); | BKE_report(op->reports, RPT_ERROR, error_msg); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (changed) { /* Got new strips? */ | if (changed) { /* Got new strips? */ | ||||
| if (ignore_selection) { | if (ignore_selection) { | ||||
| if (use_cursor_position) { | if (use_cursor_position) { | ||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(video_edit)) { | ||||
| if (SEQ_time_right_handle_frame_get(scene, seq) == split_frame && | if (SEQ_time_right_handle_frame_get(video_edit, seq) == split_frame && | ||||
| seq->machine == split_channel) { | seq->machine == split_channel) { | ||||
| seq_selected = seq->flag & SEQ_ALLSEL; | seq_selected = seq->flag & SEQ_ALLSEL; | ||||
| } | } | ||||
| } | } | ||||
| if (!seq_selected) { | if (!seq_selected) { | ||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(video_edit)) { | ||||
| if (SEQ_time_left_handle_frame_get(scene, seq) == split_frame && | if (SEQ_time_left_handle_frame_get(video_edit, seq) == split_frame && | ||||
| seq->machine == split_channel) { | seq->machine == split_channel) { | ||||
| seq->flag &= ~SEQ_ALLSEL; | seq->flag &= ~SEQ_ALLSEL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (split_side != SEQ_SIDE_BOTH) { | if (split_side != SEQ_SIDE_BOTH) { | ||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(video_edit)) { | ||||
| if (split_side == SEQ_SIDE_LEFT) { | if (split_side == SEQ_SIDE_LEFT) { | ||||
| if (SEQ_time_left_handle_frame_get(scene, seq) >= split_frame) { | if (SEQ_time_left_handle_frame_get(video_edit, seq) >= split_frame) { | ||||
| seq->flag &= ~SEQ_ALLSEL; | seq->flag &= ~SEQ_ALLSEL; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (SEQ_time_right_handle_frame_get(scene, seq) <= split_frame) { | if (SEQ_time_right_handle_frame_get(video_edit, seq) <= split_frame) { | ||||
| seq->flag &= ~SEQ_ALLSEL; | seq->flag &= ~SEQ_ALLSEL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (changed) { | if (changed) { | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| /* Passthrough to selection if used as tool. */ | /* Passthrough to selection if used as tool. */ | ||||
| return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; | return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; | ||||
| } | } | ||||
| static int sequencer_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| View2D *v2d = UI_view2d_fromcontext(C); | View2D *v2d = UI_view2d_fromcontext(C); | ||||
| int split_side = RNA_enum_get(op->ptr, "side"); | int split_side = RNA_enum_get(op->ptr, "side"); | ||||
| int split_frame = scene->r.cfra; | int split_frame = video_edit->r.cfra; | ||||
| if (split_side == SEQ_SIDE_MOUSE) { | if (split_side == SEQ_SIDE_MOUSE) { | ||||
| if (ED_operator_sequencer_active(C) && v2d) { | if (ED_operator_sequencer_active(C) && v2d) { | ||||
| split_side = mouse_frame_side(v2d, event->mval[0], split_frame); | split_side = mouse_frame_side(v2d, event->mval[0], split_frame); | ||||
| } | } | ||||
| else { | else { | ||||
| split_side = SEQ_SIDE_BOTH; | split_side = SEQ_SIDE_BOTH; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Duplicate Strips Operator | /** \name Duplicate Strips Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| if (ed == NULL) { | if (video_edit == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| Sequence *active_seq = SEQ_select_active_get(scene); | Sequence *active_seq = SEQ_select_active_get(video_edit); | ||||
| ListBase duplicated_strips = {NULL, NULL}; | ListBase duplicated_strips = {NULL, NULL}; | ||||
| SEQ_sequence_base_dupli_recursive(scene, scene, &duplicated_strips, ed->seqbasep, 0, 0); | SEQ_sequence_base_dupli_recursive( | ||||
| ED_sequencer_deselect_all(scene); | video_edit, video_edit, &duplicated_strips, video_edit->seqbasep, 0, 0); | ||||
| ED_sequencer_deselect_all(video_edit); | |||||
| if (duplicated_strips.first == NULL) { | if (duplicated_strips.first == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* Duplicate animation. | /* Duplicate animation. | ||||
| * First backup original curves from scene and duplicate strip curves from backup into scene. | * First backup original curves from scene and duplicate strip curves from backup into scene. | ||||
| * This way, when pasted strips are renamed, curves are renamed with them. Finally, restore | * This way, when pasted strips are renamed, curves are renamed with them. Finally, restore | ||||
| * original curves from backup. | * original curves from backup. | ||||
| */ | */ | ||||
| ListBase fcurves_original_backup = {NULL, NULL}; | ListBase fcurves_original_backup = {NULL, NULL}; | ||||
| SEQ_animation_backup_original(scene, &fcurves_original_backup); | SEQ_animation_backup_original(video_edit, &fcurves_original_backup); | ||||
| Sequence *seq = duplicated_strips.first; | Sequence *seq = duplicated_strips.first; | ||||
| /* Rely on the nseqbase list being added at the end. | /* Rely on the nseqbase list being added at the end. | ||||
| * Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */ | * Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */ | ||||
| BLI_movelisttolist(ed->seqbasep, &duplicated_strips); | BLI_movelisttolist(video_edit->seqbasep, &duplicated_strips); | ||||
| /* Handle duplicated strips: set active, select, ensure unique name and duplicate animation | /* Handle duplicated strips: set active, select, ensure unique name and duplicate animation | ||||
| * data. */ | * data. */ | ||||
| for (; seq; seq = seq->next) { | for (; seq; seq = seq->next) { | ||||
| if (active_seq != NULL && STREQ(seq->name, active_seq->name)) { | if (active_seq != NULL && STREQ(seq->name, active_seq->name)) { | ||||
| SEQ_select_active_set(scene, seq); | SEQ_select_active_set(video_edit, seq); | ||||
| } | } | ||||
| seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); | seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); | ||||
| seq->flag |= SEQ_IGNORE_CHANNEL_LOCK; | seq->flag |= SEQ_IGNORE_CHANNEL_LOCK; | ||||
| SEQ_animation_duplicate(scene, seq, &fcurves_original_backup); | SEQ_animation_duplicate(video_edit, seq, &fcurves_original_backup); | ||||
| SEQ_ensure_unique_name(seq, scene); | SEQ_ensure_unique_name(seq, video_edit); | ||||
| } | } | ||||
| SEQ_animation_restore_original(scene, &fcurves_original_backup); | SEQ_animation_restore_original(video_edit, &fcurves_original_backup); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_duplicate(wmOperatorType *ot) | void SEQUENCER_OT_duplicate(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Duplicate Strips"; | ot->name = "Duplicate Strips"; | ||||
| ot->idname = "SEQUENCER_OT_duplicate"; | ot->idname = "SEQUENCER_OT_duplicate"; | ||||
| Show All 25 Lines | if (ED_scene_delete(C, bmain, seq->scene)) { | ||||
| WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, seq->scene); | WM_event_add_notifier(C, NC_SCENE | NA_REMOVED, seq->scene); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static int sequencer_delete_exec(bContext *C, wmOperator *op) | static int sequencer_delete_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| ListBase *seqbasep = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | ListBase *seqbasep = SEQ_active_seqbase_get(video_edit); | ||||
| const bool delete_data = RNA_boolean_get(op->ptr, "delete_data"); | const bool delete_data = RNA_boolean_get(op->ptr, "delete_data"); | ||||
| if (sequencer_view_has_preview_poll(C) && !sequencer_view_preview_only_poll(C)) { | if (sequencer_view_has_preview_poll(C) && !sequencer_view_preview_only_poll(C)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| SEQ_prefetch_stop(scene); | SEQ_prefetch_stop(video_edit); | ||||
| SeqCollection *selected_strips = selected_strips_from_context(C); | SeqCollection *selected_strips = selected_strips_from_context(C); | ||||
| Sequence *seq; | Sequence *seq; | ||||
| SEQ_ITERATOR_FOREACH (seq, selected_strips) { | SEQ_ITERATOR_FOREACH (seq, selected_strips) { | ||||
| SEQ_edit_flag_for_removal(scene, seqbasep, seq); | SEQ_edit_flag_for_removal(video_edit, seqbasep, seq); | ||||
| if (delete_data) { | if (delete_data) { | ||||
| sequencer_delete_strip_data(C, seq); | sequencer_delete_strip_data(C, seq); | ||||
| } | } | ||||
| } | } | ||||
| SEQ_edit_remove_flagged_sequences(scene, seqbasep); | SEQ_edit_remove_flagged_sequences(video_edit, seqbasep); | ||||
| SEQ_collection_free(selected_strips); | SEQ_collection_free(selected_strips); | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| DEG_relations_tag_update(bmain); | DEG_relations_tag_update(bmain); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| ListBase *markers = &scene->markers; | ListBase *markers = &video_edit->markers; | ||||
| if (region->regiontype == RGN_TYPE_WINDOW && !BLI_listbase_is_empty(markers)) { | if (region->regiontype == RGN_TYPE_WINDOW && !BLI_listbase_is_empty(markers)) { | ||||
| /* Bounding box of 30 pixels is used for markers shortcuts, | /* Bounding box of 30 pixels is used for markers shortcuts, | ||||
| * prevent conflict with markers shortcuts here. | * prevent conflict with markers shortcuts here. | ||||
| */ | */ | ||||
| if (event->mval[1] <= 30) { | if (event->mval[1] <= 30) { | ||||
| return OPERATOR_PASS_THROUGH; | return OPERATOR_PASS_THROUGH; | ||||
| } | } | ||||
| Show All 30 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Clear Strip Offset Operator | /** \name Clear Strip Offset Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| 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 = video_edit->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 = 0; | seq->startofs = seq->endofs = 0; | ||||
| } | } | ||||
| } | } | ||||
| /* Update lengths, etc. */ | /* Update lengths, etc. */ | ||||
| seq = ed->seqbasep->first; | seq = video_edit->seqbasep->first; | ||||
| while (seq) { | while (seq) { | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seq); | ||||
| seq = seq->next; | seq = seq->next; | ||||
| } | } | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->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)) { | ||||
| if (SEQ_transform_test_overlap(scene, ed->seqbasep, seq)) { | if (SEQ_transform_test_overlap(video_edit, video_edit->seqbasep, seq)) { | ||||
| SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); | SEQ_transform_seqbase_shuffle(video_edit, video_edit->seqbasep, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_offset_clear(wmOperatorType *ot) | void SEQUENCER_OT_offset_clear(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| Show All 12 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Separate Images Operator | /** \name Separate Images Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_separate_images_exec(bContext *C, wmOperator *op) | static int sequencer_separate_images_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | ListBase *seqbase = SEQ_active_seqbase_get(video_edit); | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(ed); | |||||
| Sequence *seq, *seq_new; | Sequence *seq, *seq_new; | ||||
| Strip *strip_new; | Strip *strip_new; | ||||
| StripElem *se, *se_new; | StripElem *se, *se_new; | ||||
| int start_ofs, timeline_frame, frame_end; | int start_ofs, timeline_frame, frame_end; | ||||
| int step = RNA_int_get(op->ptr, "length"); | int step = RNA_int_get(op->ptr, "length"); | ||||
| seq = seqbase->first; /* Poll checks this is valid. */ | seq = seqbase->first; /* Poll checks this is valid. */ | ||||
| SEQ_prefetch_stop(scene); | SEQ_prefetch_stop(video_edit); | ||||
| while (seq) { | while (seq) { | ||||
| if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { | if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { | ||||
| Sequence *seq_next; | Sequence *seq_next; | ||||
| /* Remove seq so overlap tests don't conflict, | /* Remove seq so overlap tests don't conflict, | ||||
| * see seq_free_sequence below for the real freeing. */ | * see seq_free_sequence below for the real freeing. */ | ||||
| BLI_remlink(seqbase, seq); | BLI_remlink(seqbase, seq); | ||||
| /* TODO: remove f-curve and assign to split image strips. | /* TODO: remove f-curve and assign to split image strips. | ||||
| * The old animation system would remove the user of `seq->ipo`. */ | * The old animation system would remove the user of `seq->ipo`. */ | ||||
| start_ofs = timeline_frame = SEQ_time_left_handle_frame_get(scene, seq); | start_ofs = timeline_frame = SEQ_time_left_handle_frame_get(video_edit, seq); | ||||
| frame_end = SEQ_time_right_handle_frame_get(scene, seq); | frame_end = SEQ_time_right_handle_frame_get(video_edit, seq); | ||||
| while (timeline_frame < frame_end) { | while (timeline_frame < frame_end) { | ||||
| /* New seq. */ | /* New seq. */ | ||||
| se = SEQ_render_give_stripelem(scene, seq, timeline_frame); | se = SEQ_render_give_stripelem(video_edit, seq, timeline_frame); | ||||
| seq_new = SEQ_sequence_dupli_recursive(scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME); | seq_new = SEQ_sequence_dupli_recursive( | ||||
| video_edit, video_edit, 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->endofs = 1 - step; | 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. */ | ||||
| se_new = MEM_reallocN(strip_new->stripdata, sizeof(*se_new)); | se_new = MEM_reallocN(strip_new->stripdata, sizeof(*se_new)); | ||||
| BLI_strncpy(se_new->name, se->name, sizeof(se_new->name)); | BLI_strncpy(se_new->name, se->name, sizeof(se_new->name)); | ||||
| strip_new->stripdata = se_new; | strip_new->stripdata = se_new; | ||||
| if (step > 1) { | if (step > 1) { | ||||
| seq_new->flag &= ~SEQ_OVERLAP; | seq_new->flag &= ~SEQ_OVERLAP; | ||||
| if (SEQ_transform_test_overlap(scene, seqbase, seq_new)) { | if (SEQ_transform_test_overlap(video_edit, seqbase, seq_new)) { | ||||
| SEQ_transform_seqbase_shuffle(seqbase, seq_new, scene); | SEQ_transform_seqbase_shuffle(video_edit, seqbase, seq_new); | ||||
| } | } | ||||
| } | } | ||||
| /* XXX, COPY FCURVES */ | /* XXX, COPY FCURVES */ | ||||
| timeline_frame++; | timeline_frame++; | ||||
| start_ofs += step; | start_ofs += step; | ||||
| } | } | ||||
| seq_next = seq->next; | seq_next = seq->next; | ||||
| SEQ_edit_flag_for_removal(scene, seqbase, seq); | SEQ_edit_flag_for_removal(video_edit, seqbase, seq); | ||||
| seq = seq_next; | seq = seq_next; | ||||
| } | } | ||||
| else { | else { | ||||
| seq = seq->next; | seq = seq->next; | ||||
| } | } | ||||
| } | } | ||||
| SEQ_edit_remove_flagged_sequences(scene, seqbase); | SEQ_edit_remove_flagged_sequences(video_edit, seqbase); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_images_separate(wmOperatorType *ot) | void SEQUENCER_OT_images_separate(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Separate Images"; | ot->name = "Separate Images"; | ||||
| Show All 14 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Toggle Meta Strip Operator | /** \name Toggle Meta Strip Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | Sequence *active_seq = SEQ_select_active_get(video_edit); | ||||
| Sequence *active_seq = SEQ_select_active_get(scene); | |||||
| SEQ_prefetch_stop(scene); | SEQ_prefetch_stop(video_edit); | ||||
| if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) { | if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) { | ||||
| /* Deselect active meta seq. */ | /* Deselect active meta seq. */ | ||||
| SEQ_select_active_set(scene, NULL); | SEQ_select_active_set(video_edit, NULL); | ||||
| SEQ_meta_stack_set(scene, active_seq); | SEQ_meta_stack_set(video_edit, active_seq); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Exit meta-strip if possible. */ | /* Exit meta-strip if possible. */ | ||||
| if (BLI_listbase_is_empty(&ed->metastack)) { | if (BLI_listbase_is_empty(&video_edit->metastack)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* Display parent meta. */ | /* Display parent meta. */ | ||||
| Sequence *meta_parent = SEQ_meta_stack_pop(ed); | Sequence *meta_parent = SEQ_meta_stack_pop(video_edit); | ||||
| SEQ_select_active_set(scene, meta_parent); | SEQ_select_active_set(video_edit, meta_parent); | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_meta_toggle(wmOperatorType *ot) | void SEQUENCER_OT_meta_toggle(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Toggle Meta Strip"; | ot->name = "Toggle Meta Strip"; | ||||
| Show All 11 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Make Meta Strip Operator | /** \name Make Meta Strip Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_meta_make_exec(bContext *C, wmOperator *op) | static int sequencer_meta_make_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | Sequence *active_seq = SEQ_select_active_get(video_edit); | ||||
| Sequence *active_seq = SEQ_select_active_get(scene); | ListBase *active_seqbase = SEQ_active_seqbase_get(video_edit); | ||||
| ListBase *active_seqbase = SEQ_active_seqbase_get(ed); | |||||
| if (SEQ_transform_seqbase_isolated_sel_check(active_seqbase) == false) { | if (SEQ_transform_seqbase_isolated_sel_check(active_seqbase) == false) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); | BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| SEQ_prefetch_stop(scene); | SEQ_prefetch_stop(video_edit); | ||||
| int channel_max = 1, meta_start_frame = MAXFRAME, meta_end_frame = MINFRAME; | int channel_max = 1, meta_start_frame = MAXFRAME, meta_end_frame = MINFRAME; | ||||
| Sequence *seqm = SEQ_sequence_alloc(active_seqbase, 1, 1, SEQ_TYPE_META); | Sequence *seqm = SEQ_sequence_alloc(active_seqbase, 1, 1, SEQ_TYPE_META); | ||||
| /* Remove all selected from main list, and put in meta. | /* Remove all selected from main list, and put in meta. | ||||
| * Sequence is moved within the same edit, no need to re-generate the UUID. */ | * Sequence is moved within the same edit, no need to re-generate the UUID. */ | ||||
| LISTBASE_FOREACH_MUTABLE (Sequence *, seq, active_seqbase) { | LISTBASE_FOREACH_MUTABLE (Sequence *, seq, active_seqbase) { | ||||
| if (seq != seqm && seq->flag & SELECT) { | if (seq != seqm && seq->flag & SELECT) { | ||||
| BLI_remlink(active_seqbase, seq); | BLI_remlink(active_seqbase, seq); | ||||
| BLI_addtail(&seqm->seqbase, seq); | BLI_addtail(&seqm->seqbase, seq); | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seq); | ||||
| channel_max = max_ii(seq->machine, channel_max); | channel_max = max_ii(seq->machine, channel_max); | ||||
| meta_start_frame = min_ii(SEQ_time_left_handle_frame_get(scene, seq), meta_start_frame); | meta_start_frame = min_ii(SEQ_time_left_handle_frame_get(video_edit, seq), meta_start_frame); | ||||
| meta_end_frame = max_ii(SEQ_time_right_handle_frame_get(scene, seq), meta_end_frame); | meta_end_frame = max_ii(SEQ_time_right_handle_frame_get(video_edit, seq), meta_end_frame); | ||||
| } | } | ||||
| } | } | ||||
| seqm->machine = active_seq ? active_seq->machine : channel_max; | seqm->machine = active_seq ? active_seq->machine : channel_max; | ||||
| strcpy(seqm->name + 2, "MetaStrip"); | strcpy(seqm->name + 2, "MetaStrip"); | ||||
| SEQ_sequence_base_unique_name_recursive(scene, &ed->seqbase, seqm); | SEQ_sequence_base_unique_name_recursive(video_edit, &video_edit->seqbase, seqm); | ||||
| seqm->start = meta_start_frame; | seqm->start = meta_start_frame; | ||||
| seqm->len = meta_end_frame - meta_start_frame; | seqm->len = meta_end_frame - meta_start_frame; | ||||
| SEQ_select_active_set(scene, seqm); | SEQ_select_active_set(video_edit, seqm); | ||||
| if (SEQ_transform_test_overlap(scene, active_seqbase, seqm)) { | if (SEQ_transform_test_overlap(video_edit, active_seqbase, seqm)) { | ||||
| SEQ_transform_seqbase_shuffle(active_seqbase, seqm, scene); | SEQ_transform_seqbase_shuffle(video_edit, active_seqbase, seqm); | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_meta_make(wmOperatorType *ot) | void SEQUENCER_OT_meta_make(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Make Meta Strip"; | ot->name = "Make Meta Strip"; | ||||
| Show All 11 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name UnMeta Strip Operator | /** \name UnMeta Strip Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | Sequence *active_seq = SEQ_select_active_get(video_edit); | ||||
| Sequence *active_seq = SEQ_select_active_get(scene); | |||||
| if (active_seq == NULL || active_seq->type != SEQ_TYPE_META) { | if (active_seq == NULL || active_seq->type != SEQ_TYPE_META) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| SEQ_prefetch_stop(scene); | SEQ_prefetch_stop(video_edit); | ||||
| LISTBASE_FOREACH (Sequence *, seq, &active_seq->seqbase) { | LISTBASE_FOREACH (Sequence *, seq, &active_seq->seqbase) { | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seq); | ||||
| } | } | ||||
| /* Remove all selected from meta, and put in main list. | /* Remove all selected from meta, and put in main list. | ||||
| * Sequence is moved within the same edit, no need to re-generate the UUID. */ | * Sequence is moved within the same edit, no need to re-generate the UUID. */ | ||||
| BLI_movelisttolist(ed->seqbasep, &active_seq->seqbase); | BLI_movelisttolist(video_edit->seqbasep, &active_seq->seqbase); | ||||
| BLI_listbase_clear(&active_seq->seqbase); | BLI_listbase_clear(&active_seq->seqbase); | ||||
| ListBase *active_seqbase = SEQ_active_seqbase_get(ed); | ListBase *active_seqbase = SEQ_active_seqbase_get(video_edit); | ||||
| SEQ_edit_flag_for_removal(scene, active_seqbase, active_seq); | SEQ_edit_flag_for_removal(video_edit, active_seqbase, active_seq); | ||||
| SEQ_edit_remove_flagged_sequences(scene, active_seqbase); | SEQ_edit_remove_flagged_sequences(video_edit, active_seqbase); | ||||
| /* Test for effects and overlap. */ | /* Test for effects and overlap. */ | ||||
| LISTBASE_FOREACH (Sequence *, seq, active_seqbase) { | LISTBASE_FOREACH (Sequence *, seq, active_seqbase) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| seq->flag &= ~SEQ_OVERLAP; | seq->flag &= ~SEQ_OVERLAP; | ||||
| if (SEQ_transform_test_overlap(scene, active_seqbase, seq)) { | if (SEQ_transform_test_overlap(video_edit, active_seqbase, seq)) { | ||||
| SEQ_transform_seqbase_shuffle(active_seqbase, seq, scene); | SEQ_transform_seqbase_shuffle(video_edit, active_seqbase, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_meta_separate(wmOperatorType *ot) | void SEQUENCER_OT_meta_separate(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "UnMeta Strip"; | ot->name = "UnMeta Strip"; | ||||
| Show All 9 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Jump to Strip Operator | /** \name Jump to Strip Operator | ||||
| * \{ */ | * \{ */ | ||||
| static bool strip_jump_internal(Scene *scene, | static bool strip_jump_internal(VideoEdit *video_edit, | ||||
| const short side, | const short side, | ||||
| const bool do_skip_mute, | const bool do_skip_mute, | ||||
| const bool do_center) | const bool do_center) | ||||
| { | { | ||||
| bool changed = false; | bool changed = false; | ||||
| int timeline_frame = scene->r.cfra; | int timeline_frame = video_edit->r.cfra; | ||||
| int next_frame = SEQ_time_find_next_prev_edit( | int next_frame = SEQ_time_find_next_prev_edit( | ||||
| scene, timeline_frame, side, do_skip_mute, do_center, false); | video_edit, timeline_frame, side, do_skip_mute, do_center, false); | ||||
| if (next_frame != timeline_frame) { | if (next_frame != timeline_frame) { | ||||
| scene->r.cfra = next_frame; | video_edit->r.cfra = next_frame; | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| static bool sequencer_strip_jump_poll(bContext *C) | static bool sequencer_strip_jump_poll(bContext *C) | ||||
| { | { | ||||
| /* Prevent changes during render. */ | /* Prevent changes during render. */ | ||||
| if (G.is_rendering) { | if (G.is_rendering) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| return sequencer_edit_poll(C); | return sequencer_edit_poll(C); | ||||
| } | } | ||||
| static int sequencer_strip_jump_exec(bContext *C, wmOperator *op) | static int sequencer_strip_jump_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| const bool next = RNA_boolean_get(op->ptr, "next"); | const bool next = RNA_boolean_get(op->ptr, "next"); | ||||
| const bool center = RNA_boolean_get(op->ptr, "center"); | const bool center = RNA_boolean_get(op->ptr, "center"); | ||||
| /* Currently do_skip_mute is always true. */ | /* Currently do_skip_mute is always true. */ | ||||
| if (!strip_jump_internal(scene, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, true, center)) { | if (!strip_jump_internal(video_edit, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, true, center)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); | DEG_id_tag_update(&video_edit->id, ID_RECALC_FRAME_CHANGE); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_FRAME, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_strip_jump(wmOperatorType *ot) | void SEQUENCER_OT_strip_jump(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Jump to Strip"; | ot->name = "Jump to Strip"; | ||||
| Show All 19 Lines | |||||
| * \{ */ | * \{ */ | ||||
| static const EnumPropertyItem prop_side_lr_types[] = { | static const EnumPropertyItem prop_side_lr_types[] = { | ||||
| {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""}, | {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""}, | ||||
| {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""}, | {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb) | static void swap_sequence(VideoEdit *video_edit, Sequence *seqa, Sequence *seqb) | ||||
| { | { | ||||
| int gap = SEQ_time_left_handle_frame_get(scene, seqb) - | int gap = SEQ_time_left_handle_frame_get(video_edit, seqb) - | ||||
| SEQ_time_right_handle_frame_get(scene, seqa); | SEQ_time_right_handle_frame_get(video_edit, seqa); | ||||
| int seq_a_start; | int seq_a_start; | ||||
| int seq_b_start; | int seq_b_start; | ||||
| seq_b_start = (seqb->start - SEQ_time_left_handle_frame_get(scene, seqb)) + | seq_b_start = (seqb->start - SEQ_time_left_handle_frame_get(video_edit, seqb)) + | ||||
| SEQ_time_left_handle_frame_get(scene, seqa); | SEQ_time_left_handle_frame_get(video_edit, seqa); | ||||
| SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start); | SEQ_transform_translate_sequence(video_edit, seqb, seq_b_start - seqb->start); | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seqb); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seqb); | ||||
| seq_a_start = (seqa->start - SEQ_time_left_handle_frame_get(scene, seqa)) + | seq_a_start = (seqa->start - SEQ_time_left_handle_frame_get(video_edit, seqa)) + | ||||
| SEQ_time_right_handle_frame_get(scene, seqb) + gap; | SEQ_time_right_handle_frame_get(video_edit, seqb) + gap; | ||||
| SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start); | SEQ_transform_translate_sequence(video_edit, seqa, seq_a_start - seqa->start); | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seqa); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seqa); | ||||
| } | } | ||||
| static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel) | static Sequence *find_next_prev_sequence(VideoEdit *video_edit, Sequence *test, int lr, int sel) | ||||
| { | { | ||||
| /* sel: 0==unselected, 1==selected, -1==don't care. */ | /* sel: 0==unselected, 1==selected, -1==don't care. */ | ||||
| Sequence *seq, *best_seq = NULL; | Sequence *seq, *best_seq = NULL; | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| int dist, best_dist; | int dist, best_dist; | ||||
| best_dist = MAXFRAME * 2; | best_dist = MAXFRAME * 2; | ||||
| if (ed == NULL) { | if (video_edit == NULL) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| seq = ed->seqbasep->first; | seq = video_edit->seqbasep->first; | ||||
| while (seq) { | while (seq) { | ||||
| if ((seq != test) && (test->machine == seq->machine) && | if ((seq != test) && (test->machine == seq->machine) && | ||||
| ((sel == -1) || (sel == (seq->flag & SELECT)))) { | ((sel == -1) || (sel == (seq->flag & SELECT)))) { | ||||
| dist = MAXFRAME * 2; | dist = MAXFRAME * 2; | ||||
| switch (lr) { | switch (lr) { | ||||
| case SEQ_SIDE_LEFT: | case SEQ_SIDE_LEFT: | ||||
| if (SEQ_time_right_handle_frame_get(scene, seq) <= | if (SEQ_time_right_handle_frame_get(video_edit, seq) <= | ||||
| SEQ_time_left_handle_frame_get(scene, test)) { | SEQ_time_left_handle_frame_get(video_edit, test)) { | ||||
| dist = SEQ_time_right_handle_frame_get(scene, test) - | dist = SEQ_time_right_handle_frame_get(video_edit, test) - | ||||
| SEQ_time_left_handle_frame_get(scene, seq); | SEQ_time_left_handle_frame_get(video_edit, seq); | ||||
| } | } | ||||
| break; | break; | ||||
| case SEQ_SIDE_RIGHT: | case SEQ_SIDE_RIGHT: | ||||
| if (SEQ_time_left_handle_frame_get(scene, seq) >= | if (SEQ_time_left_handle_frame_get(video_edit, seq) >= | ||||
| SEQ_time_right_handle_frame_get(scene, test)) { | SEQ_time_right_handle_frame_get(video_edit, test)) { | ||||
| dist = SEQ_time_left_handle_frame_get(scene, seq) - | dist = SEQ_time_left_handle_frame_get(video_edit, seq) - | ||||
| SEQ_time_right_handle_frame_get(scene, test); | SEQ_time_right_handle_frame_get(video_edit, test); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| if (dist == 0) { | if (dist == 0) { | ||||
| best_seq = seq; | best_seq = seq; | ||||
| break; | break; | ||||
| } | } | ||||
| Show All 9 Lines | |||||
| static bool seq_is_parent(Sequence *par, Sequence *seq) | static bool seq_is_parent(Sequence *par, Sequence *seq) | ||||
| { | { | ||||
| return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq)); | return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq)); | ||||
| } | } | ||||
| static int sequencer_swap_exec(bContext *C, wmOperator *op) | static int sequencer_swap_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | Sequence *active_seq = SEQ_select_active_get(video_edit); | ||||
| Sequence *active_seq = SEQ_select_active_get(scene); | ListBase *seqbase = SEQ_active_seqbase_get(video_edit); | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(ed); | |||||
| Sequence *seq, *iseq; | Sequence *seq, *iseq; | ||||
| int side = RNA_enum_get(op->ptr, "side"); | int side = RNA_enum_get(op->ptr, "side"); | ||||
| if (active_seq == NULL) { | if (active_seq == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| seq = find_next_prev_sequence(scene, active_seq, side, -1); | seq = find_next_prev_sequence(video_edit, active_seq, side, -1); | ||||
| if (seq) { | if (seq) { | ||||
| /* Disallow effect strips. */ | /* Disallow effect strips. */ | ||||
| if (SEQ_effect_get_num_inputs(seq->type) >= 1 && | if (SEQ_effect_get_num_inputs(seq->type) >= 1 && | ||||
| (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3)) { | (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if ((SEQ_effect_get_num_inputs(active_seq->type) >= 1) && | if ((SEQ_effect_get_num_inputs(active_seq->type) >= 1) && | ||||
| (active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3)) { | (active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| switch (side) { | switch (side) { | ||||
| case SEQ_SIDE_LEFT: | case SEQ_SIDE_LEFT: | ||||
| swap_sequence(scene, seq, active_seq); | swap_sequence(video_edit, seq, active_seq); | ||||
| break; | break; | ||||
| case SEQ_SIDE_RIGHT: | case SEQ_SIDE_RIGHT: | ||||
| swap_sequence(scene, active_seq, seq); | swap_sequence(video_edit, active_seq, seq); | ||||
| break; | break; | ||||
| } | } | ||||
| /* Do this in a new loop since both effects need to be calculated first. */ | /* Do this in a new loop since both effects need to be calculated first. */ | ||||
| for (iseq = seqbase->first; iseq; iseq = iseq->next) { | for (iseq = seqbase->first; iseq; iseq = iseq->next) { | ||||
| if ((iseq->type & SEQ_TYPE_EFFECT) && | if ((iseq->type & SEQ_TYPE_EFFECT) && | ||||
| (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { | (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { | ||||
| /* This may now overlap. */ | /* This may now overlap. */ | ||||
| if (SEQ_transform_test_overlap(scene, seqbase, iseq)) { | if (SEQ_transform_test_overlap(video_edit, seqbase, iseq)) { | ||||
| SEQ_transform_seqbase_shuffle(seqbase, iseq, scene); | SEQ_transform_seqbase_shuffle(video_edit, seqbase, iseq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| void SEQUENCER_OT_swap(wmOperatorType *ot) | void SEQUENCER_OT_swap(wmOperatorType *ot) | ||||
| { | { | ||||
| Show All 17 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Set Render Size Operator | /** \name Set Render Size Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *active_seq = SEQ_select_active_get(scene); | Sequence *active_seq = SEQ_select_active_get(video_edit); | ||||
| StripElem *se = NULL; | StripElem *se = NULL; | ||||
| if (active_seq == NULL || active_seq->strip == NULL) { | if (active_seq == NULL || active_seq->strip == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| switch (active_seq->type) { | switch (active_seq->type) { | ||||
| case SEQ_TYPE_IMAGE: | case SEQ_TYPE_IMAGE: | ||||
| se = SEQ_render_give_stripelem(scene, active_seq, scene->r.cfra); | se = SEQ_render_give_stripelem(video_edit, active_seq, video_edit->r.cfra); | ||||
| break; | break; | ||||
| case SEQ_TYPE_MOVIE: | case SEQ_TYPE_MOVIE: | ||||
| se = active_seq->strip->stripdata; | se = active_seq->strip->stripdata; | ||||
| break; | break; | ||||
| default: | default: | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (se == NULL) { | if (se == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* Prevent setting the render size if sequence values aren't initialized. */ | /* Prevent setting the render size if sequence values aren't initialized. */ | ||||
| if (se->orig_width <= 0 || se->orig_height <= 0) { | if (se->orig_width <= 0 || se->orig_height <= 0) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| scene->r.xsch = se->orig_width; | video_edit->r.xsch = se->orig_width; | ||||
| scene->r.ysch = se->orig_height; | video_edit->r.ysch = se->orig_height; | ||||
| active_seq->strip->transform->scale_x = active_seq->strip->transform->scale_y = 1.0f; | active_seq->strip->transform->scale_x = active_seq->strip->transform->scale_y = 1.0f; | ||||
| active_seq->strip->transform->xofs = active_seq->strip->transform->yofs = 0.0f; | active_seq->strip->transform->xofs = active_seq->strip->transform->yofs = 0.0f; | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, active_seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, active_seq); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_RENDER_OPTIONS, video_edit); | ||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_rendersize(wmOperatorType *ot) | void SEQUENCER_OT_rendersize(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| Show All 10 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Copy Operator | /** \name Copy Operator | ||||
| * \{ */ | * \{ */ | ||||
| static void seq_copy_del_sound(Scene *scene, Sequence *seq) | static void seq_copy_del_sound(VideoEdit *video_edit, Sequence *seq) | ||||
| { | { | ||||
| if (seq->type == SEQ_TYPE_META) { | if (seq->type == SEQ_TYPE_META) { | ||||
| Sequence *iseq; | Sequence *iseq; | ||||
| for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) { | for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) { | ||||
| seq_copy_del_sound(scene, iseq); | seq_copy_del_sound(video_edit, iseq); | ||||
| } | } | ||||
| } | } | ||||
| else if (seq->scene_sound) { | else if (seq->scene_sound) { | ||||
| BKE_sound_remove_scene_sound(scene, seq->scene_sound); | /** FIXME: Make use of sound here. */ | ||||
| // BKE_sound_remove_scene_sound(scene, seq->scene_sound); | |||||
| seq->scene_sound = NULL; | seq->scene_sound = NULL; | ||||
| } | } | ||||
| } | } | ||||
| static void sequencer_copy_animation(Scene *scene, Sequence *seq) | static void sequencer_copy_animation(VideoEdit *video_edit, Sequence *seq) | ||||
| { | { | ||||
| if (scene->adt == NULL || scene->adt->action == NULL || | if (video_edit->adt == NULL || video_edit->adt->action == NULL || | ||||
| BLI_listbase_is_empty(&scene->adt->action->curves)) { | BLI_listbase_is_empty(&video_edit->adt->action->curves)) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Add curves for strips inside meta strip. */ | /* Add curves for strips inside meta strip. */ | ||||
| if (seq->type == SEQ_TYPE_META) { | if (seq->type == SEQ_TYPE_META) { | ||||
| LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { | LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { | ||||
| sequencer_copy_animation(scene, meta_child); | sequencer_copy_animation(video_edit, meta_child); | ||||
| } | } | ||||
| } | } | ||||
| GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); | GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &video_edit->adt->action->curves); | ||||
| if (fcurves == NULL) { | if (fcurves == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { | GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { | ||||
| BLI_addtail(&fcurves_clipboard, BKE_fcurve_copy(fcu)); | BLI_addtail(&fcurves_clipboard, BKE_fcurve_copy(fcu)); | ||||
| } | } | ||||
| GSET_FOREACH_END(); | GSET_FOREACH_END(); | ||||
| BLI_gset_free(fcurves, NULL); | BLI_gset_free(fcurves, NULL); | ||||
| } | } | ||||
| static int sequencer_copy_exec(bContext *C, wmOperator *op) | static int sequencer_copy_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| SEQ_clipboard_free(); | SEQ_clipboard_free(); | ||||
| if (SEQ_transform_seqbase_isolated_sel_check(ed->seqbasep) == false) { | if (SEQ_transform_seqbase_isolated_sel_check(video_edit->seqbasep) == false) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); | BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* NOTE: The UUID is re-generated on paste, so we can keep UUID in the clipboard since | /* NOTE: The UUID is re-generated on paste, so we can keep UUID in the clipboard since | ||||
| * nobody can reach them anyway. | * nobody can reach them anyway. | ||||
| * This reduces chance or running out of UUIDs if a cat falls asleep on Ctrl-C. */ | * This reduces chance or running out of UUIDs if a cat falls asleep on Ctrl-C. */ | ||||
| SEQ_sequence_base_dupli_recursive(scene, | SEQ_sequence_base_dupli_recursive(video_edit, | ||||
| scene, | video_edit, | ||||
| &seqbase_clipboard, | &seqbase_clipboard, | ||||
| ed->seqbasep, | video_edit->seqbasep, | ||||
| 0, | 0, | ||||
| (LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_FREE_NO_MAIN)); | (LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_FREE_NO_MAIN)); | ||||
| seqbase_clipboard_frame = scene->r.cfra; | seqbase_clipboard_frame = video_edit->r.cfra; | ||||
| SEQ_clipboard_active_seq_name_store(scene); | SEQ_clipboard_active_seq_name_store(video_edit); | ||||
| LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { | LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { | ||||
| /* Copy curves. */ | /* Copy curves. */ | ||||
| sequencer_copy_animation(scene, seq); | sequencer_copy_animation(video_edit, seq); | ||||
| /* Remove anything that references the current scene. */ | /* Remove anything that references the current video edit. */ | ||||
| seq_copy_del_sound(scene, seq); | seq_copy_del_sound(video_edit, seq); | ||||
| } | } | ||||
| /* Replace datablock pointers with copies, to keep things working in case | /* Replace datablock pointers with copies, to keep things working in case | ||||
| * data-blocks get deleted or another .blend file is opened. */ | * data-blocks get deleted or another .blend file is opened. */ | ||||
| SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard); | SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Show All 14 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Paste Operator | /** \name Paste Operator | ||||
| * \{ */ | * \{ */ | ||||
| void ED_sequencer_deselect_all(Scene *scene) | void ED_sequencer_deselect_all(VideoEdit *video_edit) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(scene); | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(video_edit)) { | ||||
| if (ed == NULL) { | |||||
| return; | |||||
| } | |||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | |||||
| seq->flag &= ~SEQ_ALLSEL; | seq->flag &= ~SEQ_ALLSEL; | ||||
| } | } | ||||
| } | } | ||||
| static void sequencer_paste_animation(bContext *C) | static void sequencer_paste_animation(bContext *C) | ||||
| { | { | ||||
| if (BLI_listbase_is_empty(&fcurves_clipboard)) { | if (BLI_listbase_is_empty(&fcurves_clipboard)) { | ||||
| return; | return; | ||||
| } | } | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| bAction *act; | bAction *act; | ||||
| if (scene->adt != NULL && scene->adt->action != NULL) { | if (video_edit->adt != NULL && video_edit->adt->action != NULL) { | ||||
| act = scene->adt->action; | act = video_edit->adt->action; | ||||
| } | } | ||||
| else { | else { | ||||
| /* get action to add F-Curve+keyframe to */ | /* get action to add F-Curve+keyframe to */ | ||||
| act = ED_id_action_ensure(bmain, &scene->id); | act = ED_id_action_ensure(bmain, &video_edit->id); | ||||
| } | } | ||||
| LISTBASE_FOREACH (FCurve *, fcu, &fcurves_clipboard) { | LISTBASE_FOREACH (FCurve *, fcu, &fcurves_clipboard) { | ||||
| BLI_addtail(&act->curves, BKE_fcurve_copy(fcu)); | BLI_addtail(&act->curves, BKE_fcurve_copy(fcu)); | ||||
| } | } | ||||
| } | } | ||||
| static int sequencer_paste_exec(bContext *C, wmOperator *op) | static int sequencer_paste_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_ensure(scene); /* Create if needed. */ | |||||
| ListBase nseqbase = {NULL, NULL}; | ListBase nseqbase = {NULL, NULL}; | ||||
| int ofs; | int ofs; | ||||
| Sequence *iseq, *iseq_first; | Sequence *iseq, *iseq_first; | ||||
| if (BLI_listbase_count(&seqbase_clipboard) == 0) { | if (BLI_listbase_count(&seqbase_clipboard) == 0) { | ||||
| BKE_report(op->reports, RPT_INFO, "No strips to paste"); | BKE_report(op->reports, RPT_INFO, "No strips to paste"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| if (RNA_boolean_get(op->ptr, "keep_offset")) { | if (RNA_boolean_get(op->ptr, "keep_offset")) { | ||||
| ofs = scene->r.cfra - seqbase_clipboard_frame; | ofs = video_edit->r.cfra - seqbase_clipboard_frame; | ||||
| } | } | ||||
| else { | else { | ||||
| int min_seq_startdisp = INT_MAX; | int min_seq_startdisp = INT_MAX; | ||||
| LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { | LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { | ||||
| if (SEQ_time_left_handle_frame_get(scene, seq) < min_seq_startdisp) { | if (SEQ_time_left_handle_frame_get(video_edit, seq) < min_seq_startdisp) { | ||||
| min_seq_startdisp = SEQ_time_left_handle_frame_get(scene, seq); | min_seq_startdisp = SEQ_time_left_handle_frame_get(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| /* Paste strips relative to the current-frame. */ | /* Paste strips relative to the current-frame. */ | ||||
| ofs = scene->r.cfra - min_seq_startdisp; | ofs = video_edit->r.cfra - min_seq_startdisp; | ||||
| } | } | ||||
| /* Paste animation. | /* Paste animation. | ||||
| * NOTE: Only fcurves are copied. Drivers and NLA action strips are not copied. | * NOTE: Only fcurves are copied. Drivers and NLA action strips are not copied. | ||||
| * First backup original curves from scene and move curves from clipboard into scene. This way, | * First backup original curves from video_edit and move curves from clipboard into video_edit. | ||||
| * when pasted strips are renamed, pasted fcurves are renamed with them. Finally restore original | * This way, when pasted strips are renamed, pasted fcurves are renamed with them. Finally | ||||
| * curves from backup. | * restore original curves from backup. | ||||
| */ | */ | ||||
| ListBase fcurves_original_backup = {NULL, NULL}; | ListBase fcurves_original_backup = {NULL, NULL}; | ||||
| SEQ_animation_backup_original(scene, &fcurves_original_backup); | SEQ_animation_backup_original(video_edit, &fcurves_original_backup); | ||||
| sequencer_paste_animation(C); | sequencer_paste_animation(C); | ||||
| /* Copy strips, temporarily restoring pointers to actual data-blocks. This | /* Copy strips, temporarily restoring pointers to actual data-blocks. This | ||||
| * must happen on the clipboard itself, so that copying does user counting | * must happen on the clipboard itself, so that copying does user counting | ||||
| * on the actual data-blocks. */ | * on the actual data-blocks. */ | ||||
| SEQ_clipboard_pointers_restore(&seqbase_clipboard, bmain); | SEQ_clipboard_pointers_restore(&seqbase_clipboard, bmain); | ||||
| SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, 0, 0); | SEQ_sequence_base_dupli_recursive(video_edit, video_edit, &nseqbase, &seqbase_clipboard, 0, 0); | ||||
| SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard); | SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard); | ||||
| iseq_first = nseqbase.first; | iseq_first = nseqbase.first; | ||||
| /* NOTE: SEQ_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences | /* NOTE: SEQ_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences | ||||
| * in the new list. */ | * in the new list. */ | ||||
| BLI_movelisttolist(ed->seqbasep, &nseqbase); | BLI_movelisttolist(video_edit->seqbasep, &nseqbase); | ||||
| /* Make sure, that pasted strips have unique names. This has to be done immediately after adding | /* Make sure, that pasted strips have unique names. This has to be done immediately after adding | ||||
| * strips to seqbase, for lookup cache to work correctly. */ | * strips to seqbase, for lookup cache to work correctly. */ | ||||
| for (iseq = iseq_first; iseq; iseq = iseq->next) { | for (iseq = iseq_first; iseq; iseq = iseq->next) { | ||||
| SEQ_ensure_unique_name(iseq, scene); | SEQ_ensure_unique_name(iseq, video_edit); | ||||
| } | } | ||||
| for (iseq = iseq_first; iseq; iseq = iseq->next) { | for (iseq = iseq_first; iseq; iseq = iseq->next) { | ||||
| if (SEQ_clipboard_pasted_seq_was_active(iseq)) { | if (SEQ_clipboard_pasted_seq_was_active(iseq)) { | ||||
| SEQ_select_active_set(scene, iseq); | SEQ_select_active_set(video_edit, iseq); | ||||
| } | } | ||||
| /* Translate after name has been changed, otherwise this will affect animdata of original | /* Translate after name has been changed, otherwise this will affect animdata of original | ||||
| * strip. */ | * strip. */ | ||||
| SEQ_transform_translate_sequence(scene, iseq, ofs); | SEQ_transform_translate_sequence(video_edit, iseq, ofs); | ||||
| /* Ensure, that pasted strips don't overlap. */ | /* Ensure, that pasted strips don't overlap. */ | ||||
| if (SEQ_transform_test_overlap(scene, ed->seqbasep, iseq)) { | if (SEQ_transform_test_overlap(video_edit, video_edit->seqbasep, iseq)) { | ||||
| SEQ_transform_seqbase_shuffle(ed->seqbasep, iseq, scene); | SEQ_transform_seqbase_shuffle(video_edit, video_edit->seqbasep, iseq); | ||||
| } | } | ||||
| } | } | ||||
| SEQ_animation_restore_original(scene, &fcurves_original_backup); | SEQ_animation_restore_original(video_edit, &fcurves_original_backup); | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| DEG_relations_tag_update(bmain); | DEG_relations_tag_update(bmain); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_paste(wmOperatorType *ot) | void SEQUENCER_OT_paste(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| Show All 21 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Sequencer Swap Data Operator | /** \name Sequencer Swap Data Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_swap_data_exec(bContext *C, wmOperator *op) | static int sequencer_swap_data_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq_act; | Sequence *seq_act; | ||||
| Sequence *seq_other; | Sequence *seq_other; | ||||
| const char *error_msg; | const char *error_msg; | ||||
| if (SEQ_select_active_get_pair(scene, &seq_act, &seq_other) == false) { | if (SEQ_select_active_get_pair(video_edit, &seq_act, &seq_other) == false) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Please select two strips"); | BKE_report(op->reports, RPT_ERROR, "Please select two strips"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (SEQ_edit_sequence_swap(scene, seq_act, seq_other, &error_msg) == false) { | if (SEQ_edit_sequence_swap(video_edit, seq_act, seq_other, &error_msg) == false) { | ||||
| BKE_report(op->reports, RPT_ERROR, error_msg); | BKE_report(op->reports, RPT_ERROR, error_msg); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (seq_act->scene_sound) { | /** FIXME: Handle sound. */ | ||||
| BKE_sound_remove_scene_sound(scene, seq_act->scene_sound); | // if (seq_act->scene_sound) { | ||||
| } | // BKE_sound_remove_scene_sound(scene, seq_act->scene_sound); | ||||
| // } | |||||
| if (seq_other->scene_sound) { | |||||
| BKE_sound_remove_scene_sound(scene, seq_other->scene_sound); | // if (seq_other->scene_sound) { | ||||
| } | // BKE_sound_remove_scene_sound(scene, seq_other->scene_sound); | ||||
| // } | |||||
| seq_act->scene_sound = NULL; | seq_act->scene_sound = NULL; | ||||
| seq_other->scene_sound = NULL; | seq_other->scene_sound = NULL; | ||||
| if (seq_act->sound) { | /** FIXME: Handle sound. */ | ||||
| BKE_sound_add_scene_sound_defaults(scene, seq_act); | // if (seq_act->sound) { | ||||
| } | // BKE_sound_add_scene_sound_defaults(scene, seq_act); | ||||
| if (seq_other->sound) { | // } | ||||
| BKE_sound_add_scene_sound_defaults(scene, seq_other); | // if (seq_other->sound) { | ||||
| } | // BKE_sound_add_scene_sound_defaults(scene, seq_other); | ||||
| // } | |||||
| SEQ_relations_invalidate_cache_raw(scene, seq_act); | SEQ_relations_invalidate_cache_raw(video_edit, seq_act); | ||||
| SEQ_relations_invalidate_cache_raw(scene, seq_other); | SEQ_relations_invalidate_cache_raw(video_edit, seq_other); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_swap_data(wmOperatorType *ot) | void SEQUENCER_OT_swap_data(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Sequencer Swap Data"; | ot->name = "Sequencer Swap Data"; | ||||
| Show All 18 Lines | static const EnumPropertyItem prop_change_effect_input_types[] = { | ||||
| {0, "A_B", 0, "A -> B", ""}, | {0, "A_B", 0, "A -> B", ""}, | ||||
| {1, "B_C", 0, "B -> C", ""}, | {1, "B_C", 0, "B -> C", ""}, | ||||
| {2, "A_C", 0, "A -> C", ""}, | {2, "A_C", 0, "A -> C", ""}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) | static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq = SEQ_select_active_get(scene); | Sequence *seq = SEQ_select_active_get(video_edit); | ||||
| Sequence **seq_1, **seq_2; | Sequence **seq_1, **seq_2; | ||||
| switch (RNA_enum_get(op->ptr, "swap")) { | switch (RNA_enum_get(op->ptr, "swap")) { | ||||
| case 0: | case 0: | ||||
| seq_1 = &seq->seq1; | seq_1 = &seq->seq1; | ||||
| seq_2 = &seq->seq2; | seq_2 = &seq->seq2; | ||||
| break; | break; | ||||
| Show All 9 Lines | static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) | ||||
| if (*seq_1 == NULL || *seq_2 == NULL) { | if (*seq_1 == NULL || *seq_2 == NULL) { | ||||
| BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, cannot swap"); | BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, cannot swap"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| SWAP(Sequence *, *seq_1, *seq_2); | SWAP(Sequence *, *seq_1, *seq_2); | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seq); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot) | void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Change Effect Input"; | ot->name = "Change Effect Input"; | ||||
| Show All 35 Lines | EnumPropertyItem sequencer_prop_effect_types[] = { | ||||
| {SEQ_TYPE_GAUSSIAN_BLUR, "GAUSSIAN_BLUR", 0, "Gaussian Blur", ""}, | {SEQ_TYPE_GAUSSIAN_BLUR, "GAUSSIAN_BLUR", 0, "Gaussian Blur", ""}, | ||||
| {SEQ_TYPE_TEXT, "TEXT", 0, "Text", ""}, | {SEQ_TYPE_TEXT, "TEXT", 0, "Text", ""}, | ||||
| {SEQ_TYPE_COLORMIX, "COLORMIX", 0, "Color Mix", ""}, | {SEQ_TYPE_COLORMIX, "COLORMIX", 0, "Color Mix", ""}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) | static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq = SEQ_select_active_get(scene); | Sequence *seq = SEQ_select_active_get(video_edit); | ||||
| const int new_type = RNA_enum_get(op->ptr, "type"); | const int new_type = RNA_enum_get(op->ptr, "type"); | ||||
| /* Free previous effect and init new effect. */ | /* Free previous effect and init new effect. */ | ||||
| struct SeqEffectHandle sh; | struct SeqEffectHandle sh; | ||||
| if ((seq->type & SEQ_TYPE_EFFECT) == 0) { | if ((seq->type & SEQ_TYPE_EFFECT) == 0) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* Can someone explain the logic behind only allowing to increase this, | /* Can someone explain the logic behind only allowing to increase this, | ||||
| * copied from 2.4x - campbell */ | * copied from 2.4x - campbell */ | ||||
| if (SEQ_effect_get_num_inputs(seq->type) < SEQ_effect_get_num_inputs(new_type)) { | if (SEQ_effect_get_num_inputs(seq->type) < SEQ_effect_get_num_inputs(new_type)) { | ||||
| BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips"); | BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| sh = SEQ_effect_handle_get(seq); | sh = SEQ_effect_handle_get(seq); | ||||
| sh.free(seq, true); | sh.free(seq, true); | ||||
| seq->type = new_type; | seq->type = new_type; | ||||
| sh = SEQ_effect_handle_get(seq); | sh = SEQ_effect_handle_get(seq); | ||||
| sh.init(seq); | sh.init(seq); | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seq); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot) | void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Change Effect Type"; | ot->name = "Change Effect Type"; | ||||
| Show All 18 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Change Data/Files Operator | /** \name Change Data/Files Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_change_path_exec(bContext *C, wmOperator *op) | static int sequencer_change_path_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq = SEQ_select_active_get(scene); | Sequence *seq = SEQ_select_active_get(video_edit); | ||||
| const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); | const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); | ||||
| const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); | const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); | ||||
| int minext_frameme, numdigits; | int minext_frameme, numdigits; | ||||
| if (seq->type == SEQ_TYPE_IMAGE) { | if (seq->type == SEQ_TYPE_IMAGE) { | ||||
| char directory[FILE_MAX]; | char directory[FILE_MAX]; | ||||
| int len; | int len; | ||||
| StripElem *se; | StripElem *se; | ||||
| Show All 36 Lines | else { | ||||
| RNA_END; | RNA_END; | ||||
| } | } | ||||
| /* Reset these else we won't see all the images. */ | /* Reset these else we won't see all the images. */ | ||||
| seq->anim_startofs = seq->anim_endofs = 0; | seq->anim_startofs = seq->anim_endofs = 0; | ||||
| /* Correct start/end frames so we don't move. | /* Correct start/end frames so we don't move. | ||||
| * Important not to set seq->len = len; allow the function to handle it. */ | * Important not to set seq->len = len; allow the function to handle it. */ | ||||
| SEQ_add_reload_new_file(bmain, scene, seq, true); | SEQ_add_reload_new_file(bmain, video_edit, seq, true); | ||||
| } | } | ||||
| else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { | else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { | ||||
| bSound *sound = seq->sound; | bSound *sound = seq->sound; | ||||
| if (sound == NULL) { | if (sound == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| RNA_string_get(op->ptr, "filepath", filepath); | RNA_string_get(op->ptr, "filepath", filepath); | ||||
| BLI_strncpy(sound->filepath, filepath, sizeof(sound->filepath)); | BLI_strncpy(sound->filepath, filepath, sizeof(sound->filepath)); | ||||
| BKE_sound_load(bmain, sound); | BKE_sound_load(bmain, sound); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Lame, set rna filepath. */ | /* Lame, set rna filepath. */ | ||||
| PointerRNA seq_ptr; | PointerRNA seq_ptr; | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| RNA_pointer_create(&scene->id, &RNA_Sequence, seq, &seq_ptr); | RNA_pointer_create(&video_edit->id, &RNA_Sequence, seq, &seq_ptr); | ||||
| RNA_string_get(op->ptr, "filepath", filepath); | RNA_string_get(op->ptr, "filepath", filepath); | ||||
| prop = RNA_struct_find_property(&seq_ptr, "filepath"); | prop = RNA_struct_find_property(&seq_ptr, "filepath"); | ||||
| RNA_property_string_set(&seq_ptr, prop, filepath); | RNA_property_string_set(&seq_ptr, prop, filepath); | ||||
| RNA_property_update(C, &seq_ptr, prop); | RNA_property_update(C, &seq_ptr, prop); | ||||
| SEQ_relations_sequence_free_anim(seq); | SEQ_relations_sequence_free_anim(seq); | ||||
| } | } | ||||
| SEQ_relations_invalidate_cache_raw(scene, seq); | SEQ_relations_invalidate_cache_raw(video_edit, seq); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq = SEQ_select_active_get(scene); | Sequence *seq = SEQ_select_active_get(video_edit); | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| BLI_path_join(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name); | BLI_path_join(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name); | ||||
| RNA_string_set(op->ptr, "directory", seq->strip->dir); | RNA_string_set(op->ptr, "directory", seq->strip->dir); | ||||
| RNA_string_set(op->ptr, "filepath", filepath); | RNA_string_set(op->ptr, "filepath", filepath); | ||||
| /* Set default display depending on seq type. */ | /* Set default display depending on seq type. */ | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Change Strip Scene Operator | /** \name Change Strip Scene Operator | ||||
| * \{ */ | * \{ */ | ||||
| static bool sequencer_strip_change_scene_poll(bContext *C) | static bool sequencer_strip_change_scene_poll(bContext *C) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(CTX_data_scene(C)); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| if (ed == NULL) { | if (video_edit == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| Sequence *seq = ed->act_seq; | Sequence *seq = SEQ_select_active_get(video_edit); | ||||
| return ((seq != NULL) && (seq->type == SEQ_TYPE_SCENE)); | return ((seq != NULL) && (seq->type == SEQ_TYPE_SCENE)); | ||||
| } | } | ||||
| static int sequencer_change_scene_exec(bContext *C, wmOperator *op) | static int sequencer_change_scene_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Scene *scene_seq = BLI_findlink(&bmain->scenes, RNA_enum_get(op->ptr, "scene")); | Scene *scene_seq = BLI_findlink(&bmain->scenes, RNA_enum_get(op->ptr, "scene")); | ||||
| if (scene_seq == NULL) { | if (scene_seq == NULL) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Scene not found"); | BKE_report(op->reports, RPT_ERROR, "Scene not found"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* Assign new scene. */ | /* Assign new scene. */ | ||||
| Sequence *seq = SEQ_select_active_get(scene); | Sequence *seq = SEQ_select_active_get(video_edit); | ||||
| if (seq) { | if (seq) { | ||||
| seq->scene = scene_seq; | seq->scene = scene_seq; | ||||
| /* Do a refresh of the sequencer data. */ | /* Do a refresh of the sequencer data. */ | ||||
| SEQ_relations_invalidate_cache_raw(scene, seq); | SEQ_relations_invalidate_cache_raw(video_edit, seq); | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO | ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&video_edit->id, ID_RECALC_AUDIO | ID_RECALC_SEQUENCER_STRIPS); | ||||
| DEG_relations_tag_update(bmain); | DEG_relations_tag_update(bmain); | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SCENEBROWSE, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int sequencer_change_scene_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_change_scene_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| if (!RNA_struct_property_is_set(op->ptr, "scene")) { | if (!RNA_struct_property_is_set(op->ptr, "scene")) { | ||||
| return WM_enum_search_invoke(C, op, event); | return WM_enum_search_invoke(C, op, event); | ||||
| Show All 30 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Export Subtitles Operator | /** \name Export Subtitles Operator | ||||
| * \{ */ | * \{ */ | ||||
| /** Comparison function suitable to be used with BLI_listbase_sort(). */ | /** Comparison function suitable to be used with BLI_listbase_sort(). */ | ||||
| static int seq_cmp_time_startdisp_channel(void *thunk, const void *a, const void *b) | static int seq_cmp_time_startdisp_channel(void *thunk, const void *a, const void *b) | ||||
| { | { | ||||
| const Scene *scene = thunk; | const VideoEdit *video_edit = thunk; | ||||
| Sequence *seq_a = (Sequence *)a; | Sequence *seq_a = (Sequence *)a; | ||||
| Sequence *seq_b = (Sequence *)b; | Sequence *seq_b = (Sequence *)b; | ||||
| int seq_a_start = SEQ_time_left_handle_frame_get(scene, seq_a); | int seq_a_start = SEQ_time_left_handle_frame_get(video_edit, seq_a); | ||||
| int seq_b_start = SEQ_time_left_handle_frame_get(scene, seq_b); | int seq_b_start = SEQ_time_left_handle_frame_get(video_edit, seq_b); | ||||
| /* If strips have the same start frame favor the one with a higher channel. */ | /* If strips have the same start frame favor the one with a higher channel. */ | ||||
| if (seq_a_start == seq_b_start) { | if (seq_a_start == seq_b_start) { | ||||
| return seq_a->machine > seq_b->machine; | return seq_a->machine > seq_b->machine; | ||||
| } | } | ||||
| return (seq_a_start > seq_b_start); | return (seq_a_start > seq_b_start); | ||||
| } | } | ||||
| static int sequencer_export_subtitles_invoke(bContext *C, | static int sequencer_export_subtitles_invoke(bContext *C, | ||||
| wmOperator *op, | wmOperator *op, | ||||
| const wmEvent *UNUSED(event)) | const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| ED_fileselect_ensure_default_filepath(C, op, ".srt"); | ED_fileselect_ensure_default_filepath(C, op, ".srt"); | ||||
| WM_event_add_fileselect(C, op); | WM_event_add_fileselect(C, op); | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| typedef struct Seq_get_text_cb_data { | typedef struct Seq_get_text_cb_data { | ||||
| ListBase *text_seq; | ListBase *text_seq; | ||||
| Scene *scene; | VideoEdit *video_edit; | ||||
| } Seq_get_text_cb_data; | } Seq_get_text_cb_data; | ||||
| static bool seq_get_text_strip_cb(Sequence *seq, void *user_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; | 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(cd->video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| /* Only text strips that are not muted and don't end with negative frame. */ | /* Only text strips that are not muted and don't end with negative frame. */ | ||||
| if ((seq->type == SEQ_TYPE_TEXT) && !SEQ_render_is_muted(channels, seq) && | if ((seq->type == SEQ_TYPE_TEXT) && !SEQ_render_is_muted(channels, seq) && | ||||
| (SEQ_time_right_handle_frame_get(cd->scene, seq) > cd->scene->r.sfra)) { | (SEQ_time_right_handle_frame_get(cd->video_edit, seq) > cd->video_edit->r.sfra)) { | ||||
| BLI_addtail(cd->text_seq, MEM_dupallocN(seq)); | BLI_addtail(cd->text_seq, MEM_dupallocN(seq)); | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) | static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq, *seq_next; | Sequence *seq, *seq_next; | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| ListBase text_seq = {0}; | ListBase text_seq = {0}; | ||||
| int iter = 0; | int iter = 0; | ||||
| FILE *file; | FILE *file; | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| if (!RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) { | if (!RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) { | ||||
| BKE_report(op->reports, RPT_ERROR, "No filename given"); | BKE_report(op->reports, RPT_ERROR, "No filename given"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| Show All 10 Lines | if (!BLI_file_touch(filepath)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| } | } | ||||
| else if (!BLI_file_is_writable(filepath)) { | else if (!BLI_file_is_writable(filepath)) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file"); | BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (ed != NULL) { | if (video_edit != NULL) { | ||||
| Seq_get_text_cb_data cb_data = {&text_seq, scene}; | Seq_get_text_cb_data cb_data = {&text_seq, video_edit}; | ||||
| SEQ_for_each_callback(&ed->seqbase, seq_get_text_strip_cb, &cb_data); | SEQ_for_each_callback(&video_edit->seqbase, seq_get_text_strip_cb, &cb_data); | ||||
| } | } | ||||
| if (BLI_listbase_is_empty(&text_seq)) { | if (BLI_listbase_is_empty(&text_seq)) { | ||||
| BKE_report(op->reports, RPT_ERROR, "No subtitles (text strips) to export"); | BKE_report(op->reports, RPT_ERROR, "No subtitles (text strips) to export"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| BLI_listbase_sort_r(&text_seq, seq_cmp_time_startdisp_channel, scene); | BLI_listbase_sort_r(&text_seq, seq_cmp_time_startdisp_channel, video_edit); | ||||
| /* Open and write file. */ | /* Open and write file. */ | ||||
| file = BLI_fopen(filepath, "w"); | file = BLI_fopen(filepath, "w"); | ||||
| for (seq = text_seq.first; seq; seq = seq_next) { | for (seq = text_seq.first; seq; seq = seq_next) { | ||||
| TextVars *data = seq->effectdata; | TextVars *data = seq->effectdata; | ||||
| char timecode_str_start[32]; | char timecode_str_start[32]; | ||||
| char timecode_str_end[32]; | char timecode_str_end[32]; | ||||
| /* Write time-code relative to start frame of scene. Don't allow negative time-codes. */ | float time_seconds_start = ((((double)video_edit->r.frs_sec_base) * | ||||
| BLI_timecode_string_from_time( | (double)(max_ii(SEQ_time_left_handle_frame_get(video_edit, seq) - | ||||
| timecode_str_start, | video_edit->r.sfra, | ||||
| 0))) / | |||||
| (double)video_edit->r.frs_sec); | |||||
| float time_seconds_end = (( | |||||
| ((double)video_edit->r.frs_sec_base) * | |||||
| (double)(SEQ_time_right_handle_frame_get(video_edit, seq) - video_edit->r.sfra) / | |||||
| (double)video_edit->r.frs_sec)); | |||||
| double fps = (((double)video_edit->r.frs_sec) / (double)video_edit->r.frs_sec_base); | |||||
| /* Write time-code relative to start frame of video_edit. Don't allow negative time-codes. */ | |||||
| BLI_timecode_string_from_time(timecode_str_start, | |||||
| sizeof(timecode_str_start), | sizeof(timecode_str_start), | ||||
| -2, | -2, | ||||
| FRA2TIME(max_ii(SEQ_time_left_handle_frame_get(scene, seq) - scene->r.sfra, 0)), | time_seconds_start, | ||||
| FPS, | fps, | ||||
| USER_TIMECODE_SUBRIP); | USER_TIMECODE_SUBRIP); | ||||
| BLI_timecode_string_from_time( | BLI_timecode_string_from_time(timecode_str_end, | ||||
| timecode_str_end, | |||||
| sizeof(timecode_str_end), | sizeof(timecode_str_end), | ||||
| -2, | -2, | ||||
| FRA2TIME(SEQ_time_right_handle_frame_get(scene, seq) - scene->r.sfra), | time_seconds_end, | ||||
| FPS, | fps, | ||||
| USER_TIMECODE_SUBRIP); | USER_TIMECODE_SUBRIP); | ||||
| fprintf( | fprintf( | ||||
| file, "%d\n%s --> %s\n%s\n\n", iter++, timecode_str_start, timecode_str_end, data->text); | file, "%d\n%s --> %s\n%s\n\n", iter++, timecode_str_start, timecode_str_end, data->text); | ||||
| seq_next = seq->next; | seq_next = seq->next; | ||||
| MEM_freeN(seq); | MEM_freeN(seq); | ||||
| } | } | ||||
| fclose(file); | fclose(file); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static bool sequencer_strip_is_text_poll(bContext *C) | static bool sequencer_strip_is_text_poll(bContext *C) | ||||
| { | { | ||||
| Editing *ed; | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Sequence *seq; | if (video_edit == NULL) { | ||||
| return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && ((seq = ed->act_seq) != NULL) && | return false; | ||||
| (seq->type == SEQ_TYPE_TEXT)); | } | ||||
| Sequence *seq = SEQ_select_active_get(video_edit); | |||||
| return (seq != NULL) && (seq->type == SEQ_TYPE_TEXT); | |||||
| } | } | ||||
| void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot) | void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Export Subtitles"; | ot->name = "Export Subtitles"; | ||||
| ot->idname = "SEQUENCER_OT_export_subtitles"; | ot->idname = "SEQUENCER_OT_export_subtitles"; | ||||
| ot->description = "Export .srt file containing text strips"; | ot->description = "Export .srt file containing text strips"; | ||||
| Show All 18 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Set Range to Strips Operator | /** \name Set Range to Strips Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op) | static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| int sfra = MAXFRAME; | int sfra = MAXFRAME; | ||||
| int efra = -MAXFRAME; | int efra = -MAXFRAME; | ||||
| bool selected = false; | bool selected = false; | ||||
| const bool preview = RNA_boolean_get(op->ptr, "preview"); | const bool preview = RNA_boolean_get(op->ptr, "preview"); | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| selected = true; | selected = true; | ||||
| sfra = min_ii(sfra, SEQ_time_left_handle_frame_get(scene, seq)); | sfra = min_ii(sfra, SEQ_time_left_handle_frame_get(video_edit, seq)); | ||||
| efra = max_ii(efra, SEQ_time_right_handle_frame_get(scene, seq) - 1); | efra = max_ii(efra, SEQ_time_right_handle_frame_get(video_edit, seq) - 1); | ||||
| } | } | ||||
| } | } | ||||
| if (!selected) { | if (!selected) { | ||||
| BKE_report(op->reports, RPT_WARNING, "Select one or more strips"); | BKE_report(op->reports, RPT_WARNING, "Select one or more strips"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (efra < 0) { | if (efra < 0) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Can't set a negative range"); | BKE_report(op->reports, RPT_ERROR, "Can't set a negative range"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (preview) { | if (preview) { | ||||
| scene->r.flag |= SCER_PRV_RANGE; | video_edit->r.flag |= SCER_PRV_RANGE; | ||||
| scene->r.psfra = max_ii(0, sfra); | video_edit->r.psfra = max_ii(0, sfra); | ||||
| scene->r.pefra = efra; | video_edit->r.pefra = efra; | ||||
| } | } | ||||
| else { | else { | ||||
| scene->r.flag &= ~SCER_PRV_RANGE; | video_edit->r.flag &= ~SCER_PRV_RANGE; | ||||
| scene->r.sfra = max_ii(0, sfra); | video_edit->r.sfra = max_ii(0, sfra); | ||||
| scene->r.efra = efra; | video_edit->r.efra = efra; | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_FRAME_RANGE, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_FRAME_RANGE, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot) | void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| Show All 31 Lines | static const EnumPropertyItem transform_reset_properties[] = { | ||||
| {STRIP_TRANSFORM_SCALE, "SCALE", 0, "Scale", "Reset strip transform scale"}, | {STRIP_TRANSFORM_SCALE, "SCALE", 0, "Scale", "Reset strip transform scale"}, | ||||
| {STRIP_TRANSFORM_ROTATION, "ROTATION", 0, "Rotation", "Reset strip transform rotation"}, | {STRIP_TRANSFORM_ROTATION, "ROTATION", 0, "Rotation", "Reset strip transform rotation"}, | ||||
| {STRIP_TRANSFORM_ALL, "ALL", 0, "All", "Reset strip transform location, scale and rotation"}, | {STRIP_TRANSFORM_ALL, "ALL", 0, "All", "Reset strip transform location, scale and rotation"}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op) | static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| const Editing *ed = SEQ_editing_get(scene); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| const int property = RNA_enum_get(op->ptr, "property"); | const int property = RNA_enum_get(op->ptr, "property"); | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) { | if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) { | ||||
| StripTransform *transform = seq->strip->transform; | StripTransform *transform = seq->strip->transform; | ||||
| switch (property) { | switch (property) { | ||||
| case STRIP_TRANSFORM_POSITION: | case STRIP_TRANSFORM_POSITION: | ||||
| transform->xofs = 0; | transform->xofs = 0; | ||||
| transform->yofs = 0; | transform->yofs = 0; | ||||
| break; | break; | ||||
| case STRIP_TRANSFORM_SCALE: | case STRIP_TRANSFORM_SCALE: | ||||
| transform->scale_x = 1.0f; | transform->scale_x = 1.0f; | ||||
| transform->scale_y = 1.0f; | transform->scale_y = 1.0f; | ||||
| break; | break; | ||||
| case STRIP_TRANSFORM_ROTATION: | case STRIP_TRANSFORM_ROTATION: | ||||
| transform->rotation = 0.0f; | transform->rotation = 0.0f; | ||||
| break; | break; | ||||
| case STRIP_TRANSFORM_ALL: | case STRIP_TRANSFORM_ALL: | ||||
| transform->xofs = 0; | transform->xofs = 0; | ||||
| transform->yofs = 0; | transform->yofs = 0; | ||||
| transform->scale_x = 1.0f; | transform->scale_x = 1.0f; | ||||
| transform->scale_y = 1.0f; | transform->scale_y = 1.0f; | ||||
| transform->rotation = 0.0f; | transform->rotation = 0.0f; | ||||
| break; | break; | ||||
| } | } | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot) | void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Clear Strip Transform"; | ot->name = "Clear Strip Transform"; | ||||
| ot->idname = "SEQUENCER_OT_strip_transform_clear"; | ot->idname = "SEQUENCER_OT_strip_transform_clear"; | ||||
| Show All 24 Lines | static const EnumPropertyItem scale_fit_methods[] = { | ||||
| {SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image so fits in preview"}, | {SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image so fits in preview"}, | ||||
| {SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image so it fills preview completely"}, | {SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image so it fills preview completely"}, | ||||
| {SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image so it fills preview"}, | {SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image so it fills preview"}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op) | static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| const Editing *ed = SEQ_editing_get(scene); | |||||
| Sequence *seq; | Sequence *seq; | ||||
| const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method"); | const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method"); | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) { | if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) { | ||||
| const int timeline_frame = scene->r.cfra; | const int timeline_frame = video_edit->r.cfra; | ||||
| StripElem *strip_elem = SEQ_render_give_stripelem(scene, seq, timeline_frame); | StripElem *strip_elem = SEQ_render_give_stripelem(video_edit, seq, timeline_frame); | ||||
| if (strip_elem == NULL) { | if (strip_elem == NULL) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| SEQ_set_scale_to_fit(seq, | SEQ_set_scale_to_fit(seq, | ||||
| strip_elem->orig_width, | strip_elem->orig_width, | ||||
| strip_elem->orig_height, | strip_elem->orig_height, | ||||
| scene->r.xsch, | video_edit->r.xsch, | ||||
| scene->r.ysch, | video_edit->r.ysch, | ||||
| fit_method); | fit_method); | ||||
| SEQ_relations_invalidate_cache_preprocessed(scene, seq); | SEQ_relations_invalidate_cache_preprocessed(video_edit, seq); | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot) | void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Strip Transform Set Fit"; | ot->name = "Strip Transform Set Fit"; | ||||
| ot->idname = "SEQUENCER_OT_strip_transform_fit"; | ot->idname = "SEQUENCER_OT_strip_transform_fit"; | ||||
| Show All 10 Lines | ot->prop = RNA_def_enum(ot->srna, | ||||
| scale_fit_methods, | scale_fit_methods, | ||||
| SEQ_SCALE_TO_FIT, | SEQ_SCALE_TO_FIT, | ||||
| "Fit Method", | "Fit Method", | ||||
| "Scale fit fit_method"); | "Scale fit fit_method"); | ||||
| } | } | ||||
| static int sequencer_strip_color_tag_set_exec(bContext *C, wmOperator *op) | static int sequencer_strip_color_tag_set_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| const Editing *ed = SEQ_editing_get(scene); | |||||
| const short color_tag = RNA_enum_get(op->ptr, "color"); | const short color_tag = RNA_enum_get(op->ptr, "color"); | ||||
| LISTBASE_FOREACH (Sequence *, seq, &ed->seqbase) { | LISTBASE_FOREACH (Sequence *, seq, &video_edit->seqbase) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| seq->color_tag = color_tag; | seq->color_tag = color_tag; | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static bool sequencer_strip_color_tag_set_poll(bContext *C) | static bool sequencer_strip_color_tag_set_poll(bContext *C) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| if (scene == NULL) { | if (video_edit == NULL) { | ||||
| return false; | |||||
| } | |||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| if (ed == NULL) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| Sequence *act_seq = ed->act_seq; | Sequence *act_seq = SEQ_select_active_get(video_edit); | ||||
| return act_seq != NULL; | return (act_seq != NULL); | ||||
| } | } | ||||
| void SEQUENCER_OT_strip_color_tag_set(struct wmOperatorType *ot) | void SEQUENCER_OT_strip_color_tag_set(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Set Color Tag"; | ot->name = "Set Color Tag"; | ||||
| ot->idname = "SEQUENCER_OT_strip_color_tag_set"; | ot->idname = "SEQUENCER_OT_strip_color_tag_set"; | ||||
| ot->description = "Set a color tag for the selected strips"; | ot->description = "Set a color tag for the selected strips"; | ||||
| Show All 12 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Set 2D Cursor Operator | /** \name Set 2D Cursor Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_set_2d_cursor_exec(bContext *C, wmOperator *op) | static int sequencer_set_2d_cursor_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| SpaceSeq *sseq = CTX_wm_space_seq(C); | SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| float cursor_pixel[2]; | float cursor_pixel[2]; | ||||
| RNA_float_get_array(op->ptr, "location", cursor_pixel); | RNA_float_get_array(op->ptr, "location", cursor_pixel); | ||||
| SEQ_image_preview_unit_from_px(scene, cursor_pixel, sseq->cursor); | SEQ_image_preview_unit_from_px(video_edit, cursor_pixel, sseq->cursor); | ||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); | ||||
| /* Use pass-through to allow click-drag to transform the cursor. */ | /* Use pass-through to allow click-drag to transform the cursor. */ | ||||
| return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; | return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; | ||||
| } | } | ||||
| static int sequencer_set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| Show All 40 Lines | |||||