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