Keying Sets UI:
authorJoshua Leung <aligorith@gmail.com>
Sat, 3 Oct 2009 04:21:38 +0000 (04:21 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sat, 3 Oct 2009 04:21:38 +0000 (04:21 +0000)
Added a way to view and edit Keying Sets via the Scene Buttons. These are still some tweaks needed to make this really workable, but should still work well enough for simply viewing and tweaking existing Keying Sets created using other means.

Additional bugfixes:
* Adjusted the size of labels on properties that had a 'label' for their name. Now it uses 1/3 of the total width instead, which looks much better for most cases.
* Added missing entries for adding Force Fields from the Info-header 'Add' menu. At some point we should unify this menu with the popup operator's one, since this is exactly the kind of situation we had hoped in avoid with new UI architectures.
* Moved all the operator defines for keyframing stuff to the 'intern' anim header instead

release/scripts/ui/buttons_scene.py
release/scripts/ui/space_info.py
source/blender/blenkernel/intern/anim_sys.c
source/blender/editors/animation/anim_intern.h
source/blender/editors/animation/anim_ops.c
source/blender/editors/animation/keyingsets.c
source/blender/editors/include/ED_keyframing.h
source/blender/editors/interface/interface_layout.c
source/blender/makesdna/DNA_anim_types.h
source/blender/makesrna/intern/rna_animation.c

index 2fbd176e36a3d31586bdcde32be47955131964a9..6467836961c1b4f5394f87e6997131803bd20ffc 100644 (file)
@@ -1,6 +1,14 @@
 
 import bpy
 
+class SceneButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "scene"
+       
+       def poll(self, context):
+               return (context.scene != None)
+
 class RenderButtonsPanel(bpy.types.Panel):
        __space_type__ = 'PROPERTIES'
        __region_type__ = 'WINDOW'
@@ -450,6 +458,84 @@ class SCENE_PT_unit(RenderButtonsPanel):
                row.active = (unit.system != 'NONE')
                row.itemR(unit, "scale_length", text="Scale")
                row.itemR(unit, "use_separate")
+               
+class SCENE_PT_keying_sets(SceneButtonsPanel):
+       __label__ = "Keying Sets"
+       __default_closed__ = True
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               scene = context.scene
+               
+               row = layout.row()
+               
+               col = row.column()
+               col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2)
+               
+               col = row.column(align=True)
+               col.itemO("anim.keying_set_add", icon='ICON_ZOOMIN', text="")
+               col.itemO("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="")
+               
+               ks = scene.active_keying_set
+               if ks:
+                       row = layout.row()
+                       
+                       col = row.column()
+                       col.itemR(ks, "name")
+                       col.itemR(ks, "absolute")
+                       
+                       col = row.column()
+                       col.itemL(text="Keyframing Settings:")
+                       col.itemR(ks, "insertkey_needed", text="Needed")
+                       col.itemR(ks, "insertkey_visual", text="Visual")
+                       
+class SCENE_PT_keying_set_paths(SceneButtonsPanel):
+       __label__ = "Active Keying Set"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               return (context.scene != None) and (context.scene.active_keying_set != None)
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               scene = context.scene
+               ks = scene.active_keying_set
+               
+               row = layout.row()
+               
+               col = row.column()
+               col.template_list(ks, "paths", ks, "active_path_index", rows=2)
+               
+               col = row.column(align=True)
+               col.itemO("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="")
+               col.itemO("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="")
+               
+               ksp = ks.active_path
+               if ksp:
+                       col = layout.column()
+                       col.itemL(text="Target:")
+                       col.itemR(ksp, "id")
+                       col.itemR(ksp, "rna_path")
+                       
+                       
+                       row = layout.row()
+                       
+                       col = row.column()
+                       col.itemL(text="Array Target:")
+                       col.itemR(ksp, "entire_array")
+                       if ksp.entire_array == False:
+                               col.itemR(ksp, "array_index")
+                               
+                       col = row.column()
+                       col.itemL(text="F-Curve Grouping:")
+                       col.itemR(ksp, "grouping")
+                       if ksp.grouping == 'NAMED':
+                               col.itemR(ksp, "group")
+                               
+                       
+                       
 
 class SCENE_PT_physics(RenderButtonsPanel):
        __label__ = "Gravity"
@@ -479,4 +565,6 @@ bpy.types.register(SCENE_PT_performance)
 bpy.types.register(SCENE_PT_post_processing)
 bpy.types.register(SCENE_PT_stamp)
 bpy.types.register(SCENE_PT_unit)
+bpy.types.register(SCENE_PT_keying_sets)
+bpy.types.register(SCENE_PT_keying_set_paths)
 bpy.types.register(SCENE_PT_physics)
index c1a2b1f427531a9ffa06e5cd62425bbd06992d7f..49261981ac2a54fd71452221d03add1c4395219f 100644 (file)
@@ -144,6 +144,10 @@ class INFO_MT_add(bpy.types.Menu):
 
                layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
                layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
+               
+               layout.itemS()
+               
+               layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY')
 
 class INFO_MT_game(bpy.types.Menu):
        __space_type__ = 'INFO'
index ab902bbbae53d88356aba486183a72e003da3acd..47f5dd116d7b655d213e4cbfa8df9b9c8e5f594f 100644 (file)
@@ -211,7 +211,7 @@ static void make_local_strips(ListBase *strips)
 
        for (strip=strips->first; strip; strip=strip->next) {
                if (strip->act) make_local_action(strip->act);
-               //if (strip->remap && strip->remap->target) make_local_action(strip->remap->target);
+               if (strip->remap && strip->remap->target) make_local_action(strip->remap->target);
                
                make_local_strips(&strip->strips);
        }
index 462ef76ea8dd71ff3b8fa0909e0357c10e7ba2f6..853aeb6c8f3dec4407338f899dbf980c522e17f4 100644 (file)
@@ -39,4 +39,44 @@ short keyingset_context_ok_poll(bContext *C, KeyingSet *ks);
 /* Main KeyingSet operations API call */
 short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks);
 
+/* Operator Define Prototypes ------------------- */
+
+/* Main Keyframe Management operators: 
+ *     These handle keyframes management from various spaces. They only make use of
+ *     Keying Sets.
+ */
+void ANIM_OT_insert_keyframe(struct wmOperatorType *ot);
+void ANIM_OT_delete_keyframe(struct wmOperatorType *ot);
+
+/* 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_menu(struct wmOperatorType *ot);
+void ANIM_OT_delete_keyframe_v3d(struct wmOperatorType *ot);
+
+/* Keyframe managment operators for UI buttons (RMB menu). */
+void ANIM_OT_insert_keyframe_button(struct wmOperatorType *ot);
+void ANIM_OT_delete_keyframe_button(struct wmOperatorType *ot);
+
+/* .......... */
+
+/* KeyingSet managment operators for UI buttons (RMB menu) */
+void ANIM_OT_add_keyingset_button(struct wmOperatorType *ot);
+void ANIM_OT_remove_keyingset_button(struct wmOperatorType *ot);
+
+/* KeyingSet management operators for RNA collections/UI buttons */
+void ANIM_OT_keying_set_add(struct wmOperatorType *ot);
+void ANIM_OT_keying_set_remove(struct wmOperatorType *ot);
+void ANIM_OT_keying_set_path_add(struct wmOperatorType *ot);
+void ANIM_OT_keying_set_path_remove(struct wmOperatorType *ot);
+
+/* .......... */
+
+/* Driver management operators for UI buttons (RMB menu) */
+void ANIM_OT_add_driver_button(struct wmOperatorType *ot);
+void ANIM_OT_remove_driver_button(struct wmOperatorType *ot);
+void ANIM_OT_copy_driver_button(struct wmOperatorType *ot);
+void ANIM_OT_paste_driver_button(struct wmOperatorType *ot);
+
 #endif // ANIM_INTERN_H
index a4038028062b8bfa4d9a32f26122ddb0b11346cb..4317204f347ad43bcaa7da72bf7d5ba1a63bf585 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_action_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -41,6 +42,7 @@
 
 #include "BKE_context.h"
 #include "BKE_utildefines.h"
+#include "BKE_sound.h"
 
 #include "UI_interface.h"
 #include "UI_view2d.h"
 #include "WM_types.h"
 
 #include "ED_anim_api.h"
-#include "ED_keyframing.h" // XXX remove?
+#include "ED_keyframing.h"
 #include "ED_markers.h"
 #include "ED_screen.h"
 
-#include "BKE_sound.h"
+#include "anim_intern.h"
 
 /* ********************** frame change operator ***************************/
 
@@ -395,15 +397,21 @@ void ED_operatortypes_anim(void)
        WM_operatortype_append(ANIM_OT_delete_keyframe_v3d);
        WM_operatortype_append(ANIM_OT_insert_keyframe_button);
        WM_operatortype_append(ANIM_OT_delete_keyframe_button);
-
+       
        
        WM_operatortype_append(ANIM_OT_add_driver_button);
        WM_operatortype_append(ANIM_OT_remove_driver_button);
        WM_operatortype_append(ANIM_OT_copy_driver_button);
        WM_operatortype_append(ANIM_OT_paste_driver_button);
        
+       
        WM_operatortype_append(ANIM_OT_add_keyingset_button);
        WM_operatortype_append(ANIM_OT_remove_keyingset_button);
+       
+       WM_operatortype_append(ANIM_OT_keying_set_add);
+       WM_operatortype_append(ANIM_OT_keying_set_remove);
+       WM_operatortype_append(ANIM_OT_keying_set_path_add);
+       WM_operatortype_append(ANIM_OT_keying_set_path_remove);
 }
 
 void ED_keymap_anim(wmWindowManager *wm)
index 81259ae7ced448f2b57131e11e2741cc443c9680..99cdf0a86f4e8446ea26c0b42082ccfcba116782 100644 (file)
 
 #include "anim_intern.h"
 
+/* ************************************************** */
+/* KEYING SETS - OPERATORS (for use in UI panels) */
+/* These operators are really duplication of existing functionality, but just for completeness,
+ * they're here too, and will give the basic data needed...
+ */
+
+/* poll callback for adding default KeyingSet */
+static int keyingset_poll_default_add (bContext *C)
+{
+       /* as long as there's an active Scene, it's fine */
+       return (CTX_data_scene(C) != NULL);
+}
+
+/* poll callback for editing active KeyingSet */
+static int keyingset_poll_active_edit (bContext *C)
+{
+       Scene *scene= CTX_data_scene(C);
+       
+       if (scene == NULL)
+               return 0;
+       
+       /* there must be an active KeyingSet (and KeyingSets) */
+       return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
+}
+
+/* poll callback for editing active KeyingSet Path */
+static int keyingset_poll_activePath_edit (bContext *C)
+{
+       Scene *scene= CTX_data_scene(C);
+       KeyingSet *ks;
+       
+       if (scene == NULL)
+               return 0;
+       if (scene->active_keyingset <= 0)
+               return 0;
+       else
+               ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+       
+       /* there must be an active KeyingSet and an active path */
+       return ((ks) && (ks->paths.first) && (ks->active_path > 0));
+}
+
+/* Add a Default (Empty) Keying Set ------------------------- */
+
+static int add_default_keyingset_exec (bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       short flag=0, keyingflag=0;
+       
+       /* validate flags 
+        *      - absolute KeyingSets should be created by default
+        */
+       flag |= KEYINGSET_ABSOLUTE;
+       
+       if (IS_AUTOKEY_FLAG(AUTOMATKEY)) 
+               keyingflag |= INSERTKEY_MATRIX;
+       if (IS_AUTOKEY_FLAG(INSERTNEEDED)) 
+               keyingflag |= INSERTKEY_NEEDED;
+               
+       /* call the API func, and set the active keyingset index */
+       BKE_keyingset_add(&scene->keyingsets, NULL, flag, keyingflag);
+       
+       scene->active_keyingset= BLI_countlist(&scene->keyingsets);
+       
+       return OPERATOR_FINISHED;
+}
+
+void ANIM_OT_keying_set_add (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Empty Keying Set";
+       ot->idname= "ANIM_OT_keying_set_add";
+       ot->description= "Add a new (empty) Keying Set to the active Scene.";
+       
+       /* callbacks */
+       ot->exec= add_default_keyingset_exec;
+       ot->poll= keyingset_poll_default_add;
+}
+
+/* Remove 'Active' Keying Set ------------------------- */
+
+static int remove_active_keyingset_exec (bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       KeyingSet *ks;
+       
+       /* verify the Keying Set to use:
+        *      - use the active one
+        *      - return error if it doesn't exist
+        */
+       if (scene->active_keyingset == 0) {
+               BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove");
+               return OPERATOR_CANCELLED;
+       }
+       else
+               ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+       
+       /* free KeyingSet's data, then remove it from the scene */
+       BKE_keyingset_free(ks);
+       
+       BLI_freelinkN(&scene->keyingsets, ks);
+       scene->active_keyingset= 0;
+       
+       return OPERATOR_FINISHED;
+}
+
+void ANIM_OT_keying_set_remove (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Removed Active Keying Set";
+       ot->idname= "ANIM_OT_keying_set_remove";
+       ot->description= "Remove the active Keying Set.";
+       
+       /* callbacks */
+       ot->exec= remove_active_keyingset_exec;
+       ot->poll= keyingset_poll_active_edit;
+}
+
+/* Add Empty Keying Set Path ------------------------- */
+
+static int add_empty_ks_path_exec (bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       KeyingSet *ks;
+       KS_Path *ksp;
+       
+       /* verify the Keying Set to use:
+        *      - use the active one
+        *      - return error if it doesn't exist
+        */
+       if (scene->active_keyingset == 0) {
+               BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to");
+               return OPERATOR_CANCELLED;
+       }
+       else
+               ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+       
+       /* don't use the API method for this, since that checks on values... */
+       ksp= MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
+       BLI_addtail(&ks->paths, ksp);
+       ks->active_path= BLI_countlist(&ks->paths) + 1;
+       
+       ksp->groupmode= KSP_GROUP_KSNAME; // XXX?
+       
+       return OPERATOR_FINISHED;
+}
+
+void ANIM_OT_keying_set_path_add (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Empty Keying Set Path";
+       ot->idname= "ANIM_OT_keying_set_path_add";
+       ot->description= "Add empty path to active Keying Set";
+       
+       /* callbacks */
+       ot->exec= add_empty_ks_path_exec;
+       ot->poll= keyingset_poll_active_edit;
+}
+
+/* Remove Active Keying Set Path ------------------------- */
+
+static int remove_active_ks_path_exec (bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       KeyingSet *ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+       
+       /* if there is a KeyingSet, find the nominated path to remove */
+       if (ks) {
+               KS_Path *ksp= BLI_findlink(&ks->paths, ks->active_path-1);
+               
+               if (ksp) {
+                       /* NOTE: sync this code with BKE_keyingset_free() */
+                       {
+                               /* free RNA-path info */
+                               MEM_freeN(ksp->rna_path);
+                               
+                               /* free path itself */
+                               BLI_freelinkN(&ks->paths, ksp);
+                       }
+                       
+                       /* fix active path index */
+                       ks->active_path= 0;
+               }
+               else {
+                       BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove");
+                       return OPERATOR_CANCELLED;
+               }
+       }
+       else {
+               BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from");
+               return OPERATOR_CANCELLED;
+       }
+       
+       return OPERATOR_FINISHED;
+}
+
+void ANIM_OT_keying_set_path_remove (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Remove Active Keying Set Path";
+       ot->idname= "ANIM_OT_keying_set_path_remove";
+       ot->description= "Remove active Path from active Keying Set.";
+       
+       /* callbacks */
+       ot->exec= remove_active_ks_path_exec;
+       ot->poll= keyingset_poll_activePath_edit;
+}
+
 /* ************************************************** */
 /* KEYING SETS - OPERATORS (for use in UI menus) */
 
index d30fccfe4dec1e222f3243a24b5afb1c3a288e91..92dda4162cc3a59a0128bd43296cefd7c377fec5 100644 (file)
@@ -97,26 +97,6 @@ short insert_keyframe(struct ID *id, struct bAction *act, const char group[], co
  */
 short delete_keyframe(struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag);
 
-/* -------- */
-
-/* Main Keyframe Management operators: 
- *     These handle keyframes management from various spaces. They only make use of
- *     Keying Sets.
- */
-void ANIM_OT_insert_keyframe(struct wmOperatorType *ot);
-void ANIM_OT_delete_keyframe(struct wmOperatorType *ot);
-
-/* 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_menu(struct wmOperatorType *ot);
-void ANIM_OT_delete_keyframe_v3d(struct wmOperatorType *ot);
-
-/* Keyframe managment operators for UI buttons. */
-void ANIM_OT_insert_keyframe_button(struct wmOperatorType *ot);
-void ANIM_OT_delete_keyframe_button(struct wmOperatorType *ot);
-
 /* ************ Keying Sets ********************** */
 
 /* temporary struct to gather data combos to keyframe
@@ -155,12 +135,6 @@ struct KeyingSet *ANIM_builtin_keyingset_get_named(struct KeyingSet *prevKS, cha
 /* Initialise builtin KeyingSets on startup */
 void init_builtin_keyingsets(void);
 
-/* -------- */
-
-/* KeyingSet managment operators for UI buttons. */
-void ANIM_OT_add_keyingset_button(struct wmOperatorType *ot);
-void ANIM_OT_remove_keyingset_button(struct wmOperatorType *ot);
-
 /* ************ Drivers ********************** */
 
 /* Returns whether there is a driver in the copy/paste buffer to paste */
@@ -187,12 +161,6 @@ short ANIM_copy_driver(struct ID *id, const char rna_path[], int array_index, sh
  */
 short ANIM_paste_driver(struct ID *id, const char rna_path[], int array_index, short flag);
 
-/* Driver management operators for UI buttons */
-void ANIM_OT_add_driver_button(struct wmOperatorType *ot);
-void ANIM_OT_remove_driver_button(struct wmOperatorType *ot);
-void ANIM_OT_copy_driver_button(struct wmOperatorType *ot);
-void ANIM_OT_paste_driver_button(struct wmOperatorType *ot);
-
 /* ************ Auto-Keyframing ********************** */
 /* Notes:
  * - All the defines for this (User-Pref settings and Per-Scene settings)
index e9160e0e416d68fd550d6beb4a3f2e46dcd31055..11dfc44906ac58feb9a028dce44e18c5bb36d6fb 100644 (file)
@@ -492,7 +492,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i
                /* XXX UI_GetStringWidth is not accurate
                labelw= UI_GetStringWidth(name);
                CLAMP(labelw, w/4, 3*w/4);*/
-               labelw= w/2;
+               labelw= w/3;
                uiDefBut(block, LABEL, 0, name, x, y, labelw, h, NULL, 0.0, 0.0, 0, 0, "");
                w= w-labelw;
        }
index 9921878e926f2bc27756ae52d296537f1a5c209c..fedde34ae18fa5672e7ac60ca8460eca191c66a2 100644 (file)
@@ -654,8 +654,10 @@ typedef struct KeyingSet {
        
        char name[64];                  /* user-viewable name for KeyingSet (for menus, etc.) */
        
-       int flag;                               /* settings for KeyingSet */
-       int keyingflag;                 /* settings to supply insertkey() with */
+       short flag;                             /* settings for KeyingSet */
+       short keyingflag;               /* settings to supply insertkey() with */
+       
+       int active_path;                /* index of the active path */
 } KeyingSet;
 
 /* KeyingSet settings */
index 4b2c11c2e0d1bc396d9c51588a46744572ad18e4..a62eef66cf0c5fdd460c7c294b71174c8166d1e1 100644 (file)
@@ -96,6 +96,49 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value)
                ksp->rna_path= NULL;
 }
 
