diff options
author | Campbell Barton <campbell@blender.org> | 2022-03-09 06:15:57 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-04-11 14:10:05 +0300 |
commit | cda33345865a2705e0cbe24448865b2bdfc7ead6 (patch) | |
tree | 5d746dbd63154d768c6e32ba8dd9d89c35844776 /source/blender/editors/animation | |
parent | b2143da253edb7609bd7bb202e5b1d8fc5d99973 (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.c | 62 |
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) |