[Bf-blender-cvs] [cda33345865] master: Fix setting key shortcuts for insert keyframe menu items

Campbell Barton noreply at git.blender.org
Mon Apr 11 13:11:11 CEST 2022


Commit: cda33345865a2705e0cbe24448865b2bdfc7ead6
Author: Campbell Barton
Date:   Wed Mar 9 14:15:57 2022 +1100
Branches: master
https://developer.blender.org/rBcda33345865a2705e0cbe24448865b2bdfc7ead6

Fix setting key shortcuts for insert keyframe menu items

It was not possible to assign a shortcut to menu items in the insert
key-frame menu going back to version 2.7x. Doing so would replace the
current key that opens the insert keyframe menu (I-key by default),
instead of binding a key to insert a key-frame for the keying-set
referenced by the menu item.

Now each menu item can be bound to a key or added to the "Quick
Favorites" menu, directly inserting a key-frame for the corresponding
keying-set.

Note that users must use the operator `anim.keyframe_insert_by_name`
when setting up key-shortcuts as `anim.keyframe_insert` is only intended
to launch the menu.

Keymap Editor:

When editing these key-map items in the key-map editor, the keying-set
identifier must be used. At the moment the key-map editor doesn't
support showing a drop-down list. The identifiers can be used from the
tool-tip or the info editor.

{F12994924}

Details:

Use `ANIM_OT_keyframe_insert_by_name` instead of
`ANIM_OT_keyframe_insert_menu` for the insert keyframe popup menu to
resolve the following issues binding keys to keying sets:

- The index of the keying set isn't stable (adding/removing keying sets
  may change it).
- Binding a key to items in the popup menu triggers a popup instead of
  inserting a key using the keying set from the menu item.

While support for using the current operator could be improved, it will
still only work for built-in keying sets, so I'd prefer to use an
operator that is intended for key-bindings.

Besides supporting binding keys to menu items there are no functional
changes.

Reviewed By: sybren

Ref D14289

===================================================================

M	source/blender/editors/animation/keyframing.c

===================================================================

diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 8d079641e9f..0d0d13e2f74 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1979,23 +1979,57 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UN
 {
   Scene *scene = CTX_data_scene(C);
 
-  /* if prompting or no active Keying Set, show the menu */
-  if ((scene->active_keyingset == 0) || RNA_boolean_get(op->ptr, "always_prompt")) {
-    uiPopupMenu *pup;
-    uiLayout *layout;
-
-    /* call the menu, which will call this operator again, hence the canceled */
-    pup = UI_popup_menu_begin(C, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
-    layout = UI_popup_menu_layout(pup);
-    uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
-    UI_popup_menu_end(C, pup);
+  /* When there is an active keying set and no request to prompt, keyframe immediately. */
+  if ((scene->active_keyingset != 0) && !RNA_boolean_get(op->ptr, "always_prompt")) {
+    /* Just call the exec() on the active keying-set. */
+    RNA_enum_set(op->ptr, "type", 0);
+    return op->type->exec(C, op);
+  }
+
+  /* Show a menu listing all keying-sets, the enum is expanded here to make use of the
+   * operator that accesses the keying-set by name. This is important for the ability
+   * to assign shortcuts to arbitrarily named keying sets. See T89560.
+   * These menu items perform the key-frame insertion (not this operator)
+   * hence the #OPERATOR_INTERFACE return. */
+  uiPopupMenu *pup = UI_popup_menu_begin(C, WM_operatortype_name(op->type, op->ptr), ICON_NONE);
+  uiLayout *layout = UI_popup_menu_layout(pup);
+
+  /* Even though `ANIM_OT_keyframe_insert_menu` can show a menu in one line,
+   * prefer `ANIM_OT_keyframe_insert_by_name` so users can bind keys to specific
+   * keying sets by name in the key-map instead of the index which isn't stable. */
+  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
+  const EnumPropertyItem *item_array = NULL;
+  int totitem;
+  bool free;
+
+  RNA_property_enum_items_gettexted(C, op->ptr, prop, &item_array, &totitem, &free);
+
+  for (int i = 0; i < totitem; i++) {
+    const EnumPropertyItem *item = &item_array[i];
+    if (item->identifier[0] != '\0') {
+      uiItemStringO(layout,
+                    item->name,
+                    item->icon,
+                    "ANIM_OT_keyframe_insert_by_name",
+                    "type",
+                    item->identifier);
+    }
+    else {
+      /* This enum shouldn't contain headings, assert there are none.
+       * NOTE: If in the future the enum includes them, additional layout code can be
+       * added to show them - although that doesn't seem likely. */
+      BLI_assert(item->name == NULL);
+      uiItemS(layout);
+    }
+  }
 
-    return OPERATOR_INTERFACE;
+  if (free) {
+    MEM_freeN((void *)item_array);
   }
 
-  /* just call the exec() on the active keyingset */
-  RNA_enum_set(op->ptr, "type", 0);
-  return op->type->exec(C, op);
+  UI_popup_menu_end(C, pup);
+
+  return OPERATOR_INTERFACE;
 }
 
 void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)



More information about the Bf-blender-cvs mailing list