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
This commit is contained in:
parent
c5b2381703
commit
4e80573a76
|
@ -2293,6 +2293,9 @@ class SEQUENCER_PT_snapping(Panel):
|
|||
col.prop(sequencer_tool_settings, "snap_ignore_muted", text="Muted Strips")
|
||||
col.prop(sequencer_tool_settings, "snap_ignore_sound", text="Sound Strips")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(sequencer_tool_settings, "use_snap_current_frame_to_strips")
|
||||
|
||||
|
||||
classes = (
|
||||
SEQUENCER_MT_change,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -2069,6 +2069,7 @@ enum {
|
|||
/** #SequencerToolSettings.snap_flag */
|
||||
#define SEQ_SNAP_IGNORE_MUTED (1 << 0)
|
||||
#define SEQ_SNAP_IGNORE_SOUND (1 << 1)
|
||||
#define SEQ_SNAP_CURRENT_FRAME_TO_STRIPS (1 << 2)
|
||||
|
||||
/** #ToolSettings.snap_node_mode */
|
||||
#define SCE_SNAP_MODE_NODE_X (1 << 0)
|
||||
|
|
|
@ -3535,6 +3535,11 @@ static void rna_def_sequencer_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SEQ_SNAP_IGNORE_SOUND);
|
||||
RNA_def_property_ui_text(prop, "Ignore Sound Strips", "Don't snap to sound strips");
|
||||
|
||||
prop = RNA_def_property(srna, "use_snap_current_frame_to_strips", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SEQ_SNAP_CURRENT_FRAME_TO_STRIPS);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Snap Current Frame to Strips", "Snap current frame to strip start or end");
|
||||
|
||||
prop = RNA_def_property(srna, "snap_distance", PROP_INT, PROP_PIXEL);
|
||||
RNA_def_property_int_sdna(prop, NULL, "snap_distance");
|
||||
RNA_def_property_int_default(prop, 15);
|
||||
|
|
Loading…
Reference in New Issue