Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_sequencer/sequencer_select.c
| Show All 10 Lines | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_video_edit_types.h" | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| Show All 20 Lines | |||||
| #include "sequencer_intern.h" | #include "sequencer_intern.h" | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Selection Utilities | /** \name Selection Utilities | ||||
| * \{ */ | * \{ */ | ||||
| SeqCollection *all_strips_from_context(bContext *C) | SeqCollection *all_strips_from_context(bContext *C) | ||||
| { | { | ||||
| 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); | ListBase *channels = SEQ_channels_displayed_get(video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| const bool is_preview = sequencer_view_has_preview_poll(C); | const bool is_preview = sequencer_view_has_preview_poll(C); | ||||
| if (is_preview) { | if (is_preview) { | ||||
| return SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); | return SEQ_query_rendered_strips(video_edit, channels, seqbase, video_edit->r.cfra, 0); | ||||
| } | } | ||||
| return SEQ_query_all_strips(seqbase); | return SEQ_query_all_strips(seqbase); | ||||
| } | } | ||||
| SeqCollection *selected_strips_from_context(bContext *C) | SeqCollection *selected_strips_from_context(bContext *C) | ||||
| { | { | ||||
| 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); | ListBase *channels = SEQ_channels_displayed_get(video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| const bool is_preview = sequencer_view_has_preview_poll(C); | const bool is_preview = sequencer_view_has_preview_poll(C); | ||||
| if (is_preview) { | if (is_preview) { | ||||
| SeqCollection *strips = SEQ_query_rendered_strips(scene, channels, seqbase, scene->r.cfra, 0); | SeqCollection *strips = SEQ_query_rendered_strips( | ||||
| video_edit, channels, seqbase, video_edit->r.cfra, 0); | |||||
| SEQ_filter_selected_strips(strips); | SEQ_filter_selected_strips(strips); | ||||
| return strips; | return strips; | ||||
| } | } | ||||
| return SEQ_query_selected_strips(seqbase); | return SEQ_query_selected_strips(seqbase); | ||||
| } | } | ||||
| static void select_surrounding_handles(Scene *scene, Sequence *test) /* XXX BRING BACK */ | static void select_surrounding_handles(VideoEdit *video_edit, Sequence *test) /* XXX BRING BACK */ | ||||
| { | { | ||||
| Sequence *neighbor; | Sequence *neighbor; | ||||
| neighbor = find_neighboring_sequence(scene, test, SEQ_SIDE_LEFT, -1); | neighbor = find_neighboring_sequence(video_edit, test, SEQ_SIDE_LEFT, -1); | ||||
| if (neighbor) { | if (neighbor) { | ||||
| /* Only select neighbor handle if matching handle from test seq is also selected, | /* Only select neighbor handle if matching handle from test seq is also selected, | ||||
| * or if neighbor was not selected at all up till now. | * or if neighbor was not selected at all up till now. | ||||
| * Otherwise, we get odd mismatch when shift-alt-rmb selecting neighbor strips... */ | * Otherwise, we get odd mismatch when shift-alt-rmb selecting neighbor strips... */ | ||||
| if (!(neighbor->flag & SELECT) || (test->flag & SEQ_LEFTSEL)) { | if (!(neighbor->flag & SELECT) || (test->flag & SEQ_LEFTSEL)) { | ||||
| neighbor->flag |= SEQ_RIGHTSEL; | neighbor->flag |= SEQ_RIGHTSEL; | ||||
| } | } | ||||
| neighbor->flag |= SELECT; | neighbor->flag |= SELECT; | ||||
| recurs_sel_seq(neighbor); | recurs_sel_seq(neighbor); | ||||
| } | } | ||||
| neighbor = find_neighboring_sequence(scene, test, SEQ_SIDE_RIGHT, -1); | neighbor = find_neighboring_sequence(video_edit, test, SEQ_SIDE_RIGHT, -1); | ||||
| if (neighbor) { | if (neighbor) { | ||||
| if (!(neighbor->flag & SELECT) || (test->flag & SEQ_RIGHTSEL)) { /* See comment above. */ | if (!(neighbor->flag & SELECT) || (test->flag & SEQ_RIGHTSEL)) { /* See comment above. */ | ||||
| neighbor->flag |= SEQ_LEFTSEL; | neighbor->flag |= SEQ_LEFTSEL; | ||||
| } | } | ||||
| neighbor->flag |= SELECT; | neighbor->flag |= SELECT; | ||||
| recurs_sel_seq(neighbor); | recurs_sel_seq(neighbor); | ||||
| } | } | ||||
| } | } | ||||
| /* Used for mouse selection in SEQUENCER_OT_select. */ | /* Used for mouse selection in SEQUENCER_OT_select. */ | ||||
| static void select_active_side( | static void select_active_side( | ||||
| const Scene *scene, ListBase *seqbase, int sel_side, int channel, int frame) | const VideoEdit *video_edit, ListBase *seqbase, int sel_side, int channel, int frame) | ||||
| { | { | ||||
| Sequence *seq; | Sequence *seq; | ||||
| for (seq = seqbase->first; seq; seq = seq->next) { | for (seq = seqbase->first; seq; seq = seq->next) { | ||||
| if (channel == seq->machine) { | if (channel == seq->machine) { | ||||
| switch (sel_side) { | switch (sel_side) { | ||||
| case SEQ_SIDE_LEFT: | case SEQ_SIDE_LEFT: | ||||
| if (frame > SEQ_time_left_handle_frame_get(scene, seq)) { | if (frame > SEQ_time_left_handle_frame_get(video_edit, seq)) { | ||||
| seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| } | } | ||||
| break; | break; | ||||
| case SEQ_SIDE_RIGHT: | case SEQ_SIDE_RIGHT: | ||||
| if (frame < SEQ_time_left_handle_frame_get(scene, seq)) { | if (frame < SEQ_time_left_handle_frame_get(video_edit, seq)) { | ||||
| seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| } | } | ||||
| break; | break; | ||||
| case SEQ_SIDE_BOTH: | case SEQ_SIDE_BOTH: | ||||
| seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Used for mouse selection in SEQUENCER_OT_select_side. */ | /* Used for mouse selection in SEQUENCER_OT_select_side. */ | ||||
| static void select_active_side_range(const Scene *scene, | static void select_active_side_range(const VideoEdit *video_edit, | ||||
| ListBase *seqbase, | ListBase *seqbase, | ||||
| const int sel_side, | const int sel_side, | ||||
| const int frame_ranges[MAXSEQ], | const int frame_ranges[MAXSEQ], | ||||
| const int frame_ignore) | const int frame_ignore) | ||||
| { | { | ||||
| Sequence *seq; | Sequence *seq; | ||||
| for (seq = seqbase->first; seq; seq = seq->next) { | for (seq = seqbase->first; seq; seq = seq->next) { | ||||
| if (seq->machine < MAXSEQ) { | if (seq->machine < MAXSEQ) { | ||||
| const int frame = frame_ranges[seq->machine]; | const int frame = frame_ranges[seq->machine]; | ||||
| if (frame == frame_ignore) { | if (frame == frame_ignore) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| switch (sel_side) { | switch (sel_side) { | ||||
| case SEQ_SIDE_LEFT: | case SEQ_SIDE_LEFT: | ||||
| if (frame > SEQ_time_left_handle_frame_get(scene, seq)) { | if (frame > SEQ_time_left_handle_frame_get(video_edit, seq)) { | ||||
| seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| } | } | ||||
| break; | break; | ||||
| case SEQ_SIDE_RIGHT: | case SEQ_SIDE_RIGHT: | ||||
| if (frame < SEQ_time_left_handle_frame_get(scene, seq)) { | if (frame < SEQ_time_left_handle_frame_get(video_edit, seq)) { | ||||
| seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| } | } | ||||
| break; | break; | ||||
| case SEQ_SIDE_BOTH: | case SEQ_SIDE_BOTH: | ||||
| seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | seq->flag &= ~(SEQ_RIGHTSEL | SEQ_LEFTSEL); | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Used for mouse selection in SEQUENCER_OT_select */ | /* Used for mouse selection in SEQUENCER_OT_select */ | ||||
| static void select_linked_time(const Scene *scene, ListBase *seqbase, Sequence *seq_link) | static void select_linked_time(const VideoEdit *video_edit, ListBase *seqbase, Sequence *seq_link) | ||||
| { | { | ||||
| Sequence *seq; | Sequence *seq; | ||||
| for (seq = seqbase->first; seq; seq = seq->next) { | for (seq = seqbase->first; seq; seq = seq->next) { | ||||
| if (seq_link->machine != seq->machine) { | if (seq_link->machine != seq->machine) { | ||||
| int left_match = (SEQ_time_left_handle_frame_get(scene, seq) == seq_link->startdisp) ? 1 : 0; | int left_match = (SEQ_time_left_handle_frame_get(video_edit, seq) == seq_link->startdisp) ? | ||||
| int right_match = (SEQ_time_right_handle_frame_get(scene, seq) == seq_link->enddisp) ? 1 : 0; | 1 : | ||||
| 0; | |||||
| int right_match = (SEQ_time_right_handle_frame_get(video_edit, seq) == seq_link->enddisp) ? | |||||
| 1 : | |||||
| 0; | |||||
| if (left_match && right_match) { | if (left_match && right_match) { | ||||
| /* Direct match, copy the selection settings. */ | /* Direct match, copy the selection settings. */ | ||||
| seq->flag &= ~(SELECT | SEQ_LEFTSEL | SEQ_RIGHTSEL); | seq->flag &= ~(SELECT | SEQ_LEFTSEL | SEQ_RIGHTSEL); | ||||
| seq->flag |= seq_link->flag & (SELECT | SEQ_LEFTSEL | SEQ_RIGHTSEL); | seq->flag |= seq_link->flag & (SELECT | SEQ_LEFTSEL | SEQ_RIGHTSEL); | ||||
| recurs_sel_seq(seq); | recurs_sel_seq(seq); | ||||
| } | } | ||||
| Show All 24 Lines | void select_surround_from_last(Scene *scene) | ||||
| if (seq == NULL) { | if (seq == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| select_surrounding_handles(scene, seq); | select_surrounding_handles(scene, seq); | ||||
| } | } | ||||
| #endif | #endif | ||||
| void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool deselect_all) | void ED_sequencer_select_sequence_single(VideoEdit *video_edit, Sequence *seq, bool deselect_all) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| if (deselect_all) { | if (deselect_all) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| } | } | ||||
| SEQ_select_active_set(scene, seq); | SEQ_select_active_set(video_edit, seq); | ||||
| if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { | if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { | ||||
| if (seq->strip) { | if (seq->strip) { | ||||
| BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); | BLI_strncpy(video_edit->act_imagedir, seq->strip->dir, FILE_MAXDIR); | ||||
| } | } | ||||
| } | } | ||||
| else if (seq->type == SEQ_TYPE_SOUND_RAM) { | else if (seq->type == SEQ_TYPE_SOUND_RAM) { | ||||
| if (seq->strip) { | if (seq->strip) { | ||||
| BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); | BLI_strncpy(video_edit->act_sounddir, seq->strip->dir, FILE_MAXDIR); | ||||
| } | } | ||||
| } | } | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| recurs_sel_seq(seq); | recurs_sel_seq(seq); | ||||
| } | } | ||||
| void seq_rectf(const Scene *scene, Sequence *seq, rctf *rect) | void seq_rectf(const VideoEdit *video_edit, Sequence *seq, rctf *rect) | ||||
| { | { | ||||
| rect->xmin = SEQ_time_left_handle_frame_get(scene, seq); | rect->xmin = SEQ_time_left_handle_frame_get(video_edit, seq); | ||||
| rect->xmax = SEQ_time_right_handle_frame_get(scene, seq); | rect->xmax = SEQ_time_right_handle_frame_get(video_edit, seq); | ||||
| rect->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM; | rect->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM; | ||||
| rect->ymax = seq->machine + SEQ_STRIP_OFSTOP; | rect->ymax = seq->machine + SEQ_STRIP_OFSTOP; | ||||
| } | } | ||||
| Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int sel) | Sequence *find_neighboring_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; | Sequence *seq; | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| if (ed == NULL) { | |||||
| return NULL; | |||||
| } | |||||
| if (sel > 0) { | if (sel > 0) { | ||||
| sel = SELECT; | sel = SELECT; | ||||
| } | } | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| 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)) || | ||||
| (sel == 0 && (seq->flag & SELECT) == 0))) { | (sel == 0 && (seq->flag & SELECT) == 0))) { | ||||
| switch (lr) { | switch (lr) { | ||||
| case SEQ_SIDE_LEFT: | case SEQ_SIDE_LEFT: | ||||
| if (SEQ_time_left_handle_frame_get(scene, test) == | if (SEQ_time_left_handle_frame_get(video_edit, test) == | ||||
| SEQ_time_right_handle_frame_get(scene, seq)) { | SEQ_time_right_handle_frame_get(video_edit, seq)) { | ||||
| return seq; | return seq; | ||||
| } | } | ||||
| break; | break; | ||||
| case SEQ_SIDE_RIGHT: | case SEQ_SIDE_RIGHT: | ||||
| if (SEQ_time_right_handle_frame_get(scene, test) == | if (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)) { | ||||
| return seq; | return seq; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2]) | Sequence *find_nearest_seq(VideoEdit *video_edit, View2D *v2d, int *hand, const int mval[2]) | ||||
| { | { | ||||
| Sequence *seq; | Sequence *seq; | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| float x, y; | float x, y; | ||||
| float pixelx; | float pixelx; | ||||
| float handsize; | float handsize; | ||||
| float displen; | float displen; | ||||
| *hand = SEQ_SIDE_NONE; | *hand = SEQ_SIDE_NONE; | ||||
| if (ed == NULL) { | |||||
| return NULL; | |||||
| } | |||||
| pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); | pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); | ||||
| UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); | UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); | ||||
| seq = ed->seqbasep->first; | seq = video_edit->seqbasep->first; | ||||
| while (seq) { | while (seq) { | ||||
| if (seq->machine == (int)y) { | if (seq->machine == (int)y) { | ||||
| /* Check for both normal strips, and strips that have been flipped horizontally. */ | /* Check for both normal strips, and strips that have been flipped horizontally. */ | ||||
| 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, seq)) && | SEQ_time_right_handle_frame_get(video_edit, seq)) && | ||||
| (SEQ_time_left_handle_frame_get(scene, seq) <= x && | (SEQ_time_left_handle_frame_get(video_edit, seq) <= x && | ||||
| SEQ_time_right_handle_frame_get(scene, seq) >= x)) || | SEQ_time_right_handle_frame_get(video_edit, seq) >= x)) || | ||||
| ((SEQ_time_left_handle_frame_get(scene, seq) > | ((SEQ_time_left_handle_frame_get(video_edit, seq) > | ||||
| SEQ_time_right_handle_frame_get(scene, seq)) && | SEQ_time_right_handle_frame_get(video_edit, seq)) && | ||||
| (SEQ_time_left_handle_frame_get(scene, seq) >= x && | (SEQ_time_left_handle_frame_get(video_edit, seq) >= x && | ||||
| SEQ_time_right_handle_frame_get(scene, seq) <= x))) { | SEQ_time_right_handle_frame_get(video_edit, seq) <= x))) { | ||||
| if (SEQ_transform_sequence_can_be_translated(seq)) { | if (SEQ_transform_sequence_can_be_translated(seq)) { | ||||
| /* Clamp handles to defined size in pixel space. */ | /* Clamp handles to defined size in pixel space. */ | ||||
| handsize = 2.0f * sequence_handle_size_get_clamped(scene, seq, pixelx); | handsize = 2.0f * sequence_handle_size_get_clamped(video_edit, seq, pixelx); | ||||
| displen = (float)abs(SEQ_time_left_handle_frame_get(scene, seq) - | displen = (float)abs(SEQ_time_left_handle_frame_get(video_edit, seq) - | ||||
| SEQ_time_right_handle_frame_get(scene, seq)); | SEQ_time_right_handle_frame_get(video_edit, seq)); | ||||
| /* Don't even try to grab the handles of small strips. */ | /* Don't even try to grab the handles of small strips. */ | ||||
| if (displen / pixelx > 16) { | if (displen / pixelx > 16) { | ||||
| /* Set the max value to handle to 1/3 of the total len when its | /* Set the max value to handle to 1/3 of the total len when its | ||||
| * less than 28. This is important because otherwise selecting | * less than 28. This is important because otherwise selecting | ||||
| * handles happens even when you click in the middle. */ | * handles happens even when you click in the middle. */ | ||||
| if ((displen / 3) < 30 * pixelx) { | if ((displen / 3) < 30 * pixelx) { | ||||
| handsize = displen / 3; | handsize = displen / 3; | ||||
| } | } | ||||
| else { | else { | ||||
| CLAMP(handsize, 7 * pixelx, 30 * pixelx); | CLAMP(handsize, 7 * pixelx, 30 * pixelx); | ||||
| } | } | ||||
| if (handsize + SEQ_time_left_handle_frame_get(scene, seq) >= x) { | if (handsize + SEQ_time_left_handle_frame_get(video_edit, seq) >= x) { | ||||
| *hand = SEQ_SIDE_LEFT; | *hand = SEQ_SIDE_LEFT; | ||||
| } | } | ||||
| else if (-handsize + SEQ_time_right_handle_frame_get(scene, seq) <= x) { | else if (-handsize + SEQ_time_right_handle_frame_get(video_edit, seq) <= x) { | ||||
| *hand = SEQ_SIDE_RIGHT; | *hand = SEQ_SIDE_RIGHT; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return seq; | return seq; | ||||
| } | } | ||||
| } | } | ||||
| seq = seq->next; | seq = seq->next; | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | while (seq) { | ||||
| if (seq->seqbase.first) { | if (seq->seqbase.first) { | ||||
| recurs_sel_seq(seq); | recurs_sel_seq(seq); | ||||
| } | } | ||||
| seq = seq->next; | seq = seq->next; | ||||
| } | } | ||||
| } | } | ||||
| static bool seq_point_image_isect(const Scene *scene, const Sequence *seq, float point[2]) | static bool seq_point_image_isect(const VideoEdit *video_edit, const Sequence *seq, float point[2]) | ||||
| { | { | ||||
| float seq_image_quad[4][2]; | float seq_image_quad[4][2]; | ||||
| SEQ_image_transform_final_quad_get(scene, seq, seq_image_quad); | SEQ_image_transform_final_quad_get(video_edit, seq, seq_image_quad); | ||||
| return isect_point_quad_v2( | return isect_point_quad_v2( | ||||
| point, seq_image_quad[0], seq_image_quad[1], seq_image_quad[2], seq_image_quad[3]); | point, seq_image_quad[0], seq_image_quad[1], seq_image_quad[2], seq_image_quad[3]); | ||||
| } | } | ||||
| static void sequencer_select_do_updates(bContext *C, Scene *scene) | static void sequencer_select_do_updates(bContext *C, VideoEdit *video_edit) | ||||
| { | { | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name (De)select All Operator | /** \name (De)select All Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_de_select_all_exec(bContext *C, wmOperator *op) | static int sequencer_de_select_all_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| int action = RNA_enum_get(op->ptr, "action"); | int action = RNA_enum_get(op->ptr, "action"); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| 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; | ||||
| } | } | ||||
| SeqCollection *strips = all_strips_from_context(C); | SeqCollection *strips = all_strips_from_context(C); | ||||
| Sequence *seq; | Sequence *seq; | ||||
| Show All 26 Lines | switch (action) { | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| SEQ_collection_free(strips); | SEQ_collection_free(strips); | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_all(struct wmOperatorType *ot) | void SEQUENCER_OT_select_all(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "(De)select All"; | ot->name = "(De)select All"; | ||||
| Show All 13 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select Inverse Operator | /** \name Select Inverse Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| 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; | ||||
| } | } | ||||
| SeqCollection *strips = all_strips_from_context(C); | SeqCollection *strips = all_strips_from_context(C); | ||||
| Sequence *seq; | Sequence *seq; | ||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | SEQ_ITERATOR_FOREACH (seq, strips) { | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| seq->flag &= ~SEQ_ALLSEL; | seq->flag &= ~SEQ_ALLSEL; | ||||
| } | } | ||||
| else { | else { | ||||
| seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL); | seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL); | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| } | } | ||||
| } | } | ||||
| SEQ_collection_free(strips); | SEQ_collection_free(strips); | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot) | void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Select Inverse"; | ot->name = "Select Inverse"; | ||||
| Show All 9 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select Operator | /** \name Select Operator | ||||
| * \{ */ | * \{ */ | ||||
| static void sequencer_select_set_active(Scene *scene, Sequence *seq) | static void sequencer_select_set_active(VideoEdit *video_edit, Sequence *seq) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(scene); | SEQ_select_active_set(video_edit, seq); | ||||
| SEQ_select_active_set(scene, seq); | |||||
| if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { | if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { | ||||
| if (seq->strip) { | if (seq->strip) { | ||||
| BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); | BLI_strncpy(video_edit->act_imagedir, seq->strip->dir, FILE_MAXDIR); | ||||
| } | } | ||||
| } | } | ||||
| else if (seq->type == SEQ_TYPE_SOUND_RAM) { | else if (seq->type == SEQ_TYPE_SOUND_RAM) { | ||||
| if (seq->strip) { | if (seq->strip) { | ||||
| BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); | BLI_strncpy(video_edit->act_sounddir, seq->strip->dir, FILE_MAXDIR); | ||||
| } | } | ||||
| } | } | ||||
| recurs_sel_seq(seq); | recurs_sel_seq(seq); | ||||
| } | } | ||||
| static void sequencer_select_side_of_frame(const bContext *C, | static void sequencer_select_side_of_frame(const bContext *C, | ||||
| const View2D *v2d, | const View2D *v2d, | ||||
| const int mval[2], | const int mval[2], | ||||
| Scene *scene) | VideoEdit *video_edit) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| const float x = UI_view2d_region_to_view_x(v2d, mval[0]); | const float x = UI_view2d_region_to_view_x(v2d, mval[0]); | ||||
| LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(video_edit)) { | ||||
| if (((x < scene->r.cfra) && | if (((x < video_edit->r.cfra) && | ||||
| (SEQ_time_right_handle_frame_get(scene, seq_iter) <= scene->r.cfra)) || | (SEQ_time_right_handle_frame_get(video_edit, seq_iter) <= video_edit->r.cfra)) || | ||||
| ((x >= scene->r.cfra) && | ((x >= video_edit->r.cfra) && | ||||
| (SEQ_time_left_handle_frame_get(scene, seq_iter) >= scene->r.cfra))) { | (SEQ_time_left_handle_frame_get(video_edit, seq_iter) >= video_edit->r.cfra))) { | ||||
| /* Select left or right. */ | /* Select left or right. */ | ||||
| seq_iter->flag |= SELECT; | seq_iter->flag |= SELECT; | ||||
| recurs_sel_seq(seq_iter); | recurs_sel_seq(seq_iter); | ||||
| } | } | ||||
| } | } | ||||
| { | { | ||||
| SpaceSeq *sseq = CTX_wm_space_seq(C); | SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| if (sseq && sseq->flag & SEQ_MARKER_TRANS) { | if (sseq && sseq->flag & SEQ_MARKER_TRANS) { | ||||
| TimeMarker *tmarker; | TimeMarker *tmarker; | ||||
| for (tmarker = scene->markers.first; tmarker; tmarker = tmarker->next) { | for (tmarker = video_edit->markers.first; tmarker; tmarker = tmarker->next) { | ||||
| if (((x < scene->r.cfra) && (tmarker->frame <= scene->r.cfra)) || | if (((x < video_edit->r.cfra) && (tmarker->frame <= video_edit->r.cfra)) || | ||||
| ((x >= scene->r.cfra) && (tmarker->frame >= scene->r.cfra))) { | ((x >= video_edit->r.cfra) && (tmarker->frame >= video_edit->r.cfra))) { | ||||
| tmarker->flag |= SELECT; | tmarker->flag |= SELECT; | ||||
| } | } | ||||
| else { | else { | ||||
| tmarker->flag &= ~SELECT; | tmarker->flag &= ~SELECT; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void sequencer_select_linked_handle(const bContext *C, | static void sequencer_select_linked_handle(const bContext *C, | ||||
| Sequence *seq, | Sequence *seq, | ||||
| const int handle_clicked) | const int handle_clicked) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| if (!ELEM(handle_clicked, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) { | if (!ELEM(handle_clicked, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) { | ||||
| /* First click selects the strip and its adjacent handles (if valid). | /* First click selects the strip and its adjacent handles (if valid). | ||||
| * Second click selects the strip, | * Second click selects the strip, | ||||
| * both of its handles and its adjacent handles (if valid). */ | * both of its handles and its adjacent handles (if valid). */ | ||||
| const bool is_striponly_selected = ((seq->flag & SEQ_ALLSEL) == SELECT); | const bool is_striponly_selected = ((seq->flag & SEQ_ALLSEL) == SELECT); | ||||
| seq->flag &= ~SEQ_ALLSEL; | seq->flag &= ~SEQ_ALLSEL; | ||||
| seq->flag |= is_striponly_selected ? SEQ_ALLSEL : SELECT; | seq->flag |= is_striponly_selected ? SEQ_ALLSEL : SELECT; | ||||
| select_surrounding_handles(scene, seq); | select_surrounding_handles(video_edit, seq); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Always select the strip under the cursor. */ | /* Always select the strip under the cursor. */ | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| /* First click selects adjacent handles on that side. | /* First click selects adjacent handles on that side. | ||||
| * Second click selects all strips in that direction. | * Second click selects all strips in that direction. | ||||
| * If there are no adjacent strips, it just selects all in that direction. | * If there are no adjacent strips, it just selects all in that direction. | ||||
| */ | */ | ||||
| int sel_side = handle_clicked; | int sel_side = handle_clicked; | ||||
| Sequence *neighbor = find_neighboring_sequence(scene, seq, sel_side, -1); | Sequence *neighbor = find_neighboring_sequence(video_edit, seq, sel_side, -1); | ||||
| if (neighbor) { | if (neighbor) { | ||||
| switch (sel_side) { | switch (sel_side) { | ||||
| case SEQ_SIDE_LEFT: | case SEQ_SIDE_LEFT: | ||||
| if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) { | if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| select_active_side(scene, | select_active_side(video_edit, | ||||
| ed->seqbasep, | video_edit->seqbasep, | ||||
| SEQ_SIDE_LEFT, | SEQ_SIDE_LEFT, | ||||
| seq->machine, | seq->machine, | ||||
| SEQ_time_left_handle_frame_get(scene, seq)); | SEQ_time_left_handle_frame_get(video_edit, seq)); | ||||
| } | } | ||||
| else { | else { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| neighbor->flag |= SELECT; | neighbor->flag |= SELECT; | ||||
| recurs_sel_seq(neighbor); | recurs_sel_seq(neighbor); | ||||
| neighbor->flag |= SEQ_RIGHTSEL; | neighbor->flag |= SEQ_RIGHTSEL; | ||||
| seq->flag |= SEQ_LEFTSEL; | seq->flag |= SEQ_LEFTSEL; | ||||
| } | } | ||||
| break; | break; | ||||
| case SEQ_SIDE_RIGHT: | case SEQ_SIDE_RIGHT: | ||||
| if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) { | if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| select_active_side(scene, | select_active_side(video_edit, | ||||
| ed->seqbasep, | video_edit->seqbasep, | ||||
| SEQ_SIDE_RIGHT, | SEQ_SIDE_RIGHT, | ||||
| seq->machine, | seq->machine, | ||||
| SEQ_time_left_handle_frame_get(scene, seq)); | SEQ_time_left_handle_frame_get(video_edit, seq)); | ||||
| } | } | ||||
| else { | else { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| neighbor->flag |= SELECT; | neighbor->flag |= SELECT; | ||||
| recurs_sel_seq(neighbor); | recurs_sel_seq(neighbor); | ||||
| neighbor->flag |= SEQ_LEFTSEL; | neighbor->flag |= SEQ_LEFTSEL; | ||||
| seq->flag |= SEQ_RIGHTSEL; | seq->flag |= SEQ_RIGHTSEL; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| select_active_side( | select_active_side(video_edit, | ||||
| scene, ed->seqbasep, sel_side, seq->machine, SEQ_time_left_handle_frame_get(scene, seq)); | video_edit->seqbasep, | ||||
| sel_side, | |||||
| seq->machine, | |||||
| SEQ_time_left_handle_frame_get(video_edit, seq)); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** Collect sequencer that are candidates for being selected. */ | /** Collect sequencer that are candidates for being selected. */ | ||||
| struct SeqSelect_Link { | struct SeqSelect_Link { | ||||
| struct SeqSelect_Link *next, *prev; | struct SeqSelect_Link *next, *prev; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| Show All 34 Lines | |||||
| /** | /** | ||||
| * Check if click happened on image which belongs to strip. | * Check if click happened on image which belongs to strip. | ||||
| * If multiple strips are found, loop through them in order | * If multiple strips are found, loop through them in order | ||||
| * (depth (top-most first) or closest to mouse when `center` is true). | * (depth (top-most first) or closest to mouse when `center` is true). | ||||
| */ | */ | ||||
| static Sequence *seq_select_seq_from_preview( | static Sequence *seq_select_seq_from_preview( | ||||
| const bContext *C, const int mval[2], const bool toggle, const bool extend, const bool center) | const bContext *C, const int mval[2], const bool toggle, const bool extend, const bool center) | ||||
| { | { | ||||
| 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); | ListBase *channels = SEQ_channels_displayed_get(video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| SpaceSeq *sseq = CTX_wm_space_seq(C); | SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| View2D *v2d = UI_view2d_fromcontext(C); | View2D *v2d = UI_view2d_fromcontext(C); | ||||
| float mouseco_view[2]; | float mouseco_view[2]; | ||||
| UI_view2d_region_to_view(v2d, mval[0], mval[1], &mouseco_view[0], &mouseco_view[1]); | UI_view2d_region_to_view(v2d, mval[0], mval[1], &mouseco_view[0], &mouseco_view[1]); | ||||
| /* Always update the coordinates (check extended after). */ | /* Always update the coordinates (check extended after). */ | ||||
| const bool use_cycle = (!WM_cursor_test_motion_and_update(mval) || extend || toggle); | const bool use_cycle = (!WM_cursor_test_motion_and_update(mval) || extend || toggle); | ||||
| SeqCollection *strips = SEQ_query_rendered_strips( | SeqCollection *strips = SEQ_query_rendered_strips( | ||||
| scene, channels, seqbase, scene->r.cfra, sseq->chanshown); | video_edit, channels, seqbase, video_edit->r.cfra, sseq->chanshown); | ||||
| /* Allow strips this far from the closest center to be included. | /* Allow strips this far from the closest center to be included. | ||||
| * This allows cycling over center points which are near enough | * This allows cycling over center points which are near enough | ||||
| * to overlapping from the users perspective. */ | * to overlapping from the users perspective. */ | ||||
| const float center_dist_sq_max = square_f(75.0f * U.pixelsize); | const float center_dist_sq_max = square_f(75.0f * U.pixelsize); | ||||
| const float center_scale_px[2] = { | const float center_scale_px[2] = { | ||||
| UI_view2d_scale_get_x(v2d), | UI_view2d_scale_get_x(v2d), | ||||
| UI_view2d_scale_get_y(v2d), | UI_view2d_scale_get_y(v2d), | ||||
| }; | }; | ||||
| struct SeqSelect_Link *slink_active = NULL; | struct SeqSelect_Link *slink_active = NULL; | ||||
| Sequence *seq_active = SEQ_select_active_get(scene); | Sequence *seq_active = SEQ_select_active_get(video_edit); | ||||
| ListBase strips_ordered = {NULL}; | ListBase strips_ordered = {NULL}; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | SEQ_ITERATOR_FOREACH (seq, strips) { | ||||
| bool isect = false; | bool isect = false; | ||||
| float center_dist_sq_test = 0.0f; | float center_dist_sq_test = 0.0f; | ||||
| if (center) { | if (center) { | ||||
| /* Detect overlapping center points (scaled by the zoom level). */ | /* Detect overlapping center points (scaled by the zoom level). */ | ||||
| float co[2]; | float co[2]; | ||||
| SEQ_image_transform_origin_offset_pixelspace_get(scene, seq, co); | SEQ_image_transform_origin_offset_pixelspace_get(video_edit, seq, co); | ||||
| sub_v2_v2(co, mouseco_view); | sub_v2_v2(co, mouseco_view); | ||||
| mul_v2_v2(co, center_scale_px); | mul_v2_v2(co, center_scale_px); | ||||
| center_dist_sq_test = len_squared_v2(co); | center_dist_sq_test = len_squared_v2(co); | ||||
| isect = center_dist_sq_test <= center_dist_sq_max; | isect = center_dist_sq_test <= center_dist_sq_max; | ||||
| if (isect) { | if (isect) { | ||||
| /* Use an active strip penalty for "center" selection when cycle is enabled. */ | /* Use an active strip penalty for "center" selection when cycle is enabled. */ | ||||
| if (use_cycle && (seq == seq_active) && (seq_active->flag & SELECT)) { | if (use_cycle && (seq == seq_active) && (seq_active->flag & SELECT)) { | ||||
| center_dist_sq_test = square_f(sqrtf(center_dist_sq_test) + (3.0f * U.pixelsize)); | center_dist_sq_test = square_f(sqrtf(center_dist_sq_test) + (3.0f * U.pixelsize)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| isect = seq_point_image_isect(scene, seq, mouseco_view); | isect = seq_point_image_isect(video_edit, seq, mouseco_view); | ||||
| } | } | ||||
| if (isect) { | if (isect) { | ||||
| struct SeqSelect_Link *slink = MEM_callocN(sizeof(*slink), __func__); | struct SeqSelect_Link *slink = MEM_callocN(sizeof(*slink), __func__); | ||||
| slink->seq = seq; | slink->seq = seq; | ||||
| slink->center_dist_sq = center_dist_sq_test; | slink->center_dist_sq = center_dist_sq_test; | ||||
| BLI_addtail(&strips_ordered, slink); | BLI_addtail(&strips_ordered, slink); | ||||
| Show All 35 Lines | |||||
| { | { | ||||
| const bool handle_already_selected = ((handle_clicked == SEQ_SIDE_LEFT) && | const bool handle_already_selected = ((handle_clicked == SEQ_SIDE_LEFT) && | ||||
| (seq->flag & SEQ_LEFTSEL)) || | (seq->flag & SEQ_LEFTSEL)) || | ||||
| ((handle_clicked == SEQ_SIDE_RIGHT) && | ((handle_clicked == SEQ_SIDE_RIGHT) && | ||||
| (seq->flag & SEQ_RIGHTSEL)); | (seq->flag & SEQ_RIGHTSEL)); | ||||
| return ((seq->flag & SELECT) && handle_clicked == SEQ_SIDE_NONE) || handle_already_selected; | return ((seq->flag & SELECT) && handle_clicked == SEQ_SIDE_NONE) || handle_already_selected; | ||||
| } | } | ||||
| static void sequencer_select_strip_impl(const Editing *ed, | static void sequencer_select_strip_impl(const VideoEdit *video_edit, | ||||
| Sequence *seq, | Sequence *seq, | ||||
| const int handle_clicked, | const int handle_clicked, | ||||
| const bool extend, | const bool extend, | ||||
| const bool deselect, | const bool deselect, | ||||
| const bool toggle) | const bool toggle) | ||||
| { | { | ||||
| const bool is_active = (ed->act_seq == seq); | const bool is_active = (video_edit->act_seq == seq); | ||||
| /* Exception for active strip handles. */ | /* Exception for active strip handles. */ | ||||
| if ((handle_clicked != SEQ_SIDE_NONE) && (seq->flag & SELECT) && is_active && toggle) { | if ((handle_clicked != SEQ_SIDE_NONE) && (seq->flag & SELECT) && is_active && toggle) { | ||||
| switch (handle_clicked) { | switch (handle_clicked) { | ||||
| case SEQ_SIDE_LEFT: | case SEQ_SIDE_LEFT: | ||||
| seq->flag ^= SEQ_LEFTSEL; | seq->flag ^= SEQ_LEFTSEL; | ||||
| break; | break; | ||||
| case SEQ_SIDE_RIGHT: | case SEQ_SIDE_RIGHT: | ||||
| Show All 33 Lines | static void sequencer_select_strip_impl(const VideoEdit *video_edit, | ||||
| else if (action == 0) { | else if (action == 0) { | ||||
| seq->flag &= ~SEQ_ALLSEL; | seq->flag &= ~SEQ_ALLSEL; | ||||
| } | } | ||||
| } | } | ||||
| static int sequencer_select_exec(bContext *C, wmOperator *op) | static int sequencer_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| View2D *v2d = UI_view2d_fromcontext(C); | View2D *v2d = UI_view2d_fromcontext(C); | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| if (ed == NULL) { | if (video_edit == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (region->regiontype == RGN_TYPE_PREVIEW) { | if (region->regiontype == RGN_TYPE_PREVIEW) { | ||||
| if (!sequencer_view_preview_only_poll(C)) { | if (!sequencer_view_preview_only_poll(C)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| const SpaceSeq *sseq = CTX_wm_space_seq(C); | const SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| Show All 13 Lines | static int sequencer_select_exec(bContext *C, wmOperator *op) | ||||
| mval[1] = RNA_int_get(op->ptr, "mouse_y"); | mval[1] = RNA_int_get(op->ptr, "mouse_y"); | ||||
| int handle_clicked = SEQ_SIDE_NONE; | int handle_clicked = SEQ_SIDE_NONE; | ||||
| Sequence *seq = NULL; | Sequence *seq = NULL; | ||||
| if (region->regiontype == RGN_TYPE_PREVIEW) { | if (region->regiontype == RGN_TYPE_PREVIEW) { | ||||
| seq = seq_select_seq_from_preview(C, mval, toggle, extend, center); | seq = seq_select_seq_from_preview(C, mval, toggle, extend, center); | ||||
| } | } | ||||
| else { | else { | ||||
| seq = find_nearest_seq(scene, v2d, &handle_clicked, mval); | seq = find_nearest_seq(video_edit, v2d, &handle_clicked, mval); | ||||
| } | } | ||||
| /* NOTE: `side_of_frame` and `linked_time` functionality is designed to be shared on one keymap, | /* NOTE: `side_of_frame` and `linked_time` functionality is designed to be shared on one keymap, | ||||
| * therefore both properties can be true at the same time. */ | * therefore both properties can be true at the same time. */ | ||||
| if (seq && RNA_boolean_get(op->ptr, "linked_time")) { | if (seq && RNA_boolean_get(op->ptr, "linked_time")) { | ||||
| if (!extend && !toggle) { | if (!extend && !toggle) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| } | } | ||||
| sequencer_select_strip_impl(ed, seq, handle_clicked, extend, deselect, toggle); | sequencer_select_strip_impl(video_edit, seq, handle_clicked, extend, deselect, toggle); | ||||
| select_linked_time(scene, ed->seqbasep, seq); | select_linked_time(video_edit, video_edit->seqbasep, seq); | ||||
| sequencer_select_do_updates(C, scene); | sequencer_select_do_updates(C, video_edit); | ||||
| sequencer_select_set_active(scene, seq); | sequencer_select_set_active(video_edit, seq); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| /* Select left, right or overlapping the current frame. */ | /* Select left, right or overlapping the current frame. */ | ||||
| if (RNA_boolean_get(op->ptr, "side_of_frame")) { | if (RNA_boolean_get(op->ptr, "side_of_frame")) { | ||||
| if (!extend && !toggle) { | if (!extend && !toggle) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| } | } | ||||
| sequencer_select_side_of_frame(C, v2d, mval, scene); | sequencer_select_side_of_frame(C, v2d, mval, video_edit); | ||||
| sequencer_select_do_updates(C, scene); | sequencer_select_do_updates(C, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| /* On Alt selection, select the strip and bordering handles. */ | /* On Alt selection, select the strip and bordering handles. */ | ||||
| if (seq && RNA_boolean_get(op->ptr, "linked_handle")) { | if (seq && RNA_boolean_get(op->ptr, "linked_handle")) { | ||||
| if (!extend && !toggle) { | if (!extend && !toggle) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| } | } | ||||
| sequencer_select_linked_handle(C, seq, handle_clicked); | sequencer_select_linked_handle(C, seq, handle_clicked); | ||||
| sequencer_select_do_updates(C, scene); | sequencer_select_do_updates(C, video_edit); | ||||
| sequencer_select_set_active(scene, seq); | sequencer_select_set_active(video_edit, seq); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others"); | const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others"); | ||||
| /* Clicking on already selected element falls on modal operation. | /* Clicking on already selected element falls on modal operation. | ||||
| * All strips are deselected on mouse button release unless extend mode is used. */ | * All strips are deselected on mouse button release unless extend mode is used. */ | ||||
| if (seq && element_already_selected(seq, handle_clicked) && wait_to_deselect_others && !toggle) { | if (seq && element_already_selected(seq, handle_clicked) && wait_to_deselect_others && !toggle) { | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| bool changed = false; | bool changed = false; | ||||
| /* Deselect everything */ | /* Deselect everything */ | ||||
| if (deselect_all || (seq && (extend == false && deselect == false && toggle == false))) { | if (deselect_all || (seq && (extend == false && deselect == false && toggle == false))) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| /* Nothing to select, but strips could be deselected. */ | /* Nothing to select, but strips could be deselected. */ | ||||
| if (!seq) { | if (!seq) { | ||||
| if (changed) { | if (changed) { | ||||
| sequencer_select_do_updates(C, scene); | sequencer_select_do_updates(C, video_edit); | ||||
| } | } | ||||
| return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED; | return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* Do actual selection. */ | /* Do actual selection. */ | ||||
| sequencer_select_strip_impl(ed, seq, handle_clicked, extend, deselect, toggle); | sequencer_select_strip_impl(video_edit, seq, handle_clicked, extend, deselect, toggle); | ||||
| sequencer_select_do_updates(C, scene); | sequencer_select_do_updates(C, video_edit); | ||||
| sequencer_select_set_active(scene, seq); | sequencer_select_set_active(video_edit, seq); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| const int retval = WM_generic_select_invoke(C, op, event); | const int retval = WM_generic_select_invoke(C, op, event); | ||||
| 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)) { | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select More Operator | /** \name Select More Operator | ||||
| * \{ */ | * \{ */ | ||||
| /* Run recursively to select linked. */ | /* Run recursively to select linked. */ | ||||
| static bool select_linked_internal(Scene *scene) | static bool select_linked_internal(VideoEdit *video_edit) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(scene); | if (video_edit == NULL) { | ||||
| if (ed == NULL) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| bool changed = false; | bool changed = false; | ||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(video_edit)) { | ||||
| if ((seq->flag & SELECT) == 0) { | if ((seq->flag & SELECT) == 0) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* Only get unselected neighbors. */ | /* Only get unselected neighbors. */ | ||||
| Sequence *neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, 0); | Sequence *neighbor = find_neighboring_sequence(video_edit, seq, SEQ_SIDE_LEFT, 0); | ||||
| if (neighbor) { | if (neighbor) { | ||||
| neighbor->flag |= SELECT; | neighbor->flag |= SELECT; | ||||
| recurs_sel_seq(neighbor); | recurs_sel_seq(neighbor); | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, 0); | neighbor = find_neighboring_sequence(video_edit, seq, SEQ_SIDE_RIGHT, 0); | ||||
| if (neighbor) { | if (neighbor) { | ||||
| neighbor->flag |= SELECT; | neighbor->flag |= SELECT; | ||||
| recurs_sel_seq(neighbor); | recurs_sel_seq(neighbor); | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| /* Select only one linked strip on each side. */ | /* Select only one linked strip on each side. */ | ||||
| static bool select_more_less_seq__internal(Scene *scene, bool select_more) | static bool select_more_less_seq__internal(VideoEdit *video_edit, bool select_more) | ||||
| { | { | ||||
| Editing *ed = SEQ_editing_get(scene); | if (video_edit == NULL) { | ||||
| if (ed == NULL) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| GSet *neighbors = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "Linked strips"); | GSet *neighbors = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "Linked strips"); | ||||
| const int neighbor_selection_filter = select_more ? 0 : SELECT; | const int neighbor_selection_filter = select_more ? 0 : SELECT; | ||||
| const int selection_filter = select_more ? SELECT : 0; | const int selection_filter = select_more ? SELECT : 0; | ||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(video_edit)) { | ||||
| if ((seq->flag & SELECT) != selection_filter) { | if ((seq->flag & SELECT) != selection_filter) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Sequence *neighbor = find_neighboring_sequence( | Sequence *neighbor = find_neighboring_sequence( | ||||
| scene, seq, SEQ_SIDE_LEFT, neighbor_selection_filter); | video_edit, seq, SEQ_SIDE_LEFT, neighbor_selection_filter); | ||||
| if (neighbor) { | if (neighbor) { | ||||
| BLI_gset_add(neighbors, neighbor); | BLI_gset_add(neighbors, neighbor); | ||||
| } | } | ||||
| neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, neighbor_selection_filter); | neighbor = find_neighboring_sequence( | ||||
| video_edit, seq, SEQ_SIDE_RIGHT, neighbor_selection_filter); | |||||
| if (neighbor) { | if (neighbor) { | ||||
| BLI_gset_add(neighbors, neighbor); | BLI_gset_add(neighbors, neighbor); | ||||
| } | } | ||||
| } | } | ||||
| bool changed = false; | bool changed = false; | ||||
| GSetIterator gsi; | GSetIterator gsi; | ||||
| BLI_gsetIterator_init(&gsi, neighbors); | BLI_gsetIterator_init(&gsi, neighbors); | ||||
| Show All 11 Lines | static bool select_more_less_seq__internal(VideoEdit *video_edit, bool select_more) | ||||
| } | } | ||||
| BLI_gset_free(neighbors, NULL); | BLI_gset_free(neighbors, NULL); | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| static int sequencer_select_more_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_select_more_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| if (!select_more_less_seq__internal(scene, true)) { | if (!select_more_less_seq__internal(video_edit, true)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_more(wmOperatorType *ot) | void SEQUENCER_OT_select_more(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Select More"; | ot->name = "Select More"; | ||||
| Show All 11 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select Less Operator | /** \name Select Less Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| if (!select_more_less_seq__internal(scene, false)) { | if (!select_more_less_seq__internal(video_edit, false)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_less(wmOperatorType *ot) | void SEQUENCER_OT_select_less(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Select Less"; | ot->name = "Select Less"; | ||||
| Show All 11 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select Pick Linked Operator | /** \name Select Pick Linked Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_select_linked_pick_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); | ||||
| bool extend = RNA_boolean_get(op->ptr, "extend"); | bool extend = RNA_boolean_get(op->ptr, "extend"); | ||||
| Sequence *mouse_seq; | Sequence *mouse_seq; | ||||
| int selected, hand; | int selected, hand; | ||||
| /* This works like UV, not mesh. */ | /* This works like UV, not mesh. */ | ||||
| mouse_seq = find_nearest_seq(scene, v2d, &hand, event->mval); | mouse_seq = find_nearest_seq(video_edit, v2d, &hand, event->mval); | ||||
| if (!mouse_seq) { | if (!mouse_seq) { | ||||
| return OPERATOR_FINISHED; /* User error as with mesh?? */ | return OPERATOR_FINISHED; /* User error as with mesh?? */ | ||||
| } | } | ||||
| if (extend == 0) { | if (extend == 0) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| } | } | ||||
| mouse_seq->flag |= SELECT; | mouse_seq->flag |= SELECT; | ||||
| recurs_sel_seq(mouse_seq); | recurs_sel_seq(mouse_seq); | ||||
| selected = 1; | selected = 1; | ||||
| while (selected) { | while (selected) { | ||||
| selected = select_linked_internal(scene); | selected = select_linked_internal(video_edit); | ||||
| } | } | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot) | void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Select Pick Linked"; | ot->name = "Select Pick Linked"; | ||||
| Show All 16 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select Linked Operator | /** \name Select Linked Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) | static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| bool selected; | bool selected; | ||||
| selected = true; | selected = true; | ||||
| while (selected) { | while (selected) { | ||||
| selected = select_linked_internal(scene); | selected = select_linked_internal(video_edit); | ||||
| } | } | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_linked(wmOperatorType *ot) | void SEQUENCER_OT_select_linked(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Select Linked"; | ot->name = "Select Linked"; | ||||
| Show All 30 Lines | static const EnumPropertyItem prop_select_handles_side_types[] = { | ||||
| {SEQ_SELECT_HANDLES_SIDE_LEFT_NEIGHBOR, "LEFT_NEIGHBOR", 0, "Left Neighbor", ""}, | {SEQ_SELECT_HANDLES_SIDE_LEFT_NEIGHBOR, "LEFT_NEIGHBOR", 0, "Left Neighbor", ""}, | ||||
| {SEQ_SELECT_HANDLES_SIDE_RIGHT_NEIGHBOR, "RIGHT_NEIGHBOR", 0, "Right Neighbor", ""}, | {SEQ_SELECT_HANDLES_SIDE_RIGHT_NEIGHBOR, "RIGHT_NEIGHBOR", 0, "Right Neighbor", ""}, | ||||
| {SEQ_SELECT_HANDLES_SIDE_BOTH_NEIGHBORS, "BOTH_NEIGHBORS", 0, "Both Neighbors", ""}, | {SEQ_SELECT_HANDLES_SIDE_BOTH_NEIGHBORS, "BOTH_NEIGHBORS", 0, "Both Neighbors", ""}, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static int sequencer_select_handles_exec(bContext *C, wmOperator *op) | static int sequencer_select_handles_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 sel_side = RNA_enum_get(op->ptr, "side"); | int sel_side = RNA_enum_get(op->ptr, "side"); | ||||
| 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) { | ||||
| Sequence *l_neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, -1); | Sequence *l_neighbor = find_neighboring_sequence(video_edit, seq, SEQ_SIDE_LEFT, -1); | ||||
| Sequence *r_neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, -1); | Sequence *r_neighbor = find_neighboring_sequence(video_edit, seq, SEQ_SIDE_RIGHT, -1); | ||||
| switch (sel_side) { | switch (sel_side) { | ||||
| case SEQ_SELECT_HANDLES_SIDE_LEFT: | case SEQ_SELECT_HANDLES_SIDE_LEFT: | ||||
| seq->flag &= ~SEQ_RIGHTSEL; | seq->flag &= ~SEQ_RIGHTSEL; | ||||
| seq->flag |= SEQ_LEFTSEL; | seq->flag |= SEQ_LEFTSEL; | ||||
| break; | break; | ||||
| case SEQ_SELECT_HANDLES_SIDE_RIGHT: | case SEQ_SELECT_HANDLES_SIDE_RIGHT: | ||||
| seq->flag &= ~SEQ_LEFTSEL; | seq->flag &= ~SEQ_LEFTSEL; | ||||
| Show All 27 Lines | if (seq->flag & SELECT) { | ||||
| r_neighbor->flag |= SEQ_LEFTSEL; | r_neighbor->flag |= SEQ_LEFTSEL; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Select strips */ | /* Select strips */ | ||||
| for (seq = ed->seqbasep->first; seq; seq = seq->next) { | for (seq = video_edit->seqbasep->first; seq; seq = seq->next) { | ||||
| if ((seq->flag & SEQ_LEFTSEL) || (seq->flag & SEQ_RIGHTSEL)) { | if ((seq->flag & SEQ_LEFTSEL) || (seq->flag & SEQ_RIGHTSEL)) { | ||||
| if (!(seq->flag & SELECT)) { | if (!(seq->flag & SELECT)) { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| recurs_sel_seq(seq); | recurs_sel_seq(seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_handles(wmOperatorType *ot) | void SEQUENCER_OT_select_handles(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Select Handles"; | ot->name = "Select Handles"; | ||||
| Show All 19 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select Side of Frame Operator | /** \name Select Side of Frame Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) | static int sequencer_select_side_of_frame_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); | |||||
| const bool extend = RNA_boolean_get(op->ptr, "extend"); | const bool extend = RNA_boolean_get(op->ptr, "extend"); | ||||
| const int side = RNA_enum_get(op->ptr, "side"); | const int side = RNA_enum_get(op->ptr, "side"); | ||||
| if (ed == NULL) { | if (video_edit == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| if (extend == false) { | if (extend == false) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| } | } | ||||
| const int timeline_frame = scene->r.cfra; | const int timeline_frame = video_edit->r.cfra; | ||||
| LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) { | LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(video_edit)) { | ||||
| bool test = false; | bool test = false; | ||||
| switch (side) { | switch (side) { | ||||
| case -1: | case -1: | ||||
| test = (timeline_frame >= SEQ_time_right_handle_frame_get(scene, seq)); | test = (timeline_frame >= SEQ_time_right_handle_frame_get(video_edit, seq)); | ||||
| break; | break; | ||||
| case 1: | case 1: | ||||
| test = (timeline_frame <= SEQ_time_left_handle_frame_get(scene, seq)); | test = (timeline_frame <= SEQ_time_left_handle_frame_get(video_edit, seq)); | ||||
| break; | break; | ||||
| case 2: | case 2: | ||||
| test = SEQ_time_strip_intersects_frame(scene, seq, timeline_frame); | test = SEQ_time_strip_intersects_frame(video_edit, seq, timeline_frame); | ||||
| break; | break; | ||||
| } | } | ||||
| if (test) { | if (test) { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| recurs_sel_seq(seq); | recurs_sel_seq(seq); | ||||
| } | } | ||||
| } | } | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot) | void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot) | ||||
| { | { | ||||
| static const EnumPropertyItem sequencer_select_left_right_types[] = { | static const EnumPropertyItem sequencer_select_left_right_types[] = { | ||||
| {-1, "LEFT", 0, "Left", "Select to the left of the current frame"}, | {-1, "LEFT", 0, "Left", "Select to the left of the current frame"}, | ||||
| Show All 24 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Select Side Operator | /** \name Select Side Operator | ||||
| * \{ */ | * \{ */ | ||||
| static int sequencer_select_side_exec(bContext *C, wmOperator *op) | static int sequencer_select_side_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); | |||||
| const int sel_side = RNA_enum_get(op->ptr, "side"); | const int sel_side = RNA_enum_get(op->ptr, "side"); | ||||
| const int frame_init = sel_side == SEQ_SIDE_LEFT ? INT_MIN : INT_MAX; | const int frame_init = sel_side == SEQ_SIDE_LEFT ? INT_MIN : INT_MAX; | ||||
| int frame_ranges[MAXSEQ]; | int frame_ranges[MAXSEQ]; | ||||
| bool selected = false; | bool selected = false; | ||||
| copy_vn_i(frame_ranges, ARRAY_SIZE(frame_ranges), frame_init); | copy_vn_i(frame_ranges, ARRAY_SIZE(frame_ranges), frame_init); | ||||
| LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { | LISTBASE_FOREACH (Sequence *, seq, video_edit->seqbasep) { | ||||
| if (UNLIKELY(seq->machine >= MAXSEQ)) { | if (UNLIKELY(seq->machine >= MAXSEQ)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| int *frame_limit_p = &frame_ranges[seq->machine]; | int *frame_limit_p = &frame_ranges[seq->machine]; | ||||
| if (seq->flag & SELECT) { | if (seq->flag & SELECT) { | ||||
| selected = true; | selected = true; | ||||
| if (sel_side == SEQ_SIDE_LEFT) { | if (sel_side == SEQ_SIDE_LEFT) { | ||||
| *frame_limit_p = max_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(scene, seq)); | *frame_limit_p = max_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(video_edit, seq)); | ||||
| } | } | ||||
| else { | else { | ||||
| *frame_limit_p = min_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(scene, seq)); | *frame_limit_p = min_ii(*frame_limit_p, SEQ_time_left_handle_frame_get(video_edit, seq)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (selected == false) { | if (selected == false) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| select_active_side_range(scene, ed->seqbasep, sel_side, frame_ranges, frame_init); | select_active_side_range(video_edit, video_edit->seqbasep, sel_side, frame_ranges, frame_init); | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_side(wmOperatorType *ot) | void SEQUENCER_OT_select_side(wmOperatorType *ot) | ||||
| { | { | ||||
| /* Identifiers. */ | /* Identifiers. */ | ||||
| ot->name = "Select Side"; | ot->name = "Select Side"; | ||||
| Show All 17 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Box Select Operator | /** \name Box Select Operator | ||||
| * \{ */ | * \{ */ | ||||
| static bool seq_box_select_rect_image_isect(const Scene *scene, const Sequence *seq, rctf *rect) | static bool seq_box_select_rect_image_isect(const VideoEdit *video_edit, | ||||
| const Sequence *seq, | |||||
| rctf *rect) | |||||
| { | { | ||||
| float seq_image_quad[4][2]; | float seq_image_quad[4][2]; | ||||
| SEQ_image_transform_final_quad_get(scene, seq, seq_image_quad); | SEQ_image_transform_final_quad_get(video_edit, seq, seq_image_quad); | ||||
| float rect_quad[4][2] = {{rect->xmax, rect->ymax}, | float rect_quad[4][2] = {{rect->xmax, rect->ymax}, | ||||
| {rect->xmax, rect->ymin}, | {rect->xmax, rect->ymin}, | ||||
| {rect->xmin, rect->ymin}, | {rect->xmin, rect->ymin}, | ||||
| {rect->xmin, rect->ymax}}; | {rect->xmin, rect->ymax}}; | ||||
| return seq_point_image_isect(scene, seq, rect_quad[0]) || | return seq_point_image_isect(video_edit, seq, rect_quad[0]) || | ||||
| seq_point_image_isect(scene, seq, rect_quad[1]) || | seq_point_image_isect(video_edit, seq, rect_quad[1]) || | ||||
| seq_point_image_isect(scene, seq, rect_quad[2]) || | seq_point_image_isect(video_edit, seq, rect_quad[2]) || | ||||
| seq_point_image_isect(scene, seq, rect_quad[3]) || | seq_point_image_isect(video_edit, seq, rect_quad[3]) || | ||||
| isect_point_quad_v2( | isect_point_quad_v2( | ||||
| seq_image_quad[0], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]) || | seq_image_quad[0], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]) || | ||||
| isect_point_quad_v2( | isect_point_quad_v2( | ||||
| seq_image_quad[1], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]) || | seq_image_quad[1], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]) || | ||||
| isect_point_quad_v2( | isect_point_quad_v2( | ||||
| seq_image_quad[2], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]) || | seq_image_quad[2], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]) || | ||||
| isect_point_quad_v2( | isect_point_quad_v2( | ||||
| seq_image_quad[3], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]); | seq_image_quad[3], rect_quad[0], rect_quad[1], rect_quad[2], rect_quad[3]); | ||||
| } | } | ||||
| static void seq_box_select_seq_from_preview(const bContext *C, rctf *rect, const eSelectOp mode) | static void seq_box_select_seq_from_preview(const bContext *C, rctf *rect, const eSelectOp mode) | ||||
| { | { | ||||
| 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); | ListBase *channels = SEQ_channels_displayed_get(video_edit); | ||||
| ListBase *channels = SEQ_channels_displayed_get(ed); | |||||
| SpaceSeq *sseq = CTX_wm_space_seq(C); | SpaceSeq *sseq = CTX_wm_space_seq(C); | ||||
| SeqCollection *strips = SEQ_query_rendered_strips( | SeqCollection *strips = SEQ_query_rendered_strips( | ||||
| scene, channels, seqbase, scene->r.cfra, sseq->chanshown); | video_edit, channels, seqbase, video_edit->r.cfra, sseq->chanshown); | ||||
| Sequence *seq; | Sequence *seq; | ||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | SEQ_ITERATOR_FOREACH (seq, strips) { | ||||
| if (!seq_box_select_rect_image_isect(scene, seq, rect)) { | if (!seq_box_select_rect_image_isect(video_edit, seq, rect)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (ELEM(mode, SEL_OP_ADD, SEL_OP_SET)) { | if (ELEM(mode, SEL_OP_ADD, SEL_OP_SET)) { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(mode == SEL_OP_SUB); | BLI_assert(mode == SEL_OP_SUB); | ||||
| seq->flag &= ~SELECT; | seq->flag &= ~SELECT; | ||||
| } | } | ||||
| } | } | ||||
| SEQ_collection_free(strips); | SEQ_collection_free(strips); | ||||
| } | } | ||||
| static int sequencer_box_select_exec(bContext *C, wmOperator *op) | static int sequencer_box_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| 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); | ||||
| Editing *ed = SEQ_editing_get(scene); | |||||
| if (ed == NULL) { | if (video_edit == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode"); | const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode"); | ||||
| const bool handles = RNA_boolean_get(op->ptr, "include_handles"); | const bool handles = RNA_boolean_get(op->ptr, "include_handles"); | ||||
| const bool select = (sel_op != SEL_OP_SUB); | const bool select = (sel_op != SEL_OP_SUB); | ||||
| if (SEL_OP_USE_PRE_DESELECT(sel_op)) { | if (SEL_OP_USE_PRE_DESELECT(sel_op)) { | ||||
| ED_sequencer_deselect_all(scene); | ED_sequencer_deselect_all(video_edit); | ||||
| } | } | ||||
| rctf rectf; | rctf rectf; | ||||
| WM_operator_properties_border_to_rctf(op, &rectf); | WM_operator_properties_border_to_rctf(op, &rectf); | ||||
| UI_view2d_region_to_view_rctf(v2d, &rectf, &rectf); | UI_view2d_region_to_view_rctf(v2d, &rectf, &rectf); | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| if (region->regiontype == RGN_TYPE_PREVIEW) { | if (region->regiontype == RGN_TYPE_PREVIEW) { | ||||
| if (!sequencer_view_preview_only_poll(C)) { | if (!sequencer_view_preview_only_poll(C)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| seq_box_select_seq_from_preview(C, &rectf, sel_op); | seq_box_select_seq_from_preview(C, &rectf, sel_op); | ||||
| sequencer_select_do_updates(C, scene); | sequencer_select_do_updates(C, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { | LISTBASE_FOREACH (Sequence *, seq, video_edit->seqbasep) { | ||||
| rctf rq; | rctf rq; | ||||
| seq_rectf(scene, seq, &rq); | seq_rectf(video_edit, seq, &rq); | ||||
| if (BLI_rctf_isect(&rq, &rectf, NULL)) { | if (BLI_rctf_isect(&rq, &rectf, NULL)) { | ||||
| if (handles) { | if (handles) { | ||||
| /* Get the handles draw size. */ | /* Get the handles draw size. */ | ||||
| float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); | float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); | ||||
| float handsize = sequence_handle_size_get_clamped(scene, seq, pixelx); | float handsize = sequence_handle_size_get_clamped(video_edit, seq, pixelx); | ||||
| /* Right handle. */ | /* Right handle. */ | ||||
| if (rectf.xmax > (SEQ_time_right_handle_frame_get(scene, seq) - handsize)) { | if (rectf.xmax > (SEQ_time_right_handle_frame_get(video_edit, seq) - handsize)) { | ||||
| if (select) { | if (select) { | ||||
| seq->flag |= SELECT | SEQ_RIGHTSEL; | seq->flag |= SELECT | SEQ_RIGHTSEL; | ||||
| } | } | ||||
| else { | else { | ||||
| /* Deselect the strip if it's left with no handles selected. */ | /* Deselect the strip if it's left with no handles selected. */ | ||||
| if ((seq->flag & SEQ_RIGHTSEL) && ((seq->flag & SEQ_LEFTSEL) == 0)) { | if ((seq->flag & SEQ_RIGHTSEL) && ((seq->flag & SEQ_LEFTSEL) == 0)) { | ||||
| seq->flag &= ~SELECT; | seq->flag &= ~SELECT; | ||||
| } | } | ||||
| seq->flag &= ~SEQ_RIGHTSEL; | seq->flag &= ~SEQ_RIGHTSEL; | ||||
| } | } | ||||
| } | } | ||||
| /* Left handle. */ | /* Left handle. */ | ||||
| if (rectf.xmin < (SEQ_time_left_handle_frame_get(scene, seq) + handsize)) { | if (rectf.xmin < (SEQ_time_left_handle_frame_get(video_edit, seq) + handsize)) { | ||||
| if (select) { | if (select) { | ||||
| seq->flag |= SELECT | SEQ_LEFTSEL; | seq->flag |= SELECT | SEQ_LEFTSEL; | ||||
| } | } | ||||
| else { | else { | ||||
| /* Deselect the strip if it's left with no handles selected. */ | /* Deselect the strip if it's left with no handles selected. */ | ||||
| if ((seq->flag & SEQ_LEFTSEL) && ((seq->flag & SEQ_RIGHTSEL) == 0)) { | if ((seq->flag & SEQ_LEFTSEL) && ((seq->flag & SEQ_RIGHTSEL) == 0)) { | ||||
| seq->flag &= ~SELECT; | seq->flag &= ~SELECT; | ||||
| } | } | ||||
| seq->flag &= ~SEQ_LEFTSEL; | seq->flag &= ~SEQ_LEFTSEL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Regular box selection. */ | /* Regular box selection. */ | ||||
| else { | else { | ||||
| SET_FLAG_FROM_TEST(seq->flag, select, SELECT); | SET_FLAG_FROM_TEST(seq->flag, select, SELECT); | ||||
| seq->flag &= ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); | seq->flag &= ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| sequencer_select_do_updates(C, scene); | sequencer_select_do_updates(C, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int sequencer_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int sequencer_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| View2D *v2d = &CTX_wm_region(C)->v2d; | View2D *v2d = &CTX_wm_region(C)->v2d; | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| if (region->regiontype == RGN_TYPE_PREVIEW && !sequencer_view_preview_only_poll(C)) { | if (region->regiontype == RGN_TYPE_PREVIEW && !sequencer_view_preview_only_poll(C)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| const bool tweak = RNA_boolean_get(op->ptr, "tweak"); | const bool tweak = RNA_boolean_get(op->ptr, "tweak"); | ||||
| if (tweak) { | if (tweak) { | ||||
| int hand_dummy; | int hand_dummy; | ||||
| int mval[2]; | int mval[2]; | ||||
| WM_event_drag_start_mval(event, region, mval); | WM_event_drag_start_mval(event, region, mval); | ||||
| Sequence *seq = find_nearest_seq(scene, v2d, &hand_dummy, mval); | Sequence *seq = find_nearest_seq(video_edit, v2d, &hand_dummy, mval); | ||||
| if (seq != NULL) { | if (seq != NULL) { | ||||
| return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; | return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; | ||||
| } | } | ||||
| } | } | ||||
| return WM_gesture_box_invoke(C, op, event); | return WM_gesture_box_invoke(C, op, event); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | if (SEQ_CHANNEL_CHECK(seq, channel) && effects[seq->type]) { | ||||
| } | } | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| static bool select_grouped_time_overlap(const Scene *scene, | static bool select_grouped_time_overlap(const VideoEdit *video_edit, | ||||
| SeqCollection *strips, | SeqCollection *strips, | ||||
| ListBase *UNUSED(seqbase), | ListBase *UNUSED(seqbase), | ||||
| Sequence *actseq) | Sequence *actseq) | ||||
| { | { | ||||
| bool changed = false; | bool changed = false; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | SEQ_ITERATOR_FOREACH (seq, strips) { | ||||
| 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, actseq) && | SEQ_time_right_handle_frame_get(video_edit, actseq) && | ||||
| SEQ_time_right_handle_frame_get(scene, seq) > | SEQ_time_right_handle_frame_get(video_edit, seq) > | ||||
| SEQ_time_left_handle_frame_get(scene, actseq)) { | SEQ_time_left_handle_frame_get(video_edit, actseq)) { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| /* Query strips that are in lower channel and intersect in time with seq_reference. */ | /* Query strips that are in lower channel and intersect in time with seq_reference. */ | ||||
| static void query_lower_channel_strips(const Scene *scene, | static void query_lower_channel_strips(const VideoEdit *video_edit, | ||||
| Sequence *seq_reference, | Sequence *seq_reference, | ||||
| ListBase *seqbase, | ListBase *seqbase, | ||||
| SeqCollection *collection) | SeqCollection *collection) | ||||
| { | { | ||||
| LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { | LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { | ||||
| if (seq_test->machine > seq_reference->machine) { | if (seq_test->machine > seq_reference->machine) { | ||||
| continue; /* Not lower channel. */ | continue; /* Not lower channel. */ | ||||
| } | } | ||||
| if (SEQ_time_right_handle_frame_get(scene, seq_test) <= | if (SEQ_time_right_handle_frame_get(video_edit, seq_test) <= | ||||
| SEQ_time_left_handle_frame_get(scene, seq_reference) || | SEQ_time_left_handle_frame_get(video_edit, seq_reference) || | ||||
| SEQ_time_left_handle_frame_get(scene, seq_test) >= | SEQ_time_left_handle_frame_get(video_edit, seq_test) >= | ||||
| SEQ_time_right_handle_frame_get(scene, seq_reference)) { | SEQ_time_right_handle_frame_get(video_edit, seq_reference)) { | ||||
| continue; /* Not intersecting in time. */ | continue; /* Not intersecting in time. */ | ||||
| } | } | ||||
| SEQ_collection_append_strip(seq_test, collection); | SEQ_collection_append_strip(seq_test, collection); | ||||
| } | } | ||||
| } | } | ||||
| /* Select all strips within time range and with lower channel of initial selection. Then select | /* Select all strips within time range and with lower channel of initial selection. Then select | ||||
| * effect chains of these strips. */ | * effect chains of these strips. */ | ||||
| static bool select_grouped_effect_link(const Scene *scene, | static bool select_grouped_effect_link(const VideoEdit *video_edit, | ||||
| SeqCollection *strips, | SeqCollection *strips, | ||||
| ListBase *seqbase, | ListBase *seqbase, | ||||
| Sequence *UNUSED(actseq), | Sequence *UNUSED(actseq), | ||||
| const int UNUSED(channel)) | const int UNUSED(channel)) | ||||
| { | { | ||||
| /* Get collection of strips. */ | /* Get collection of strips. */ | ||||
| SEQ_filter_selected_strips(strips); | SEQ_filter_selected_strips(strips); | ||||
| const int selected_strip_count = SEQ_collection_len(strips); | const int selected_strip_count = SEQ_collection_len(strips); | ||||
| // XXX this uses scene as arg, so it does not work with iterator :( I had thought about this, but | SEQ_collection_expand(video_edit, seqbase, strips, query_lower_channel_strips); | ||||
| // expand function is just so useful... I can just add scene and inject it I guess..... | SEQ_collection_expand(video_edit, seqbase, strips, SEQ_query_strip_effect_chain); | ||||
| SEQ_collection_expand(scene, seqbase, strips, query_lower_channel_strips); | |||||
| SEQ_collection_expand(scene, seqbase, strips, SEQ_query_strip_effect_chain); | |||||
| /* Check if other strips will be affected. */ | /* Check if other strips will be affected. */ | ||||
| const bool changed = SEQ_collection_len(strips) > selected_strip_count; | const bool changed = SEQ_collection_len(strips) > selected_strip_count; | ||||
| /* Actual logic. */ | /* Actual logic. */ | ||||
| Sequence *seq; | Sequence *seq; | ||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | SEQ_ITERATOR_FOREACH (seq, strips) { | ||||
| seq->flag |= SELECT; | seq->flag |= SELECT; | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| #undef SEQ_IS_SOUND | #undef SEQ_IS_SOUND | ||||
| #undef SEQ_IS_EFFECT | #undef SEQ_IS_EFFECT | ||||
| #undef SEQ_USE_DATA | #undef SEQ_USE_DATA | ||||
| static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) | static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | VideoEdit *video_edit = CTX_data_video_edit(C); | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | ListBase *seqbase = SEQ_active_seqbase_get(video_edit); | ||||
| Sequence *actseq = SEQ_select_active_get(scene); | Sequence *actseq = SEQ_select_active_get(video_edit); | ||||
| const bool is_preview = sequencer_view_has_preview_poll(C); | const bool is_preview = sequencer_view_has_preview_poll(C); | ||||
| if (is_preview && !sequencer_view_preview_only_poll(C)) { | if (is_preview && !sequencer_view_preview_only_poll(C)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| SeqCollection *strips = all_strips_from_context(C); | SeqCollection *strips = all_strips_from_context(C); | ||||
| Show All 27 Lines | case SEQ_SELECT_GROUP_TYPE_EFFECT: | ||||
| break; | break; | ||||
| case SEQ_SELECT_GROUP_DATA: | case SEQ_SELECT_GROUP_DATA: | ||||
| changed |= select_grouped_data(strips, seqbase, actseq, channel); | changed |= select_grouped_data(strips, seqbase, actseq, channel); | ||||
| break; | break; | ||||
| case SEQ_SELECT_GROUP_EFFECT: | case SEQ_SELECT_GROUP_EFFECT: | ||||
| changed |= select_grouped_effect(strips, seqbase, actseq, channel); | changed |= select_grouped_effect(strips, seqbase, actseq, channel); | ||||
| break; | break; | ||||
| case SEQ_SELECT_GROUP_EFFECT_LINK: | case SEQ_SELECT_GROUP_EFFECT_LINK: | ||||
| changed |= select_grouped_effect_link(scene, strips, seqbase, actseq, channel); | changed |= select_grouped_effect_link(video_edit, strips, seqbase, actseq, channel); | ||||
| break; | break; | ||||
| case SEQ_SELECT_GROUP_OVERLAP: | case SEQ_SELECT_GROUP_OVERLAP: | ||||
| changed |= select_grouped_time_overlap(scene, strips, seqbase, actseq); | changed |= select_grouped_time_overlap(video_edit, strips, seqbase, actseq); | ||||
| break; | break; | ||||
| default: | default: | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| break; | break; | ||||
| } | } | ||||
| SEQ_collection_free(strips); | SEQ_collection_free(strips); | ||||
| if (changed) { | if (changed) { | ||||
| ED_outliner_select_sync_from_sequence_tag(C); | ED_outliner_select_sync_from_sequence_tag(C); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); | WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_SEQUENCER | NA_SELECTED, video_edit); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| void SEQUENCER_OT_select_grouped(wmOperatorType *ot) | void SEQUENCER_OT_select_grouped(wmOperatorType *ot) | ||||
| { | { | ||||
| Show All 28 Lines | |||||