static int buttons_context_path_particle(ButsContextPath *path) { Object *ob; ParticleSystem *psys; PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have (pinned) particle settings, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) { return 1; } /* if we have an object, get the active particle system */ if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; if (ob && ob->type == OB_MESH) { psys = psys_get_current(ob); RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &path->ptr[path->len]); path->len++; return 1; } } /* no path to a particle system possible */ return 0; }
static int buttons_context_path_pose_bone(ButsContextPath *path) { PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a (pinned) PoseBone, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) { return 1; } /* if we have an armature, get the active bone */ if (buttons_context_path_object(path)) { Object *ob = path->ptr[path->len - 1].data; bArmature *arm = ob->data; /* path->ptr[path->len-1].data - works too */ if (ob->type != OB_ARMATURE || arm->edbo) { return 0; } else { if (arm->act_bone) { bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, arm->act_bone->name); if (pchan) { RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]); path->len++; return 1; } } } } /* no path to a bone possible */ return 0; }
static int buttons_context_path_data(ButsContextPath *path, int type) { Object *ob; PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a data, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && (type == -1 || type == OB_MESH)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_Curve) && (type == -1 || ELEM(type, OB_CURVE, OB_SURF, OB_FONT))) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (type == -1 || type == OB_ARMATURE)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (type == -1 || type == OB_MBALL)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_Lamp) && (type == -1 || type == OB_LAMP)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) return 1; /* try to get an object in the path, no pinning supported here */ else if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; if (ob && (type == -1 || type == ob->type)) { RNA_id_pointer_create(ob->data, &path->ptr[path->len]); path->len++; return 1; } } /* no path to data possible */ return 0; }
static int buttons_context_path_material(ButsContextPath *path, int for_texture) { Object *ob; PointerRNA *ptr= &path->ptr[path->len-1]; Material *ma; /* if we already have a (pinned) material, we're done */ if(RNA_struct_is_a(ptr->type, &RNA_Material)) { return 1; } /* if we have an object, use the object material slot */ else if(buttons_context_path_object(path)) { ob= path->ptr[path->len-1].data; if(ob && ob->type && (ob->type<OB_LAMP)) { ma= give_current_material(ob, ob->actcol); RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); path->len++; if(for_texture && give_current_material_texture_node(ma)) return 1; ma= give_node_material(ma); if(ma) { RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); path->len++; } return 1; } } /* no path to a material possible */ return 0; }
static int buttons_context_path_modifier(ButsContextPath *path) { Object *ob; if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; if (ob && ELEM(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE)) return 1; } return 0; }
static int buttons_context_path_material(ButsContextPath *path, bool for_texture, bool new_shading) { Object *ob; PointerRNA *ptr = &path->ptr[path->len - 1]; Material *ma; /* if we already have a (pinned) material, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Material)) { return 1; } /* if we have an object, use the object material slot */ else if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; if (ob && OB_TYPE_SUPPORT_MATERIAL(ob->type)) { ma = give_current_material(ob, ob->actcol); RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); path->len++; if (for_texture && give_current_material_texture_node(ma)) return 1; if (!new_shading) { /* Only try to get mat from node in case of old shading system (see T40331). */ ma = give_node_material(ma); if (ma) { RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); path->len++; } } return 1; } } /* no path to a material possible */ return 0; }
static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag) { SpaceButs *sbuts = CTX_wm_space_buts(C); ID *id; int found; memset(path, 0, sizeof(*path)); path->flag = flag; path->tex_ctx = sbuts->texture_context; /* if some ID datablock is pinned, set the root pointer */ if (sbuts->pinid) { id = sbuts->pinid; RNA_id_pointer_create(id, &path->ptr[0]); path->len++; } /* no pinned root, use scene as root */ if (path->len == 0) { id = (ID *)CTX_data_scene(C); RNA_id_pointer_create(id, &path->ptr[0]); path->len++; } /* now for each buttons context type, we try to construct a path, * tracing back recursively */ switch (mainb) { case BCONTEXT_SCENE: case BCONTEXT_RENDER: found = buttons_context_path_scene(path); break; case BCONTEXT_RENDER_LAYER: #ifdef WITH_FREESTYLE if (buttons_context_linestyle_pinnable(C)) { found = buttons_context_path_linestyle(path); if (found) { break; } } #endif found = buttons_context_path_scene(path); break; case BCONTEXT_WORLD: found = buttons_context_path_world(path); break; case BCONTEXT_OBJECT: case BCONTEXT_PHYSICS: case BCONTEXT_CONSTRAINT: found = buttons_context_path_object(path); break; case BCONTEXT_MODIFIER: found = buttons_context_path_modifier(path); break; case BCONTEXT_DATA: found = buttons_context_path_data(path, -1); break; case BCONTEXT_PARTICLE: found = buttons_context_path_particle(path); break; case BCONTEXT_MATERIAL: found = buttons_context_path_material(path, false, (sbuts->texuser != NULL)); break; case BCONTEXT_TEXTURE: found = buttons_context_path_texture(path, sbuts->texuser); break; case BCONTEXT_BONE: found = buttons_context_path_bone(path); if (!found) found = buttons_context_path_data(path, OB_ARMATURE); break; case BCONTEXT_BONE_CONSTRAINT: found = buttons_context_path_pose_bone(path); break; default: found = 0; break; } return found; }
static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct) { if (ct) { /* new shading system */ PointerRNA *ptr = &path->ptr[path->len - 1]; ID *id; /* if we already have a (pinned) texture, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Texture)) return 1; if (!ct->user) return 0; id = ct->user->id; if (id) { if (GS(id->name) == ID_BR) buttons_context_path_brush(path); else if (GS(id->name) == ID_MA) buttons_context_path_material(path, false, true); else if (GS(id->name) == ID_WO) buttons_context_path_world(path); else if (GS(id->name) == ID_LA) buttons_context_path_data(path, OB_LAMP); else if (GS(id->name) == ID_PA) buttons_context_path_particle(path); else if (GS(id->name) == ID_OB) buttons_context_path_object(path); else if (GS(id->name) == ID_LS) buttons_context_path_linestyle(path); } if (ct->texture) { RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); path->len++; } return 1; } else { /* old shading system */ Material *ma; Lamp *la; World *wo; ParticleSystem *psys; FreestyleLineStyle *ls; Tex *tex; PointerRNA *ptr = &path->ptr[path->len - 1]; /* if we already have a (pinned) texture, we're done */ if (RNA_struct_is_a(ptr->type, &RNA_Texture)) { return 1; } /* try world */ else if ((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { wo = path->ptr[path->len - 1].data; if (wo && GS(wo->id.name) == ID_WO) { tex = give_current_world_texture(wo); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; return 1; } } /* try particles */ else if ((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) { if (path->ptr[path->len - 1].type == &RNA_ParticleSettings) { ParticleSettings *part = path->ptr[path->len - 1].data; tex = give_current_particle_texture(part); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; return 1; } else { psys = path->ptr[path->len - 1].data; if (psys && psys->part && GS(psys->part->id.name) == ID_PA) { tex = give_current_particle_texture(psys->part); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; return 1; } } } /* try material */ else if ((path->tex_ctx == SB_TEXC_MATERIAL) && buttons_context_path_material(path, true, false)) { ma = path->ptr[path->len - 1].data; if (ma) { tex = give_current_material_texture(ma); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; return 1; } } /* try lamp */ else if ((path->tex_ctx == SB_TEXC_LAMP) && buttons_context_path_data(path, OB_LAMP)) { la = path->ptr[path->len - 1].data; if (la) { tex = give_current_lamp_texture(la); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; return 1; } } /* try linestyle */ else if ((path->tex_ctx == SB_TEXC_LINESTYLE) && buttons_context_path_linestyle(path)) { ls = path->ptr[path->len - 1].data; if (ls) { tex = give_current_linestyle_texture(ls); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; return 1; } } } /* no path to a texture possible */ return 0; }