Anim: Deselect Keys before inserting new keys

This commit changes the keying code to deselect keyframes when inserting new keys.
This has been discussed in the Animation & Rigging module meeting [1].
There is also an RCS post about that [2].
Doing this brings key creation in line with object creation,
where only the newly created object is selected.
There has been a previous attempt [3] to do a similar thing.

### Changes
When inserting keys by pressing `I` in the viewport or choosing a keying set,
all keys of the `Action` get deselected before inserting new keys.
New keys are selected by default.
Python RNA functions are **NOT** affected, meaning addons using
those functions will not deselect any keys by default.
The developer has to choose to do so.
To make that easier, there is a new RNA function on the action
`deselect_keys`

[1]: https://devtalk.blender.org/t/2024-05-02-animation-rigging-module-meeting/34493#patches-review-decision-time-5
[2]: https://blender.community/c/rightclickselect/K0hbbc
[3]: https://archive.blender.org/developer/D11623

Pull Request: https://projects.blender.org/blender/blender/pulls/121908
This commit is contained in:
Christoph Lendenfeld
2024-07-18 14:48:00 +02:00
committed by Christoph Lendenfeld
parent c7ecaf67fd
commit 6ef77a0d22
17 changed files with 231 additions and 0 deletions

View File

@@ -178,6 +178,19 @@ class InsertKeyTest(AbstractKeyframingTest, unittest.TestCase):
_fcurve_paths_match(keyed_object.animation_data.action.fcurves, keyed_rna_paths)
bpy.data.objects.remove(keyed_object, do_unlink=True)
def test_key_selection_state(self):
keyed_object = _create_animation_object()
bpy.context.preferences.edit.key_insert_channels = {"LOCATION"}
with bpy.context.temp_override(**_get_view3d_context()):
bpy.ops.anim.keyframe_insert()
bpy.context.scene.frame_set(5)
bpy.ops.anim.keyframe_insert()
for fcurve in keyed_object.animation_data.action.fcurves:
self.assertEqual(len(fcurve.keyframe_points), 2)
self.assertFalse(fcurve.keyframe_points[0].select_control_point)
self.assertTrue(fcurve.keyframe_points[1].select_control_point)
class VisualKeyingTest(AbstractKeyframingTest, unittest.TestCase):
""" Check if visual keying produces the correct keyframe values. """
@@ -368,6 +381,20 @@ class AutoKeyframingTest(AbstractKeyframingTest, unittest.TestCase):
expected_paths = [f"{bone_path}.location", f"{bone_path}.rotation_euler", f"{bone_path}.scale"]
_fcurve_paths_match(action.fcurves, expected_paths)
def test_key_selection_state(self):
armature_obj = _create_armature()
bpy.ops.object.mode_set(mode='POSE')
bpy.ops.transform.translate(value=(1, 0, 0))
bpy.context.scene.frame_set(5)
bpy.ops.transform.translate(value=(0, 1, 0))
bpy.ops.object.mode_set(mode='OBJECT')
action = armature_obj.animation_data.action
for fcurve in action.fcurves:
self.assertEqual(len(fcurve.keyframe_points), 2)
self.assertFalse(fcurve.keyframe_points[0].select_control_point)
self.assertTrue(fcurve.keyframe_points[1].select_control_point)
class InsertAvailableTest(AbstractKeyframingTest, unittest.TestCase):