4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * ***** END GPL LICENSE BLOCK *****
25 /** \file blender/editors/interface/interface_anim.c
26 * \ingroup edinterface
33 #include "MEM_guardedalloc.h"
35 #include "DNA_anim_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_screen_types.h"
39 #include "BLI_listbase.h"
40 #include "BLI_string.h"
41 #include "BLI_utildefines.h"
43 #include "BKE_context.h"
44 #include "BKE_animsys.h"
45 #include "BKE_fcurve.h"
46 #include "BKE_global.h"
48 #include "ED_keyframing.h"
50 #include "UI_interface.h"
52 #include "RNA_access.h"
57 #include "interface_intern.h"
59 static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, int *driven)
61 return rna_get_fcurve(&but->rnapoin, but->rnaprop, but->rnaindex, action, driven);
64 void ui_but_anim_flag(uiBut *but, float cfra)
69 but->flag &= ~(UI_BUT_ANIMATED|UI_BUT_ANIMATED_KEY|UI_BUT_DRIVEN);
71 fcu= ui_but_get_fcurve(but, NULL, &driven);
75 but->flag |= UI_BUT_ANIMATED;
77 if(fcurve_frame_has_keyframe(fcu, cfra, 0))
78 but->flag |= UI_BUT_ANIMATED_KEY;
81 but->flag |= UI_BUT_DRIVEN;
86 int ui_but_anim_expression_get(uiBut *but, char *str, int maxlen)
89 ChannelDriver *driver;
92 fcu= ui_but_get_fcurve(but, NULL, &driven);
97 if(driver && driver->type == DRIVER_TYPE_PYTHON) {
98 BLI_strncpy(str, driver->expression, maxlen);
106 int ui_but_anim_expression_set(uiBut *but, const char *str)
109 ChannelDriver *driver;
112 fcu= ui_but_get_fcurve(but, NULL, &driven);
117 if(driver && driver->type == DRIVER_TYPE_PYTHON) {
118 BLI_strncpy(driver->expression, str, sizeof(driver->expression));
119 driver->flag |= DRIVER_FLAG_RECOMPILE;
120 WM_event_add_notifier(but->block->evil_C, NC_ANIMATION|ND_KEYFRAME, NULL);
128 /* create new expression for button (i.e. a "scripted driver"), if it can be created... */
129 int ui_but_anim_expression_create(uiBut *but, const char *str)
131 bContext *C = but->block->evil_C;
137 /* button must have RNA-pointer to a numeric-capable property */
138 if (ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
140 printf("ERROR: create expression failed - button has no RNA info attached\n");
144 /* make sure we have animdata for this */
145 // FIXME: until materials can be handled by depsgraph, don't allow drivers to be created for them
146 id = (ID *)but->rnapoin.id.data;
147 if ((id == NULL) || (GS(id->name)==ID_MA) || (GS(id->name)==ID_TE)) {
149 printf("ERROR: create expression failed - invalid id-datablock for adding drivers (%p)\n", id);
154 path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
157 fcu = verify_driver_fcurve(id, path, but->rnaindex, 1);
159 ChannelDriver *driver= fcu->driver;
162 /* set type of driver */
163 driver->type = DRIVER_TYPE_PYTHON;
165 /* set the expression */
166 // TODO: need some way of identifying variables used
167 BLI_strncpy(driver->expression, str, sizeof(driver->expression));
169 /* FIXME: for now, assume that
170 * - for expressions, users are likely to be using "frame" -> current frame" as a variable
171 * - driver_add_new_variable() adds a single-prop variable by default
177 dvar = driver_add_new_variable(driver);
178 BLI_strncpy(dvar->name, "frame", sizeof(dvar->name));
180 dtar = &dvar->targets[0];
181 dtar->id = (ID *)CTX_data_scene(C); // XXX: should we check that C is valid first?
182 dtar->rna_path = BLI_sprintfN("frame_current");
186 driver->flag |= DRIVER_FLAG_RECOMPILE;
187 WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME, NULL);
196 void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
203 fcu= ui_but_get_fcurve(but, &action, &driven);
206 id= but->rnapoin.id.data;
208 // TODO: this should probably respect the keyingset only option for anim
209 if(autokeyframe_cfra_can_key(scene, id)) {
210 ReportList *reports = CTX_wm_reports(C);
211 short flag = ANIM_get_keyframing_flags(scene, 1);
213 fcu->flag &= ~FCURVE_SELECTED;
214 insert_keyframe(reports, id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
215 WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
220 void ui_but_anim_insert_keyframe(bContext *C)
222 /* this operator calls uiContextActiveProperty */
223 WM_operator_name_call(C, "ANIM_OT_keyframe_insert_button", WM_OP_INVOKE_DEFAULT, NULL);
226 void ui_but_anim_delete_keyframe(bContext *C)
228 /* this operator calls uiContextActiveProperty */
229 WM_operator_name_call(C, "ANIM_OT_keyframe_delete_button", WM_OP_INVOKE_DEFAULT, NULL);
232 void ui_but_anim_add_driver(bContext *C)
234 /* this operator calls uiContextActiveProperty */
235 WM_operator_name_call(C, "ANIM_OT_driver_button_add", WM_OP_INVOKE_DEFAULT, NULL);
238 void ui_but_anim_remove_driver(bContext *C)
240 /* this operator calls uiContextActiveProperty */
241 WM_operator_name_call(C, "ANIM_OT_driver_button_remove", WM_OP_INVOKE_DEFAULT, NULL);
244 void ui_but_anim_copy_driver(bContext *C)
246 /* this operator calls uiContextActiveProperty */
247 WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
250 void ui_but_anim_paste_driver(bContext *C)
252 /* this operator calls uiContextActiveProperty */
253 WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
256 void ui_but_anim_add_keyingset(bContext *C)
258 /* this operator calls uiContextActiveProperty */
259 WM_operator_name_call(C, "ANIM_OT_keyingset_button_add", WM_OP_INVOKE_DEFAULT, NULL);
262 void ui_but_anim_remove_keyingset(bContext *C)
264 /* this operator calls uiContextActiveProperty */
265 WM_operator_name_call(C, "ANIM_OT_keyingset_button_remove", WM_OP_INVOKE_DEFAULT, NULL);