diff options
Diffstat (limited to 'source/blender/editors/space_sequencer/sequencer_edit.c')
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_edit.c | 467 |
1 files changed, 323 insertions, 144 deletions
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 01259bb688f..aaf398bf3a1 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -37,6 +37,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BLF_translation.h" @@ -49,7 +50,6 @@ #include "BKE_report.h" #include "BKE_sound.h" -#include "IMB_imbuf.h" #include "WM_api.h" #include "WM_types.h" @@ -59,11 +59,15 @@ /* for menu/popup icons etc etc*/ +#include "ED_numinput.h" #include "ED_screen.h" #include "ED_transform.h" #include "ED_sequencer.h" +#include "ED_space_api.h" #include "UI_view2d.h" +#include "UI_interface.h" + /* own include */ #include "sequencer_intern.h" @@ -145,11 +149,12 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog struct SeqIndexBuildContext *context = link->data; BKE_sequencer_proxy_rebuild(context, stop, do_update, progress); - } - - if (*stop) { - pj->stop = 1; - fprintf(stderr, "Canceling proxy rebuild on users request...\n"); + + if (*stop) { + pj->stop = 1; + fprintf(stderr, "Canceling proxy rebuild on users request...\n"); + break; + } } } @@ -178,6 +183,11 @@ static void seq_proxy_build_job(const bContext *C) struct SeqIndexBuildContext *context; LinkData *link; Sequence *seq; + GSet *file_list; + + if (ed == NULL) { + return; + } wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies", WM_JOB_PROGRESS, WM_JOB_TYPE_SEQ_BUILD_PROXY); @@ -195,16 +205,19 @@ static void seq_proxy_build_job(const bContext *C) WM_jobs_callbacks(wm_job, proxy_startjob, NULL, NULL, proxy_endjob); } + file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); SEQP_BEGIN (ed, seq) { if ((seq->flag & SELECT)) { - context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq); + context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq, file_list); link = BLI_genericNodeN(context); BLI_addtail(&pj->queue, link); } } SEQ_END + BLI_gset_free(file_list, MEM_freeN); + if (!WM_jobs_is_running(wm_job)) { G.is_break = false; WM_jobs_start(CTX_wm_manager(C), wm_job); @@ -385,7 +398,7 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ displen = (float)abs(seq->startdisp - seq->enddisp); if (displen / pixelx > 16) { /* don't even try to grab the handles of small strips */ - /* Set the max value to handle to 1/3 of the total len when its less then 28. + /* Set the max value to handle to 1/3 of the total len when its less than 28. * This is important because otherwise selecting handles happens even when you click in the middle */ if ((displen / 3) < 30 * pixelx) { @@ -494,6 +507,13 @@ bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq) ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF)); } +bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq) +{ + return (ELEM(sseq->view, SEQ_VIEW_SEQUENCE, SEQ_VIEW_SEQUENCE_PREVIEW) && + ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF)); +} + + int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str) { Editing *ed = BKE_sequencer_editing_get(scene, false); @@ -975,13 +995,13 @@ static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene) // XXX if (0 == sbutton(to, 0, sizeof(to)-1, "To: ")) // return; - if (strcmp(to, from) == 0) + if (STREQ(to, from)) return; SEQP_BEGIN (ed, seq) { if (seq->flag & SELECT) { - if (strncmp(seq->strip->dir, from, strlen(from)) == 0) { + if (STREQLEN(seq->strip->dir, from, strlen(from))) { printf("found %s\n", seq->strip->dir); /* strip off the beginning */ @@ -1129,7 +1149,7 @@ int sequencer_strip_has_path_poll(bContext *C) return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq))); } -int sequencer_view_poll(bContext *C) +int sequencer_view_preview_poll(bContext *C) { SpaceSeq *sseq = CTX_wm_space_seq(C); Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), false); @@ -1139,6 +1159,15 @@ int sequencer_view_poll(bContext *C) return 0; } +int sequencer_view_strips_poll(bContext *C) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + if (sseq && ED_space_sequencer_check_show_strip(sseq)) + return 1; + + return 0; +} + /* snap operator*/ static int sequencer_snap_exec(bContext *C, wmOperator *op) { @@ -1231,8 +1260,7 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot) RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX); } - -typedef struct TrimData { +typedef struct SlipData { int init_mouse[2]; float init_mouseloc[2]; TransSeq *ts; @@ -1241,7 +1269,9 @@ typedef struct TrimData { int num_seq; bool slow; int slow_offset; /* offset at the point where offset was turned on */ -} TrimData; + void *draw_handle; + NumInput num_input; +} SlipData; static void transseq_backup(TransSeq *ts, Sequence *seq) { @@ -1274,20 +1304,35 @@ static void transseq_restore(TransSeq *ts, Sequence *seq) seq->len = ts->len; } -static int trim_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool first_level) +static void draw_slip_extensions(const bContext *C, ARegion *ar, void *data) +{ + Scene *scene = CTX_data_scene(C); + SlipData *td = data; + int i; + + for (i = 0; i < td->num_seq; i++) { + Sequence *seq = td->seq_array[i]; + + if ((seq->type != SEQ_TYPE_META) && td->trim[i]) { + draw_sequence_extensions(scene, ar, seq); + } + } +} + +static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim) { Sequence *seq; int num_items = 0; for (seq = seqbasep->first; seq; seq = seq->next) { - if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { + if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { seq_array[offset + num_items] = seq; - trim[offset + num_items] = first_level; + trim[offset + num_items] = do_trim; num_items++; if (seq->type == SEQ_TYPE_META) { /* trim the sub-sequences */ - num_items += trim_add_sequences_rec(&seq->seqbase, seq_array, trim, num_items + offset, false); + num_items += slip_add_sequences_rec(&seq->seqbase, seq_array, trim, num_items + offset, false); } else if (seq->type & SEQ_TYPE_EFFECT) { trim[offset + num_items] = false; @@ -1298,7 +1343,7 @@ static int trim_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool return num_items; } -static int trim_count_sequences_rec(ListBase *seqbasep, bool first_level) +static int slip_count_sequences_rec(ListBase *seqbasep, bool first_level) { Sequence *seq; int trimmed_sequences = 0; @@ -1309,7 +1354,7 @@ static int trim_count_sequences_rec(ListBase *seqbasep, bool first_level) if (seq->type == SEQ_TYPE_META) { /* trim the sub-sequences */ - trimmed_sequences += trim_count_sequences_rec(&seq->seqbase, false); + trimmed_sequences += slip_count_sequences_rec(&seq->seqbase, false); } } } @@ -1317,33 +1362,43 @@ static int trim_count_sequences_rec(ListBase *seqbasep, bool first_level) return trimmed_sequences; } -static int sequencer_trim_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - TrimData *data; + SlipData *data; Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, false); + ARegion *ar = CTX_wm_region(C); float mouseloc[2]; int num_seq, i; View2D *v2d = UI_view2d_fromcontext(C); /* first recursively cound the trimmed elements */ - num_seq = trim_count_sequences_rec(ed->seqbasep, true); + num_seq = slip_count_sequences_rec(ed->seqbasep, true); if (num_seq == 0) return OPERATOR_CANCELLED; - data = op->customdata = MEM_mallocN(sizeof(TrimData), "trimdata"); + data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); data->num_seq = num_seq; - trim_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); + initNumInput(&data->num_input); + data->num_input.idx_max = 0; + data->num_input.val_flag[0] |= NUM_NO_FRACTION; + data->num_input.unit_sys = USER_UNIT_NONE; + data->num_input.unit_type[0] = 0; + + + slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); for (i = 0; i < num_seq; i++) { transseq_backup(data->ts + i, data->seq_array[i]); } + data->draw_handle = ED_region_draw_cb_activate(ar->type, draw_slip_extensions, data, REGION_DRAW_POST_VIEW); + 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); @@ -1353,10 +1408,13 @@ static int sequencer_trim_invoke(bContext *C, wmOperator *op, const wmEvent *eve WM_event_add_modal_handler(C, op); + /* notify so we draw extensions immediately */ + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_RUNNING_MODAL; } -static bool sequencer_trim_recursively(Scene *scene, TrimData *data, int offset) +static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) { /* only data types supported for now */ @@ -1415,9 +1473,9 @@ static bool sequencer_trim_recursively(Scene *scene, TrimData *data, int offset) return false; } -static int sequencer_trim_exec(bContext *C, wmOperator *op) +static int sequencer_slip_exec(bContext *C, wmOperator *op) { - TrimData *data; + SlipData *data; Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, false); int num_seq, i; @@ -1425,80 +1483,125 @@ static int sequencer_trim_exec(bContext *C, wmOperator *op) bool success = false; /* first recursively cound the trimmed elements */ - num_seq = trim_count_sequences_rec(ed->seqbasep, true); + num_seq = slip_count_sequences_rec(ed->seqbasep, true); if (num_seq == 0) return OPERATOR_CANCELLED; - data = op->customdata = MEM_mallocN(sizeof(TrimData), "trimdata"); + data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata"); data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform"); data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences"); data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim"); data->num_seq = num_seq; - trim_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); + slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true); for (i = 0; i < num_seq; i++) { transseq_backup(data->ts + i, data->seq_array[i]); } - success = sequencer_trim_recursively(scene, data, offset); + success = sequencer_slip_recursively(scene, data, offset); MEM_freeN(data->seq_array); MEM_freeN(data->trim); MEM_freeN(data->ts); MEM_freeN(data); - if (success) return OPERATOR_FINISHED; - else return OPERATOR_CANCELLED; + if (success) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + + +static void sequencer_slip_update_header(Scene *scene, ScrArea *sa, SlipData *data, int offset) +{ +#define HEADER_LENGTH 40 + char msg[HEADER_LENGTH]; + + if (sa) { + if (hasNumInput(&data->num_input)) { + char num_str[NUM_STR_REP_LEN]; + outputNumInput(&data->num_input, num_str, &scene->unit); + BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %s", num_str); + } + else { + BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %d", offset); + } + } + + ED_area_headerprint(sa, msg); + +#undef HEADER_LENGTH } -static int sequencer_trim_modal(bContext *C, wmOperator *op, const wmEvent *event) +static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event) { Scene *scene = CTX_data_scene(C); - TrimData *data = (TrimData *)op->customdata; + SlipData *data = (SlipData *)op->customdata; ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + const bool has_numInput = hasNumInput(&data->num_input); + bool handled = true; + + /* Modal numinput active, try to handle numeric inputs first... */ + if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) { + float offset; + applyNumInput(&data->num_input, &offset); + + sequencer_slip_update_header(scene, sa, data, (int)offset); + + RNA_int_set(op->ptr, "offset", offset); + + if (sequencer_slip_recursively(scene, data, offset)) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + } + + return OPERATOR_RUNNING_MODAL; + } switch (event->type) { case MOUSEMOVE: { - float mouseloc[2]; - int offset; - int mouse_x; - View2D *v2d = UI_view2d_fromcontext(C); - - if (data->slow) { - mouse_x = event->mval[0] - data->slow_offset; - mouse_x *= 0.1f; - mouse_x += data->slow_offset; - } - else { - mouse_x = event->mval[0]; - } + if (!has_numInput) { + float mouseloc[2]; + int offset; + int mouse_x; + View2D *v2d = UI_view2d_fromcontext(C); + + if (data->slow) { + mouse_x = event->mval[0] - data->slow_offset; + mouse_x *= 0.1f; + mouse_x += data->slow_offset; + } + else { + mouse_x = event->mval[0]; + } - /* choose the side based on which side of the playhead the mouse is on */ - UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]); - offset = mouseloc[0] - data->init_mouseloc[0]; + /* choose the side based on which side of the playhead the mouse is on */ + UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]); + offset = mouseloc[0] - data->init_mouseloc[0]; - RNA_int_set(op->ptr, "offset", offset); + sequencer_slip_update_header(scene, sa, data, offset); - if (sa) { -#define HEADER_LENGTH 40 - char msg[HEADER_LENGTH]; - BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %d", offset); -#undef HEADER_LENGTH - ED_area_headerprint(sa, msg); - } + RNA_int_set(op->ptr, "offset", offset); - if (sequencer_trim_recursively(scene, data, offset)) { - WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + if (sequencer_slip_recursively(scene, data, offset)) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + } } break; } case LEFTMOUSE: + case RETKEY: + case SPACEKEY: { + ED_region_draw_cb_exit(ar->type, data->draw_handle); MEM_freeN(data->seq_array); MEM_freeN(data->trim); MEM_freeN(data->ts); @@ -1527,6 +1630,8 @@ static int sequencer_trim_modal(bContext *C, wmOperator *op, const wmEvent *even BKE_sequence_calc(scene, seq); } + ED_region_draw_cb_exit(ar->type, data->draw_handle); + MEM_freeN(data->seq_array); MEM_freeN(data->ts); MEM_freeN(data->trim); @@ -1546,33 +1651,50 @@ static int sequencer_trim_modal(bContext *C, wmOperator *op, const wmEvent *even case RIGHTSHIFTKEY: case LEFTSHIFTKEY: - if (event->val == KM_PRESS) { - data->slow = true; - data->slow_offset = event->mval[0]; - } - else if (event->val == KM_RELEASE) { - data->slow = false; + if (!has_numInput) { + if (event->val == KM_PRESS) { + data->slow = true; + data->slow_offset = event->mval[0]; + } + else if (event->val == KM_RELEASE) { + data->slow = false; + } } break; default: + handled = false; break; } + /* Modal numinput inactive, try to handle numeric inputs last... */ + if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) { + float offset; + applyNumInput(&data->num_input, &offset); + + sequencer_slip_update_header(scene, sa, data, (int)offset); + + RNA_int_set(op->ptr, "offset", offset); + + if (sequencer_slip_recursively(scene, data, offset)) { + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + } + } + return OPERATOR_RUNNING_MODAL; } -void SEQUENCER_OT_trim(struct wmOperatorType *ot) +void SEQUENCER_OT_slip(struct wmOperatorType *ot) { /* identifiers */ ot->name = "Trim Strips"; - ot->idname = "SEQUENCER_OT_trim"; + ot->idname = "SEQUENCER_OT_slip"; ot->description = "Trim the contents of the active strip"; /* api callbacks */ - ot->invoke = sequencer_trim_invoke; - ot->modal = sequencer_trim_modal; - ot->exec = sequencer_trim_exec; + ot->invoke = sequencer_slip_invoke; + ot->modal = sequencer_slip_modal; + ot->exec = sequencer_slip_exec; ot->poll = sequencer_edit_poll; /* flags */ @@ -1582,7 +1704,6 @@ void SEQUENCER_OT_trim(struct wmOperatorType *ot) INT32_MIN, INT32_MAX); } - /* mute operator */ static int sequencer_mute_exec(bContext *C, wmOperator *op) { @@ -2425,8 +2546,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene); int channel_max = 1; - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, false) == false) { - BKE_report(op->reports, RPT_ERROR, "Please select more than one or all related strips"); + if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { + BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } @@ -2805,74 +2926,13 @@ void SEQUENCER_OT_view_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; } - -static int find_next_prev_edit(Scene *scene, int cfra, - const short side, - const bool do_skip_mute, const bool do_center) -{ - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq; - - int dist, best_dist, best_frame = cfra; - int seq_frames[2], seq_frames_tot; - - best_dist = MAXFRAME * 2; - - if (ed == NULL) return cfra; - - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - int i; - - if (do_skip_mute && (seq->flag & SEQ_MUTE)) { - continue; - } - - if (do_center) { - seq_frames[0] = (seq->startdisp + seq->enddisp) / 2; - seq_frames_tot = 1; - } - else { - seq_frames[0] = seq->startdisp; - seq_frames[1] = seq->enddisp; - - seq_frames_tot = 2; - } - - for (i = 0; i < seq_frames_tot; i++) { - const int seq_frame = seq_frames[i]; - - dist = MAXFRAME * 2; - - switch (side) { - case SEQ_SIDE_LEFT: - if (seq_frame < cfra) { - dist = cfra - seq_frame; - } - break; - case SEQ_SIDE_RIGHT: - if (seq_frame > cfra) { - dist = seq_frame - cfra; - } - break; - } - - if (dist < best_dist) { - best_frame = seq_frame; - best_dist = dist; - } - } - } - - return best_frame; -} - static bool strip_jump_internal(Scene *scene, const short side, const bool do_skip_mute, const bool do_center) { bool changed = false; int cfra = CFRA; - int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center); + int nfra = BKE_sequencer_find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center, false); if (nfra != cfra) { CFRA = nfra; @@ -3119,7 +3179,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) BKE_sequencer_free_clipboard(); - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, true) == false) { + if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } @@ -3345,7 +3405,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot) ot->invoke = WM_border_select_invoke; ot->exec = view_ghost_border_exec; ot->modal = WM_border_select_modal; - ot->poll = sequencer_view_poll; + ot->poll = sequencer_view_preview_poll; ot->cancel = WM_border_select_cancel; /* flags */ @@ -3356,13 +3416,48 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot) } /* rebuild_proxy operator */ -static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) + +static int sequencer_rebuild_proxy_invoke(bContext *C, wmOperator *UNUSED(op), + const wmEvent *UNUSED(event)) { seq_proxy_build_job(C); return OPERATOR_FINISHED; } +static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Editing *ed = BKE_sequencer_editing_get(scene, false); + Sequence *seq; + GSet *file_list; + + if (ed == NULL) { + return OPERATOR_CANCELLED; + } + + file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); + + SEQP_BEGIN(ed, seq) + { + if ((seq->flag & SELECT)) { + struct SeqIndexBuildContext *context; + short stop = 0, do_update; + float progress; + context = BKE_sequencer_proxy_rebuild_context(bmain, scene, seq, file_list); + BKE_sequencer_proxy_rebuild(context, &stop, &do_update, &progress); + BKE_sequencer_proxy_rebuild_finish(context, 0); + BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + } + } + SEQ_END + + BLI_gset_free(file_list, MEM_freeN); + + return OPERATOR_FINISHED; +} + void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot) { /* identifiers */ @@ -3371,13 +3466,98 @@ void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot) ot->description = "Rebuild all selected proxies and timecode indices using the job system"; /* api callbacks */ + ot->invoke = sequencer_rebuild_proxy_invoke; ot->exec = sequencer_rebuild_proxy_exec; - ot->poll = ED_operator_sequencer_active; /* flags */ ot->flag = OPTYPE_REGISTER; } +static int sequencer_enable_proxies_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y); +} + +static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Editing *ed = BKE_sequencer_editing_get(scene, false); + Sequence *seq; + bool proxy_25 = RNA_boolean_get(op->ptr, "proxy_25"); + bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50"); + bool proxy_75 = RNA_boolean_get(op->ptr, "proxy_75"); + bool proxy_100 = RNA_boolean_get(op->ptr, "proxy_100"); + bool override = RNA_boolean_get(op->ptr, "override"); + bool turnon = true; + + if (ed == NULL || !(proxy_25 || proxy_50 || proxy_75 || proxy_100)) { + turnon = false; + } + + SEQP_BEGIN(ed, seq) + { + if ((seq->flag & SELECT)) { + if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, SEQ_TYPE_MULTICAM)) { + BKE_sequencer_proxy_set(seq, turnon); + if (seq->strip->proxy == NULL) { + continue; + } + + if (proxy_25) + seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_25; + else + seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_25; + + if (proxy_50) + seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_50; + else + seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_50; + + if (proxy_75) + seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_75; + else + seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_75; + + if (proxy_100) + seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_100; + else + seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_100; + + if (!override) + seq->strip->proxy->build_flags |= SEQ_PROXY_SKIP_EXISTING; + else + seq->strip->proxy->build_flags &= ~SEQ_PROXY_SKIP_EXISTING; + } + } + } + SEQ_END + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + + return OPERATOR_FINISHED; +} + +void SEQUENCER_OT_enable_proxies(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Selected Strip Proxies"; + ot->idname = "SEQUENCER_OT_enable_proxies"; + ot->description = "Enable selected proxies on all selected Movie strips"; + + /* api callbacks */ + ot->invoke = sequencer_enable_proxies_invoke; + ot->exec = sequencer_enable_proxies_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER; + + RNA_def_boolean(ot->srna, "proxy_25", false, "25%", ""); + RNA_def_boolean(ot->srna, "proxy_50", false, "50%", ""); + RNA_def_boolean(ot->srna, "proxy_75", false, "75%", ""); + RNA_def_boolean(ot->srna, "proxy_100", false, "100%", ""); + RNA_def_boolean(ot->srna, "override", false, "Override", ""); +} + /* change ops */ static EnumPropertyItem prop_change_effect_input_types[] = { @@ -3614,8 +3794,7 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, + WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY); } - |