diff --git a/scripts/startup/bl_ui/space_graph.py b/scripts/startup/bl_ui/space_graph.py index 1ca530ac3ba..7df05c233b2 100644 --- a/scripts/startup/bl_ui/space_graph.py +++ b/scripts/startup/bl_ui/space_graph.py @@ -159,6 +159,7 @@ class GRAPH_MT_view(Menu): layout.prop(st, "use_realtime_update") layout.prop(st, "show_sliders") layout.prop(st, "use_auto_merge_keyframes") + layout.prop(st, "autolock_translation_axis") layout.separator() if st.mode != 'DRIVERS': diff --git a/source/blender/editors/transform/transform_convert_graph.cc b/source/blender/editors/transform/transform_convert_graph.cc index 251f9f4b7f1..61c482b62eb 100644 --- a/source/blender/editors/transform/transform_convert_graph.cc +++ b/source/blender/editors/transform/transform_convert_graph.cc @@ -27,6 +27,7 @@ #include "UI_view2d.hh" #include "transform.hh" +#include "transform_constraints.hh" #include "transform_convert.hh" #include "transform_mode.hh" #include "transform_snap.hh" @@ -145,6 +146,24 @@ static bool graph_edit_use_local_center(TransInfo *t) return ((t->around == V3D_AROUND_LOCAL_ORIGINS) && (graph_edit_is_translation_mode(t) == false)); } +static void enable_autolock(TransInfo *t, SpaceGraph *space_graph) +{ + /* Locking the axis makes most sense for translation. We may want to enable it for scaling as + * well if artists require that. */ + if (t->mode != TFM_TRANSLATION) { + return; + } + + /* These flags are set when using tweak mode on handles. */ + if ((space_graph->runtime.flag & SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT) || + (space_graph->runtime.flag & SIPO_RUNTIME_FLAG_TWEAK_HANDLES_RIGHT)) + { + return; + } + + initSelectConstraint(t); +} + /** * Get the effective selection of a triple for transform, i.e. return if the left handle, right * handle and/or the center point should be affected by transform. @@ -367,6 +386,8 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } } + bool at_least_one_key_selected = false; + /* loop 2: build transdata arrays */ LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { AnimData *adt = ANIM_nla_mapping_get(&ac, ale); @@ -405,7 +426,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) TransDataCurveHandleFlags *hdata = nullptr; graph_bezt_get_transform_selection(t, bezt, use_handle, &sel_left, &sel_key, &sel_right); - + at_least_one_key_selected |= sel_key; if (is_prop_edit) { bool is_sel = (sel_key || sel_left || sel_right); /* we always select all handles for proportional editing if central handle is selected */ @@ -616,6 +637,10 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } } + if (sipo->flag & SIPO_AUTOLOCK_AXIS && at_least_one_key_selected) { + enable_autolock(t, sipo); + } + /* cleanup temp list */ ANIM_animdata_freelist(&anim_data); } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 2f4ea48cea1..2f9b3b1d01e 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -509,7 +509,8 @@ typedef enum eGraphEdit_Flag { SIPO_NOTRANSKEYCULL = (1 << 1), /* don't show any keyframe handles at all */ SIPO_NOHANDLES = (1 << 2), - /* SIPO_NODRAWCFRANUM = (1 << 3), DEPRECATED */ + /* Automatically lock the transform to whichever axis the cursor has moved the most. */ + SIPO_AUTOLOCK_AXIS = (1 << 3), /* show timing in seconds instead of frames */ SIPO_DRAWTIME = (1 << 4), /* draw names of F-Curves beside the respective curves */ diff --git a/source/blender/makesrna/intern/rna_space.cc b/source/blender/makesrna/intern/rna_space.cc index b5db3085864..1152ab2f68e 100644 --- a/source/blender/makesrna/intern/rna_space.cc +++ b/source/blender/makesrna/intern/rna_space.cc @@ -6422,6 +6422,13 @@ static void rna_def_space_graph(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Handles", "Show handles of Bézier control points"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, nullptr); + prop = RNA_def_property(srna, "autolock_translation_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, nullptr, "flag", SIPO_AUTOLOCK_AXIS); + RNA_def_property_ui_text(prop, + "Auto-Lock Key Axis", + "Automatically locks the movement of keyframes to the dominant axis"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, nullptr); + prop = RNA_def_property(srna, "use_only_selected_keyframe_handles", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", SIPO_SELVHANDLESONLY); RNA_def_property_ui_text(