From 7356e72e1bae613ece9c9d1fb40a494f3eea9a60 Mon Sep 17 00:00:00 2001 From: John Kiril Swenson Date: Wed, 12 Mar 2025 03:36:32 +0100 Subject: [PATCH] VSE: Snap to Frame Range, Snap by Default This patch adds the ability to snap to the frame range bounds in the VSE timeline, on by default. End frame snap location is offset by 1 to ensure the snap point aligns with the visible end frame boundary (otherwise e.g. right handle of strip would be one frame short). Timeline and preview snapping is also turned on by default using the same versioning block. Pull Request: https://projects.blender.org/blender/blender/pulls/135753 --- scripts/startup/bl_ui/space_sequencer.py | 2 ++ source/blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenloader/intern/versioning_400.cc | 10 ++++++++++ .../editors/transform/transform_snap_sequencer.cc | 5 +++++ source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesrna/intern/rna_scene.cc | 5 +++++ 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/scripts/startup/bl_ui/space_sequencer.py b/scripts/startup/bl_ui/space_sequencer.py index 648be806b4e..b5bac540983 100644 --- a/scripts/startup/bl_ui/space_sequencer.py +++ b/scripts/startup/bl_ui/space_sequencer.py @@ -3022,6 +3022,7 @@ class SEQUENCER_PT_snapping(Panel): bl_space_type = 'SEQUENCE_EDITOR' bl_region_type = 'HEADER' bl_label = "" + bl_ui_units_x = 11 def draw(self, _context): pass @@ -3072,6 +3073,7 @@ class SEQUENCER_PT_sequencer_snapping(Panel): layout.use_property_decorate = False col = layout.column(heading="Snap to", align=True) + col.prop(sequencer_tool_settings, "snap_to_frame_range") col.prop(sequencer_tool_settings, "snap_to_current_frame") col.prop(sequencer_tool_settings, "snap_to_hold_offset") col.prop(sequencer_tool_settings, "snap_to_markers") diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index e3fe20fcb31..8cbf2f6a653 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 4 +#define BLENDER_FILE_SUBVERSION 5 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index e00387b6b30..c3a782b4efb 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -5985,6 +5985,16 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) FOREACH_NODETREE_END; } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 5)) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + ToolSettings *tool_settings = scene->toolsettings; + tool_settings->snap_flag_seq |= SCE_SNAP; + + SequencerToolSettings *sequencer_tool_settings = blender::seq::tool_settings_ensure(scene); + sequencer_tool_settings->snap_mode |= SEQ_SNAP_TO_FRAME_RANGE; + } + } + /* Always run this versioning; meshes are written with the legacy format which always needs to * be converted to the new format on file load. Can be moved to a subversion check in a larger * breaking release. */ diff --git a/source/blender/editors/transform/transform_snap_sequencer.cc b/source/blender/editors/transform/transform_snap_sequencer.cc index b3fbf44541e..9fd44b3dcce 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.cc +++ b/source/blender/editors/transform/transform_snap_sequencer.cc @@ -261,6 +261,11 @@ static void points_build_targets_timeline(const Scene *scene, } } + if (snap_mode & SEQ_SNAP_TO_FRAME_RANGE) { + snap_data->target_snap_points.append(float2(PSFRA)); + snap_data->target_snap_points.append(float2(PEFRA + 1)); + } + for (Strip *strip : strip_targets) { snap_data->target_snap_points.append(float2(seq::time_left_handle_frame_get(scene, strip))); snap_data->target_snap_points.append(float2(seq::time_right_handle_frame_get(scene, strip))); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 152239204b2..91641764d1b 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2490,6 +2490,7 @@ enum { SEQ_SNAP_TO_STRIPS_PREVIEW = 1 << 6, SEQ_SNAP_TO_RETIMING = 1 << 7, + SEQ_SNAP_TO_FRAME_RANGE = 1 << 8, }; /** #SequencerToolSettings::snap_flag */ diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc index 1c9cfab5ce5..adf54fcb5ef 100644 --- a/source/blender/makesrna/intern/rna_scene.cc +++ b/source/blender/makesrna/intern/rna_scene.cc @@ -4227,6 +4227,11 @@ static void rna_def_sequencer_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Retiming Keys", "Snap to retiming keys"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */ + prop = RNA_def_property(srna, "snap_to_frame_range", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, nullptr, "snap_mode", SEQ_SNAP_TO_FRAME_RANGE); + RNA_def_property_ui_text(prop, "Frame Range", "Snap to preview or scene start and end frame"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */ + prop = RNA_def_property(srna, "snap_to_borders", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "snap_mode", SEQ_SNAP_TO_PREVIEW_BORDERS); RNA_def_property_ui_text(prop, "Borders", "Snap to preview borders");