+
+static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr)
+{
+       KeyingSet *ks= (KeyingSet *)ptr->data;
+       
+       /* only editable if there are some paths to change to */
+       return (ks->paths.first != NULL);
+}
+
+static PointerRNA rna_KeyingSet_active_ksPath_get(PointerRNA *ptr)
+{
+       KeyingSet *ks= (KeyingSet *)ptr->data;
+       return rna_pointer_inherit_refine(ptr, &RNA_KeyingSetPath, BLI_findlink(&ks->paths, ks->active_path-1));
+}
+
+static void rna_KeyingSet_active_ksPath_set(PointerRNA *ptr, PointerRNA value)
+{
+       KeyingSet *ks= (KeyingSet *)ptr->data;
+       KS_Path *ksp= (KS_Path*)value.data;
+       ks->active_path= BLI_findindex(&ks->paths, ksp) + 1;
+}
+
+static int rna_KeyingSet_active_ksPath_index_get(PointerRNA *ptr)
+{
+       KeyingSet *ks= (KeyingSet *)ptr->data;
+       return MAX2(ks->active_path-1, 0);
+}
+
+static void rna_KeyingSet_active_ksPath_index_set(PointerRNA *ptr, int value)
+{
+       KeyingSet *ks= (KeyingSet *)ptr->data;
+       ks->active_path= value+1;
+}
+
+static void rna_KeyingSet_active_ksPath_index_range(PointerRNA *ptr, int *min, int *max)
+{
+       KeyingSet *ks= (KeyingSet *)ptr->data;
+
+       *min= 0;
+       *max= BLI_countlist(&ks->paths)-1;
+       *max= MAX2(0, *max);
+}
+
 #else
 
 
