diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-04-01 02:36:13 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-04-01 02:36:13 +0400 |
commit | 3a28a7450596f46281431bd163b9a237eb481055 (patch) | |
tree | 54268464f1adc33111b7bb3afde1ce1c64bf5897 /source/blender | |
parent | 4861ddf350e776c09f319d6db7fb96634d952da6 (diff) |
Animato - Support for 'BuiltIn' and 'Relative' Keying Sets
When inserting keyframes in the 3D-View (support will be extended to other editors in due course) using the IKEY hotkey, the menu which appears will now consist of 3 parts:
* 'Active Keying Set' - this option allows you to use the user-defined KeyingSet which is active for the current scene (i.e. the one seen in the TimeLine/Outliner headers)
* User defined Keying Sets - a list of all such available KeyingSets is included, and entries can be chosen from there
* Built-In Keying Sets - see later...
To achieve this, several changes needed to be made first:
* Added support for 'relative' in addition to 'absolute' Keying Sets. Relative Keying Sets are Keying Sets which operate on data from the current context (i.e. a 'location' KeyingSet will add location keyframes for selected objects/bones/nodes as opposed to location keyframes for some particular object). The is a tentative 'templates' requirement system here, which still needs to be fully fleshed out.
* Added support for builtin Keying Sets (i.e. 'Location', 'Rotation', 'Scaling', and 'LocRot' as a few initial demonstrations), which replaces the temporary Insert Keyframe operator for the 3D-View (IKEY). These are effectively relative Keying Set definitions which are included in Blender by default and stored in a list separate from user-defined ones. Volunteer help in defining a few more of these for other editors will be welcome soon.
* Removed/replaced much of the crappy temporary Keyframing operator code, though a few tweaks could still be done.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_constraint.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 24 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 11 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_ops.c | 5 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 941 | ||||
-rw-r--r-- | source/blender/editors/include/ED_keyframing.h | 10 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 3 |
11 files changed, 560 insertions, 448 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 0d8c81a5a75..6e69906b71d 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -110,11 +110,13 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type); /* Constraint function prototypes */ void unique_constraint_name(struct bConstraint *con, struct ListBase *list); -void free_constraints(struct ListBase *conlist); +void free_constraints(struct ListBase *list); void copy_constraints(struct ListBase *dst, struct ListBase *src); void relink_constraints(struct ListBase *list); void free_constraint_data(struct bConstraint *con); +struct bConstraint *constraints_get_active(struct ListBase *list); + /* Constraints + Proxies function prototypes */ void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src); short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 0097b30b685..ee72c374b5a 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -4,6 +4,7 @@ #include <stdio.h> #include <string.h> +#include <stddef.h> #include "MEM_guardedalloc.h" @@ -238,6 +239,9 @@ KeyingSet *BKE_keyingset_add (ListBase *list, const char name[], short flag, sho /* add KeyingSet to list */ BLI_addtail(list, ks); + /* make sure KeyingSet has a unique name (this helps with identification) */ + BLI_uniquename(list, ks, "Keying Set", offsetof(KeyingSet, name), 64); + /* return new KeyingSet for further editing */ return ks; } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b238116f0a1..ed8562847a9 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3203,17 +3203,16 @@ void free_constraint_data (bConstraint *con) } /* Free all constraints from a constraint-stack */ -void free_constraints (ListBase *conlist) +void free_constraints (ListBase *list) { bConstraint *con; /* Free constraint data and also any extra data */ - for (con= conlist->first; con; con= con->next) { + for (con= list->first; con; con= con->next) free_constraint_data(con); - } /* Free the whole list */ - BLI_freelistN(conlist); + BLI_freelistN(list); } /* Reassign links that constraints have to other data (called during file loading?) */ @@ -3266,6 +3265,23 @@ void copy_constraints (ListBase *dst, ListBase *src) } } +/* finds the 'active' constraint in a constraint stack */ +bConstraint *constraints_get_active (ListBase *list) +{ + bConstraint *con; + + /* search for the first constraint with the 'active' flag set */ + if (list) { + for (con= list->first; con; con= con->next) { + if (con->flag & CONSTRAINT_ACTIVE) + return con; + } + } + + /* no active constraint found */ + return NULL; +} + /* -------- Constraints and Proxies ------- */ /* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 2dfa1db171f..3fa9457d86e 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -177,7 +177,7 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo float xminv=999999999.0f, xmaxv=-999999999.0f; float yminv=999999999.0f, ymaxv=-999999999.0f; short foundvert=0; - int i; + unsigned int i; if (fcu->totvert) { if (fcu->bezt) { @@ -418,7 +418,7 @@ void calchandles_fcurve (FCurve *fcu) void testhandles_fcurve (FCurve *fcu) { BezTriple *bezt; - int a; + unsigned int a; /* only beztriples have handles (bpoints don't though) */ if ELEM(NULL, fcu, fcu->bezt) @@ -475,7 +475,7 @@ void sort_time_fcurve (FCurve *fcu) /* currently, will only be needed when there are beztriples */ if (fcu->bezt) { BezTriple *bezt; - int a; + unsigned int a; /* loop over ALL points to adjust position in array and recalculate handles */ for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) { @@ -509,7 +509,7 @@ void sort_time_fcurve (FCurve *fcu) /* This function tests if any BezTriples are out of order, thus requiring a sort */ short test_time_fcurve (FCurve *fcu) { - int a; + unsigned int a; /* sanity checks */ if (fcu == NULL) @@ -895,7 +895,8 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim { BezTriple *bezt, *prevbezt, *lastbezt; float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac; - int a, b; + unsigned int a; + int b; float cvalue = 0.0f; /* get pointers */ diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index f8c7cc909ae..15a4babf90a 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -380,8 +380,9 @@ void ED_operatortypes_anim(void) // XXX this is used all over... maybe for screen instead? WM_operatortype_append(ANIM_OT_insert_keyframe); WM_operatortype_append(ANIM_OT_delete_keyframe); - WM_operatortype_append(ANIM_OT_insert_keyframe_old); - WM_operatortype_append(ANIM_OT_delete_keyframe_old); + WM_operatortype_append(ANIM_OT_insert_keyframe_menu); + //WM_operatortype_append(ANIM_OT_delete_keyframe_menu); + WM_operatortype_append(ANIM_OT_delete_keyframe_old); // xxx remove? WM_operatortype_append(ANIM_OT_keyingset_add_new); WM_operatortype_append(ANIM_OT_keyingset_add_destination); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index b04eaa0c378..0206de12c82 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -61,10 +61,10 @@ typedef struct bCommonKeySrc { /* general data/destination-source settings */ ID *id; /* id-block this comes from */ - char *rna_path; /* base path to use */ // xxx.... maybe we don't need this? /* specific cases */ - bPoseChannel *pchan; /* only needed when doing recalcs... */ + bPoseChannel *pchan; + bConstraint *con; } bCommonKeySrc; /* ******************************************* */ @@ -867,7 +867,7 @@ short deletekey (ID *id, const char group[], const char rna_path[], int array_in } /* ******************************************* */ -/* KEYINGSETS */ +/* KEYING SETS - EDITING API */ /* Operators ------------------------------------------- */ @@ -1042,15 +1042,8 @@ char *ANIM_build_keyingsets_menu (ListBase *list, short for_edit) } - /* ******************************************* */ -/* KEYFRAME MODIFICATION */ - -/* mode for commonkey_modifykey */ -enum { - COMMONKEY_MODE_INSERT = 0, - COMMONKEY_MODE_DELETE, -} eCommonModifyKey_Modes; +/* KEYING SETS - BUILTIN */ #if 0 // XXX old keyingsets code based on adrcodes... to be restored in due course @@ -1570,229 +1563,319 @@ typedef enum eKS_Contexts { } eKS_Contexts; -/* ---------------- KeyingSet Tools ------------------- */ +#endif // XXX old keyingsets code based on adrcodes... to be restored in due course + +/* Macros for Declaring KeyingSets ------------------- */ + +/* A note about this system for declaring built-in Keying Sets: + * One may ask, "What is the purpose of all of these macros and static arrays?" and + * "Why not call the KeyingSets API defined in BKE_animsys.h?". The answer is two-fold. + * + * 1) Firstly, we use static arrays of struct definitions instead of function calls, as + * it reduces the start-up overhead and allocated-memory footprint of Blender. If we called + * the KeyingSets API to build these sets, the overhead of checking for unique names, allocating + * memory for each and every path and KeyingSet, scattered around in RAM, all of which would increase + * the startup time (which is totally unacceptable) and could lead to fragmentation+slower access times. + * 2) Since we aren't using function calls, we need a nice way of defining these KeyingSets in a way which + * is easily readable and less prone to breakage from changes to the underlying struct definitions. Further, + * adding additional entries SHOULD NOT require custom code to be written to access these new entries/sets. + * Therefore, here we have a system with nice, human-readable statements via macros, and static arrays which + * are linked together using more special macros + struct definitions, allowing for such a generic + simple + * initialisation function (init_builtin_keyingsets()) compared with that of something like the Nodes system. + */ + +/* Struct type for declaring builtin KeyingSets in as entries in static arrays*/ +typedef struct bBuiltinKeyingSet { + KeyingSet ks; /* the KeyingSet to build */ + int tot; /* the total number of paths defined */ + KS_Path paths[64]; /* the paths for the KeyingSet to use */ +} bBuiltinKeyingSet; + + /* WARNING: the following macros must be kept in sync with the + * struct definitions in DNA_anim_types.h! + */ + +/* macro for defining a builtin KeyingSet */ +#define BI_KS_DEFINE(name, keyingflag) \ + {NULL, NULL, {NULL, NULL}, name, KEYINGSET_BUILTIN, keyingflag} + +/* macro to start defining paths for a builtin KeyingSet */ +#define BI_KS_PATHS_BEGIN(tot) \ + tot, { + +/* macro to finish defining paths for a builtin KeyingSet */ +#define BI_KS_PATHS_END \ + } + +/* macro for defining a builtin KeyingSet's path */ +#define BI_KSP_DEFINE(id_type, templates, prop_path, array_index, flag, groupflag) \ + {NULL, NULL, NULL, "", id_type, templates, prop_path, array_index, flag, groupflag} + +/* ---- */ + +/* Struct type for finding all the arrays of builtin KeyingSets */ +typedef struct bBuiltinKSContext { + bBuiltinKeyingSet *bks; /* array of KeyingSet definitions */ + int tot; /* number of KeyingSets in this array */ +} bBuiltinKSContext; + +/* macro for defining builtin KeyingSet sets + * NOTE: all the arrays of sets must follow this naming convention! + */ +#define BKSC_TEMPLATE(ctx_name) {&def_builtin_keyingsets_##ctx_name[0], sizeof(def_builtin_keyingsets_##ctx_name)/sizeof(bBuiltinKeyingSet)} + + +/* 3D-View Builtin KeyingSets ------------------------ */ -/* helper for commonkey_context_get() - get keyingsets for 3d-view */ -static void commonkey_context_getv3d (const bContext *C, ListBase *sources, bKeyingContext **ksc) +static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] = { - Scene *scene= CTX_data_scene(C); - Object *ob; - IpoCurve *icu; + /* Simple Keying Sets ************************************* */ + /* Keying Set - "Location" ---------- */ + { + /* KeyingSet Definition */ + BI_KS_DEFINE("Location", 0), + + /* Path Definitions */ + BI_KS_PATHS_BEGIN(1) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME) + BI_KS_PATHS_END + }, + + /* Keying Set - "Rotation" ---------- */ + { + /* KeyingSet Definition */ + BI_KS_DEFINE("Rotation", 0), + + /* Path Definitions */ + BI_KS_PATHS_BEGIN(1) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME) + BI_KS_PATHS_END + }, - if ((OBACT) && (OBACT->flag & OB_POSEMODE)) { - bPoseChannel *pchan; + /* Keying Set - "Scaling" ---------- */ + { + /* KeyingSet Definition */ + BI_KS_DEFINE("Scaling", 0), - /* pose-level */ - ob= OBACT; - *ksc= &ks_contexts[KSC_V3D_PCHAN]; - // XXX - //set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */ + /* Path Definitions */ + BI_KS_PATHS_BEGIN(1) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scaling", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME) + BI_KS_PATHS_END + }, + + /* Compound Keying Sets *********************************** */ + /* Keying Set - "LocRot" ---------- */ + { + /* KeyingSet Definition */ + BI_KS_DEFINE("LocRot", 0), - /* loop through posechannels */ - for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { - if (pchan->flag & POSE_KEY) { - bCommonKeySrc *cks; - - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); - - /* set id-block to key to, and action */ - cks->id= (ID *)ob; - cks->act= ob->action; - - /* set pchan */ - cks->pchan= pchan; - cks->actname= pchan->name; - } - } + /* Path Definitions */ + BI_KS_PATHS_BEGIN(2) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME), + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME) + BI_KS_PATHS_END } - else { - /* object-level */ - *ksc= &ks_contexts[KSC_V3D_OBJECT]; - - /* loop through bases */ - // XXX but we're only supposed to do this on editable ones, not just selected ones! - CTX_DATA_BEGIN(C, Base*, base, selected_bases) { - bCommonKeySrc *cks; - - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); +}; + +/* All Builtin KeyingSets ------------------------ */ + +/* total number of builtin KeyingSet contexts */ +#define MAX_BKSC_TYPES 1 + +/* array containing all the available builtin KeyingSets definition sets + * - size of this is MAX_BKSC_TYPES+1 so that we don't smash the stack + */ +static bBuiltinKSContext def_builtin_keyingsets[MAX_BKSC_TYPES+1] = +{ + BKSC_TEMPLATE(v3d) + /* add more contexts above this line... */ +}; + + +/* ListBase of these KeyingSets chained up ready for usage */ +static ListBase builtin_keyingsets = {NULL, NULL}; + +/* Utility API ------------------------ */ + +/* Link up all of the builtin Keying Sets when starting up Blender + * This is called from WM_init() in wm_init_exit.c + */ +void init_builtin_keyingsets (void) +{ + bBuiltinKSContext *bksc; + bBuiltinKeyingSet *bks; + int bksc_i, bks_i; + + /* loop over all the sets of KeyingSets, setting them up, and chaining them to the builtins list */ + for (bksc_i= 0, bksc= &def_builtin_keyingsets[0]; bksc_i < MAX_BKSC_TYPES; bksc_i++, bksc++) + { + /* for each set definitions for a builtin KeyingSet, chain the paths to that KeyingSet and add */ + for (bks_i= 0, bks= bksc->bks; bks_i < bksc->tot; bks_i++, bks++) + { + KeyingSet *ks= &bks->ks; + KS_Path *ksp; + int pIndex; - /* set id-block to key to */ - ob= base->object; - cks->id= (ID *)ob; + /* loop over paths, linking them to the KeyingSet and each other */ + for (pIndex= 0, ksp= &bks->paths[0]; pIndex < bks->tot; pIndex++, ksp++) + BLI_addtail(&ks->paths, ksp); + + /* add KeyingSet to builtin sets list */ + BLI_addtail(&builtin_keyingsets, ks); } - CTX_DATA_END; } } -/* helper for commonkey_context_get() - get keyingsets for buttons window */ -static void commonkey_context_getsbuts (const bContext *C, ListBase *sources, bKeyingContext **ksc) +/* ******************************************* */ +/* KEYFRAME MODIFICATION */ + +/* mode for commonkey_modifykey */ +enum { + COMMONKEY_MODE_INSERT = 0, + COMMONKEY_MODE_DELETE, +} eCommonModifyKey_Modes; + +/* KeyingSet Menu Helpers ------------ */ + +/* Extract the maximum set of requirements from the KeyingSet */ +static int keyingset_relative_get_templates (KeyingSet *ks) { -#if 0 // XXX dunno what's the future of this stuff... - bCommonKeySrc *cks; + KS_Path *ksp; + int templates= 0; - /* check on tab-type */ - switch (G.buts->mainb) { - case CONTEXT_SHADING: /* ------------- Shading buttons ---------------- */ - /* subtabs include "Material", "Texture", "Lamp", "World"*/ - switch (G.buts->tab[CONTEXT_SHADING]) { - case TAB_SHADING_MAT: /* >------------- Material Tab -------------< */ - { - Material *ma= editnode_get_active_material(G.buts->lockpoin); - - if (ma) { - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); - - /* set data */ - cks->id= (ID *)ma; - cks->ipo= ma->ipo; - cks->map= texchannel_to_adrcode(ma->texact); - - /* set keyingsets */ - *ksc= &ks_contexts[KSC_BUTS_MAT]; - return; - } - } - break; - case TAB_SHADING_WORLD: /* >------------- World Tab -------------< */ - { - World *wo= G.buts->lockpoin; - - if (wo) { - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); - - /* set data */ - cks->id= (ID *)wo; - cks->ipo= wo->ipo; - cks->map= texchannel_to_adrcode(wo->texact); - - /* set keyingsets */ - *ksc= &ks_contexts[KSC_BUTS_WO]; - return; - } - } - break; - case TAB_SHADING_LAMP: /* >------------- Lamp Tab -------------< */ - { - Lamp *la= G.buts->lockpoin; - - if (la) { - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); - - /* set data */ - cks->id= (ID *)la; - cks->ipo= la->ipo; - cks->map= texchannel_to_adrcode(la->texact); - - /* set keyingsets */ - *ksc= &ks_contexts[KSC_BUTS_LA]; - return; - } - } - break; - case TAB_SHADING_TEX: /* >------------- Texture Tab -------------< */ - { - Tex *tex= G.buts->lockpoin; - - if (tex) { - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); - - /* set data */ - cks->id= (ID *)tex; - cks->ipo= tex->ipo; - - /* set keyingsets */ - *ksc= &ks_contexts[KSC_BUTS_TEX]; - return; - } - } - break; - } - break; + /* loop over the paths (could be slow to do for a number of KeyingSets)? */ + for (ksp= ks->paths.first; ksp; ksp= ksp->next) { + /* add the destination's templates to the set of templates required for the set */ + templates |= ksp->templates; + } - case CONTEXT_OBJECT: /* ------------- Object buttons ---------------- */ - { - Object *ob= OBACT; - - if (ob) { - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); - - /* set id-block to key to */ - cks->id= (ID *)ob; - cks->ipo= ob->ipo; - - /* set keyingsets */ - *ksc= &ks_contexts[KSC_BUTS_OB]; - return; - } - } - break; + return templates; +} + +/* Check if context data is suitable for the given absolute Keying Set */ +static short keyingset_context_ok_poll (bContext *C, KeyingSet *ks) +{ + ScrArea *sa= CTX_wm_area(C); - case CONTEXT_EDITING: /* ------------- Editing buttons ---------------- */ + /* data retrieved from context depends on active editor */ + if (sa == NULL) return 0; + + switch (sa->spacetype) { + case SPACE_VIEW3D: { - Object *ob= OBACT; + Object *obact= CTX_data_active_object(C); - if ((ob) && (ob->type==OB_CAMERA) && (G.buts->lockpoin)) { /* >---------------- camera buttons ---------------< */ - Camera *ca= G.buts->lockpoin; + /* if in posemode, check if 'pose-channels' requested for in KeyingSet */ + if ((obact && obact->pose) && (obact->flag & OB_POSEMODE)) { + /* check for posechannels */ - /* add new keyframing destination */ - cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); - BLI_addtail(sources, cks); - - /* set id-block to key to */ - cks->id= (ID *)ca; - cks->ipo= ca->ipo; + } + else { + /* check for selected object */ - /* set keyingsets */ - *ksc= &ks_contexts[KSC_BUTS_CAM]; - return; } } - break; + break; } -#endif // XXX end of buttons stuff to port... - /* if nothing happened... */ - *ksc= NULL; + + return 1; } -#endif // XXX old keyingsets code based on adrcodes... to be restored in due course - -#if 0 // XXX new relative keyingsets code +/* KeyingSet Context Operations ------------ */ -/* Check if context data is suitable for the given absolute Keying Set */ -static short keyingset_context_ok_poll (bContext *C, KeyingSet *ks) +/* Get list of data-sources from context (in 3D-View) for inserting keyframes using the given relative Keying Set */ +static short commonkey_get_context_v3d_data (bContext *C, ListBase *dsources, KeyingSet *ks) { + bCommonKeySrc *cks; + Object *obact= CTX_data_active_object(C); + int templates; + short ok= 0; + + /* get the templates in use in this KeyingSet which we should supply data for */ + templates = keyingset_relative_get_templates(ks); + + /* check if the active object is in PoseMode (i.e. only deal with bones) */ + // TODO: check with the templates to see what we really need to store + if ((obact && obact->pose) && (obact->flag & OB_POSEMODE)) { + /* Pose Mode: Selected bones */ +#if 0 + //set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */ + + /* loop through posechannels */ + //for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { + // if (pchan->flag & POSE_KEY) { + // } + //} +#endif + + CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) + { + /* add a new keying-source */ + cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); + BLI_addtail(dsources, cks); + + /* set necessary info */ + cks->id= &obact->id; + cks->pchan= pchan; + + if (templates & KSP_TEMPLATE_CONSTRAINT) + cks->con= constraints_get_active(&pchan->constraints); + + ok= 1; + } + CTX_DATA_END; + } + else { + /* Object Mode: Selected objects */ + CTX_DATA_BEGIN(C, Base*, base, selected_bases) + { + Object *ob= base->object; + + /* add a new keying-source */ + cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc"); + BLI_addtail(dsources, cks); + + /* set necessary info */ + cks->id= &ob->id; + + if (templates & KSP_TEMPLATE_CONSTRAINT) + cks->con= constraints_get_active(&ob->constraints); + + ok= 1; + } + CTX_DATA_END; + } - return 1; + /* return whether any data was extracted */ + return ok; } /* Get list of data-sources from context for inserting keyframes using the given relative Keying Set */ static short commonkey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks) { + ScrArea *sa= CTX_wm_area(C); + /* for now, the active area is used to determine what set of contexts apply */ + if (sa == NULL) + return 0; + + switch (sa->spacetype) { + case SPACE_VIEW3D: /* 3D-View: Selected Objects or Bones */ + return commonkey_get_context_v3d_data(C, dsources, ks); + } + + /* nothing happened */ + return 0; } -#endif // XXX new relative keyingsets code +/* KeyingSet Operations (Insert/Delete Keyframes) ------------ */ /* Given a KeyingSet and context info (if required), modify keyframes for the channels specified * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets. * Returns the number of channels that keyframes were added to */ -static int commonkey_modifykey (ListBase *dsources, KeyingSet *ks, short mode, float cfra) +static int commonkey_modifykey (bContext *C, ListBase *dsources, KeyingSet *ks, short mode, float cfra) { KS_Path *ksp; int kflag=0, success= 0; @@ -1851,26 +1934,125 @@ static int commonkey_modifykey (ListBase *dsources, KeyingSet *ks, short mode, f if (mode == COMMONKEY_MODE_INSERT) success+= insertkey(ksp->id, groupname, ksp->rna_path, i, cfra, kflag); else if (mode == COMMONKEY_MODE_DELETE) - success+= deletekey(ksp->id, groupname, ksp->rna_path, i, cfra, kflag); + success+= deletekey(ksp->id, groupname, ksp->rna_path, i, cfra, kflag); } - // TODO: set recalc tags on the ID? + /* send notifiers and set recalc-flags */ + // TODO: hopefully this doesn't result in execessive flooding of the notifier stack + if (C && ksp->id) { + switch (GS(ksp->id->name)) { + case ID_OB: /* Object (or Object-Related) Keyframes */ + { + Object *ob= (Object *)ksp->id; + + ob->recalc |= OB_RECALC; + WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, ksp->id); + } + break; + case ID_MA: /* Material Keyframes */ + WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, ksp->id); + break; + } + } } } -#if 0 // XXX still need to figure out how to get such keyingsets working - else if (dsources) { + else if (dsources && dsources->first) { /* for each one of the 'sources', resolve the template markers and expand arrays, then insert keyframes */ bCommonKeySrc *cks; - char *path = NULL; - int index=0, tot=0; /* for each 'source' for keyframe data, resolve each of the paths from the KeyingSet */ for (cks= dsources->first; cks; cks= cks->next) { + /* for each path in KeyingSet, construct a path using the templates */ + for (ksp= ks->paths.first; ksp; ksp= ksp->next) { + DynStr *pathds= BLI_dynstr_new(); + char *path = NULL; + int arraylen, i; + + /* construct the path */ + // FIXME: this currently only works with a few hardcoded cases + if ((ksp->templates & KSP_TEMPLATE_PCHAN) && (cks->pchan)) { + /* add basic pose-channel path access */ + BLI_dynstr_append(pathds, "pose.pose_channels[\""); + BLI_dynstr_append(pathds, cks->pchan->name); + BLI_dynstr_append(pathds, "\"]"); + } + if ((ksp->templates & KSP_TEMPLATE_CONSTRAINT) && (cks->con)) { + /* add basic constraint path access */ + BLI_dynstr_append(pathds, "constraints[\""); + BLI_dynstr_append(pathds, cks->con->name); + BLI_dynstr_append(pathds, "\"]"); + } + { + /* add property stored in KeyingSet Path */ + if (BLI_dynstr_get_len(pathds)) + BLI_dynstr_append(pathds, "."); + BLI_dynstr_append(pathds, ksp->rna_path); + + /* convert to C-string */ + path= BLI_dynstr_get_cstring(pathds); + BLI_dynstr_free(pathds); + } + + /* get pointer to name of group to add channels to */ + if (ksp->groupmode == KSP_GROUP_NONE) + groupname= NULL; + else if (ksp->groupmode == KSP_GROUP_KSNAME) + groupname= ks->name; + else + groupname= ksp->group; + + /* init arraylen and i - arraylen should be greater than i so that + * normal non-array entries get keyframed correctly + */ + i= ksp->array_index; + arraylen= i+1; + + /* get length of array if whole array option is enabled */ + if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) { + PointerRNA id_ptr, ptr; + PropertyRNA *prop; + + RNA_id_pointer_create(cks->id, &id_ptr); + if (RNA_path_resolve(&id_ptr, path, &ptr, &prop) && prop) + arraylen= RNA_property_array_length(&ptr, prop); + } + + /* for each possible index, perform operation + * - assume that arraylen is greater than index + */ + for (; i < arraylen; i++) { + /* action to take depends on mode */ + if (mode == COMMONKEY_MODE_INSERT) + success+= insertkey(cks->id, groupname, path, i, cfra, kflag); + else if (mode == COMMONKEY_MODE_DELETE) + success+= deletekey(cks->id, groupname, path, i, cfra, kflag); + } + + /* free the path */ + MEM_freeN(path); + } + /* send notifiers and set recalc-flags */ + // TODO: hopefully this doesn't result in execessive flooding of the notifier stack + if (C && cks->id) { + switch (GS(cks->id->name)) { + case ID_OB: /* Object (or Object-Related) Keyframes */ + { + Object *ob= (Object *)cks->id; + + ob->recalc |= OB_RECALC; + WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, cks->id); + } + break; + case ID_MA: /* Material Keyframes */ + WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, cks->id); + break; + } + } } } -#endif // XXX still need to figure out how to get such + /* return the number of channels successfully affected */ return success; } @@ -1904,38 +2086,56 @@ static int modify_key_op_poll(bContext *C) /* Insert Key Operator ------------------------ */ -/* NOTE: - * This is one of the 'simpler new-style' Insert Keyframe operators which relies on Keying Sets. - * For now, these are absolute Keying Sets only, so there is very little context info involved. - * - * -- Joshua Leung, Feb 2009 - */ - static int insert_key_exec (bContext *C, wmOperator *op) { ListBase dsources = {NULL, NULL}; Scene *scene= CTX_data_scene(C); KeyingSet *ks= NULL; + int type= RNA_int_get(op->ptr, "type"); float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap short success; - /* try to get KeyingSet */ - if (scene->active_keyingset > 0) + /* 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, scene->active_keyingset-1); - /* report failure */ + else + ks= BLI_findlink(&builtin_keyingsets, -type-1); + + /* report failures */ if (ks == NULL) { BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); return OPERATOR_CANCELLED; } + /* get context info for relative Keying Sets */ + if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) { + /* exit if no suitable data obtained */ + if (commonkey_get_context_data(C, &dsources, ks) == 0) { + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + return OPERATOR_CANCELLED; + } + } + /* try to insert keyframes for the channels specified by KeyingSet */ - success= commonkey_modifykey(&dsources, ks, COMMONKEY_MODE_INSERT, cfra); + success= commonkey_modifykey(C, &dsources, ks, COMMONKEY_MODE_INSERT, cfra); printf("KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success); /* report failure? */ if (success == 0) BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes"); + /* free temp context-data if available */ + if (dsources.first) { + /* we assume that there is no extra data that needs to be freed from here... */ + BLI_freelistN(&dsources); + } + /* send updates */ ED_anim_dag_flush_update(C); @@ -1957,42 +2157,126 @@ void ANIM_OT_insert_keyframe (wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* settings */ + RNA_def_boolean(ot->srna, "builtin", 0, "Built-In Keying Set", "Use one of the relative Keying Sets defined by default"); } -/* Delete Key Operator ------------------------ */ +/* Insert Key Operator (With Menu) ------------------------ */ -/* NOTE: - * This is one of the 'simpler new-style' Insert Keyframe operators which relies on Keying Sets. - * For now, these are absolute Keying Sets only, so there is very little context info involved. - * - * -- Joshua Leung, Feb 2009 +/* XXX + * This operator pops up a menu which sets gets the index of the keyingset to use, + * setting the global settings, and calling the insert-keyframe operator using these + * settings */ + +static int insert_key_menu_invoke (bContext *C, wmOperator *op, wmEvent *event) +{ + Scene *scene= CTX_data_scene(C); + KeyingSet *ks; + uiMenuItem *head; + int i = 0; + + head= uiPupMenuBegin("Insert Keyframe", 0); + + /* active Keying Set */ + uiMenuItemIntO(head, "Active Keying Set", 0, "ANIM_OT_insert_keyframe_menu", "type", i++); + uiMenuSeparator(head); + + /* user-defined Keying Sets + * - these are listed in the order in which they were defined for the active scene + */ + for (ks= scene->keyingsets.first; ks; ks= ks->next) + uiMenuItemIntO(head, ks->name, 0, "ANIM_OT_insert_keyframe_menu", "type", i++); + uiMenuSeparator(head); + + /* builtin Keying Sets */ + // XXX polling the entire list may lag + i= -1; + for (ks= builtin_keyingsets.first; ks; ks= ks->next) { + /* only show KeyingSet if context is suitable */ + if (keyingset_context_ok_poll(C, ks)) { + uiMenuItemIntO(head, ks->name, 0, "ANIM_OT_insert_keyframe_menu", "type", i--); + } + } + + uiPupMenuEnd(C, head); + + return OPERATOR_CANCELLED; +} +void ANIM_OT_insert_keyframe_menu (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Insert Keyframe"; + ot->idname= "ANIM_OT_insert_keyframe_menu"; + + /* callbacks */ + ot->invoke= insert_key_menu_invoke; + ot->exec= insert_key_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties + * - NOTE: here the type is int not enum, since many of the indicies here are determined dynamically + */ + RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1); +} + +/* Delete Key Operator ------------------------ */ + static int delete_key_exec (bContext *C, wmOperator *op) { ListBase dsources = {NULL, NULL}; Scene *scene= CTX_data_scene(C); - KeyingSet *ks= NULL; + KeyingSet *ks= NULL; + int type= RNA_int_get(op->ptr, "type"); float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap short success; - /* try to get KeyingSet */ - if (scene->active_keyingset > 0) + /* 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, scene->active_keyingset-1); + else + ks= BLI_findlink(&builtin_keyingsets, -type-1); + /* report failure */ if (ks == NULL) { BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); return OPERATOR_CANCELLED; } + /* get context info for relative Keying Sets */ + if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) { + /* exit if no suitable data obtained */ + if (commonkey_get_context_data(C, &dsources, ks) == 0) { + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + return OPERATOR_CANCELLED; + } + } + /* try to insert keyframes for the channels specified by KeyingSet */ - success= commonkey_modifykey(&dsources, ks, COMMONKEY_MODE_DELETE, cfra); + success= commonkey_modifykey(C, &dsources, ks, COMMONKEY_MODE_DELETE, cfra); printf("KeyingSet '%s' - Successfully removed %d Keyframes \n", ks->name, success); /* report failure? */ if (success == 0) BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes"); + /* free temp context-data if available */ + if (dsources.first) { + /* we assume that there is no extra data that needs to be freed from here... */ + BLI_freelistN(&dsources); + } + /* send updates */ ED_anim_dag_flush_update(C); @@ -2014,220 +2298,18 @@ void ANIM_OT_delete_keyframe (wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* Insert Key Operator ------------------------ */ - -/* XXX WARNING: - * This is currently just a basic operator, which work in 3d-view context on objects/bones only - * and will insert keyframes for a few settings only. This is until it becomes clear how - * to separate (or not) the process for RNA-path creation between context + keyingsets. - * - * -- Joshua Leung, Jan 2009 - */ - -/* defines for basic insert-key testing operator */ - // XXX this will definitely be replaced -EnumPropertyItem prop_insertkey_types[] = { - {0, "KEYINGSET", "Active KeyingSet", ""}, - {1, "OBLOC", "Object Location", ""}, - {2, "OBROT", "Object Rotation", ""}, - {3, "OBSCALE", "Object Scale", ""}, - {4, "MAT_COL", "Active Material - Color", ""}, - {5, "PCHANLOC", "Pose-Channel Location", ""}, - {6, "PCHANROT", "Pose-Channel Rotation", ""}, - {7, "PCHANSCALE", "Pose-Channel Scale", ""}, - {0, NULL, NULL, NULL} -}; - -static int insert_key_old_invoke (bContext *C, wmOperator *op, wmEvent *event) -{ - Object *ob= CTX_data_active_object(C); - uiMenuItem *head; - - if (ob == NULL) - return OPERATOR_CANCELLED; - - head= uiPupMenuBegin("Insert Keyframe", 0); - - /* active keyingset */ - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 0); - - /* selective inclusion */ - if ((ob->pose) && (ob->flag & OB_POSEMODE)) { - /* bone types */ - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 5); - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 6); - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 7); - } - else { - /* object types */ - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 1); - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 2); - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 3); - uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 4); - } - - uiPupMenuEnd(C, head); - - return OPERATOR_CANCELLED; -} - -static int insert_key_old_exec (bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - short mode= RNA_enum_get(op->ptr, "type"); - float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap - - /* for now, handle 'active keyingset' one separately */ - if (mode == 0) { - ListBase dsources = {NULL, NULL}; - KeyingSet *ks= NULL; - short success; - - /* try to get KeyingSet */ - if (scene->active_keyingset > 0) - ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); - /* report failure */ - if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); - return OPERATOR_CANCELLED; - } - - /* try to insert keyframes for the channels specified by KeyingSet */ - success= commonkey_modifykey(&dsources, ks, COMMONKEY_MODE_INSERT, cfra); - printf("KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success); - - /* report failure? */ - if (success == 0) - BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes"); - } - else { - // more comprehensive tests will be needed - CTX_DATA_BEGIN(C, Base*, base, selected_bases) - { - Object *ob= base->object; - ID *id= (ID *)ob; - short success= 0; - - /* check which keyframing mode chosen for this object */ - if (mode < 4) { - /* object-based keyframes */ - switch (mode) { - case 4: /* color of active material (only for geometry...) */ - // NOTE: this is just a demo... but ideally we'd go through materials instead of active one only so reference stays same - // XXX no group for now - success+= insertkey(id, NULL, "active_material.diffuse_color", 0, cfra, 0); - success+= insertkey(id, NULL, "active_material.diffuse_color", 1, cfra, 0); - success+= insertkey(id, NULL, "active_material.diffuse_color", 2, cfra, 0); - break; - case 3: /* object scale */ - success+= insertkey(id, "Object Transforms", "scale", 0, cfra, 0); - success+= insertkey(id, "Object Transforms", "scale", 1, cfra, 0); - success+= insertkey(id, "Object Transforms", "scale", 2, cfra, 0); - break; - case 2: /* object rotation */ - success+= insertkey(id, "Object Transforms", "rotation", 0, cfra, 0); - success+= insertkey(id, "Object Transforms", "rotation", 1, cfra, 0); - success+= insertkey(id, "Object Transforms", "rotation", 2, cfra, 0); - break; - default: /* object location */ - success+= insertkey(id, "Object Transforms", "location", 0, cfra, 0); - success+= insertkey(id, "Object Transforms", "location", 1, cfra, 0); - success+= insertkey(id, "Object Transforms", "location", 2, cfra, 0); - break; - } - - ob->recalc |= OB_RECALC_OB; - } - else if ((ob->pose) && (ob->flag & OB_POSEMODE)) { - /* PoseChannel based keyframes */ - bPoseChannel *pchan; - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - /* only if selected */ - if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) { - char buf[512]; - - switch (mode) { - case 7: /* pchan scale */ - sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name); - success+= insertkey(id, pchan->name, buf, 0, cfra, 0); - success+= insertkey(id, pchan->name, buf, 1, cfra, 0); - success+= insertkey(id, pchan->name, buf, 2, cfra, 0); - break; - case 6: /* pchan rotation */ - if (pchan->rotmode == PCHAN_ROT_QUAT) { - sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name); - success+= insertkey(id, pchan->name, buf, 0, cfra, 0); - success+= insertkey(id, pchan->name, buf, 1, cfra, 0); - success+= insertkey(id, pchan->name, buf, 2, cfra, 0); - success+= insertkey(id, pchan->name, buf, 3, cfra, 0); - } - else { - sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name); - success+= insertkey(id, pchan->name, buf, 0, cfra, 0); - success+= insertkey(id, pchan->name, buf, 1, cfra, 0); - success+= insertkey(id, pchan->name, buf, 2, cfra, 0); - } - break; - default: /* pchan location */ - sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name); - success+= insertkey(id, pchan->name, buf, 0, cfra, 0); - success+= insertkey(id, pchan->name, buf, 1, cfra, 0); - success+= insertkey(id, pchan->name, buf, 2, cfra, 0); - break; - } - } - } - - ob->recalc |= OB_RECALC_OB; - } - - printf("Ob '%s' - Successfully added %d Keyframes \n", id->name+2, success); - } - CTX_DATA_END; - } - - /* send updates */ - ED_anim_dag_flush_update(C); - - if (mode == 0) /* for now, only send ND_KEYS for KeyingSets */ - WM_event_add_notifier(C, ND_KEYS, NULL); - else if (mode == 4) /* material color requires different notifiers */ - WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, NULL); - else - WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL); - - return OPERATOR_FINISHED; -} - -void ANIM_OT_insert_keyframe_old (wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name= "Insert Keyframe"; - ot->idname= "ANIM_OT_insert_keyframe_old"; - - /* callbacks */ - ot->invoke= insert_key_old_invoke; - ot->exec= insert_key_old_exec; - ot->poll= ED_operator_areaactive; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - /* properties */ - // XXX update this for the latest RNA stuff styles... - prop= RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_insertkey_types); + /* properties + * - NOTE: here the type is int not enum, since many of the indicies here are determined dynamically + */ + RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1); } /* Delete Key Operator ------------------------ */ /* XXX WARNING: * This is currently just a basic operator, which work in 3d-view context on objects only. + * Should this be kept? It does have advantages over a version which requires selecting a keyingset to use... * -- Joshua Leung, Jan 2009 */ @@ -2264,7 +2346,6 @@ static int delete_key_old_exec (bContext *C, wmOperator *op) /* send updates */ ED_anim_dag_flush_update(C); - // XXX what if it was a material keyframe? WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL); return OPERATOR_FINISHED; @@ -2277,7 +2358,7 @@ void ANIM_OT_delete_keyframe_old (wmOperatorType *ot) ot->idname= "ANIM_OT_delete_keyframe_old"; /* callbacks */ - ot->invoke= WM_operator_confirm; // XXX we will need our own one eventually, to cope with the dynamic menus... + ot->invoke= WM_operator_confirm; ot->exec= delete_key_old_exec; ot->poll= ED_operator_areaactive; diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index b2846fc0bd9..16e0dbc8c35 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -69,6 +69,9 @@ short deletekey(struct ID *id, const char group[], const char rna_path[], int ar /* Generate menu of KeyingSets */ char *ANIM_build_keyingsets_menu(struct ListBase *list, short for_edit); +/* Initialise builtin KeyingSets on startup */ +void init_builtin_keyingsets(void); + /* KeyingSet Editing Operators: * These can add a new KeyingSet and/or add 'destinations' to the KeyingSets, * acting as a means by which they can be added outside the Outliner. @@ -83,12 +86,13 @@ void ANIM_OT_keyingset_add_destination(struct wmOperatorType *ot); void ANIM_OT_insert_keyframe(struct wmOperatorType *ot); void ANIM_OT_delete_keyframe(struct wmOperatorType *ot); -/* Main Keyframe Management operators (legacy style): +/* Main Keyframe Management operators: * These handle keyframes management from various spaces. They will handle the menus * required for each space. */ -void ANIM_OT_insert_keyframe_old(struct wmOperatorType *ot); -void ANIM_OT_delete_keyframe_old(struct wmOperatorType *ot); +void ANIM_OT_insert_keyframe_menu(struct wmOperatorType *ot); +void ANIM_OT_delete_keyframe_menu(struct wmOperatorType *ot); // xxx unimplemented yet +void ANIM_OT_delete_keyframe_old(struct wmOperatorType *ot); // xxx rename and keep? /* ************ Auto-Keyframing ********************** */ /* Notes: diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 8cbf9bf5287..6c8c6e6b60f 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -136,7 +136,7 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_verify_item(keymap, "OBJECT_OT_duplicate_add", DKEY, KM_PRESS, KM_SHIFT, 0); // XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith - WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_old", IKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "ANIM_OT_delete_keyframe_old", IKEY, KM_PRESS, KM_ALT, 0); WM_keymap_verify_item(keymap, "GROUP_OT_group_create", GKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 54652587c53..93297e37d4d 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -3088,7 +3088,7 @@ static KeyingSet *verify_active_keyingset(Scene *scene, short add) /* add if none found */ // XXX the default settings have yet to evolve if ((add) && (ks==NULL)) { - ks= BKE_keyingset_add(&scene->keyingsets, "KeyingSet", KEYINGSET_ABSOLUTE, 0); + ks= BKE_keyingset_add(&scene->keyingsets, "Keying Set", KEYINGSET_ABSOLUTE, 0); scene->active_keyingset= BLI_countlist(&scene->keyingsets); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index d5828f7e3a3..90b1ec7c9be 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -588,7 +588,7 @@ typedef struct Scene { int frame_step; /* User-Defined KeyingSets */ - int active_keyingset; /* index of the active KeyingSet. first KeyingSet has index 1 */ + int active_keyingset; /* index of the active KeyingSet. first KeyingSet has index 1, 'none' active is 0, 'add new' is -1 */ ListBase keyingsets; /* KeyingSets for the given frame */ } Scene; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 990a862a102..1fa184e74a4 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -83,6 +83,7 @@ #include "wm_window.h" #include "ED_armature.h" +#include "ED_keyframing.h" #include "ED_node.h" #include "ED_previewrender.h" #include "ED_space_api.h" @@ -125,6 +126,8 @@ void WM_init(bContext *C) BLF_init(); BLF_lang_init(); + init_builtin_keyingsets(); /* editors/animation/keyframing.c */ + /* get the default database, plus a wm */ WM_read_homefile(C, NULL); |