move ED_object_pose_armature --> object_pose_armature_get to so we dont get bad level...
[blender-staging.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 /** \file blender/editors/screen/screen_context.c
28  *  \ingroup edscr
29  */
30
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "DNA_object_types.h"
36 #include "DNA_armature_types.h"
37 #include "DNA_sequence_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_screen_types.h"
40
41 #include "BLI_utildefines.h"
42
43
44 #include "BKE_context.h"
45 #include "BKE_object.h"
46 #include "BKE_action.h"
47 #include "BKE_armature.h"
48 #include "BKE_sequencer.h"
49
50 #include "RNA_access.h"
51
52 #include "ED_object.h"
53 #include "ED_armature.h"
54
55 #include "screen_intern.h"
56
57 const char *screen_context_dir[] = {
58         "scene", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
59         "selected_objects", "selected_bases",
60         "selected_editable_objects", "selected_editable_bases",
61         "visible_bones", "editable_bones", "selected_bones", "selected_editable_bones",
62         "visible_pose_bones", "selected_pose_bones", "active_bone", "active_pose_bone",
63         "active_base", "active_object", "object", "edit_object",
64         "sculpt_object", "vertex_paint_object", "weight_paint_object",
65         "image_paint_object", "particle_edit_object",
66         "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
67         NULL};
68
69 int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
70 {
71         bScreen *sc= CTX_wm_screen(C);
72         Scene *scene= sc->scene;
73         Base *base;
74         unsigned int lay = scene->lay;
75
76 #if 0   /* Using the context breaks adding objects in the UI. Need to find out why - campbell */
77         Object *obact= CTX_data_active_object(C);
78         Object *obedit= CTX_data_edit_object(C);
79         base= CTX_data_active_base(C);
80 #else
81         Object *obedit= scene->obedit; 
82         Object *obact= OBACT;
83         base= BASACT;
84 #endif
85
86         if(CTX_data_dir(member)) {
87                 CTX_data_dir_set(result, screen_context_dir);
88                 return 1;
89         }
90         else if(CTX_data_equals(member, "scene")) {
91                 CTX_data_id_pointer_set(result, &scene->id);
92                 return 1;
93         }
94         else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
95                 int visible_objects= CTX_data_equals(member, "visible_objects");
96
97                 for(base=scene->base.first; base; base=base->next) {
98                         if(((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & scene->lay)) {
99                                 if(visible_objects)
100                                         CTX_data_id_list_add(result, &base->object->id);
101                                 else
102                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
103                         }
104                 }
105                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
106                 return 1;
107         }
108         else if(CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
109                 int selectable_objects= CTX_data_equals(member, "selectable_objects");
110
111                 for(base=scene->base.first; base; base=base->next) {
112                         if(base->lay & lay) {
113                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0 && (base->object->restrictflag & OB_RESTRICT_SELECT)==0) {
114                                         if(selectable_objects)
115                                                 CTX_data_id_list_add(result, &base->object->id);
116                                         else
117                                                 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
118                                 }
119                         }
120                 }
121                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
122                 return 1;
123         }
124         else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
125                 int selected_objects= CTX_data_equals(member, "selected_objects");
126
127                 for(base=scene->base.first; base; base=base->next) {
128                         if((base->flag & SELECT) && (base->lay & scene->lay)) {
129                                 if(selected_objects)
130                                         CTX_data_id_list_add(result, &base->object->id);
131                                 else
132                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
133                         }
134                 }
135                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
136                 return 1;
137         }
138         else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
139                 int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects");
140
141                 for(base=scene->base.first; base; base=base->next) {
142                         if((base->flag & SELECT) && (base->lay & scene->lay)) {
143                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
144                                         if(0==object_is_libdata(base->object)) {
145                                                 if(selected_editable_objects)
146                                                         CTX_data_id_list_add(result, &base->object->id);
147                                                 else
148                                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
149                                         }
150                                 }
151                         }
152                 }
153                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
154                 return 1;
155         }
156         else if(CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
157                 bArmature *arm= (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
158                 EditBone *ebone, *flipbone=NULL;
159                 int editable_bones= CTX_data_equals(member, "editable_bones");
160                 
161                 if (arm && arm->edbo) {
162                         /* Attention: X-Axis Mirroring is also handled here... */
163                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
164                                 /* first and foremost, bone must be visible and selected */
165                                 if (EBONE_VISIBLE(arm, ebone)) {
166                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
167                                          * so that most users of this data don't need to explicitly check for it themselves.
168                                          * 
169                                          * We need to make sure that these mirrored copies are not selected, otherwise some
170                                          * bones will be operated on twice.
171                                          */
172                                         if (arm->flag & ARM_MIRROR_EDIT)
173                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
174                                         
175                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
176                                         if (editable_bones) {
177                                                 /* only selected + editable */
178                                                 if (EBONE_EDITABLE(ebone)) {
179                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
180                                                 
181                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
182                                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
183                                                 }
184                                         }
185                                         else {
186                                                 /* only include bones if visible */
187                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
188                                                 
189                                                 if ((flipbone) && EBONE_VISIBLE(arm, flipbone)==0)
190                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
191                                         }
192                                 }
193                         }       
194                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
195                         return 1;
196                 }
197         }
198         else if(CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
199                 bArmature *arm= (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
200                 EditBone *ebone, *flipbone=NULL;
201                 int selected_editable_bones= CTX_data_equals(member, "selected_editable_bones");
202                 
203                 if (arm && arm->edbo) {
204                         /* Attention: X-Axis Mirroring is also handled here... */
205                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
206                                 /* first and foremost, bone must be visible and selected */
207                                 if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
208                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
209                                          * so that most users of this data don't need to explicitly check for it themselves.
210                                          * 
211                                          * We need to make sure that these mirrored copies are not selected, otherwise some
212                                          * bones will be operated on twice.
213                                          */
214                                         if (arm->flag & ARM_MIRROR_EDIT)
215                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
216                                         
217                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
218                                         if (selected_editable_bones) {
219                                                 /* only selected + editable */
220                                                 if (EBONE_EDITABLE(ebone)) {
221                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
222                                                 
223                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
224                                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
225                                                 }
226                                         }
227                                         else {
228                                                 /* only include bones if selected */
229                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
230                                                 
231                                                 if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
232                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
233                                         }
234                                 }
235                         }       
236                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
237                         return 1;
238                 }
239         }
240         else if(CTX_data_equals(member, "visible_pose_bones")) {
241                 Object *obpose= object_pose_armature_get(obact);
242                 bArmature *arm= (obpose) ? obpose->data : NULL;
243                 bPoseChannel *pchan;
244                 
245                 if (obpose && obpose->pose && arm) {
246                         for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) {
247                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
248                                 if (PBONE_VISIBLE(arm, pchan->bone)) {
249                                         CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
250                                 }
251                         }
252                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
253                         return 1;
254                 }
255         }
256         else if(CTX_data_equals(member, "selected_pose_bones")) {
257                 Object *obpose= object_pose_armature_get(obact);
258                 bArmature *arm= (obpose) ? obpose->data : NULL;
259                 bPoseChannel *pchan;
260                 
261                 if (obpose && obpose->pose && arm) {
262                         for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) {
263                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
264                                 if (PBONE_VISIBLE(arm, pchan->bone)) {
265                                         if (pchan->bone->flag & BONE_SELECTED)
266                                                 CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
267                                 }
268                         }
269                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
270                         return 1;
271                 }
272         }
273         else if(CTX_data_equals(member, "active_bone")) {
274                 if(obact && obact->type == OB_ARMATURE) {
275                         bArmature *arm= obact->data;
276                         if(arm->edbo) {
277                                 if(arm->act_edbone) {
278                                         CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
279                                         return 1;
280                                 }
281                         }
282                         else {
283                                 if(arm->act_bone) {
284                                         CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
285                                         return 1;
286                                 }
287                         }
288                 }
289         }
290         else if(CTX_data_equals(member, "active_pose_bone")) {
291                 bPoseChannel *pchan;
292                 Object *obpose= object_pose_armature_get(obact);
293                 
294                 pchan= get_active_posechannel(obpose);
295                 if (pchan) {
296                         CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
297                         return 1;
298                 }
299         }
300         else if(CTX_data_equals(member, "active_base")) {
301                 if(base)
302                         CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base);
303
304                 return 1;
305         }
306         else if(CTX_data_equals(member, "active_object")) {
307                 if(obact)
308                         CTX_data_id_pointer_set(result, &obact->id);
309
310                 return 1;
311         }
312         else if(CTX_data_equals(member, "object")) {
313                 if(obact)
314                         CTX_data_id_pointer_set(result, &obact->id);
315
316                 return 1;
317         }
318         else if(CTX_data_equals(member, "edit_object")) {
319                 /* convenience for now, 1 object per scene in editmode */
320                 if(obedit)
321                         CTX_data_id_pointer_set(result, &obedit->id);
322                 
323                 return 1;
324         }
325         else if(CTX_data_equals(member, "sculpt_object")) {
326                 if(obact && (obact->mode & OB_MODE_SCULPT))
327                         CTX_data_id_pointer_set(result, &obact->id);
328
329                 return 1;
330         }
331         else if(CTX_data_equals(member, "vertex_paint_object")) {
332                 if(obact && (obact->mode & OB_MODE_VERTEX_PAINT))
333                         CTX_data_id_pointer_set(result, &obact->id);
334
335                 return 1;
336         }
337         else if(CTX_data_equals(member, "weight_paint_object")) {
338                 if(obact && (obact->mode & OB_MODE_WEIGHT_PAINT))
339                         CTX_data_id_pointer_set(result, &obact->id);
340
341                 return 1;
342         }
343         else if(CTX_data_equals(member, "image_paint_object")) {
344                 if(obact && (obact->mode & OB_MODE_TEXTURE_PAINT))
345                         CTX_data_id_pointer_set(result, &obact->id);
346
347                 return 1;
348         }
349         else if(CTX_data_equals(member, "particle_edit_object")) {
350                 if(obact && (obact->mode & OB_MODE_PARTICLE_EDIT))
351                         CTX_data_id_pointer_set(result, &obact->id);
352
353                 return 1;
354         }
355         else if(CTX_data_equals(member, "sequences")) {
356                 Editing *ed= seq_give_editing(scene, FALSE);
357                 if(ed) {
358                         Sequence *seq;
359                         for (seq= ed->seqbasep->first; seq; seq= seq->next) {
360                                 CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
361                         }
362                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
363                         return 1;
364                 }
365         }
366         else if(CTX_data_equals(member, "selected_sequences")) {
367                 Editing *ed= seq_give_editing(scene, FALSE);
368                 if(ed) {
369                         Sequence *seq;
370                         for (seq= ed->seqbasep->first; seq; seq= seq->next) {
371                                 if (seq->flag & SELECT) {
372                                         CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
373                                 }
374                         }
375                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
376                         return 1;
377                 }
378         }
379         else if(CTX_data_equals(member, "selected_editable_sequences")) {
380                 Editing *ed= seq_give_editing(scene, FALSE);
381                 if(ed) {
382                         Sequence *seq;
383                         for (seq= ed->seqbasep->first; seq; seq= seq->next) {
384                                 if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
385                                         CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
386                                 }
387                         }
388                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
389                         return 1;
390                 }
391         }
392         else {
393                 return 0; /* not found */
394         }
395
396         return -1; /* found but not available */
397 }
398