Keying Sets: Added options to add/remove properties from the active Keying Set to the RMB menu (and also via KKEY and ALT-K respectively)

This commit is contained in:
Joshua Leung 2009-09-04 07:26:32 +00:00
parent 62dd488ad1
commit 15ef88b902
9 changed files with 249 additions and 11 deletions

@ -239,7 +239,7 @@ KS_Path *BKE_keyingset_find_destination (KeyingSet *ks, ID *id, const char group
if ((ksp->rna_path==0) || strcmp(rna_path, ksp->rna_path))
eq_path= 0;
/* index */
/* index - need to compare whole-array setting too... */
if (ksp->array_index != array_index)
eq_index= 0;

@ -1,18 +1,42 @@
/* Testing code for 2.5 animation system
* Copyright 2009, Joshua Leung
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place * Suite 330, Boston, MA 02111*1307, USA.
*
* The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung
* This is a new part of Blender (with some old code)
*
* Contributor(s): Joshua Leung
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef ANIM_INTERN_H
#define ANIM_INTERN_H
/* KeyingSets/Keyframing Interface ------------- */
/* list of builtin KeyingSets (defined in keyingsets.c) */
extern ListBase builtin_keyingsets;
/* for builtin keyingsets - context poll */
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);
#endif // ANIM_INTERN_H

@ -381,13 +381,14 @@ void ANIM_OT_time_toggle(wmOperatorType *ot)
void ED_operatortypes_anim(void)
{
/* Animation Editors only -------------------------- */
WM_operatortype_append(ANIM_OT_change_frame);
WM_operatortype_append(ANIM_OT_time_toggle);
WM_operatortype_append(ANIM_OT_previewrange_set);
WM_operatortype_append(ANIM_OT_previewrange_clear);
// XXX this is used all over... maybe for screen instead?
/* Entire UI --------------------------------------- */
WM_operatortype_append(ANIM_OT_insert_keyframe);
WM_operatortype_append(ANIM_OT_delete_keyframe);
WM_operatortype_append(ANIM_OT_insert_keyframe_menu);
@ -398,6 +399,9 @@ void ED_operatortypes_anim(void)
WM_operatortype_append(ANIM_OT_add_driver_button);
WM_operatortype_append(ANIM_OT_remove_driver_button);
WM_operatortype_append(ANIM_OT_add_keyingset_button);
WM_operatortype_append(ANIM_OT_remove_keyingset_button);
}
void ED_keymap_anim(wmWindowManager *wm)

@ -281,7 +281,7 @@ void ANIM_OT_add_driver_button (wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Insert a keyframe for all element of the array.");
RNA_def_boolean(ot->srna, "all", 1, "All", "Create drivers for all elements of the array.");
}
/* Remove Driver Button Operator ------------------------ */
@ -344,7 +344,7 @@ void ANIM_OT_remove_driver_button (wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyfames from all elements of the array.");
RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array.");
}
/* ************************************************** */

