Blender V2.61 - r43446

screen_context.c

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