diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-10 12:27:32 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-10 12:47:43 +0300 |
commit | 1a12c9edab4ac89c8a87c20ad3a2195d0e681bc8 (patch) | |
tree | 1cd7e5771f4dd232fec39f678071836da8a1789e /source/blender | |
parent | 99f1e3d57fa1ee1f4400c299f1247ac5c614b6f0 (diff) |
Keyframing: add operators that use keying-set ID's
Unfortunately we can't use insert/delete_keyframe operators in keymaps
because the enums aren't known at the time of keymap registration
and the keying sets are dynamic and use a poll function.
Add a version of insert/delete operators that takes a string
instead of an enum. Needed for D4626.
Also extract int to keying-set into a utility function.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/animation/anim_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 151 | ||||
-rw-r--r-- | source/blender/editors/animation/keyingsets.c | 34 | ||||
-rw-r--r-- | source/blender/editors/include/ED_keyframing.h | 4 |
5 files changed, 164 insertions, 29 deletions
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index af1fd0e31c4..4661d19378a 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -38,6 +38,8 @@ extern ListBase builtin_keyingsets; */ void ANIM_OT_keyframe_insert(struct wmOperatorType *ot); void ANIM_OT_keyframe_delete(struct wmOperatorType *ot); +void ANIM_OT_keyframe_insert_by_name(struct wmOperatorType *ot); +void ANIM_OT_keyframe_delete_by_name(struct wmOperatorType *ot); /* Main Keyframe Management operators: * These handle keyframes management from various spaces. They will handle the menus diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index b4e60d29a40..2287f2e0347 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -505,6 +505,8 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_keyframe_insert_button); WM_operatortype_append(ANIM_OT_keyframe_delete_button); WM_operatortype_append(ANIM_OT_keyframe_clear_button); + WM_operatortype_append(ANIM_OT_keyframe_insert_by_name); + WM_operatortype_append(ANIM_OT_keyframe_delete_by_name); WM_operatortype_append(ANIM_OT_driver_button_add); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 4cea8ddbf74..a86538f3cec 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -80,6 +80,8 @@ #include "anim_intern.h" +static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op, PropertyRNA *prop, Scene *scene); + /* ************************************************** */ /* Keyframing Setting Wrangling */ @@ -1587,26 +1589,12 @@ static int insert_key_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); bool ob_edit_mode = false; - KeyingSet *ks = NULL; - int type = RNA_enum_get(op->ptr, "type"); + float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap short success; - /* type is the Keying Set the user specified to use when calling the operator: - * - type == 0: use scene's active Keying Set - * - type > 0: use a user-defined Keying Set from the active scene - * - type < 0: use a builtin Keying Set - */ - if (type == 0) - type = scene->active_keyingset; - if (type > 0) - ks = BLI_findlink(&scene->keyingsets, type - 1); - else - ks = BLI_findlink(&builtin_keyingsets, -type - 1); - - /* report failures */ + KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene); if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "No active keying set"); return OPERATOR_CANCELLED; } @@ -1677,6 +1665,36 @@ void ANIM_OT_keyframe_insert(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN); } +/* Clone of 'ANIM_OT_keyframe_insert' which uses a name for the keying set instead of an enum. */ +void ANIM_OT_keyframe_insert_by_name(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Insert Keyframe (by name)"; + ot->idname = "ANIM_OT_keyframe_insert_by_name"; + ot->description = "Alternate access to 'Insert Keyframe' for keymaps to use"; + + /* callbacks */ + ot->exec = insert_key_exec; + ot->poll = modify_key_op_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* keyingset to use (idname) */ + prop = RNA_def_string_file_path(ot->srna, "type", "Type", MAX_ID_NAME - 2, "", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + ot->prop = prop; + + /* confirm whether a keyframe was added by showing a popup + * - by default, this is enabled, since this operator is assumed to be called independently + */ + prop = RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Insert", + "Show a popup when the keyframes get successfully added"); + RNA_def_property_flag(prop, PROP_HIDDEN); +} + /* Insert Key Operator (With Menu) ------------------------ */ /* This operator checks if a menu should be shown for choosing the KeyingSet to use, * then calls the menu if necessary before @@ -1752,22 +1770,36 @@ void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot) static int delete_key_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - KeyingSet *ks = NULL; - int type = RNA_enum_get(op->ptr, "type"); float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap short success; - /* type is the Keying Set the user specified to use when calling the operator: - * - type == 0: use scene's active Keying Set - * - type > 0: use a user-defined Keying Set from the active scene - * - type < 0: use a builtin Keying Set - */ - if (type == 0) - type = scene->active_keyingset; - if (type > 0) - ks = BLI_findlink(&scene->keyingsets, type - 1); - else - ks = BLI_findlink(&builtin_keyingsets, -type - 1); + KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene); + if (ks == NULL) { + return OPERATOR_CANCELLED; + } + + const int prop_type = RNA_property_type(op->type->prop); + if (prop_type == PROP_ENUM) { + int type = RNA_property_enum_get(op->ptr, op->type->prop); + ks = ANIM_keyingset_get_from_enum_type(scene, type); + if (ks == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active keying set"); + return OPERATOR_CANCELLED; + } + } + else if (prop_type == PROP_STRING) { + char type_id[MAX_ID_NAME - 2]; + RNA_property_string_get(op->ptr, op->type->prop, type_id); + ks = ANIM_keyingset_get_from_idname(scene, type_id); + + if (ks == NULL) { + BKE_reportf(op->reports, RPT_ERROR, "No active keying set '%s' not found", type_id); + return OPERATOR_CANCELLED; + } + } + else { + BLI_assert(0); + } /* report failure */ if (ks == NULL) { @@ -1828,6 +1860,34 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot) "Show a popup when the keyframes get successfully removed"); } +void ANIM_OT_keyframe_delete_by_name(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Delete Keying-Set Keyframe (by name)"; + ot->idname = "ANIM_OT_keyframe_delete_by_name"; + ot->description = "Alternate access to 'Delete Keyframe' for keymaps to use"; + + /* callbacks */ + ot->exec = delete_key_exec; + ot->poll = modify_key_op_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* keyingset to use (idname) */ + prop = RNA_def_string_file_path(ot->srna, "type", "Type", MAX_ID_NAME - 2, "", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + ot->prop = prop; + + /* confirm whether a keyframe was added by showing a popup + * - by default, this is enabled, since this operator is assumed to be called independently + */ + RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Delete", + "Show a popup when the keyframes get successfully removed"); +} + /* Delete Key Operator ------------------------ */ /* NOTE: Although this version is simpler than the more generic version for KeyingSets, * it is more useful for animators working in the 3D view. @@ -2597,3 +2657,36 @@ bool ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel * return false; } } + +/* -------------------------------------------------------------------- */ +/** \name Internal Utilities + * \{ */ + +/** Use for insert/delete key-frame. */ +static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op, PropertyRNA *prop, Scene *scene) +{ + KeyingSet *ks = NULL; + const int prop_type = RNA_property_type(prop); + if (prop_type == PROP_ENUM) { + int type = RNA_property_enum_get(op->ptr, prop); + ks = ANIM_keyingset_get_from_enum_type(scene, type); + if (ks == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active keying set"); + } + } + else if (prop_type == PROP_STRING) { + char type_id[MAX_ID_NAME - 2]; + RNA_property_string_get(op->ptr, prop, type_id); + ks = ANIM_keyingset_get_from_idname(scene, type_id); + + if (ks == NULL) { + BKE_reportf(op->reports, RPT_ERROR, "Keying set '%s' not found", type_id); + } + } + else { + BLI_assert(0); + } + return ks; +} + +/** \} */ diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index d532e22e7f7..654543c9d5d 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -784,6 +784,40 @@ const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNU return item; } +/** + * Get the keying set from enum values generated in #ANIM_keying_sets_enum_itemf. + * + * Type is the Keying Set the user specified to use when calling the operator: + * - type == 0: use scene's active Keying Set + * - type > 0: use a user-defined Keying Set from the active scene + * - type < 0: use a builtin Keying Set + */ +KeyingSet *ANIM_keyingset_get_from_enum_type(Scene *scene, int type) +{ + KeyingSet *ks = NULL; + + if (type == 0) { + type = scene->active_keyingset; + } + + if (type > 0) { + ks = BLI_findlink(&scene->keyingsets, type - 1); + } + else { + ks = BLI_findlink(&builtin_keyingsets, -type - 1); + } + return ks; +} + +KeyingSet *ANIM_keyingset_get_from_idname(Scene *scene, const char *idname) +{ + KeyingSet *ks = BLI_findstring(&scene->keyingsets, idname, offsetof(KeyingSet, idname)); + if (ks == NULL) { + ks = BLI_findstring(&builtin_keyingsets, idname, offsetof(KeyingSet, idname)); + } + return ks; +} + /* ******************************************* */ /* KEYFRAME MODIFICATION */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 78a9f13e64f..51dfa3c7dff 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -229,6 +229,10 @@ struct KeyingSet *ANIM_get_keyingset_for_autokeying(struct Scene *scene, const c /* Dynamically populate an enum of Keying Sets */ const struct EnumPropertyItem *ANIM_keying_sets_enum_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free); +/* Use to get the keying set from the int value used by enums. */ +KeyingSet *ANIM_keyingset_get_from_enum_type(struct Scene *scene, int type); +KeyingSet *ANIM_keyingset_get_from_idname(struct Scene *scene, const char *idname); + /* Check if KeyingSet can be used in the current context */ bool ANIM_keyingset_context_ok_poll(struct bContext *C, struct KeyingSet *ks); |