@@ -127,6 +170,7 @@ static void rna_def_keyingset_path(BlenderRNA *brna)
        //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable
        RNA_def_property_string_funcs(prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length", "rna_ksPath_RnaPath_set");
        RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property setting.");
+       RNA_def_struct_name_property(srna, prop); // XXX this is the best indicator for now...
        
        prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
        //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable
@@ -157,6 +201,18 @@ static void rna_def_keyingset(BlenderRNA *brna)
        RNA_def_property_struct_type(prop, "KeyingSetPath");
        RNA_def_property_ui_text(prop, "Paths", "Keying Set Paths to define settings that get keyframed together.");
        
+       prop= RNA_def_property(srna, "active_path", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "KeyingSetPath");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_editable_func(prop, "rna_KeyingSet_active_ksPath_editable");
+       RNA_def_property_pointer_funcs(prop, "rna_KeyingSet_active_ksPath_get", "rna_KeyingSet_active_ksPath_set", NULL);
+       RNA_def_property_ui_text(prop, "Active Keying Set", "Active Keying Set used to insert/delete keyframes.");
+       
+       prop= RNA_def_property(srna, "active_path_index", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "active_path");
+       RNA_def_property_int_funcs(prop, "rna_KeyingSet_active_ksPath_index_get", "rna_KeyingSet_active_ksPath_index_set", "rna_KeyingSet_active_ksPath_index_range");
+       RNA_def_property_ui_text(prop, "Active Path Index", "Current Keying Set index.");
+       
        /* Flags */
        prop= RNA_def_property(srna, "builtin", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);