Blender  V2.59
screen_context.c
Go to the documentation of this file.
00001 /*
00002  * $Id: screen_context.c 36001 2011-04-04 15:13:37Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2008 Blender Foundation.
00021  * All rights reserved.
00022  *
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include <stdlib.h>
00033 #include <string.h>
00034 
00035 #include "DNA_object_types.h"
00036 #include "DNA_armature_types.h"
00037 #include "DNA_sequence_types.h"
00038 #include "DNA_scene_types.h"
00039 #include "DNA_screen_types.h"
00040 
00041 #include "BLI_utildefines.h"
00042 
00043 
00044 #include "BKE_context.h"
00045 #include "BKE_object.h"
00046 #include "BKE_action.h"
00047 #include "BKE_armature.h"
00048 #include "BKE_sequencer.h"
00049 
00050 #include "RNA_access.h"
00051 
00052 #include "ED_object.h"
00053 #include "ED_armature.h"
00054 
00055 #include "screen_intern.h"
00056 
00057 const char *screen_context_dir[] = {
00058         "scene", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
00059         "selected_objects", "selected_bases",
00060         "selected_editable_objects", "selected_editable_bases",
00061         "visible_bones", "editable_bones", "selected_bones", "selected_editable_bones",
00062         "visible_pose_bones", "selected_pose_bones", "active_bone", "active_pose_bone",
00063         "active_base", "active_object", "object", "edit_object",
00064         "sculpt_object", "vertex_paint_object", "weight_paint_object",
00065         "image_paint_object", "particle_edit_object",
00066         "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
00067         NULL};
00068 
00069 int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
00070 {
00071         bScreen *sc= CTX_wm_screen(C);
00072         Scene *scene= sc->scene;
00073         Base *base;
00074         unsigned int lay = scene->lay;
00075 
00076 #if 0   /* Using the context breaks adding objects in the UI. Need to find out why - campbell */
00077         Object *obact= CTX_data_active_object(C);
00078         Object *obedit= CTX_data_edit_object(C);
00079         base= CTX_data_active_base(C);
00080 #else
00081         Object *obedit= scene->obedit; 
00082         Object *obact= OBACT;
00083         base= BASACT;
00084 #endif
00085 
00086         if(CTX_data_dir(member)) {
00087                 CTX_data_dir_set(result, screen_context_dir);
00088                 return 1;
00089         }
00090         else if(CTX_data_equals(member, "scene")) {
00091                 CTX_data_id_pointer_set(result, &scene->id);
00092                 return 1;
00093         }
00094         else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
00095                 int visible_objects= CTX_data_equals(member, "visible_objects");
00096 
00097                 for(base=scene->base.first; base; base=base->next) {
00098                         if(((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & scene->lay)) {
00099                                 if(visible_objects)
00100                                         CTX_data_id_list_add(result, &base->object->id);
00101                                 else
00102                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
00103                         }
00104                 }
00105                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00106                 return 1;
00107         }
00108         else if(CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
00109                 int selectable_objects= CTX_data_equals(member, "selectable_objects");
00110 
00111                 for(base=scene->base.first; base; base=base->next) {
00112                         if(base->lay & lay) {
00113                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0 && (base->object->restrictflag & OB_RESTRICT_SELECT)==0) {
00114                                         if(selectable_objects)
00115                                                 CTX_data_id_list_add(result, &base->object->id);
00116                                         else
00117                                                 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
00118                                 }
00119                         }
00120                 }
00121                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00122                 return 1;
00123         }
00124         else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
00125                 int selected_objects= CTX_data_equals(member, "selected_objects");
00126 
00127                 for(base=scene->base.first; base; base=base->next) {
00128                         if((base->flag & SELECT) && (base->lay & scene->lay)) {
00129                                 if(selected_objects)
00130                                         CTX_data_id_list_add(result, &base->object->id);
00131                                 else
00132                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
00133                         }
00134                 }
00135                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00136                 return 1;
00137         }
00138         else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
00139                 int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects");
00140 
00141                 for(base=scene->base.first; base; base=base->next) {
00142                         if((base->flag & SELECT) && (base->lay & scene->lay)) {
00143                                 if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
00144                                         if(0==object_is_libdata(base->object)) {
00145                                                 if(selected_editable_objects)
00146                                                         CTX_data_id_list_add(result, &base->object->id);
00147                                                 else
00148                                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
00149                                         }
00150                                 }
00151                         }
00152                 }
00153                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00154                 return 1;
00155         }
00156         else if(CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
00157                 bArmature *arm= (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
00158                 EditBone *ebone, *flipbone=NULL;
00159                 int editable_bones= CTX_data_equals(member, "editable_bones");
00160                 
00161                 if (arm && arm->edbo) {
00162                         /* Attention: X-Axis Mirroring is also handled here... */
00163                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
00164                                 /* first and foremost, bone must be visible and selected */
00165                                 if (EBONE_VISIBLE(arm, ebone)) {
00166                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
00167                                          * so that most users of this data don't need to explicitly check for it themselves.
00168                                          * 
00169                                          * We need to make sure that these mirrored copies are not selected, otherwise some
00170                                          * bones will be operated on twice.
00171                                          */
00172                                         if (arm->flag & ARM_MIRROR_EDIT)
00173                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
00174                                         
00175                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
00176                                         if (editable_bones) {
00177                                                 /* only selected + editable */
00178                                                 if (EBONE_EDITABLE(ebone)) {
00179                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
00180                                                 
00181                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
00182                                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
00183                                                 }
00184                                         }
00185                                         else {
00186                                                 /* only include bones if visible */
00187                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
00188                                                 
00189                                                 if ((flipbone) && EBONE_VISIBLE(arm, flipbone)==0)
00190                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
00191                                         }
00192                                 }
00193                         }       
00194                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00195                         return 1;
00196                 }
00197         }
00198         else if(CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
00199                 bArmature *arm= (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
00200                 EditBone *ebone, *flipbone=NULL;
00201                 int selected_editable_bones= CTX_data_equals(member, "selected_editable_bones");
00202                 
00203                 if (arm && arm->edbo) {
00204                         /* Attention: X-Axis Mirroring is also handled here... */
00205                         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
00206                                 /* first and foremost, bone must be visible and selected */
00207                                 if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
00208                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
00209                                          * so that most users of this data don't need to explicitly check for it themselves.
00210                                          * 
00211                                          * We need to make sure that these mirrored copies are not selected, otherwise some
00212                                          * bones will be operated on twice.
00213                                          */
00214                                         if (arm->flag & ARM_MIRROR_EDIT)
00215                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
00216                                         
00217                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
00218                                         if (selected_editable_bones) {
00219                                                 /* only selected + editable */
00220                                                 if (EBONE_EDITABLE(ebone)) {
00221                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
00222                                                 
00223                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
00224                                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
00225                                                 }
00226                                         }
00227                                         else {
00228                                                 /* only include bones if selected */
00229                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
00230                                                 
00231                                                 if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
00232                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
00233                                         }
00234                                 }
00235                         }       
00236                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00237                         return 1;
00238                 }
00239         }
00240         else if(CTX_data_equals(member, "visible_pose_bones")) {
00241                 Object *obpose= ED_object_pose_armature(obact);
00242                 bArmature *arm= (obpose) ? obpose->data : NULL;
00243                 bPoseChannel *pchan;
00244                 
00245                 if (obpose && obpose->pose && arm) {
00246                         for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) {
00247                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
00248                                 if (PBONE_VISIBLE(arm, pchan->bone)) {
00249                                         CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
00250                                 }
00251                         }
00252                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00253                         return 1;
00254                 }
00255         }
00256         else if(CTX_data_equals(member, "selected_pose_bones")) {
00257                 Object *obpose= ED_object_pose_armature(obact);
00258                 bArmature *arm= (obpose) ? obpose->data : NULL;
00259                 bPoseChannel *pchan;
00260                 
00261                 if (obpose && obpose->pose && arm) {
00262                         for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) {
00263                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
00264                                 if (PBONE_VISIBLE(arm, pchan->bone)) {
00265                                         if (pchan->bone->flag & BONE_SELECTED)
00266                                                 CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
00267                                 }
00268                         }
00269                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00270                         return 1;
00271                 }
00272         }
00273         else if(CTX_data_equals(member, "active_bone")) {
00274                 if(obact && obact->type == OB_ARMATURE) {
00275                         bArmature *arm= obact->data;
00276                         if(arm->edbo) {
00277                                 if(arm->act_edbone) {
00278                                         CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
00279                                         return 1;
00280                                 }
00281                         }
00282                         else {
00283                                 if(arm->act_bone) {
00284                                         CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
00285                                         return 1;
00286                                 }
00287                         }
00288                 }
00289         }
00290         else if(CTX_data_equals(member, "active_pose_bone")) {
00291                 bPoseChannel *pchan;
00292                 Object *obpose= ED_object_pose_armature(obact);
00293                 
00294                 pchan= get_active_posechannel(obpose);
00295                 if (pchan) {
00296                         CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
00297                         return 1;
00298                 }
00299         }
00300         else if(CTX_data_equals(member, "active_base")) {
00301                 if(base)
00302                         CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base);
00303 
00304                 return 1;
00305         }
00306         else if(CTX_data_equals(member, "active_object")) {
00307                 if(obact)
00308                         CTX_data_id_pointer_set(result, &obact->id);
00309 
00310                 return 1;
00311         }
00312         else if(CTX_data_equals(member, "object")) {
00313                 if(obact)
00314                         CTX_data_id_pointer_set(result, &obact->id);
00315 
00316                 return 1;
00317         }
00318         else if(CTX_data_equals(member, "edit_object")) {
00319                 /* convenience for now, 1 object per scene in editmode */
00320                 if(obedit)
00321                         CTX_data_id_pointer_set(result, &obedit->id);
00322                 
00323                 return 1;
00324         }
00325         else if(CTX_data_equals(member, "sculpt_object")) {
00326                 if(obact && (obact->mode & OB_MODE_SCULPT))
00327                         CTX_data_id_pointer_set(result, &obact->id);
00328 
00329                 return 1;
00330         }
00331         else if(CTX_data_equals(member, "vertex_paint_object")) {
00332                 if(obact && (obact->mode & OB_MODE_VERTEX_PAINT))
00333                         CTX_data_id_pointer_set(result, &obact->id);
00334 
00335                 return 1;
00336         }
00337         else if(CTX_data_equals(member, "weight_paint_object")) {
00338                 if(obact && (obact->mode & OB_MODE_WEIGHT_PAINT))
00339                         CTX_data_id_pointer_set(result, &obact->id);
00340 
00341                 return 1;
00342         }
00343         else if(CTX_data_equals(member, "image_paint_object")) {
00344                 if(obact && (obact->mode & OB_MODE_TEXTURE_PAINT))
00345                         CTX_data_id_pointer_set(result, &obact->id);
00346 
00347                 return 1;
00348         }
00349         else if(CTX_data_equals(member, "particle_edit_object")) {
00350                 if(obact && (obact->mode & OB_MODE_PARTICLE_EDIT))
00351                         CTX_data_id_pointer_set(result, &obact->id);
00352 
00353                 return 1;
00354         }
00355         else if(CTX_data_equals(member, "sequences")) {
00356                 Editing *ed= seq_give_editing(scene, FALSE);
00357                 if(ed) {
00358                         Sequence *seq;
00359                         for (seq= ed->seqbasep->first; seq; seq= seq->next) {
00360                                 CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
00361                         }
00362                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00363                         return 1;
00364                 }
00365         }
00366         else if(CTX_data_equals(member, "selected_sequences")) {
00367                 Editing *ed= seq_give_editing(scene, FALSE);
00368                 if(ed) {
00369                         Sequence *seq;
00370                         for (seq= ed->seqbasep->first; seq; seq= seq->next) {
00371                                 if (seq->flag & SELECT) {
00372                                         CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
00373                                 }
00374                         }
00375                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00376                         return 1;
00377                 }
00378         }
00379         else if(CTX_data_equals(member, "selected_editable_sequences")) {
00380                 Editing *ed= seq_give_editing(scene, FALSE);
00381                 if(ed) {
00382                         Sequence *seq;
00383                         for (seq= ed->seqbasep->first; seq; seq= seq->next) {
00384                                 if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
00385                                         CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
00386                                 }
00387                         }
00388                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
00389                         return 1;
00390                 }
00391         }
00392         else {
00393                 return 0; /* not found */
00394         }
00395 
00396         return -1; /* found but not available */
00397 }
00398