Blender V2.61 - r43446

interface_anim.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s):
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 
00031 #include "MEM_guardedalloc.h"
00032 
00033 #include "DNA_anim_types.h"
00034 #include "DNA_scene_types.h"
00035 #include "DNA_screen_types.h"
00036 
00037 #include "BLI_listbase.h"
00038 #include "BLI_string.h"
00039 #include "BLI_string_utf8.h"
00040 #include "BLI_utildefines.h"
00041 
00042 #include "BKE_context.h"
00043 #include "BKE_animsys.h"
00044 #include "BKE_fcurve.h"
00045 #include "BKE_global.h"
00046 
00047 #include "ED_keyframing.h"
00048 
00049 #include "UI_interface.h"
00050 
00051 #include "RNA_access.h"
00052 
00053 #include "WM_api.h"
00054 #include "WM_types.h"
00055 
00056 #include "interface_intern.h"
00057 
00058 static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, int *driven)
00059 {
00060     return rna_get_fcurve(&but->rnapoin, but->rnaprop, but->rnaindex, action, driven);
00061 }
00062 
00063 void ui_but_anim_flag(uiBut *but, float cfra)
00064 {
00065     FCurve *fcu;
00066     int driven;
00067 
00068     but->flag &= ~(UI_BUT_ANIMATED|UI_BUT_ANIMATED_KEY|UI_BUT_DRIVEN);
00069 
00070     fcu= ui_but_get_fcurve(but, NULL, &driven);
00071 
00072     if(fcu) {
00073         if(!driven) {
00074             but->flag |= UI_BUT_ANIMATED;
00075             
00076             if(fcurve_frame_has_keyframe(fcu, cfra, 0))
00077                 but->flag |= UI_BUT_ANIMATED_KEY;
00078         }
00079         else {
00080             but->flag |= UI_BUT_DRIVEN;
00081         }
00082     }
00083 }
00084 
00085 int ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen)
00086 {
00087     FCurve *fcu;
00088     ChannelDriver *driver;
00089     int driven;
00090 
00091     fcu= ui_but_get_fcurve(but, NULL, &driven);
00092 
00093     if(fcu && driven) {
00094         driver= fcu->driver;
00095 
00096         if(driver && driver->type == DRIVER_TYPE_PYTHON) {
00097             BLI_strncpy(str, driver->expression, maxlen);
00098             return 1;
00099         }
00100     }
00101 
00102     return 0;
00103 }
00104 
00105 int ui_but_anim_expression_set(uiBut *but, const char *str)
00106 {
00107     FCurve *fcu;
00108     ChannelDriver *driver;
00109     int driven;
00110 
00111     fcu= ui_but_get_fcurve(but, NULL, &driven);
00112 
00113     if(fcu && driven) {
00114         driver= fcu->driver;
00115         
00116         if(driver && driver->type == DRIVER_TYPE_PYTHON) {
00117             BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
00118             driver->flag |= DRIVER_FLAG_RECOMPILE;
00119             WM_event_add_notifier(but->block->evil_C, NC_ANIMATION|ND_KEYFRAME, NULL);
00120             return 1;
00121         }
00122     }
00123 
00124     return 0;
00125 }
00126 
00127 /* create new expression for button (i.e. a "scripted driver"), if it can be created... */
00128 int ui_but_anim_expression_create(uiBut *but, const char *str)
00129 {
00130     bContext *C = but->block->evil_C;
00131     ID *id;
00132     FCurve *fcu;
00133     char *path;
00134     short ok=0;
00135     
00136     /* button must have RNA-pointer to a numeric-capable property */
00137     if (ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
00138         if (G.f & G_DEBUG) 
00139             printf("ERROR: create expression failed - button has no RNA info attached\n");
00140         return 0;
00141     }
00142     
00143     /* make sure we have animdata for this */
00144     // FIXME: until materials can be handled by depsgraph, don't allow drivers to be created for them
00145     id = (ID *)but->rnapoin.id.data;
00146     if ((id == NULL) || (GS(id->name)==ID_MA) || (GS(id->name)==ID_TE)) {
00147         if (G.f & G_DEBUG)
00148             printf("ERROR: create expression failed - invalid id-datablock for adding drivers (%p)\n", id);
00149         return 0;
00150     }
00151     
00152     /* get path */
00153     path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
00154     
00155     /* create driver */
00156     fcu = verify_driver_fcurve(id, path, but->rnaindex, 1);
00157     if (fcu) {
00158         ChannelDriver *driver= fcu->driver;
00159         
00160         if (driver) {
00161             /* set type of driver */
00162             driver->type = DRIVER_TYPE_PYTHON;
00163             
00164             /* set the expression */
00165             // TODO: need some way of identifying variables used
00166             BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
00167 
00168             /* updates */
00169             driver->flag |= DRIVER_FLAG_RECOMPILE;
00170             WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME, NULL);
00171         }
00172     }
00173     
00174     MEM_freeN(path);
00175     
00176     return ok;
00177 }
00178 
00179 void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
00180 {
00181     ID *id;
00182     bAction *action;
00183     FCurve *fcu;
00184     int driven;
00185 
00186     fcu= ui_but_get_fcurve(but, &action, &driven);
00187 
00188     if(fcu && !driven) {
00189         id= but->rnapoin.id.data;
00190         
00191         // TODO: this should probably respect the keyingset only option for anim
00192         if(autokeyframe_cfra_can_key(scene, id)) {
00193             ReportList *reports = CTX_wm_reports(C);
00194             short flag = ANIM_get_keyframing_flags(scene, 1);
00195             
00196             fcu->flag &= ~FCURVE_SELECTED;
00197             insert_keyframe(reports, id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
00198             WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
00199         }
00200     }
00201 }
00202 
00203 void ui_but_anim_insert_keyframe(bContext *C)
00204 {
00205     /* this operator calls uiContextActiveProperty */
00206     WM_operator_name_call(C, "ANIM_OT_keyframe_insert_button", WM_OP_INVOKE_DEFAULT, NULL);
00207 }
00208 
00209 void ui_but_anim_delete_keyframe(bContext *C)
00210 {
00211     /* this operator calls uiContextActiveProperty */
00212     WM_operator_name_call(C, "ANIM_OT_keyframe_delete_button", WM_OP_INVOKE_DEFAULT, NULL);
00213 }
00214 
00215 void ui_but_anim_add_driver(bContext *C)
00216 {
00217     /* this operator calls uiContextActiveProperty */
00218     WM_operator_name_call(C, "ANIM_OT_driver_button_add", WM_OP_INVOKE_DEFAULT, NULL);
00219 }
00220 
00221 void ui_but_anim_remove_driver(bContext *C)
00222 {
00223     /* this operator calls uiContextActiveProperty */
00224     WM_operator_name_call(C, "ANIM_OT_driver_button_remove", WM_OP_INVOKE_DEFAULT, NULL);
00225 }
00226 
00227 void ui_but_anim_copy_driver(bContext *C)
00228 {
00229     /* this operator calls uiContextActiveProperty */
00230     WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
00231 }
00232 
00233 void ui_but_anim_paste_driver(bContext *C)
00234 {
00235     /* this operator calls uiContextActiveProperty */
00236     WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
00237 }
00238 
00239 void ui_but_anim_add_keyingset(bContext *C)
00240 {
00241     /* this operator calls uiContextActiveProperty */
00242     WM_operator_name_call(C, "ANIM_OT_keyingset_button_add", WM_OP_INVOKE_DEFAULT, NULL);
00243 }
00244 
00245 void ui_but_anim_remove_keyingset(bContext *C)
00246 {
00247     /* this operator calls uiContextActiveProperty */
00248     WM_operator_name_call(C, "ANIM_OT_keyingset_button_remove", WM_OP_INVOKE_DEFAULT, NULL);
00249 }