@ -77,6 +77,171 @@
#include "anim_intern.h"
/* ************************************************** */
/* KEYING SETS - OPERATORS (for use in UI menus) */
/* Add to KeyingSet Button Operator ------------------------ */
static int add_keyingset_button_exec (bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
KeyingSet *ks = NULL;
PropertyRNA *prop= NULL;
PointerRNA ptr;
char *path = NULL;
short success= 0;
int index=0, pflag=0;
int all= RNA_boolean_get(op->ptr, "all");
/* verify the Keying Set to use:
* - use the active one for now (more control over this can be added later)
* - add a new one if it doesn't exist
*/
if (scene->active_keyingset == 0) {
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 */
ks= BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", flag, keyingflag);
scene->active_keyingset= BLI_countlist(&scene->keyingsets);
}
else
ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
/* try to add to keyingset using property retrieved from UI */
memset(&ptr, 0, sizeof(PointerRNA));
uiAnimContextProperty(C, &ptr, &prop, &index);
/* check if property is able to be added */
if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) {
path= RNA_path_from_ID_to_property(&ptr, prop);
if (path) {
/* set flags */
if (all)
pflag |= KSP_FLAG_WHOLE_ARRAY;
/* add path to this setting */
BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
/* free the temp path created */
MEM_freeN(path);
}
}
if (success) {
/* send updates */
ED_anim_dag_flush_update(C);
/* for now, only send ND_KEYS for KeyingSets */
WM_event_add_notifier(C, ND_KEYS, NULL);
}
return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
}
void ANIM_OT_add_keyingset_button (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add to Keying Set";
ot->idname= "ANIM_OT_add_keyingset_button";
/* callbacks */
ot->exec= add_keyingset_button_exec;
//op->poll= ???
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set.");
}
/* Remove from KeyingSet Button Operator ------------------------ */
static int remove_keyingset_button_exec (bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
KeyingSet *ks = NULL;
PropertyRNA *prop= NULL;
PointerRNA ptr;
char *path = NULL;
short success= 0;
int index=0;
/* verify the Keying Set to use:
* - use the active one for now (more control over this can be added later)
* - return error if it doesn't exist
*/
if (scene->active_keyingset == 0) {
BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from");
return OPERATOR_CANCELLED;
}
else
ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
/* try to add to keyingset using property retrieved from UI */
memset(&ptr, 0, sizeof(PointerRNA));
uiAnimContextProperty(C, &ptr, &prop, &index);
if (ptr.data && prop) {
path= RNA_path_from_ID_to_property(&ptr, prop);
if (path) {
KS_Path *ksp;
/* try to find a path matching this description */
ksp= BKE_keyingset_find_destination(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
if (ksp) {
/* just free it... */
MEM_freeN(ksp->rna_path);
BLI_freelinkN(&ks->paths, ksp);
success= 1;
}
/* free temp path used */
MEM_freeN(path);
}
}
if (success) {
/* send updates */
ED_anim_dag_flush_update(C);
/* for now, only send ND_KEYS for KeyingSets */
WM_event_add_notifier(C, ND_KEYS, NULL);
}
return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
}
void ANIM_OT_remove_keyingset_button (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Remove from Keying Set";
ot->idname= "ANIM_OT_remove_keyingset_button";
/* callbacks */
ot->exec= remove_keyingset_button_exec;
//op->poll= ???
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
/* ************************************************** */
/* KEYING SETS - EDITING API */

@ -155,6 +155,12 @@ 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 ********************** */
/* Main Driver Management API calls:

@ -209,6 +209,18 @@ void ui_but_anim_remove_driver(bContext *C)
WM_operator_name_call(C, "ANIM_OT_remove_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_add_keyingset(bContext *C)
{
/* this operator calls uiAnimContextProperty above */
WM_operator_name_call(C, "ANIM_OT_add_keyingset_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_remove_keyingset(bContext *C)
{
/* this operator calls uiAnimContextProperty above */
WM_operator_name_call(C, "ANIM_OT_remove_keyingset_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_menu(bContext *C, uiBut *but)
{
uiPopupMenu *pup;
@ -265,6 +277,20 @@ void ui_but_anim_menu(bContext *C, uiBut *but)
uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0);
}
if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) {
uiItemS(layout);
if(length) {
uiItemBooleanO(layout, "Add All to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 1);
uiItemBooleanO(layout, "Add Single to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 0);
uiItemBooleanO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button", "all", 0);
}
else {
uiItemBooleanO(layout, "Add to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 0);
uiItemBooleanO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button", "all", 0);
}
}
uiPupMenuEnd(C, pup);
}
}

@ -3265,7 +3265,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
ui_but_copy_paste(C, but, data, (event->type == CKEY)? 'c': 'v');
return WM_UI_HANDLER_BREAK;
}
/* handle keyframeing */
/* handle keyframing */
else if(event->type == IKEY && event->val == KM_PRESS) {
if(event->alt)
ui_but_anim_delete_keyframe(C);
@ -3276,7 +3276,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
return WM_UI_HANDLER_BREAK;
}
/* handle driver adding */
/* handle drivers */
else if(event->type == DKEY && event->val == KM_PRESS) {
if(event->alt)
ui_but_anim_remove_driver(C);
@ -3287,6 +3287,17 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
return WM_UI_HANDLER_BREAK;
}
/* handle keyingsets */
else if(event->type == KKEY && event->val == KM_PRESS) {
if(event->alt)
ui_but_anim_remove_keyingset(C);
else
ui_but_anim_remove_keyingset(C);
ED_region_tag_redraw(CTX_wm_region(C));
return WM_UI_HANDLER_BREAK;
}
/* handle menu */
else if(event->type == RIGHTMOUSE && event->val == KM_PRESS) {
/* RMB has two options now */

@ -467,6 +467,8 @@ void ui_but_anim_insert_keyframe(struct bContext *C);
void ui_but_anim_delete_keyframe(struct bContext *C);
void ui_but_anim_add_driver(struct bContext *C);
void ui_but_anim_remove_driver(struct bContext *C);
void ui_but_anim_add_keyingset(struct bContext *C);
void ui_but_anim_remove_keyingset(struct bContext *C);
void ui_but_anim_menu(struct bContext *C, uiBut *but);
int ui_but_anim_expression_get(uiBut *but, char *str, int maxlen);
int ui_but_anim_expression_set(uiBut *but, const char *str);