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
path: root/source
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-04-10 17:08:12 +0400
committerJoshua Leung <aligorith@gmail.com>2009-04-10 17:08:12 +0400
commit6593bbaca2ceb248426c55e14ceb21bb46553fd1 (patch)
tree9e778b12484bd6d03c349bcebae4219076c7d09a /source
parentbe8b7ead51a5efb5dbd762075ee52812465ba8d6 (diff)
2.5 - Groundwork for Adding/Removing Drivers
Drivers can now be Added/Removed from buttons using the D/Alt-D hotkeys, and also through the menu. Driver settings (i.e. the target) are not set by default. To set those, go to the Graph Editor (see notes). Notes: * Buildsystem maintainers - I've added a new file "editors/animation/drivers.c" * Widget colours for the driven-setting indications are needed * To see the new drivers, go into Graph Editor -> "Drivers" mode. Currently, there's a little bug there which prevents editing of the new drivers.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/animation/anim_ops.c3
-rw-r--r--source/blender/editors/animation/drivers.c289
-rw-r--r--source/blender/editors/animation/keyframing.c2
-rw-r--r--source/blender/editors/include/ED_keyframing.h17
-rw-r--r--source/blender/editors/include/UI_interface.h1
-rw-r--r--source/blender/editors/interface/interface_anim.c66
-rw-r--r--source/blender/editors/interface/interface_handlers.c11
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_widgets.c2
9 files changed, 376 insertions, 17 deletions
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index b7a59822e71..e899cc1d520 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -386,6 +386,9 @@ void ED_operatortypes_anim(void)
WM_operatortype_append(ANIM_OT_delete_keyframe_button);
WM_operatortype_append(ANIM_OT_delete_keyframe_old); // xxx remove?
+ WM_operatortype_append(ANIM_OT_add_driver_button);
+ WM_operatortype_append(ANIM_OT_remove_driver_button);
+
WM_operatortype_append(ANIM_OT_keyingset_add_new);
WM_operatortype_append(ANIM_OT_keyingset_add_destination);
}
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
new file mode 100644
index 00000000000..15aad71f224
--- /dev/null
+++ b/source/blender/editors/animation/drivers.c
@@ -0,0 +1,289 @@
+/* Testing code for 2.5 animation system
+ * Copyright 2009, Joshua Leung
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_dynstr.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_constraint.h"
+#include "BKE_fcurve.h"
+#include "BKE_utildefines.h"
+#include "BKE_context.h"
+#include "BKE_report.h"
+#include "BKE_key.h"
+#include "BKE_material.h"
+
+#include "ED_anim_api.h"
+#include "ED_keyframing.h"
+#include "ED_keyframes_edit.h"
+#include "ED_screen.h"
+#include "ED_util.h"
+
+#include "UI_interface.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+/* ************************************************** */
+/* Animation Data Validation */
+
+/* Get (or add relevant data to be able to do so) F-Curve from the driver stack,
+ * for the given Animation Data block. This assumes that all the destinations are valid.
+ */
+FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_index, short add)
+{
+ AnimData *adt;
+ FCurve *fcu;
+
+ /* sanity checks */
+ if ELEM(NULL, id, rna_path)
+ return NULL;
+
+ /* init animdata if none available yet */
+ adt= BKE_animdata_from_id(id);
+ if ((adt == NULL) && (add))
+ adt= BKE_id_add_animdata(id);
+ if (adt == NULL) {
+ /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
+ return NULL;
+ }
+
+ /* try to find f-curve matching for this setting
+ * - add if not found and allowed to add one
+ * TODO: add auto-grouping support? how this works will need to be resolved
+ */
+ fcu= list_find_fcurve(&adt->drivers, rna_path, array_index);
+
+ if ((fcu == NULL) && (add)) {
+ /* use default settings to make a F-Curve */
+ fcu= MEM_callocN(sizeof(FCurve), "FCurve");
+
+ fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
+
+ /* store path - make copy, and store that */
+ fcu->rna_path= BLI_strdupn(rna_path, strlen(rna_path));
+ fcu->array_index= array_index;
+
+ /* add some new driver data */
+ fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
+
+ /* just add F-Curve to end of driver list */
+ BLI_addtail(&adt->drivers, fcu);
+ }
+
+ /* return the F-Curve */
+ return fcu;
+}
+
+/* ************************************************** */
+/* Driver Management API */
+
+/* Main Driver Management API calls:
+ * Add a new driver for the specified property on the given ID block
+ */
+short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short flag)
+{
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ FCurve *fcu;
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
+ printf("Insert Key: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
+ return 0;
+ }
+
+ /* create F-Curve with Driver */
+ fcu= verify_driver_fcurve(id, rna_path, array_index, 1);
+
+ /* done */
+ return (fcu != NULL);
+}
+
+/* Main Driver Management API calls:
+ * Remove the driver for the specified property on the given ID block (if available)
+ */
+short ANIM_remove_driver (struct ID *id, const char rna_path[], int array_index, short flag)
+{
+ AnimData *adt;
+ FCurve *fcu;
+
+ /* get F-Curve
+ * Note: here is one of the places where we don't want new F-Curve + Driver added!
+ * so 'add' var must be 0
+ */
+ /* we don't check the validity of the path here yet, but it should be ok... */
+ fcu= verify_driver_fcurve(id, rna_path, array_index, 0);
+ adt= BKE_animdata_from_id(id);
+
+ /* only continue if we have an driver to remove */
+ if (adt && fcu) {
+ /* remove F-Curve from driver stack, then free it */
+ BLI_remlink(&adt->drivers, fcu);
+ free_fcurve(fcu);
+
+ /* done successfully */
+ return 1;
+ }
+
+ /* failed */
+ return 0;
+}
+
+
+/* ************************************************** */
+/* UI-Button Interface */
+
+/* Add Driver Button Operator ------------------------ */
+
+static int add_driver_button_exec (bContext *C, wmOperator *op)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop= NULL;
+ char *path;
+ short success= 0;
+ int a, index, length, all= RNA_boolean_get(op->ptr, "all");
+
+ /* try to insert keyframe using property retrieved from UI */
+ memset(&ptr, 0, sizeof(PointerRNA));
+ uiAnimContextProperty(C, &ptr, &prop, &index);
+
+ if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) {
+ path= RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ if (all) {
+ length= RNA_property_array_length(&ptr, prop);
+
+ if (length) index= 0;
+ else length= 1;
+ }
+ else
+ length= 1;
+
+ for (a=0; a<length; a++)
+ success+= ANIM_add_driver(ptr.id.data, path, index+a, 0);
+
+ 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); // XXX
+ }
+
+ return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
+}
+
+void ANIM_OT_add_driver_button (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Driver";
+ ot->idname= "ANIM_OT_add_driver_button";
+
+ /* callbacks */
+ ot->exec= add_driver_button_exec;
+ //op->poll= ???
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Insert a keyframe for all element of the array.");
+}
+
+/* Remove Driver Button Operator ------------------------ */
+
+static int remove_driver_button_exec (bContext *C, wmOperator *op)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop= NULL;
+ char *path;
+ short success= 0;
+ int a, index, length, all= RNA_boolean_get(op->ptr, "all");
+
+ /* try to insert keyframe 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) {
+ if (all) {
+ length= RNA_property_array_length(&ptr, prop);
+
+ if(length) index= 0;
+ else length= 1;
+ }
+ else
+ length= 1;
+
+ for (a=0; a<length; a++)
+ success+= ANIM_remove_driver(ptr.id.data, path, index+a, 0);
+
+ 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); // XXX
+ }
+
+ return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
+}
+
+void ANIM_OT_remove_driver_button (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove Driver";
+ ot->idname= "ANIM_OT_remove_driver_button";
+
+ /* callbacks */
+ ot->exec= remove_driver_button_exec;
+ //op->poll= ???
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyfames from all elements of the array.");
+}
+
+/* ************************************************** */
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index f6d23af932a..d87e61ae9ad 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -825,7 +825,7 @@ short deletekey (ID *id, const char group[], const char rna_path[], int array_in
fcu= verify_fcurve(id, group, rna_path, array_index, 0);
adt= BKE_animdata_from_id(id);
- /* only continue if we have an ipo-curve to remove keyframes from */
+ /* only continue if we have an F-Curve to remove keyframes from */
if (adt && adt->action && fcu) {
bAction *act= adt->action;
short found = -1;
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 5e4e0d4a44d..98a44d3ef2b 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -95,10 +95,25 @@ void ANIM_OT_delete_keyframe_menu(struct wmOperatorType *ot); // xxx unimplement
void ANIM_OT_delete_keyframe_old(struct wmOperatorType *ot); // xxx rename and keep?
/* Keyframe managment operators for UI buttons. */
-
void ANIM_OT_insert_keyframe_button(struct wmOperatorType *ot);
void ANIM_OT_delete_keyframe_button(struct wmOperatorType *ot);
+/* ************ Drivers ********************** */
+
+/* Main Driver Management API calls:
+ * Add a new driver for the specified property on the given ID block
+ */
+short ANIM_add_driver (struct ID *id, const char rna_path[], int array_index, short flag);
+
+/* Main Driver Management API calls:
+ * Remove the driver for the specified property on the given ID block (if available)
+ */
+short ANIM_remove_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);
+
/* ************ Auto-Keyframing ********************** */
/* Notes:
* - All the defines for this (User-Pref settings and Per-Scene settings)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 7c36f89cb41..9c8cba94fae 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -133,6 +133,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle;
#define UI_NO_HILITE (1<<19)
#define UI_BUT_ANIMATED (1<<20)
#define UI_BUT_ANIMATED_KEY (1<<21)
+#define UI_BUT_DRIVEN (1<<22)
/* Button types, bits stored in 1 value... and a short even!
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 75fe8331184..3b89fbddebc 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -27,28 +27,41 @@
void ui_but_anim_flag(uiBut *but, float cfra)
{
- but->flag &= ~(UI_BUT_ANIMATED|UI_BUT_ANIMATED_KEY);
+ but->flag &= ~(UI_BUT_ANIMATED|UI_BUT_ANIMATED_KEY|UI_BUT_DRIVEN);
if(but->rnaprop && but->rnapoin.id.data) {
AnimData *adt= BKE_animdata_from_id(but->rnapoin.id.data);
FCurve *fcu;
char *path;
- if(adt && adt->action && adt->action->curves.first) {
- /* XXX this function call can become a performance bottleneck */
- path= RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
-
- if(path) {
- fcu= list_find_fcurve(&adt->action->curves, path, but->rnaindex);
-
- if(fcu) {
- but->flag |= UI_BUT_ANIMATED;
-
- if(on_keyframe_fcurve(fcu, cfra))
- but->flag |= UI_BUT_ANIMATED_KEY;
+ if (adt) {
+ if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
+ /* XXX this function call can become a performance bottleneck */
+ path= RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
+
+ if (path) {
+ /* animation takes priority over drivers */
+ if (adt->action && adt->action->curves.first) {
+ fcu= list_find_fcurve(&adt->action->curves, path, but->rnaindex);
+
+ if (fcu) {
+ but->flag |= UI_BUT_ANIMATED;
+
+ if (on_keyframe_fcurve(fcu, cfra))
+ but->flag |= UI_BUT_ANIMATED_KEY;
+ }
+ }
+
+ /* if not animated, check if driven */
+ if ((but->flag & UI_BUT_ANIMATED)==0 && (adt->drivers.first)) {
+ fcu= list_find_fcurve(&adt->drivers, path, but->rnaindex);
+
+ if (fcu)
+ but->flag |= UI_BUT_DRIVEN;
+ }
+
+ MEM_freeN(path);
}
-
- MEM_freeN(path);
}
}
}
@@ -86,6 +99,19 @@ void ui_but_anim_delete_keyframe(bContext *C)
WM_operator_name_call(C, "ANIM_OT_delete_keyframe_button", WM_OP_INVOKE_DEFAULT, NULL);
}
+void ui_but_anim_add_driver(bContext *C)
+{
+ /* this operator calls uiAnimContextProperty above */
+ WM_operator_name_call(C, "ANIM_OT_add_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
+}
+
+void ui_but_anim_remove_driver(bContext *C)
+{
+ /* this operator calls uiAnimContextProperty above */
+ WM_operator_name_call(C, "ANIM_OT_remove_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
+}
+
+// TODO: refine the logic for adding/removing drivers...
void ui_but_anim_menu(bContext *C, uiBut *but)
{
uiMenuItem *head;
@@ -100,18 +126,28 @@ void ui_but_anim_menu(bContext *C, uiBut *but)
if(length) {
uiMenuItemBooleanO(head, "Delete Keyframes", 0, "ANIM_OT_delete_keyframe_button", "all", 1);
uiMenuItemBooleanO(head, "Delete Single Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0);
+
+ uiMenuItemBooleanO(head, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 1);
+ uiMenuItemBooleanO(head, "Remove Single Driver", 0, "ANIM_OT_remove_driver_button", "all", 0);
}
else {
uiMenuItemBooleanO(head, "Delete Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0);
+
+ uiMenuItemBooleanO(head, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 0);
}
}
else if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) {
if(length) {
uiMenuItemBooleanO(head, "Insert Keyframes", 0, "ANIM_OT_insert_keyframe_button", "all", 1);
uiMenuItemBooleanO(head, "Insert Single Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0);
+
+ uiMenuItemBooleanO(head, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 1);
+ uiMenuItemBooleanO(head, "Add Single Driver", 0, "ANIM_OT_add_driver_button", "all", 0);
}
else {
uiMenuItemBooleanO(head, "Insert Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0);
+
+ uiMenuItemBooleanO(head, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0);
}
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 6fc0ad37ee3..b41fe7b9b7d 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2610,6 +2610,17 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
return WM_UI_HANDLER_BREAK;
}
+ /* handle driver adding */
+ else if(event->type == DKEY && event->val == KM_PRESS) {
+ if(event->alt)
+ ui_but_anim_remove_driver(C);
+ else
+ ui_but_anim_add_driver(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) {
ui_but_anim_menu(C, but);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 2e975c871cf..8061d075e22 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -393,6 +393,8 @@ void uiStyleExit(void);
void ui_but_anim_flag(uiBut *but, float cfra);
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_menu(struct bContext *C, uiBut *but);
#endif
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 958cde4efe4..d226ee4a45e 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1053,6 +1053,8 @@ static void widget_state(uiWidgetType *wt, int state)
QUATCOPY(wt->wcol.inner, wt->wcol.inner_key_sel)
else if(state & UI_BUT_ANIMATED)
QUATCOPY(wt->wcol.inner, wt->wcol.inner_anim_sel)
+ //else if(state & UI_BUT_DRIVEN)
+ // QUATCOPY(wt->wcol.inner, wt->wcol.inner_driven_sel)
else
QUATCOPY(wt->wcol.inner, wt->wcol.inner_sel)