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:
authorJoshua Leung <aligorith@gmail.com>2009-02-11 15:19:42 +0300
committerJoshua Leung <aligorith@gmail.com>2009-02-11 15:19:42 +0300
commit7d3c88772b4cdf9cec8966390e84bdd21802395f (patch)
tree9b3545b7c16ff34b7dcc25b1b59348221f1d9b29 /source/blender/editors
parentba32199b23fb1b745109d7b25b8d7c6cdf903cd1 (diff)
Keying Sets: Initial commit of skeleton code
When fully implemented, these will be the clearest demonstration of 'Everything is Animateable', as they will allow users to define an arbitary group of settings through selecting items in the Datablocks (RNA-Viewer) View of the Outliner to define custom 'sets'. Such Keying Sets are known as the 'absolute' ones, which are created for a custom purpose. Of course, 'builtin' Keying Sets will still be provided. Such built-in ones will not work on any particular paths, but will use context info to maintain the legacy method of inserting keyframes (via IKEY menu). Currently, KeyingSets cannot be created/edited through the UI, though the backend code is in place to do this.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/keyframing.c264
-rw-r--r--source/blender/editors/include/ED_keyframing.h5
-rw-r--r--source/blender/editors/space_action/action_draw.c2
-rw-r--r--source/blender/editors/space_graph/graph_draw.c3
-rw-r--r--source/blender/editors/space_outliner/outliner.c40
-rw-r--r--source/blender/editors/space_outliner/outliner_header.c1
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h2
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c7
-rw-r--r--source/blender/editors/space_time/time_header.c17
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c1
10 files changed, 243 insertions, 99 deletions
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index df3a7b85a45..42ed4fddc99 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -30,6 +30,7 @@
#include "BKE_fcurve.h"
#include "BKE_utildefines.h"
#include "BKE_context.h"
+#include "BKE_report.h"
#include "BKE_key.h"
#include "BKE_material.h"
@@ -39,6 +40,8 @@
#include "ED_screen.h"
#include "ED_util.h"
+#include "UI_interface.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -63,35 +66,6 @@ typedef struct bCommonKeySrc {
bPoseChannel *pchan; /* only needed when doing recalcs... */
} bCommonKeySrc;
-/* -------------- Keying Sets ------------------- */
-
-#if 0 // XXX I'm not sure how these will work for now...
-
-/* keying set - a set of channels that will be keyframed together */
-// TODO: move this to a header to allow custom sets someday?
-typedef struct bKeyingSet {
- /* callback func to consider if keyingset should be included
- * (by default, if this is undefined, item will be shown)
- */
- short (*include_cb)(struct bKeyingSet *, const char *);
-
- char name[48]; /* name of keyingset */
- int blocktype; /* nearest ID-blocktype to where data can be found */
- short flag; /* flags to use when setting keyframes */
-
- short chan_num; /* number of channels to insert keyframe in */
- char (*paths)[256]; /* adrcodes for channels to insert keys for (ideally would be variable-len, but limit of 32 will suffice) */
-} bKeyingSet;
-
-/* keying set context - an array of keying sets and the number of them */
-typedef struct bKeyingContext {
- bKeyingSet *keyingsets; /* array containing the keyingsets of interest */
- bKeyingSet *lastused; /* item that was chosen last time*/
- int tot; /* number of keyingsets in */
-} bKeyingContext;
-
-#endif
-
/* ******************************************* */
/* Animation Data Validation */
@@ -184,7 +158,7 @@ FCurve *verify_fcurve (ID *id, const char group[], const char rna_path[], const
/* -------------- BezTriple Insertion -------------------- */
/* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */
-#define BEZT_INSERT_THRESH 0.00001
+#define BEZT_INSERT_THRESH 0.00001f
/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
* Returns the index to insert at (data already at that index will be offset if replace is 0)
@@ -899,6 +873,37 @@ enum {
COMMONKEY_MODE_DELETE,
} eCommonModifyKey_Modes;
+
+/* Build menu-string of available keying-sets (allocates memory for string)
+ * NOTE: mode must not be longer than 64 chars
+ */
+char *ANIM_build_keyingsets_menu (ListBase *list)
+{
+ DynStr *pupds= BLI_dynstr_new();
+ KeyingSet *ks;
+ char buf[64];
+ char *str;
+
+ /* add title first */
+ BLI_dynstr_append(pupds, "Keying Sets%t|");
+
+ /* add dummy entry for none-active */
+ BLI_dynstr_append(pupds, "<No Keying Set Active>%x0|");
+
+ /* loop through keyingsets, adding them */
+ for (ks= list->first; ks; ks= ks->next) {
+ BLI_dynstr_append(pupds, ks->name);
+ BLI_snprintf( buf, 64, "%s", ((ks->next)?"|":"") );
+ BLI_dynstr_append(pupds, buf);
+ }
+
+ /* convert to normal MEM_malloc'd string */
+ str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+
+ return str;
+}
+
#if 0 // XXX old keyingsets code based on adrcodes... to be restored in due course
/* --------- KeyingSet Adrcode Getters ------------ */
@@ -1786,57 +1791,6 @@ static void commonkey_context_refresh (bContext *C)
/* --- */
-/* Build menu-string of available keying-sets (allocates memory for string)
- * NOTE: mode must not be longer than 64 chars
- */
-static char *build_keyingsets_menu (bKeyingContext *ksc, const char mode[48])
-{
- DynStr *pupds= BLI_dynstr_new();
- bKeyingSet *ks;
- char buf[64];
- char *str;
- int i, n;
-
- /* add title first */
- BLI_snprintf(buf, 64, "%s Key %%t|", mode);
- BLI_dynstr_append(pupds, buf);
-
- /* loop through keyingsets, adding them */
- for (ks=ksc->keyingsets, i=0, n=1; i < ksc->tot; ks++, i++, n++) {
- /* check if keyingset can be used */
- if (ks->flag == -1) {
- /* optional separator? */
- if (ks->include_cb) {
- if (ks->include_cb(ks, mode)) {
- BLI_snprintf( buf, 64, "%s%s", ks->name, ((n < ksc->tot)?"|":"") );
- BLI_dynstr_append(pupds, buf);
- }
- }
- else {
- BLI_snprintf( buf, 64, "%%l%s", ((n < ksc->tot)?"|":"") );
- BLI_dynstr_append(pupds, buf);
- }
- }
- else if ( (ks->include_cb==NULL) || (ks->include_cb(ks, mode)) ) {
- /* entry can be included */
- BLI_dynstr_append(pupds, ks->name);
-
- /* check if special "shapekey" entry */
- if (ks->flag == -3)
- BLI_snprintf( buf, 64, "%%x0%s", ((n < ksc->tot)?"|":"") );
- else
- BLI_snprintf( buf, 64, "%%x%d%s", n, ((n < ksc->tot)?"|":"") );
- BLI_dynstr_append(pupds, buf);
- }
- }
-
- /* convert to normal MEM_malloc'd string */
- str= BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-
- return str;
-}
-
/* Get the keying set that was chosen by the user from the menu */
static bKeyingSet *get_keyingset_fromcontext (bKeyingContext *ksc, short index)
{
@@ -2033,6 +1987,68 @@ void common_modifykey (bContext *C, short mode)
#endif // XXX old keyingsets code based on adrcodes... to be restored in due course
+/* 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)
+{
+ KS_Path *ksp;
+ int kflag, success= 0;
+ char *groupname= NULL;
+
+ /* get flags to use */
+ if (mode == COMMONKEY_MODE_INSERT) {
+ /* use KeyingSet's flags as base */
+ kflag= ks->keyingflag;
+
+ /* suppliment with info from the context */
+ if (IS_AUTOKEY_FLAG(AUTOMATKEY)) kflag |= INSERTKEY_MATRIX;
+ if (IS_AUTOKEY_FLAG(INSERTNEEDED)) kflag |= INSERTKEY_NEEDED;
+ // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
+ }
+ else if (mode == COMMONKEY_MODE_DELETE)
+ kflag= 0;
+
+
+ /* check if the KeyingSet is absolute or not (i.e. does it requires sources info) */
+ if (ks->flag & KEYINGSET_ABSOLUTE) {
+ /* Absolute KeyingSets are simpler to use, as all the destination info has already been
+ * provided by the user, and is stored, ready to use, in the KeyingSet paths.
+ */
+ for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+ /* get pointer to name of group to add channels to */
+ if (ksp->flag & KSP_FLAG_GROUP_NONE)
+ groupname= NULL;
+ else if (ksp->flag & KSP_FLAG_GROUP_KSNAME)
+ groupname= ks->name;
+ else
+ groupname= ksp->group;
+
+ /* action to take depends on mode */
+ if (mode == COMMONKEY_MODE_INSERT)
+ success+= insertkey(ksp->id, groupname, ksp->rna_path, ksp->array_index, cfra, kflag);
+ else if (mode == COMMONKEY_MODE_DELETE)
+ success+= deletekey(ksp->id, groupname, ksp->rna_path, ksp->array_index, cfra, kflag);
+ }
+ }
+#if 0 // XXX still need to figure out how to get such keyingsets working
+ else if (dsources) {
+ /* 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) {
+
+ }
+ }
+#endif // XXX still need to figure out how to get such
+
+ return success;
+}
+
/* Insert Key Operator ------------------------ */
/* XXX WARNING:
@@ -2046,15 +2062,49 @@ void common_modifykey (bContext *C, short mode)
/* defines for basic insert-key testing operator */
// XXX this will definitely be replaced
EnumPropertyItem prop_insertkey_types[] = {
- {0, "OBLOC", "Object Location", ""},
- {1, "OBROT", "Object Rotation", ""},
- {2, "OBSCALE", "Object Scale", ""},
- {3, "MAT_COL", "Active Material - Color", ""},
- {4, "PCHANLOC", "Pose-Channel Location", ""},
- {5, "PCHANROT", "Pose-Channel Rotation", ""},
- {6, "PCHANSCALE", "Pose-Channel Scale", ""},
+ {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_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", "type", 0);
+
+ /* selective inclusion */
+ if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
+ /* bone types */
+ uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe", "type", 5);
+ uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe", "type", 6);
+ uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe", "type", 7);
+ }
+ else {
+ /* object types */
+ uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe", "type", 1);
+ uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe", "type", 2);
+ uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe", "type", 3);
+ uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe", "type", 4);
+ }
+
+ uiPupMenuEnd(C, head);
+
+ return OPERATOR_CANCELLED;
+}
static int insert_key_exec (bContext *C, wmOperator *op)
{
@@ -2062,6 +2112,34 @@ static int insert_key_exec (bContext *C, wmOperator *op)
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");
+ return OPERATOR_CANCELLED; // XXX?
+ }
+ else
+ return OPERATOR_FINISHED;
+ }
+
// XXX more comprehensive tests will be needed
CTX_DATA_BEGIN(C, Base*, base, selected_bases)
{
@@ -2073,24 +2151,24 @@ static int insert_key_exec (bContext *C, wmOperator *op)
if (mode < 4) {
/* object-based keyframes */
switch (mode) {
- case 3: /* color of active material (only for geometry...) */
+ 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 2: /* object scale */
+ 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 1: /* object rotation */
+ 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 */
+ case 1: /* 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);
@@ -2167,7 +2245,7 @@ void ANIM_OT_insert_keyframe (wmOperatorType *ot)
ot->idname= "ANIM_OT_insert_keyframe";
/* callbacks */
- ot->invoke= WM_menu_invoke; // XXX we will need our own one eventually, to cope with the dynamic menus...
+ ot->invoke= insert_key_invoke;
ot->exec= insert_key_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 91dbbec873f..e7441188fc3 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -31,6 +31,8 @@
struct ListBase;
struct ID;
+struct KeyingSet;
+
struct FCurve;
struct BezTriple;
@@ -81,6 +83,9 @@ short insertkey(struct ID *id, const char group[], const char rna_path[], int ar
short deletekey(struct ID *id, const char group[], const char rna_path[], int array_index, float cfra, short flag);
+/* Generate menu of KeyingSets */
+char *ANIM_build_keyingsets_menu(struct ListBase *list);
+
/* Main Keyframe Management operators:
* These handle keyframes management from various spaces. They will handle the menus
* required for each space.
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 9b3852e63bf..ccee97ad605 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -867,7 +867,7 @@ void draw_channel_names(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
offset += 17;
}
else {
- /* for ipo/constraint channels */
+ /* for normal channels */
UI_icon_draw(x+offset, yminc, special);
offset += 17;
}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 7adb90e7464..8df483b9048 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -689,7 +689,6 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
int items, i;
/* build list of curves to draw */
- // XXX enable ANIMFILTER_CURVEVISIBLE when we have a method to set them
filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CURVESONLY|ANIMFILTER_CURVEVISIBLE);
items= ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -1135,7 +1134,7 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
offset += 17;
}
else {
- /* for ipo/constraint channels */
+ /* for normal channels */
UI_icon_draw(x+offset, yminc, special);
offset += 17;
}
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index fbc475d3bdd..11d8cf50d4b 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -64,6 +64,7 @@
#include "IMB_imbuf_types.h"
+#include "BKE_animsys.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_deform.h"
@@ -3086,6 +3087,45 @@ void outliner_operation_menu(Scene *scene, ARegion *ar, SpaceOops *soops)
}
}
+/* ***************** KEYINGSET OPERATIONS *************** */
+
+/* These operators are only available in databrowser mode for now, as
+ * they depend on having RNA paths and/or hierarchies available.
+ */
+
+/* find the 'active' KeyingSet, and add if not found (if adding is allowed) */
+// TODO: should this be an API func?
+static KeyingSet *verify_active_keyingset(Scene *scene, short add)
+{
+ KeyingSet *ks= NULL;
+
+ /* try to find one from scene */
+ if (scene->active_keyingset > 0)
+ ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+
+ /* 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);
+
+ return ks;
+}
+
+/* ---------------------------------- */
+
+
+void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot)
+{
+
+}
+
+
+/* ---------------------------------- */
+
+void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot)
+{
+
+}
/* ***************** DRAW *************** */
diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c
index 2c114f3099b..7add3f85ea0 100644
--- a/source/blender/editors/space_outliner/outliner_header.c
+++ b/source/blender/editors/space_outliner/outliner_header.c
@@ -44,6 +44,7 @@
#include "BKE_main.h"
#include "BKE_screen.h"
+#include "ED_keyframing.h"
#include "ED_screen.h"
#include "ED_util.h"
#include "ED_types.h"
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index e7e75833d43..067c14dc257 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -119,6 +119,8 @@ void outliner_select(struct SpaceOops *soops, struct ListBase *lb, int *index, s
void draw_outliner(const struct bContext *C);
void OUTLINER_OT_activate_click(struct wmOperatorType *ot);
+void OUTLINER_OT_keyingset_add_selected(struct wmOperatorType *ot);
+void OUTLINER_OT_keyingset_remove_selected(struct wmOperatorType *ot);
#if 0
extern void outliner_mouse_event(Scene *scene, ARegion *ar, SpaceOops *soops, short event);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 7d1155cb5d7..295d7ade97c 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -44,6 +44,9 @@
void outliner_operatortypes(void)
{
WM_operatortype_append(OUTLINER_OT_activate_click);
+
+ WM_operatortype_append(OUTLINER_OT_keyingset_add_selected);
+ WM_operatortype_append(OUTLINER_OT_keyingset_remove_selected);
}
void outliner_keymap(wmWindowManager *wm)
@@ -51,6 +54,10 @@ void outliner_keymap(wmWindowManager *wm)
ListBase *keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OOPS, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_activate_click", LEFTMOUSE, KM_PRESS, 0, 0);
+
+ /* keying sets - only for databrowse */
+ WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_add_selected", KKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_remove_selected", KKEY, KM_PRESS, KM_ALT, 0);
}
diff --git a/source/blender/editors/space_time/time_header.c b/source/blender/editors/space_time/time_header.c
index 65946a4288b..1f03530b680 100644
--- a/source/blender/editors/space_time/time_header.c
+++ b/source/blender/editors/space_time/time_header.c
@@ -43,6 +43,7 @@
#include "BKE_global.h"
#include "BKE_screen.h"
+#include "ED_keyframing.h"
#include "ED_screen.h"
#include "ED_types.h"
#include "ED_util.h"
@@ -429,6 +430,7 @@ void time_header_buttons(const bContext *C, ARegion *ar)
Scene *scene= CTX_data_scene(C);
uiBlock *block;
int xco, yco= 3;
+ char *menustr= NULL;
block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS, UI_HELV);
uiBlockSetHandleFunc(block, do_time_buttons, NULL);
@@ -539,12 +541,21 @@ void time_header_buttons(const bContext *C, ARegion *ar)
xco+= 16;
- uiDefIconBut(block, BUT, B_TL_INSERTKEY, ICON_KEY_HLT,
- xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Insert Keyframe for the context of the largest area (IKEY)");
- xco+= XIC+4;
+
+ menustr= ANIM_build_keyingsets_menu(&scene->keyingsets);
+ uiDefButI(block, MENU, B_DIFF,
+ menustr,
+ xco, yco, (int)5.5*XIC, YIC, &(scene->active_keyingset), 0, 1, 0, 0,
+ "Active Keying Set (i.e. set of channels to Insert Keyframes for)");
+ MEM_freeN(menustr);
+ xco+= (6*XIC);
+
uiDefIconBut(block, BUT, B_TL_DELETEKEY, ICON_KEY_DEHLT,
xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Delete Keyframe for the context of the largest area (ALTKEY-IKEY)");
xco+= XIC+4;
+ uiDefIconBut(block, BUT, B_TL_INSERTKEY, ICON_KEY_HLT,
+ xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Insert Keyframe for the context of the largest area (IKEY)");
+ xco+= XIC+4;
xco+= 16;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 556d52e4aff..c1c5dec52a7 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -78,6 +78,7 @@
#include "ED_armature.h"
#include "ED_curve.h"
#include "ED_editparticle.h"
+#include "ED_keyframing.h"
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_screen.h"