Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Hamalainen <blender@miikah.org>2011-11-09 19:46:53 +0400
committerMiika Hamalainen <blender@miikah.org>2011-11-09 19:46:53 +0400
commit1b4a54ad73c058baa59ffdc9e5f18b0b79030fb0 (patch)
treea5b84d392ea14b0d760a5e24f7a8e51f203d558c /source/blender/editors/space_buttons
parentedec46b0a6aac18f406991b9e16228d4bd848c61 (diff)
parentbc5ec4e69cf3308c2563239c0e8372b853800a78 (diff)
Merge with trunk r41701soc-2011-carrot
Diffstat (limited to 'source/blender/editors/space_buttons')
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c255
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h49
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c469
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c7
5 files changed, 688 insertions, 93 deletions
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 98295f21cd4..9de804d275f 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", "dynamic_paint", 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 <stdlib.h>
+#include <string.h>
+
+#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; a<MAX_MTEX; a++) {
+ mtex = psys->part->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;
}