NLA SoC: Merge from 2.5
[blender.git] / source / blender / editors / interface / interface_anim.c
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "MEM_guardedalloc.h"
7
8 #include "DNA_anim_types.h"
9 #include "DNA_scene_types.h"
10 #include "DNA_screen_types.h"
11
12 #include "BLI_listbase.h"
13
14 #include "BKE_animsys.h"
15 #include "BKE_context.h"
16 #include "BKE_fcurve.h"
17
18 #include "RNA_access.h"
19 #include "RNA_types.h"
20
21 #include "ED_keyframing.h"
22
23 #include "UI_interface.h"
24
25 #include "WM_api.h"
26 #include "WM_types.h"
27
28 #include "interface_intern.h"
29
30 void ui_but_anim_flag(uiBut *but, float cfra)
31 {
32         but->flag &= ~(UI_BUT_ANIMATED|UI_BUT_ANIMATED_KEY|UI_BUT_DRIVEN);
33         
34         /* there must be some RNA-pointer + property combo for this button */
35         if (but->rnaprop && but->rnapoin.id.data && 
36                 RNA_property_animateable(&but->rnapoin, but->rnaprop)) 
37         {
38                 AnimData *adt= BKE_animdata_from_id(but->rnapoin.id.data);
39                 FCurve *fcu;
40                 char *path;
41                 
42                 if (adt) {
43                         if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
44                                 /* XXX this function call can become a performance bottleneck */
45                                 path= RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
46                                 
47                                 if (path) {
48                                         /* animation takes priority over drivers */
49                                         if (adt->action && adt->action->curves.first) {
50                                                 fcu= list_find_fcurve(&adt->action->curves, path, but->rnaindex);
51                                                 
52                                                 if (fcu) {
53                                                         but->flag |= UI_BUT_ANIMATED;
54                                                         
55                                                         if (fcurve_frame_has_keyframe(fcu, cfra, 0))
56                                                                 but->flag |= UI_BUT_ANIMATED_KEY;
57                                                 }
58                                         }
59                                         
60                                         /* if not animated, check if driven */
61                                         if ((but->flag & UI_BUT_ANIMATED)==0 && (adt->drivers.first)) {
62                                                 fcu= list_find_fcurve(&adt->drivers, path, but->rnaindex);
63                                                 
64                                                 if (fcu)
65                                                         but->flag |= UI_BUT_DRIVEN;
66                                         }
67                                         
68                                         MEM_freeN(path);
69                                 }
70                         }
71                 }
72         }
73 }
74
75 void uiAnimContextProperty(const bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index)
76 {
77         ARegion *ar= CTX_wm_region(C);
78         uiBlock *block;
79         uiBut *but;
80
81         if(ar) {
82                 for(block=ar->uiblocks.first; block; block=block->next) {
83                         for(but=block->buttons.first; but; but= but->next) {
84                                 if(but->active && but->rnapoin.id.data) {
85                                         *ptr= but->rnapoin;
86                                         *prop= but->rnaprop;
87                                         *index= but->rnaindex;
88                                         return;
89                                 }
90                         }
91                 }
92         }
93 }
94
95 void ui_but_anim_insert_keyframe(bContext *C)
96 {
97         /* this operator calls uiAnimContextProperty above */
98         WM_operator_name_call(C, "ANIM_OT_insert_keyframe_button", WM_OP_INVOKE_DEFAULT, NULL);
99 }
100
101 void ui_but_anim_delete_keyframe(bContext *C)
102 {
103         /* this operator calls uiAnimContextProperty above */
104         WM_operator_name_call(C, "ANIM_OT_delete_keyframe_button", WM_OP_INVOKE_DEFAULT, NULL);
105 }
106
107 void ui_but_anim_add_driver(bContext *C)
108 {
109         /* this operator calls uiAnimContextProperty above */
110         WM_operator_name_call(C, "ANIM_OT_add_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
111 }
112
113 void ui_but_anim_remove_driver(bContext *C)
114 {
115         /* this operator calls uiAnimContextProperty above */
116         WM_operator_name_call(C, "ANIM_OT_remove_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
117 }
118
119 void ui_but_anim_menu(bContext *C, uiBut *but)
120 {
121         uiPopupMenu *pup;
122         uiLayout *layout;
123         int length;
124
125         if(but->rnapoin.data && but->rnaprop) {
126                 pup= uiPupMenuBegin(C, RNA_property_ui_name(but->rnaprop), 0);
127                 layout= uiPupMenuLayout(pup);
128                 
129                 length= RNA_property_array_length(but->rnaprop);
130                 
131                 if(but->flag & UI_BUT_ANIMATED_KEY) {
132                         if(length) {
133                                 uiItemBooleanO(layout, "Replace Keyframes", 0, "ANIM_OT_insert_keyframe_button", "all", 1);
134                                 uiItemBooleanO(layout, "Replace Single Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0);
135                                 uiItemBooleanO(layout, "Delete Keyframes", 0, "ANIM_OT_delete_keyframe_button", "all", 1);
136                                 uiItemBooleanO(layout, "Delete Single Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0);
137                         }
138                         else {
139                                 uiItemBooleanO(layout, "Replace Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0);
140                                 uiItemBooleanO(layout, "Delete Keyframe", 0, "ANIM_OT_delete_keyframe_button", "all", 0);
141                         }
142                 }
143                 else if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) {
144                         if(length) {
145                                 uiItemBooleanO(layout, "Insert Keyframes", 0, "ANIM_OT_insert_keyframe_button", "all", 1);
146                                 uiItemBooleanO(layout, "Insert Single Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0);
147                         }
148                         else 
149                                 uiItemBooleanO(layout, "Insert Keyframe", 0, "ANIM_OT_insert_keyframe_button", "all", 0);
150                 }
151                 
152                 if(but->flag & UI_BUT_DRIVEN) {
153                         uiItemS(layout);
154                         
155                         if(length) {
156                                 uiItemBooleanO(layout, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 1);
157                                 uiItemBooleanO(layout, "Remove Single Driver", 0, "ANIM_OT_remove_driver_button", "all", 0);
158                         }
159                         else
160                                 uiItemBooleanO(layout, "Remove Driver", 0, "ANIM_OT_remove_driver_button", "all", 0);
161                 }
162                 else if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) {
163                         uiItemS(layout);
164                         
165                         if(length) {
166                                 uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 1);
167                                 uiItemBooleanO(layout, "Add Single Driver", 0, "ANIM_OT_add_driver_button", "all", 0);
168                         }
169                         else
170                                 uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0);
171                 }
172
173                 uiPupMenuEnd(C, pup);
174         }
175 }
176