From 28ee0f92184af8ba6f44d08eda23ce5eb3815697 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 8 Nov 2011 13:07:16 +0000 Subject: Texturing: texture and 3d view draw type changes, these should only have any effect for a render engine using new shading nodes. In short: * No longer uses images assigned to faces in the uv layer, rather the active image texture node is what is edited/painted/drawn. * Textured draw type now shows the active image texture node, with solid lighting. * Material draw mode shows GLSL shader of a simplified material node tree, using solid lighting. * Textures for modifiers, brushes, etc, are now available from a dropdown in the texture tab in the properties editor. These do not use new shading nodes yet. http://wiki.blender.org/index.php/Dev:2.6/Source/Render/TextureWorkflow --- .../blender/editors/space_buttons/CMakeLists.txt | 1 + .../editors/space_buttons/buttons_context.c | 255 +++++++---- .../blender/editors/space_buttons/buttons_intern.h | 49 ++- .../editors/space_buttons/buttons_texture.c | 469 +++++++++++++++++++++ .../blender/editors/space_buttons/space_buttons.c | 7 + 5 files changed, 688 insertions(+), 93 deletions(-) create mode 100644 source/blender/editors/space_buttons/buttons_texture.c (limited to 'source/blender/editors/space_buttons') diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index dbb96b68587..ee118f12062 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -38,6 +38,7 @@ set(SRC buttons_context.c buttons_header.c buttons_ops.c + buttons_texture.c space_buttons.c buttons_intern.h diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 6d6f73e98d8..e38ac7bd413 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -54,7 +54,6 @@ #include "BKE_screen.h" #include "BKE_texture.h" - #include "RNA_access.h" #include "ED_armature.h" @@ -66,13 +65,6 @@ #include "buttons_intern.h" // own include -typedef struct ButsContextPath { - PointerRNA ptr[8]; - int len; - int flag; - int tex_ctx; -} ButsContextPath; - static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, StructRNA *type) { PointerRNA *ptr; @@ -373,102 +365,141 @@ static int buttons_context_path_brush(ButsContextPath *path) return 0; } -static int buttons_context_path_texture(ButsContextPath *path) +static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct) { - Material *ma; - Lamp *la; - Brush *br; - World *wo; - ParticleSystem *psys; - Tex *tex; - PointerRNA *ptr= &path->ptr[path->len-1]; - int orig_len = path->len; + 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; - } - /* try brush */ - if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) { - br= path->ptr[path->len-1].data; - - if(br) { - tex= give_current_brush_texture(br); + /* if we already have a (pinned) texture, we're done */ + if(RNA_struct_is_a(ptr->type, &RNA_Texture)) + return 1; - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + 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, 0); + 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); + } + + if(ct->texture) { + RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); path->len++; - return 1; } - } - /* try world */ - 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; + } + else { + /* old shading system */ + Material *ma; + Lamp *la; + Brush *br; + World *wo; + ParticleSystem *psys; + Tex *tex; + PointerRNA *ptr= &path->ptr[path->len-1]; + int orig_len = path->len; + + /* if we already have a (pinned) texture, we're done */ + if(RNA_struct_is_a(ptr->type, &RNA_Texture)) { return 1; } - } - /* try particles */ - 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; + /* try brush */ + if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) { + br= path->ptr[path->len-1].data; + + if(br) { + tex= give_current_brush_texture(br); - tex= give_current_particle_texture(part); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } } - else { - psys= path->ptr[path->len-1].data; + /* try world */ + if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { + wo= path->ptr[path->len-1].data; - if(psys && psys->part && GS(psys->part->id.name)==ID_PA) { - tex= give_current_particle_texture(psys->part); + 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 material */ - if(buttons_context_path_material(path, 1)) { - ma= path->ptr[path->len-1].data; + /* try particles */ + 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; - if(ma) { - tex= give_current_material_texture(ma); + 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; - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; + 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 lamp */ - if(buttons_context_path_data(path, OB_LAMP)) { - la= path->ptr[path->len-1].data; + /* try material */ + if(buttons_context_path_material(path, 1)) { + ma= path->ptr[path->len-1].data; - if(la) { - tex= give_current_lamp_texture(la); + if(ma) { + tex= give_current_material_texture(ma); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } } - } - /* try brushes again in case of no material, lamp, etc */ - path->len = orig_len; - if(buttons_context_path_brush(path)) { - br= path->ptr[path->len-1].data; - - if(br) { - tex= give_current_brush_texture(br); + /* try lamp */ + if(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 brushes again in case of no material, lamp, etc */ + path->len = orig_len; + if(buttons_context_path_brush(path)) { + br= path->ptr[path->len-1].data; - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; + if(br) { + tex= give_current_brush_texture(br); + + RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); + path->len++; + return 1; + } } } @@ -530,7 +561,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma found= buttons_context_path_material(path, 0); break; case BCONTEXT_TEXTURE: - found= buttons_context_path_texture(path); + found= buttons_context_path_texture(path, sbuts->texuser); break; case BCONTEXT_BONE: found= buttons_context_path_bone(path); @@ -580,6 +611,8 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts) PointerRNA *ptr; int a, pflag= 0, flag= 0; + buttons_texture_context_compute(C, sbuts); + if(!sbuts->path) sbuts->path= MEM_callocN(sizeof(ButsContextPath), "ButsContextPath"); @@ -649,7 +682,8 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts) const char *buttons_context_dir[] = { "world", "object", "mesh", "armature", "lattice", "curve", "meta_ball", "lamp", "speaker", "camera", "material", "material_slot", - "texture", "texture_slot", "bone", "edit_bone", "pose_bone", "particle_system", "particle_system_editable", + "texture", "texture_slot", "texture_user", "bone", "edit_bone", + "pose_bone", "particle_system", "particle_system_editable", "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL}; int buttons_context(const bContext *C, const char *member, bContextDataResult *result) @@ -710,7 +744,17 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r return 1; } else if(CTX_data_equals(member, "texture")) { - set_pointer_type(path, result, &RNA_Texture); + ButsContextTexture *ct= sbuts->texuser; + + if(ct) { + /* new shading system */ + CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture); + } + else { + /* old shading system */ + set_pointer_type(path, result, &RNA_Texture); + } + return 1; } else if(CTX_data_equals(member, "material_slot")) { @@ -729,23 +773,52 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r return 1; } - else if(CTX_data_equals(member, "texture_node")) { - PointerRNA *ptr; + else if(CTX_data_equals(member, "texture_user")) { + ButsContextTexture *ct= sbuts->texuser; - if((ptr=get_pointer_type(path, &RNA_Material))) { - Material *ma= ptr->data; + if(!ct) + return 0; /* old shading system */ - if(ma) { - bNode *node= give_current_material_texture_node(ma); - CTX_data_pointer_set(result, &ma->id, &RNA_Node, node); - } + if(ct->user && ct->user->ptr.data) { + ButsTextureUser *user= ct->user; + CTX_data_pointer_set(result, user->ptr.id.data, user->ptr.type, user->ptr.data); } return 1; } + else if(CTX_data_equals(member, "texture_node")) { + ButsContextTexture *ct= sbuts->texuser; + + if(ct) { + /* new shading system */ + if(ct->user && ct->user->node) + CTX_data_pointer_set(result, &ct->user->ntree->id, &RNA_Node, ct->user->node); + + return 1; + } + else { + /* old shading system */ + PointerRNA *ptr; + + if((ptr=get_pointer_type(path, &RNA_Material))) { + Material *ma= ptr->data; + + if(ma) { + bNode *node= give_current_material_texture_node(ma); + CTX_data_pointer_set(result, &ma->id, &RNA_Node, node); + } + } + + return 1; + } + } else if(CTX_data_equals(member, "texture_slot")) { + ButsContextTexture *ct= sbuts->texuser; PointerRNA *ptr; + if(ct) + return 0; /* new shading system */ + if((ptr=get_pointer_type(path, &RNA_Material))) { Material *ma= ptr->data; diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index 27084488163..aa692a940d8 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -31,14 +31,20 @@ #ifndef ED_BUTTONS_INTERN_H #define ED_BUTTONS_INTERN_H +#include "DNA_listBase.h" +#include "RNA_types.h" + struct ARegion; struct ARegionType; +struct ID; +struct SpaceButs; +struct Tex; struct bContext; struct bContextDataResult; -struct SpaceButs; +struct bNode; +struct bNodeTree; struct uiLayout; struct wmOperatorType; -struct ID; /* buts->scaflag */ #define BUTS_SENS_SEL 1 @@ -53,6 +59,42 @@ struct ID; #define BUTS_SENS_STATE 512 #define BUTS_ACT_STATE 1024 +/* context data */ + +typedef struct ButsContextPath { + PointerRNA ptr[8]; + int len; + int flag; + int tex_ctx; +} ButsContextPath; + +typedef struct ButsTextureUser { + struct ButsTextureUser *next, *prev; + + struct ID *id; + + PointerRNA ptr; + PropertyRNA *prop; + + struct bNodeTree *ntree; + struct bNode *node; + + const char *category; + int icon; + const char *name; + + int index; +} ButsTextureUser; + +typedef struct ButsContextTexture { + ListBase users; + + struct Tex *texture; + + struct ButsTextureUser *user; + int index; +} ButsContextTexture; + /* internal exports only */ /* buttons_header.c */ @@ -67,6 +109,9 @@ struct ID *buttons_context_id_path(const struct bContext *C); extern const char *buttons_context_dir[]; /* doc access */ +/* buttons_texture.c */ +void buttons_texture_context_compute(const struct bContext *C, struct SpaceButs *sbuts); + /* buttons_ops.c */ void BUTTONS_OT_file_browse(struct wmOperatorType *ot); void BUTTONS_OT_directory_browse(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c new file mode 100644 index 00000000000..dd9f3c57896 --- /dev/null +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -0,0 +1,469 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_buttons/buttons_texture.c + * \ingroup spbuttons + */ + + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "DNA_brush_types.h" +#include "DNA_ID.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_world_types.h" + +#include "BKE_context.h" +#include "BKE_material.h" +#include "BKE_modifier.h" +#include "BKE_node.h" +#include "BKE_paint.h" +#include "BKE_particle.h" +#include "BKE_scene.h" + +#include "RNA_access.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "ED_node.h" +#include "ED_screen.h" + +#include "../interface/interface_intern.h" + +#include "buttons_intern.h" // own include + +/************************* Texture User **************************/ + +static void buttons_texture_user_property_add(ListBase *users, ID *id, + PointerRNA ptr, PropertyRNA *prop, + const char *category, int icon, const char *name) +{ + ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser"); + + user->id= id; + user->ptr = ptr; + user->prop = prop; + user->category = category; + user->icon = icon; + user->name = name; + user->index = BLI_countlist(users); + + BLI_addtail(users, user); +} + +static void buttons_texture_user_node_add(ListBase *users, ID *id, + bNodeTree *ntree, bNode *node, + const char *category, int icon, const char *name) +{ + ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser"); + + user->id= id; + user->ntree = ntree; + user->node = node; + user->category = category; + user->icon = icon; + user->name = name; + user->index = BLI_countlist(users); + + BLI_addtail(users, user); +} + +static void buttons_texture_users_find_nodetree(ListBase *users, ID *id, + bNodeTree *ntree, const char *category) +{ + bNode *node; + + if(ntree) { + for(node=ntree->nodes.first; node; node=node->next) { + if(node->typeinfo->nclass == NODE_CLASS_TEXTURE) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + prop = RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_node_add(users, id, ntree, node, + category, RNA_struct_ui_icon(ptr.type), node->name); + } + else if(node->type == NODE_GROUP && node->id) { + buttons_texture_users_find_nodetree(users, id, (bNodeTree*)node->id, category); + } + } + } +} + +static void buttons_texture_modifier_foreach(void *userData, Object *ob, ModifierData *md, const char *propname) +{ + PointerRNA ptr; + PropertyRNA *prop; + ListBase *users = userData; + + RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr); + prop = RNA_struct_find_property(&ptr, propname); + + buttons_texture_user_property_add(users, &ob->id, ptr, prop, + "Modifiers", RNA_struct_ui_icon(ptr.type), md->name); +} + +static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceButs *sbuts) +{ + Scene *scene= NULL; + Object *ob= NULL; + Material *ma= NULL; + Lamp *la= NULL; + World *wrld= NULL; + Brush *brush= NULL; + ID *pinid = sbuts->pinid; + + /* get data from context */ + if(pinid) { + if(GS(pinid->name) == ID_SCE) + scene= (Scene*)pinid; + else if(GS(pinid->name) == ID_OB) + ob= (Object*)pinid; + else if(GS(pinid->name) == ID_LA) + la= (Lamp*)pinid; + else if(GS(pinid->name) == ID_WO) + wrld= (World*)pinid; + else if(GS(pinid->name) == ID_MA) + ma= (Material*)pinid; + else if(GS(pinid->name) == ID_BR) + brush= (Brush*)pinid; + } + + if(!scene) + scene= CTX_data_scene(C); + + if(!(pinid || pinid == &scene->id)) { + ob= (scene->basact)? scene->basact->object: NULL; + wrld= scene->world; + brush= paint_brush(paint_get_active(scene)); + } + + if(ob && ob->type == OB_LAMP && !la) + la= ob->data; + if(ob && !ma) + ma= give_current_material(ob, ob->actcol); + + /* fill users */ + users->first = users->last = NULL; + + if(ma) + buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, "Material"); + if(la) + buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp"); + if(wrld) + buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, "World"); + + if(ob) { + ParticleSystem *psys= psys_get_current(ob); + MTex *mtex; + int a; + + /* modifiers */ + modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users); + + /* particle systems */ + if(psys) { + /* todo: these slots are not in the UI */ + for(a=0; apart->mtex[a]; + + if(mtex) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex, &ptr); + prop = RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_property_add(users, &psys->part->id, ptr, prop, + "Particles", RNA_struct_ui_icon(&RNA_ParticleSettings), psys->name); + } + } + } + + /* field */ + if(ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&ob->id, &RNA_FieldSettings, ob->pd, &ptr); + prop = RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_property_add(users, &ob->id, ptr, prop, + "Fields", ICON_FORCE_TEXTURE, "Texture Field"); + } + } + + /* brush */ + if(brush) { + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mtex, &ptr); + prop= RNA_struct_find_property(&ptr, "texture"); + + buttons_texture_user_property_add(users, &brush->id, ptr, prop, + "Brush", ICON_BRUSH_DATA, brush->id.name+2); + } +} + +void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts) +{ + /* gatheravailable texture users in context. runs on every draw of + properties editor, before the buttons are created. */ + ButsContextTexture *ct= sbuts->texuser; + Scene *scene= CTX_data_scene(C); + + if(!scene_use_new_shading_nodes(scene)) { + if(ct) { + MEM_freeN(ct); + BLI_freelistN(&ct->users); + sbuts->texuser= NULL; + } + + return; + } + + if(!ct) { + ct= MEM_callocN(sizeof(ButsContextTexture), "ButsContextTexture"); + sbuts->texuser= ct; + } + else { + BLI_freelistN(&ct->users); + } + + buttons_texture_users_from_context(&ct->users, C, sbuts); + + /* set one user as active based on active index */ + if(ct->index >= BLI_countlist(&ct->users)) + ct->index= 0; + + ct->user = BLI_findlink(&ct->users, ct->index); + ct->texture = NULL; + + if(ct->user) { + if(ct->user->ptr.data) { + PointerRNA texptr; + Tex *tex; + + /* get texture datablock pointer if it's a property */ + texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop); + tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL; + + ct->texture = tex; + } + else if(ct->user->node && !(ct->user->node->flag & NODE_ACTIVE_TEXTURE)) { + ButsTextureUser *user; + + /* detect change of active texture node in same node tree, in that + case we also automatically switch to the other node */ + for(user=ct->users.first; user; user=user->next) { + if(user->ntree == ct->user->ntree && user->node != ct->user->node) { + if(user->node->flag & NODE_ACTIVE_TEXTURE) { + ct->user = user; + ct->index = BLI_findindex(&ct->users, user); + break; + } + } + } + } + } +} + +static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)) +{ + /* callback when selecting a texture user in the menu */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user = (ButsTextureUser*)user_p; + PointerRNA texptr; + Tex *tex; + + if(!ct) + return; + + /* set user as active */ + if(user->node) { + ED_node_set_active(CTX_data_main(C), user->ntree, user->node); + ct->texture = NULL; + } + else { + texptr = RNA_property_pointer_get(&user->ptr, user->prop); + tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL; + + ct->texture = tex; + } + + ct->user = user; + ct->index = user->index; +} + +static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUSED(arg)) +{ + /* callback when opening texture user selection menu, to create buttons. */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user; + uiBlock *block = uiLayoutGetBlock(layout); + const char *last_category = NULL; + + for(user=ct->users.first; user; user=user->next) { + uiBut *but; + char name[UI_MAX_NAME_STR]; + + /* add label per category */ + if(!last_category || strcmp(last_category, user->category) != 0) { + uiItemL(layout, user->category, ICON_NONE); + but= block->buttons.last; + but->flag= UI_TEXT_LEFT; + } + + /* create button */ + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); + + but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiButSetNFunc(but, template_texture_select, MEM_dupallocN(user), NULL); + + last_category = user->category; + } +} + +void uiTemplateTextureUser(uiLayout *layout, bContext *C) +{ + /* texture user selection dropdown menu. the available users have been + gathered before drawing in ButsContextTexture, we merely need to + display the current item. */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + uiBlock *block = uiLayoutGetBlock(layout); + uiBut *but; + ButsTextureUser *user; + char name[UI_MAX_NAME_STR]; + + if(!ct) + return; + + /* get current user */ + user= ct->user; + + if(!user) { + uiItemL(layout, "No textures in context.", ICON_NONE); + return; + } + + /* create button */ + BLI_snprintf(name, UI_MAX_NAME_STR, "%s", user->name); + + if(user->icon) { + but= uiDefIconTextMenuBut(block, template_texture_user_menu, NULL, + user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, ""); + } + else { + but= uiDefMenuBut(block, template_texture_user_menu, NULL, + name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, ""); + } + + /* some cosmetic tweaks */ + but->type= MENU; + but->flag |= UI_TEXT_LEFT; + but->flag &= ~UI_ICON_SUBMENU; +} + +/************************* Texture Show **************************/ + +static void template_texture_show(bContext *C, void *data_p, void *prop_p) +{ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user; + + if(!ct) + return; + + for(user=ct->users.first; user; user=user->next) + if(user->ptr.data == data_p && user->prop == prop_p) + break; + + if(user) { + /* select texture */ + template_texture_select(C, user, NULL); + + /* change context */ + sbuts->mainb= BCONTEXT_TEXTURE; + sbuts->mainbuser= sbuts->mainb; + sbuts->preview= 1; + + /* redraw editor */ + ED_area_tag_redraw(CTX_wm_area(C)); + } +} + +void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, PropertyRNA *prop) +{ + /* button to quickly show texture in texture tab */ + SpaceButs *sbuts = CTX_wm_space_buts(C); + ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL; + ButsTextureUser *user; + + /* only show button in other tabs in properties editor */ + if(!ct || sbuts->mainb == BCONTEXT_TEXTURE) + return; + + /* find corresponding texture user */ + for(user=ct->users.first; user; user=user->next) + if(user->ptr.data == ptr->data && user->prop == prop) + break; + + /* draw button */ + if(user) { + uiBlock *block = uiLayoutGetBlock(layout); + uiBut *but; + + but= uiDefIconBut(block, BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, "Show texture in texture tab"); + uiButSetFunc(but, template_texture_show, user->ptr.data, user->prop); + } +} + diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 4c328d174e9..0c326af406f 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -104,6 +104,12 @@ static void buttons_free(SpaceLink *sl) if(sbuts->path) MEM_freeN(sbuts->path); + + if(sbuts->texuser) { + ButsContextTexture *ct= sbuts->texuser; + BLI_freelistN(&ct->users); + MEM_freeN(ct); + } } /* spacetype; init callback */ @@ -127,6 +133,7 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ sbutsn->ri= NULL; sbutsn->path= NULL; + sbutsn->texuser= NULL; return (SpaceLink *)sbutsn; } -- cgit v1.2.3