diff options
author | Richard Antalik <richardantalik@gmail.com> | 2021-07-07 04:20:59 +0300 |
---|---|---|
committer | Richard Antalik <richardantalik@gmail.com> | 2021-07-07 04:26:14 +0300 |
commit | 4e80573a7699f2e5c54a7dd186274ff6279dcad6 (patch) | |
tree | de8018021ceca8300deac5e400727c7109bd5add /source/blender/editors | |
parent | c5b2381703aab69e539b2a3cde234f10d6d8097a (diff) |
VSE: Use snapping settings for scrubbing
Use "Snap Playhead to Strips" option to enable playhead snapping.
Change behavior of CTRL key to invert snapping similar to transform operator.
Currently this option is disabled by default. It makes editing quite unpleasant
for me personally, but ideally I should gather feedback from more users.
Reviewed By: campbellbarton
Differential Revision: https://developer.blender.org/D11745
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/animation/anim_ops.c | 82 |
1 files changed, 77 insertions, 5 deletions
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 73b9b118148..6f3277397c5 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -51,8 +51,10 @@ #include "DEG_depsgraph.h" +#include "SEQ_iterator.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" +#include "SEQ_transform.h" #include "anim_intern.h" @@ -81,6 +83,49 @@ static bool change_frame_poll(bContext *C) return false; } +static int seq_snap_threshold_get_frame_distance(bContext *C) +{ + const int snap_distance = SEQ_tool_settings_snap_distance_get(CTX_data_scene(C)); + const ARegion *region = CTX_wm_region(C); + return round_fl_to_int(UI_view2d_region_to_view_x(®ion->v2d, snap_distance) - + UI_view2d_region_to_view_x(®ion->v2d, 0)); +} + +static void seq_frame_snap_update_best(const int position, + const int timeline_frame, + int *r_best_frame, + int *r_best_distance) +{ + if (abs(position - timeline_frame) < *r_best_distance) { + *r_best_distance = abs(position - timeline_frame); + *r_best_frame = position; + } +} + +static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_frame) +{ + + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene, false)); + SeqCollection *strips = SEQ_query_all_strips(seqbase); + + int best_frame = 0; + int best_distance = MAXFRAME; + Sequence *seq; + SEQ_ITERATOR_FOREACH (seq, strips) { + seq_frame_snap_update_best( + SEQ_transform_get_left_handle_frame(seq), timeline_frame, &best_frame, &best_distance); + seq_frame_snap_update_best( + SEQ_transform_get_right_handle_frame(seq), timeline_frame, &best_frame, &best_distance); + } + SEQ_collection_free(strips); + + if (best_distance < seq_snap_threshold_get_frame_distance(C)) { + return best_frame; + } + + return timeline_frame; +} + /* Set the new frame number */ static void change_frame_apply(bContext *C, wmOperator *op) { @@ -90,7 +135,7 @@ static void change_frame_apply(bContext *C, wmOperator *op) if (do_snap) { if (CTX_wm_space_seq(C)) { - frame = SEQ_time_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false); + frame = seq_frame_apply_snap(C, scene, frame); } else { frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame); @@ -181,6 +226,18 @@ static void change_frame_seq_preview_end(bContext *C) } } +static bool use_sequencer_snapping(bContext *C) +{ + if (!CTX_wm_space_seq(C)) { + return false; + } + + Scene *scene = CTX_data_scene(C); + short snap_flag = SEQ_tool_settings_snap_flag_get(scene); + return (scene->toolsettings->snap_flag & SCE_SNAP_SEQ) && + (snap_flag & SEQ_SNAP_CURRENT_FRAME_TO_STRIPS); +} + /* Modal Operator init */ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event) { @@ -190,6 +247,10 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event */ RNA_float_set(op->ptr, "frame", frame_from_event(C, event)); + if (use_sequencer_snapping(C)) { + RNA_boolean_set(op->ptr, "snap", true); + } + change_frame_seq_preview_begin(C, event); change_frame_apply(C, op); @@ -231,11 +292,22 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event) case EVT_LEFTCTRLKEY: case EVT_RIGHTCTRLKEY: - if (event->val == KM_RELEASE) { - RNA_boolean_set(op->ptr, "snap", false); + /* Use Ctrl key to invert snapping in sequencer. */ + if (use_sequencer_snapping(C)) { + if (event->val == KM_RELEASE) { + RNA_boolean_set(op->ptr, "snap", true); + } + else if (event->val == KM_PRESS) { + RNA_boolean_set(op->ptr, "snap", false); + } } - else if (event->val == KM_PRESS) { - RNA_boolean_set(op->ptr, "snap", true); + else { + if (event->val == KM_RELEASE) { + RNA_boolean_set(op->ptr, "snap", false); + } + else if (event->val == KM_PRESS) { + RNA_boolean_set(op->ptr, "snap", true); + } } break; } |