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:
authorCampbell Barton <campbell@blender.org>2022-03-09 06:15:57 +0300
committerCampbell Barton <campbell@blender.org>2022-04-11 14:10:05 +0300
commitcda33345865a2705e0cbe24448865b2bdfc7ead6 (patch)
tree5d746dbd63154d768c6e32ba8dd9d89c35844776 /source/blender/editors/animation
parentb2143da253edb7609bd7bb202e5b1d8fc5d99973 (diff)
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
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r--source/blender/editors/animation/keyframing.c62
1 files changed, 48 insertions, 14 deletions
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)