Keying Sets UI:

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
This commit is contained in:
Joshua Leung 2009-10-03 04:21:38 +00:00
parent 97d8839ad5
commit f4c697cf7f
10 changed files with 414 additions and 39 deletions

@ -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)

@ -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'

@ -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);
}

@ -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

@ -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"
@ -52,11 +54,11 @@
#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)

@ -77,6 +77,215 @@
#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) */

@ -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)

@ -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;
}

@ -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 */

@ -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);