use armature active bone as a pointer rather then a flag for each bone that needs...
[blender.git] / source / blender / editors / screen / screen_context.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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. 
10  *
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.
15  *
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "DNA_object_types.h"
31 #include "DNA_armature_types.h"
32 #include "DNA_action_types.h"
33 #include "DNA_scene_types.h"
34 #include "DNA_screen_types.h"
35
36 #include "BKE_context.h"
37 #include "BKE_utildefines.h"
38 #include "BKE_global.h"
39 #include "BKE_action.h"
40
41 #include "RNA_access.h"
42
43 #include "ED_object.h"
44 #include "ED_armature.h"
45
46 int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
47 {
48         bScreen *sc= CTX_wm_screen(C);
49         Scene *scene= sc->scene;
50         Base *base;
51
52 #if 0   /* Using the context breaks adding objects in the UI. Need to find out why - campbell */
53         Object *obact= CTX_data_active_object(C);
54         Object *obedit= CTX_data_edit_object(C);
55         base= CTX_data_active_base(C);
56 #else
57         Object *obedit= scene->obedit; 
58         Object *obact= OBACT;
59         base= BASACT;
60 #endif
61
62         if(CTX_data_dir(member)) {
63                 static const char *dir[] = {
64                         "scene", "selected_objects", "selected_bases",
65                         "selected_editable_objects", "selected_editable_bases",
66                         "visible_bones", "editable_bones", "selected_bones", "selected_editable_bones",
67                         "visible_pchans", "selected_pchans", "active_bone", "active_pchan",
68                         "active_base", "active_object", "edit_object",
69                         "sculpt_object", "vertex_paint_object", "weight_paint_object",
70                         "texture_paint_object", "brush", "particle_edit_object", NULL};
71
72                 CTX_data_dir_set(result, dir);
73                 return 1;
74         }
75         else if(CTX_data_equals(member, "scene")) {
76                 CTX_data_id_pointer_set(result, &scene->id);
77                 return 1;
78         }
79         else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
80                 int selected_objects= CTX_data_equals(member, "selected_objects");
81
82                 for(base=scene->base.first; base; base=base->next) {
83                         if((base->flag & SELECT) && (base->lay & scene->lay)) {
84                                 if(selected_objects)
85                                         CTX_data_id_list_add(result, &base->object->id);
86                                 else
87                                         CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
88                         }
89                 }
90
91                 return 1;
92         }
93         else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
94                 int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects");
95
96                 for(base=scene->base.first; base; base=base->next) {
97                         if((base->flag & SELECT) && (base->lay & scene->lay)) {
98                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
99                                         if(0==object_is_libdata(base->object)) {
100                                                 if(selected_editable_objects)
101                                                         CTX_data_id_list_add(result, &base->object->id);
102                                                 else
103                                                         CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
104                                         }
105                                 }
106                         }
107                 }
108
109                 return 1;
110         }
111         else if(CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
112                 bArmature *arm= (obedit) ? obedit->data : NULL;
113                 EditBone *ebone, *flipbone=NULL;
114                 int editable_bones= CTX_data_equals(member, "editable_bones");
115                 
116                 if (arm && arm->edbo) {
117                         /* Attention: X-Axis Mirroring is also handled here... */
118                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
119                                 /* first and foremost, bone must be visible and selected */
120                                 if (EBONE_VISIBLE(arm, ebone)) {
121                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
122                                          * so that most users of this data don't need to explicitly check for it themselves.
123                                          * 
124                                          * We need to make sure that these mirrored copies are not selected, otherwise some
125                                          * bones will be operated on twice.
126                                          */
127                                         if (arm->flag & ARM_MIRROR_EDIT)
128                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
129                                         
130                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
131                                         if (editable_bones) {
132                                                 /* only selected + editable */
133                                                 if (EBONE_EDITABLE(ebone)) {
134                                                         CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
135                                                 
136                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
137                                                                 CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
138                                                 }
139                                         }
140                                         else {
141                                                 /* only include bones if visible */
142                                                 CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
143                                                 
144                                                 if ((flipbone) && EBONE_VISIBLE(arm, flipbone)==0)
145                                                         CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
146                                         }
147                                 }
148                         }       
149                         
150                         return 1;
151                 }
152         }
153         else if(CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
154                 bArmature *arm= (obedit) ? obedit->data : NULL;
155                 EditBone *ebone, *flipbone=NULL;
156                 int selected_editable_bones= CTX_data_equals(member, "selected_editable_bones");
157                 
158                 if (arm && arm->edbo) {
159                         /* Attention: X-Axis Mirroring is also handled here... */
160                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
161                                 /* first and foremost, bone must be visible and selected */
162                                 if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
163                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
164                                          * so that most users of this data don't need to explicitly check for it themselves.
165                                          * 
166                                          * We need to make sure that these mirrored copies are not selected, otherwise some
167                                          * bones will be operated on twice.
168                                          */
169                                         if (arm->flag & ARM_MIRROR_EDIT)
170                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
171                                         
172                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
173                                         if (selected_editable_bones) {
174                                                 /* only selected + editable */
175                                                 if (EBONE_EDITABLE(ebone)) {
176                                                         CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
177                                                 
178                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
179                                                                 CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
180                                                 }
181                                         }
182                                         else {
183                                                 /* only include bones if selected */
184                                                 CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
185                                                 
186                                                 if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
187                                                         CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
188                                         }
189                                 }
190                         }       
191                         
192                         return 1;
193                 }
194         }
195         else if(CTX_data_equals(member, "visible_pchans")) {
196                 bArmature *arm= (obact) ? obact->data : NULL;
197                 bPoseChannel *pchan;
198                 
199                 if (obact && obact->pose && arm) {
200                         for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) {
201                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
202                                 if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
203                                         CTX_data_list_add(result, &obact->id, &RNA_PoseChannel, pchan);
204                                 }
205                         }
206                         
207                         return 1;
208                 }
209         }
210         else if(CTX_data_equals(member, "selected_pchans")) {
211                 bArmature *arm= (obact) ? obact->data : NULL;
212                 bPoseChannel *pchan;
213                 
214                 if (obact && obact->pose && arm) {
215                         for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) {
216                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
217                                 if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
218                                         if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone)
219                                                 CTX_data_list_add(result, &obact->id, &RNA_PoseChannel, pchan);
220                                 }
221                         }
222                         
223                         return 1;
224                 }
225         }
226         else if(CTX_data_equals(member, "active_bone")) {
227                 bArmature *arm= (obact) ? obact->data : NULL;
228                 if(arm->edbo) {
229                         if(arm->act_edbone) {
230                                 CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
231                                 return 1;
232                         }
233                 }
234                 else {
235                         if(arm->act_bone) {
236                                 CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
237                                 return 1;
238                         }
239                 }
240         }
241         else if(CTX_data_equals(member, "active_pchan")) {
242                 bPoseChannel *pchan;
243                 
244                 pchan= get_active_posechannel(obact);
245                 if (pchan) {
246                         CTX_data_pointer_set(result, &obact->id, &RNA_PoseChannel, pchan);
247                         return 1;
248                 }
249         }
250         else if(CTX_data_equals(member, "active_base")) {
251                 if(base)
252                         CTX_data_pointer_set(result, &scene->id, &RNA_UnknownType, base);
253
254                 return 1;
255         }
256         else if(CTX_data_equals(member, "active_object")) {
257                 if(obact)
258                         CTX_data_id_pointer_set(result, &obact->id);
259
260                 return 1;
261         }
262         else if(CTX_data_equals(member, "object")) {
263                 if(obact)
264                         CTX_data_id_pointer_set(result, &obact->id);
265
266                 return 1;
267         }
268         else if(CTX_data_equals(member, "edit_object")) {
269                 /* convenience for now, 1 object per scene in editmode */
270                 if(obedit)
271                         CTX_data_id_pointer_set(result, &obedit->id);
272                 
273                 return 1;
274         }
275         else if(CTX_data_equals(member, "sculpt_object")) {
276                 if(obact && (obact->mode & OB_MODE_SCULPT))
277                         CTX_data_id_pointer_set(result, &obact->id);
278
279                 return 1;
280         }
281         else if(CTX_data_equals(member, "vertex_paint_object")) {
282                 if(obact && (obact->mode & OB_MODE_VERTEX_PAINT))
283                         CTX_data_id_pointer_set(result, &obact->id);
284
285                 return 1;
286         }
287         else if(CTX_data_equals(member, "weight_paint_object")) {
288                 if(obact && (obact->mode & OB_MODE_WEIGHT_PAINT))
289                         CTX_data_id_pointer_set(result, &obact->id);
290
291                 return 1;
292         }
293         else if(CTX_data_equals(member, "texture_paint_object")) {
294                 if(obact && (obact->mode & OB_MODE_TEXTURE_PAINT))
295                         CTX_data_id_pointer_set(result, &obact->id);
296
297                 return 1;
298         }
299         else if(CTX_data_equals(member, "particle_edit_object")) {
300                 if(obact && (obact->mode & OB_MODE_PARTICLE_EDIT))
301                         CTX_data_id_pointer_set(result, &obact->id);
302
303                 return 1;
304         }
305
306         return 0;
307 }
308