Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py3
-rw-r--r--source/blender/editors/animation/anim_ops.c82
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_scene.c5
4 files changed, 86 insertions, 5 deletions
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 5e92e088b36..55714e0b0a5 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -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,
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(&region->v2d, snap_distance) -
+ UI_view2d_region_to_view_x(&region->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;
}
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 5fc6cdf58a3..cd752b220a3 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -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)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index cb1b0dbd1e5..0a91d5f01bc 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -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);