Blender V2.61 - r43446
|
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) 2009 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <stdlib.h> 00032 #include <string.h> 00033 00034 #include "MEM_guardedalloc.h" 00035 00036 #include "BLI_listbase.h" 00037 #include "BLI_utildefines.h" 00038 00039 #include "DNA_armature_types.h" 00040 #include "DNA_lamp_types.h" 00041 #include "DNA_material_types.h" 00042 #include "DNA_node_types.h" 00043 #include "DNA_scene_types.h" 00044 #include "DNA_world_types.h" 00045 #include "DNA_speaker_types.h" 00046 #include "DNA_brush_types.h" 00047 00048 #include "BKE_context.h" 00049 #include "BKE_action.h" 00050 #include "BKE_material.h" 00051 #include "BKE_modifier.h" 00052 #include "BKE_paint.h" 00053 #include "BKE_particle.h" 00054 #include "BKE_screen.h" 00055 #include "BKE_texture.h" 00056 00057 #include "RNA_access.h" 00058 00059 #include "ED_armature.h" 00060 #include "ED_screen.h" 00061 #include "ED_physics.h" 00062 00063 #include "UI_interface.h" 00064 #include "UI_resources.h" 00065 00066 #include "buttons_intern.h" // own include 00067 00068 static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, StructRNA *type) 00069 { 00070 PointerRNA *ptr; 00071 int a; 00072 00073 for(a=0; a<path->len; a++) { 00074 ptr= &path->ptr[a]; 00075 00076 if(RNA_struct_is_a(ptr->type, type)) { 00077 CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data); 00078 return 1; 00079 } 00080 } 00081 00082 return 0; 00083 } 00084 00085 static PointerRNA *get_pointer_type(ButsContextPath *path, StructRNA *type) 00086 { 00087 PointerRNA *ptr; 00088 int a; 00089 00090 for(a=0; a<path->len; a++) { 00091 ptr= &path->ptr[a]; 00092 00093 if(RNA_struct_is_a(ptr->type, type)) 00094 return ptr; 00095 } 00096 00097 return NULL; 00098 } 00099 00100 /************************* Creating the Path ************************/ 00101 00102 static int buttons_context_path_scene(ButsContextPath *path) 00103 { 00104 PointerRNA *ptr= &path->ptr[path->len-1]; 00105 00106 /* this one just verifies */ 00107 return RNA_struct_is_a(ptr->type, &RNA_Scene); 00108 } 00109 00110 /* note: this function can return 1 without adding a world to the path 00111 * so the buttons stay visible, but be sure to check the ID type if a ID_WO */ 00112 static int buttons_context_path_world(ButsContextPath *path) 00113 { 00114 Scene *scene; 00115 World *world; 00116 PointerRNA *ptr= &path->ptr[path->len-1]; 00117 00118 /* if we already have a (pinned) world, we're done */ 00119 if(RNA_struct_is_a(ptr->type, &RNA_World)) { 00120 return 1; 00121 } 00122 /* if we have a scene, use the scene's world */ 00123 else if(buttons_context_path_scene(path)) { 00124 scene= path->ptr[path->len-1].data; 00125 world= scene->world; 00126 00127 if(world) { 00128 RNA_id_pointer_create(&scene->world->id, &path->ptr[path->len]); 00129 path->len++; 00130 return 1; 00131 } 00132 else { 00133 return 1; 00134 } 00135 } 00136 00137 /* no path to a world possible */ 00138 return 0; 00139 } 00140 00141 00142 static int buttons_context_path_object(ButsContextPath *path) 00143 { 00144 Scene *scene; 00145 Object *ob; 00146 PointerRNA *ptr= &path->ptr[path->len-1]; 00147 00148 /* if we already have a (pinned) object, we're done */ 00149 if(RNA_struct_is_a(ptr->type, &RNA_Object)) { 00150 return 1; 00151 } 00152 /* if we have a scene, use the scene's active object */ 00153 else if(buttons_context_path_scene(path)) { 00154 scene= path->ptr[path->len-1].data; 00155 ob= (scene->basact)? scene->basact->object: NULL; 00156 00157 if(ob) { 00158 RNA_id_pointer_create(&ob->id, &path->ptr[path->len]); 00159 path->len++; 00160 00161 return 1; 00162 } 00163 } 00164 00165 /* no path to a object possible */ 00166 return 0; 00167 } 00168 00169 static int buttons_context_path_data(ButsContextPath *path, int type) 00170 { 00171 Object *ob; 00172 PointerRNA *ptr= &path->ptr[path->len-1]; 00173 00174 /* if we already have a data, we're done */ 00175 if(RNA_struct_is_a(ptr->type, &RNA_Mesh) && (type == -1 || type == OB_MESH)) return 1; 00176 else if(RNA_struct_is_a(ptr->type, &RNA_Curve) && (type == -1 || ELEM3(type, OB_CURVE, OB_SURF, OB_FONT))) return 1; 00177 else if(RNA_struct_is_a(ptr->type, &RNA_Armature) && (type == -1 || type == OB_ARMATURE)) return 1; 00178 else if(RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (type == -1 || type == OB_MBALL)) return 1; 00179 else if(RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) return 1; 00180 else if(RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) return 1; 00181 else if(RNA_struct_is_a(ptr->type, &RNA_Lamp) && (type == -1 || type == OB_LAMP)) return 1; 00182 else if(RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) return 1; 00183 /* try to get an object in the path, no pinning supported here */ 00184 else if(buttons_context_path_object(path)) { 00185 ob= path->ptr[path->len-1].data; 00186 00187 if(ob && (type == -1 || type == ob->type)) { 00188 RNA_id_pointer_create(ob->data, &path->ptr[path->len]); 00189 path->len++; 00190 00191 return 1; 00192 } 00193 } 00194 00195 /* no path to data possible */ 00196 return 0; 00197 } 00198 00199 static int buttons_context_path_modifier(ButsContextPath *path) 00200 { 00201 Object *ob; 00202 00203 if(buttons_context_path_object(path)) { 00204 ob= path->ptr[path->len-1].data; 00205 00206 if(ob && ELEM5(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE)) 00207 return 1; 00208 } 00209 00210 return 0; 00211 } 00212 00213 static int buttons_context_path_material(ButsContextPath *path, int for_texture) 00214 { 00215 Object *ob; 00216 PointerRNA *ptr= &path->ptr[path->len-1]; 00217 Material *ma; 00218 00219 /* if we already have a (pinned) material, we're done */ 00220 if(RNA_struct_is_a(ptr->type, &RNA_Material)) { 00221 return 1; 00222 } 00223 /* if we have an object, use the object material slot */ 00224 else if(buttons_context_path_object(path)) { 00225 ob= path->ptr[path->len-1].data; 00226 00227 if(ob && OB_TYPE_SUPPORT_MATERIAL(ob->type)) { 00228 ma= give_current_material(ob, ob->actcol); 00229 RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); 00230 path->len++; 00231 00232 if(for_texture && give_current_material_texture_node(ma)) 00233 return 1; 00234 00235 ma= give_node_material(ma); 00236 if(ma) { 00237 RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); 00238 path->len++; 00239 } 00240 return 1; 00241 } 00242 } 00243 00244 /* no path to a material possible */ 00245 return 0; 00246 } 00247 00248 static int buttons_context_path_bone(ButsContextPath *path) 00249 { 00250 bArmature *arm; 00251 EditBone *edbo; 00252 00253 /* if we have an armature, get the active bone */ 00254 if(buttons_context_path_data(path, OB_ARMATURE)) { 00255 arm= path->ptr[path->len-1].data; 00256 00257 if(arm->edbo) { 00258 if(arm->act_edbone) { 00259 edbo= arm->act_edbone; 00260 RNA_pointer_create(&arm->id, &RNA_EditBone, edbo, &path->ptr[path->len]); 00261 path->len++; 00262 return 1; 00263 } 00264 } 00265 else { 00266 if(arm->act_bone) { 00267 RNA_pointer_create(&arm->id, &RNA_Bone, arm->act_bone, &path->ptr[path->len]); 00268 path->len++; 00269 return 1; 00270 } 00271 } 00272 } 00273 00274 /* no path to a bone possible */ 00275 return 0; 00276 } 00277 00278 static int buttons_context_path_pose_bone(ButsContextPath *path) 00279 { 00280 PointerRNA *ptr= &path->ptr[path->len-1]; 00281 00282 /* if we already have a (pinned) PoseBone, we're done */ 00283 if(RNA_struct_is_a(ptr->type, &RNA_PoseBone)) { 00284 return 1; 00285 } 00286 00287 /* if we have an armature, get the active bone */ 00288 if(buttons_context_path_object(path)) { 00289 Object *ob= path->ptr[path->len-1].data; 00290 bArmature *arm= ob->data; /* path->ptr[path->len-1].data - works too */ 00291 00292 if(ob->type != OB_ARMATURE || arm->edbo) { 00293 return 0; 00294 } 00295 else { 00296 if(arm->act_bone) { 00297 bPoseChannel *pchan= get_pose_channel(ob->pose, arm->act_bone->name); 00298 if(pchan) { 00299 RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]); 00300 path->len++; 00301 return 1; 00302 } 00303 } 00304 } 00305 } 00306 00307 /* no path to a bone possible */ 00308 return 0; 00309 } 00310 00311 00312 static int buttons_context_path_particle(ButsContextPath *path) 00313 { 00314 Object *ob; 00315 ParticleSystem *psys; 00316 PointerRNA *ptr= &path->ptr[path->len-1]; 00317 00318 /* if we already have (pinned) particle settings, we're done */ 00319 if(RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) { 00320 return 1; 00321 } 00322 /* if we have an object, get the active particle system */ 00323 if(buttons_context_path_object(path)) { 00324 ob= path->ptr[path->len-1].data; 00325 00326 if(ob && ob->type == OB_MESH) { 00327 psys= psys_get_current(ob); 00328 00329 RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &path->ptr[path->len]); 00330 path->len++; 00331 return 1; 00332 } 00333 } 00334 00335 /* no path to a particle system possible */ 00336 return 0; 00337 } 00338 00339 static int buttons_context_path_brush(ButsContextPath *path) 00340 { 00341 Scene *scene; 00342 Brush *br= NULL; 00343 PointerRNA *ptr= &path->ptr[path->len-1]; 00344 00345 /* if we already have a (pinned) brush, we're done */ 00346 if(RNA_struct_is_a(ptr->type, &RNA_Brush)) { 00347 return 1; 00348 } 00349 /* if we have a scene, use the toolsettings brushes */ 00350 else if(buttons_context_path_scene(path)) { 00351 scene= path->ptr[path->len-1].data; 00352 00353 if(scene) 00354 br= paint_brush(paint_get_active(scene)); 00355 00356 if(br) { 00357 RNA_id_pointer_create((ID *)br, &path->ptr[path->len]); 00358 path->len++; 00359 00360 return 1; 00361 } 00362 } 00363 00364 /* no path to a brush possible */ 00365 return 0; 00366 } 00367 00368 static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct) 00369 { 00370 if(ct) { 00371 /* new shading system */ 00372 PointerRNA *ptr= &path->ptr[path->len-1]; 00373 ID *id; 00374 00375 /* if we already have a (pinned) texture, we're done */ 00376 if(RNA_struct_is_a(ptr->type, &RNA_Texture)) 00377 return 1; 00378 00379 if(!ct->user) 00380 return 0; 00381 00382 id= ct->user->id; 00383 00384 if(id) { 00385 if(GS(id->name) == ID_BR) 00386 buttons_context_path_brush(path); 00387 else if(GS(id->name) == ID_MA) 00388 buttons_context_path_material(path, 0); 00389 else if(GS(id->name) == ID_WO) 00390 buttons_context_path_world(path); 00391 else if(GS(id->name) == ID_LA) 00392 buttons_context_path_data(path, OB_LAMP); 00393 else if(GS(id->name) == ID_PA) 00394 buttons_context_path_particle(path); 00395 else if(GS(id->name) == ID_OB) 00396 buttons_context_path_object(path); 00397 } 00398 00399 if(ct->texture) { 00400 RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); 00401 path->len++; 00402 } 00403 00404 return 1; 00405 } 00406 else { 00407 /* old shading system */ 00408 Material *ma; 00409 Lamp *la; 00410 Brush *br; 00411 World *wo; 00412 ParticleSystem *psys; 00413 Tex *tex; 00414 PointerRNA *ptr= &path->ptr[path->len-1]; 00415 int orig_len = path->len; 00416 00417 /* if we already have a (pinned) texture, we're done */ 00418 if(RNA_struct_is_a(ptr->type, &RNA_Texture)) { 00419 return 1; 00420 } 00421 /* try brush */ 00422 if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) { 00423 br= path->ptr[path->len-1].data; 00424 00425 if(br) { 00426 tex= give_current_brush_texture(br); 00427 00428 RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); 00429 path->len++; 00430 return 1; 00431 } 00432 } 00433 /* try world */ 00434 if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { 00435 wo= path->ptr[path->len-1].data; 00436 00437 if(wo && GS(wo->id.name)==ID_WO) { 00438 tex= give_current_world_texture(wo); 00439 00440 RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); 00441 path->len++; 00442 return 1; 00443 } 00444 } 00445 /* try particles */ 00446 if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) { 00447 if(path->ptr[path->len-1].type == &RNA_ParticleSettings) { 00448 ParticleSettings *part = path->ptr[path->len-1].data; 00449 00450 tex= give_current_particle_texture(part); 00451 RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); 00452 path->len++; 00453 return 1; 00454 } 00455 else { 00456 psys= path->ptr[path->len-1].data; 00457 00458 if(psys && psys->part && GS(psys->part->id.name)==ID_PA) { 00459 tex= give_current_particle_texture(psys->part); 00460 00461 RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); 00462 path->len++; 00463 return 1; 00464 } 00465 } 00466 } 00467 /* try material */ 00468 if(buttons_context_path_material(path, 1)) { 00469 ma= path->ptr[path->len-1].data; 00470 00471 if(ma) { 00472 tex= give_current_material_texture(ma); 00473 00474 RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); 00475 path->len++; 00476 return 1; 00477 } 00478 } 00479 /* try lamp */ 00480 if(buttons_context_path_data(path, OB_LAMP)) { 00481 la= path->ptr[path->len-1].data; 00482 00483 if(la) { 00484 tex= give_current_lamp_texture(la); 00485 00486 RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); 00487 path->len++; 00488 return 1; 00489 } 00490 } 00491 /* try brushes again in case of no material, lamp, etc */ 00492 path->len = orig_len; 00493 if(buttons_context_path_brush(path)) { 00494 br= path->ptr[path->len-1].data; 00495 00496 if(br) { 00497 tex= give_current_brush_texture(br); 00498 00499 RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); 00500 path->len++; 00501 return 1; 00502 } 00503 } 00504 } 00505 00506 /* no path to a texture possible */ 00507 return 0; 00508 } 00509 00510 00511 static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag) 00512 { 00513 SpaceButs *sbuts= CTX_wm_space_buts(C); 00514 ID *id; 00515 int found; 00516 00517 memset(path, 0, sizeof(*path)); 00518 path->flag= flag; 00519 path->tex_ctx = sbuts->texture_context; 00520 00521 /* if some ID datablock is pinned, set the root pointer */ 00522 if(sbuts->pinid) { 00523 id= sbuts->pinid; 00524 00525 RNA_id_pointer_create(id, &path->ptr[0]); 00526 path->len++; 00527 } 00528 00529 /* no pinned root, use scene as root */ 00530 if(path->len == 0) { 00531 id= (ID*)CTX_data_scene(C); 00532 RNA_id_pointer_create(id, &path->ptr[0]); 00533 path->len++; 00534 } 00535 00536 /* now for each buttons context type, we try to construct a path, 00537 * tracing back recursively */ 00538 switch(mainb) { 00539 case BCONTEXT_SCENE: 00540 case BCONTEXT_RENDER: 00541 found= buttons_context_path_scene(path); 00542 break; 00543 case BCONTEXT_WORLD: 00544 found= buttons_context_path_world(path); 00545 break; 00546 case BCONTEXT_OBJECT: 00547 case BCONTEXT_PHYSICS: 00548 case BCONTEXT_CONSTRAINT: 00549 found= buttons_context_path_object(path); 00550 break; 00551 case BCONTEXT_MODIFIER: 00552 found= buttons_context_path_modifier(path); 00553 break; 00554 case BCONTEXT_DATA: 00555 found= buttons_context_path_data(path, -1); 00556 break; 00557 case BCONTEXT_PARTICLE: 00558 found= buttons_context_path_particle(path); 00559 break; 00560 case BCONTEXT_MATERIAL: 00561 found= buttons_context_path_material(path, 0); 00562 break; 00563 case BCONTEXT_TEXTURE: 00564 found= buttons_context_path_texture(path, sbuts->texuser); 00565 break; 00566 case BCONTEXT_BONE: 00567 found= buttons_context_path_bone(path); 00568 if(!found) 00569 found= buttons_context_path_data(path, OB_ARMATURE); 00570 break; 00571 case BCONTEXT_BONE_CONSTRAINT: 00572 found= buttons_context_path_pose_bone(path); 00573 break; 00574 default: 00575 found= 0; 00576 break; 00577 } 00578 00579 return found; 00580 } 00581 00582 static int buttons_shading_context(const bContext *C, int mainb) 00583 { 00584 Object *ob= CTX_data_active_object(C); 00585 00586 if(ELEM3(mainb, BCONTEXT_MATERIAL, BCONTEXT_WORLD, BCONTEXT_TEXTURE)) 00587 return 1; 00588 if(mainb == BCONTEXT_DATA && ob && ELEM(ob->type, OB_LAMP, OB_CAMERA)) 00589 return 1; 00590 00591 return 0; 00592 } 00593 00594 static int buttons_shading_new_context(const bContext *C, int flag) 00595 { 00596 Object *ob= CTX_data_active_object(C); 00597 00598 if(flag & (1 << BCONTEXT_MATERIAL)) 00599 return BCONTEXT_MATERIAL; 00600 else if(ob && ELEM(ob->type, OB_LAMP, OB_CAMERA) && (flag & (1 << BCONTEXT_DATA))) 00601 return BCONTEXT_DATA; 00602 else if(flag & (1 << BCONTEXT_WORLD)) 00603 return BCONTEXT_WORLD; 00604 00605 return BCONTEXT_RENDER; 00606 } 00607 00608 void buttons_context_compute(const bContext *C, SpaceButs *sbuts) 00609 { 00610 ButsContextPath *path; 00611 PointerRNA *ptr; 00612 int a, pflag= 0, flag= 0; 00613 00614 buttons_texture_context_compute(C, sbuts); 00615 00616 if(!sbuts->path) 00617 sbuts->path= MEM_callocN(sizeof(ButsContextPath), "ButsContextPath"); 00618 00619 path= sbuts->path; 00620 00621 /* for each context, see if we can compute a valid path to it, if 00622 * this is the case, we know we have to display the button */ 00623 for(a=0; a<BCONTEXT_TOT; a++) { 00624 if(buttons_context_path(C, path, a, pflag)) { 00625 flag |= (1<<a); 00626 00627 /* setting icon for data context */ 00628 if(a == BCONTEXT_DATA) { 00629 ptr= &path->ptr[path->len-1]; 00630 00631 if(ptr->type) 00632 sbuts->dataicon= RNA_struct_ui_icon(ptr->type); 00633 else 00634 sbuts->dataicon= ICON_EMPTY_DATA; 00635 } 00636 } 00637 } 00638 00639 /* always try to use the tab that was explicitly 00640 * set to the user, so that once that context comes 00641 * back, the tab is activated again */ 00642 sbuts->mainb= sbuts->mainbuser; 00643 00644 /* in case something becomes invalid, change */ 00645 if((flag & (1 << sbuts->mainb)) == 0) { 00646 if(sbuts->flag & SB_SHADING_CONTEXT) { 00647 /* try to keep showing shading related buttons */ 00648 sbuts->mainb= buttons_shading_new_context(C, flag); 00649 } 00650 else if(flag & BCONTEXT_OBJECT) { 00651 sbuts->mainb= BCONTEXT_OBJECT; 00652 } 00653 else { 00654 for(a=0; a<BCONTEXT_TOT; a++) { 00655 if(flag & (1 << a)) { 00656 sbuts->mainb= a; 00657 break; 00658 } 00659 } 00660 } 00661 } 00662 00663 buttons_context_path(C, path, sbuts->mainb, pflag); 00664 00665 if(!(flag & (1 << sbuts->mainb))) { 00666 if(flag & (1 << BCONTEXT_OBJECT)) 00667 sbuts->mainb= BCONTEXT_OBJECT; 00668 else 00669 sbuts->mainb= BCONTEXT_SCENE; 00670 } 00671 00672 if(buttons_shading_context(C, sbuts->mainb)) 00673 sbuts->flag |= SB_SHADING_CONTEXT; 00674 else 00675 sbuts->flag &= ~SB_SHADING_CONTEXT; 00676 00677 sbuts->pathflag= flag; 00678 } 00679 00680 /************************* Context Callback ************************/ 00681 00682 const char *buttons_context_dir[] = { 00683 "world", "object", "mesh", "armature", "lattice", "curve", 00684 "meta_ball", "lamp", "speaker", "camera", "material", "material_slot", 00685 "texture", "texture_slot", "texture_user", "bone", "edit_bone", 00686 "pose_bone", "particle_system", "particle_system_editable", 00687 "cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint", NULL}; 00688 00689 int buttons_context(const bContext *C, const char *member, bContextDataResult *result) 00690 { 00691 SpaceButs *sbuts= CTX_wm_space_buts(C); 00692 ButsContextPath *path= sbuts?sbuts->path:NULL; 00693 00694 if(!path) 00695 return 0; 00696 00697 /* here we handle context, getting data from precomputed path */ 00698 if(CTX_data_dir(member)) { 00699 CTX_data_dir_set(result, buttons_context_dir); 00700 return 1; 00701 } 00702 else if(CTX_data_equals(member, "world")) { 00703 set_pointer_type(path, result, &RNA_World); 00704 return 1; 00705 } 00706 else if(CTX_data_equals(member, "object")) { 00707 set_pointer_type(path, result, &RNA_Object); 00708 return 1; 00709 } 00710 else if(CTX_data_equals(member, "mesh")) { 00711 set_pointer_type(path, result, &RNA_Mesh); 00712 return 1; 00713 } 00714 else if(CTX_data_equals(member, "armature")) { 00715 set_pointer_type(path, result, &RNA_Armature); 00716 return 1; 00717 } 00718 else if(CTX_data_equals(member, "lattice")) { 00719 set_pointer_type(path, result, &RNA_Lattice); 00720 return 1; 00721 } 00722 else if(CTX_data_equals(member, "curve")) { 00723 set_pointer_type(path, result, &RNA_Curve); 00724 return 1; 00725 } 00726 else if(CTX_data_equals(member, "meta_ball")) { 00727 set_pointer_type(path, result, &RNA_MetaBall); 00728 return 1; 00729 } 00730 else if(CTX_data_equals(member, "lamp")) { 00731 set_pointer_type(path, result, &RNA_Lamp); 00732 return 1; 00733 } 00734 else if(CTX_data_equals(member, "camera")) { 00735 set_pointer_type(path, result, &RNA_Camera); 00736 return 1; 00737 } 00738 else if(CTX_data_equals(member, "speaker")) { 00739 set_pointer_type(path, result, &RNA_Speaker); 00740 return 1; 00741 } 00742 else if(CTX_data_equals(member, "material")) { 00743 set_pointer_type(path, result, &RNA_Material); 00744 return 1; 00745 } 00746 else if(CTX_data_equals(member, "texture")) { 00747 ButsContextTexture *ct= sbuts->texuser; 00748 00749 if(ct) { 00750 /* new shading system */ 00751 CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture); 00752 } 00753 else { 00754 /* old shading system */ 00755 set_pointer_type(path, result, &RNA_Texture); 00756 } 00757 00758 return 1; 00759 } 00760 else if(CTX_data_equals(member, "material_slot")) { 00761 PointerRNA *ptr= get_pointer_type(path, &RNA_Object); 00762 00763 if(ptr) { 00764 Object *ob= ptr->data; 00765 00766 if(ob && OB_TYPE_SUPPORT_MATERIAL(ob->type) && ob->totcol) { 00767 /* a valid actcol isn't ensured [#27526] */ 00768 int matnr= ob->actcol-1; 00769 if(matnr < 0) matnr= 0; 00770 CTX_data_pointer_set(result, &ob->id, &RNA_MaterialSlot, &ob->mat[matnr]); 00771 } 00772 } 00773 00774 return 1; 00775 } 00776 else if(CTX_data_equals(member, "texture_user")) { 00777 ButsContextTexture *ct= sbuts->texuser; 00778 00779 if(!ct) 00780 return 0; /* old shading system */ 00781 00782 if(ct->user && ct->user->ptr.data) { 00783 ButsTextureUser *user= ct->user; 00784 CTX_data_pointer_set(result, user->ptr.id.data, user->ptr.type, user->ptr.data); 00785 } 00786 00787 return 1; 00788 } 00789 else if(CTX_data_equals(member, "texture_node")) { 00790 ButsContextTexture *ct= sbuts->texuser; 00791 00792 if(ct) { 00793 /* new shading system */ 00794 if(ct->user && ct->user->node) 00795 CTX_data_pointer_set(result, &ct->user->ntree->id, &RNA_Node, ct->user->node); 00796 00797 return 1; 00798 } 00799 else { 00800 /* old shading system */ 00801 PointerRNA *ptr; 00802 00803 if((ptr=get_pointer_type(path, &RNA_Material))) { 00804 Material *ma= ptr->data; 00805 00806 if(ma) { 00807 bNode *node= give_current_material_texture_node(ma); 00808 CTX_data_pointer_set(result, &ma->nodetree->id, &RNA_Node, node); 00809 } 00810 } 00811 00812 return 1; 00813 } 00814 } 00815 else if(CTX_data_equals(member, "texture_slot")) { 00816 ButsContextTexture *ct= sbuts->texuser; 00817 PointerRNA *ptr; 00818 00819 if(ct) 00820 return 0; /* new shading system */ 00821 00822 if((ptr=get_pointer_type(path, &RNA_Material))) { 00823 Material *ma= ptr->data; 00824 00825 /* if we have a node material, get slot from material in material node */ 00826 if(ma && ma->use_nodes && ma->nodetree) { 00827 /* if there's an active texture node in the node tree, 00828 * then that texture is in context directly, without a texture slot */ 00829 if (give_current_material_texture_node(ma)) 00830 return 0; 00831 00832 ma= give_node_material(ma); 00833 if (ma) 00834 CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]); 00835 else 00836 return 0; 00837 } else if(ma) { 00838 CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]); 00839 } 00840 } 00841 else if((ptr=get_pointer_type(path, &RNA_Lamp))) { 00842 Lamp *la= ptr->data; 00843 00844 if(la) 00845 CTX_data_pointer_set(result, &la->id, &RNA_LampTextureSlot, la->mtex[(int)la->texact]); 00846 } 00847 else if((ptr=get_pointer_type(path, &RNA_World))) { 00848 World *wo= ptr->data; 00849 00850 if(wo) 00851 CTX_data_pointer_set(result, &wo->id, &RNA_WorldTextureSlot, wo->mtex[(int)wo->texact]); 00852 } 00853 else if((ptr=get_pointer_type(path, &RNA_Brush))) { /* how to get this into context? */ 00854 Brush *br= ptr->data; 00855 00856 if(br) 00857 CTX_data_pointer_set(result, &br->id, &RNA_BrushTextureSlot, &br->mtex); 00858 } 00859 else if((ptr=get_pointer_type(path, &RNA_ParticleSystem))) { 00860 ParticleSettings *part= ((ParticleSystem *)ptr->data)->part; 00861 00862 if(part) 00863 CTX_data_pointer_set(result, &part->id, &RNA_ParticleSettingsTextureSlot, part->mtex[(int)part->texact]); 00864 } 00865 00866 return 1; 00867 } 00868 else if(CTX_data_equals(member, "bone")) { 00869 set_pointer_type(path, result, &RNA_Bone); 00870 return 1; 00871 } 00872 else if(CTX_data_equals(member, "edit_bone")) { 00873 set_pointer_type(path, result, &RNA_EditBone); 00874 return 1; 00875 } 00876 else if(CTX_data_equals(member, "pose_bone")) { 00877 set_pointer_type(path, result, &RNA_PoseBone); 00878 return 1; 00879 } 00880 else if(CTX_data_equals(member, "particle_system")) { 00881 set_pointer_type(path, result, &RNA_ParticleSystem); 00882 return 1; 00883 } 00884 else if(CTX_data_equals(member, "particle_system_editable")) { 00885 if(PE_poll((bContext*)C)) 00886 set_pointer_type(path, result, &RNA_ParticleSystem); 00887 else 00888 CTX_data_pointer_set(result, NULL, &RNA_ParticleSystem, NULL); 00889 return 1; 00890 } 00891 else if(CTX_data_equals(member, "cloth")) { 00892 PointerRNA *ptr= get_pointer_type(path, &RNA_Object); 00893 00894 if(ptr && ptr->data) { 00895 Object *ob= ptr->data; 00896 ModifierData *md= modifiers_findByType(ob, eModifierType_Cloth); 00897 CTX_data_pointer_set(result, &ob->id, &RNA_ClothModifier, md); 00898 return 1; 00899 } 00900 } 00901 else if(CTX_data_equals(member, "soft_body")) { 00902 PointerRNA *ptr= get_pointer_type(path, &RNA_Object); 00903 00904 if(ptr && ptr->data) { 00905 Object *ob= ptr->data; 00906 ModifierData *md= modifiers_findByType(ob, eModifierType_Softbody); 00907 CTX_data_pointer_set(result, &ob->id, &RNA_SoftBodyModifier, md); 00908 return 1; 00909 } 00910 } 00911 else if(CTX_data_equals(member, "fluid")) { 00912 PointerRNA *ptr= get_pointer_type(path, &RNA_Object); 00913 00914 if(ptr && ptr->data) { 00915 Object *ob= ptr->data; 00916 ModifierData *md= modifiers_findByType(ob, eModifierType_Fluidsim); 00917 CTX_data_pointer_set(result, &ob->id, &RNA_FluidSimulationModifier, md); 00918 return 1; 00919 } 00920 } 00921 00922 else if(CTX_data_equals(member, "smoke")) { 00923 PointerRNA *ptr= get_pointer_type(path, &RNA_Object); 00924 00925 if(ptr && ptr->data) { 00926 Object *ob= ptr->data; 00927 ModifierData *md= modifiers_findByType(ob, eModifierType_Smoke); 00928 CTX_data_pointer_set(result, &ob->id, &RNA_SmokeModifier, md); 00929 return 1; 00930 } 00931 } 00932 else if(CTX_data_equals(member, "collision")) { 00933 PointerRNA *ptr= get_pointer_type(path, &RNA_Object); 00934 00935 if(ptr && ptr->data) { 00936 Object *ob= ptr->data; 00937 ModifierData *md= modifiers_findByType(ob, eModifierType_Collision); 00938 CTX_data_pointer_set(result, &ob->id, &RNA_CollisionModifier, md); 00939 return 1; 00940 } 00941 } 00942 else if(CTX_data_equals(member, "brush")) { 00943 set_pointer_type(path, result, &RNA_Brush); 00944 return 1; 00945 } 00946 else if(CTX_data_equals(member, "dynamic_paint")) { 00947 PointerRNA *ptr= get_pointer_type(path, &RNA_Object); 00948 00949 if(ptr && ptr->data) { 00950 Object *ob= ptr->data; 00951 ModifierData *md= modifiers_findByType(ob, eModifierType_DynamicPaint); 00952 CTX_data_pointer_set(result, &ob->id, &RNA_DynamicPaintModifier, md); 00953 return 1; 00954 } 00955 } 00956 else { 00957 return 0; /* not found */ 00958 } 00959 00960 return -1; /* found but not available */ 00961 } 00962 00963 /************************* Drawing the Path ************************/ 00964 00965 static void pin_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2)) 00966 { 00967 SpaceButs *sbuts= CTX_wm_space_buts(C); 00968 00969 if(sbuts->flag & SB_PIN_CONTEXT) { 00970 sbuts->pinid= buttons_context_id_path(C); 00971 } 00972 else 00973 sbuts->pinid= NULL; 00974 00975 ED_area_tag_redraw(CTX_wm_area(C)); 00976 } 00977 00978 void buttons_context_draw(const bContext *C, uiLayout *layout) 00979 { 00980 SpaceButs *sbuts= CTX_wm_space_buts(C); 00981 ButsContextPath *path= sbuts->path; 00982 uiLayout *row; 00983 uiBlock *block; 00984 uiBut *but; 00985 PointerRNA *ptr; 00986 char namebuf[128], *name; 00987 int a, icon; 00988 00989 if(!path) 00990 return; 00991 00992 row= uiLayoutRow(layout, 1); 00993 uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT); 00994 00995 block= uiLayoutGetBlock(row); 00996 uiBlockSetEmboss(block, UI_EMBOSSN); 00997 but= uiDefIconButBitC(block, ICONTOG, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag, 0, 0, 0, 0, "Follow context or keep fixed datablock displayed"); 00998 uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ 00999 uiButSetFunc(but, pin_cb, NULL, NULL); 01000 01001 for(a=0; a<path->len; a++) { 01002 ptr= &path->ptr[a]; 01003 01004 if(a != 0) 01005 uiItemL(row, "", VICO_SMALL_TRI_RIGHT_VEC); 01006 01007 if(ptr->data) { 01008 icon= RNA_struct_ui_icon(ptr->type); 01009 name= RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), NULL); 01010 01011 if(name) { 01012 if(!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE) && ptr->type == &RNA_Scene) 01013 uiItemLDrag(row, ptr, "", icon); /* save some space */ 01014 else 01015 uiItemLDrag(row, ptr, name, icon); 01016 01017 if(name != namebuf) 01018 MEM_freeN(name); 01019 } 01020 else 01021 uiItemL(row, "", icon); 01022 } 01023 } 01024 } 01025 01026 static void buttons_panel_context(const bContext *C, Panel *pa) 01027 { 01028 buttons_context_draw(C, pa->layout); 01029 } 01030 01031 void buttons_context_register(ARegionType *art) 01032 { 01033 PanelType *pt; 01034 01035 pt= MEM_callocN(sizeof(PanelType), "spacetype buttons panel context"); 01036 strcpy(pt->idname, "BUTTONS_PT_context"); 01037 strcpy(pt->label, "Context"); 01038 pt->draw= buttons_panel_context; 01039 pt->flag= PNL_NO_HEADER; 01040 BLI_addtail(&art->paneltypes, pt); 01041 } 01042 01043 ID *buttons_context_id_path(const bContext *C) 01044 { 01045 SpaceButs *sbuts= CTX_wm_space_buts(C); 01046 ButsContextPath *path= sbuts->path; 01047 PointerRNA *ptr; 01048 int a; 01049 01050 if(path->len) { 01051 for(a=path->len-1; a>=0; a--) { 01052 ptr= &path->ptr[a]; 01053 01054 /* pin particle settings instead of system, since only settings are an idblock*/ 01055 if(sbuts->mainb == BCONTEXT_PARTICLE && sbuts->flag & SB_PIN_CONTEXT) { 01056 if(ptr->type == &RNA_ParticleSystem && ptr->data) { 01057 ParticleSystem *psys = (ParticleSystem *)ptr->data; 01058 return &psys->part->id; 01059 } 01060 } 01061 01062 if(ptr->id.data) { 01063 return ptr->id.data; 01064 break; 01065 } 01066 } 01067 } 01068 01069 return NULL; 01070 }