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:
Diffstat (limited to 'source/blender/src/drawnode.c')
-rw-r--r--source/blender/src/drawnode.c300
1 files changed, 179 insertions, 121 deletions
diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c
index a64cc2d674e..40c40db30a5 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -47,6 +47,8 @@
#include "BKE_global.h"
#include "BKE_object.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_utildefines.h"
@@ -57,8 +59,10 @@
#include "BIF_interface_icons.h"
#include "BIF_language.h"
#include "BIF_mywindow.h"
+#include "BIF_previewrender.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
+#include "BIF_space.h"
#include "BSE_drawipo.h"
#include "BSE_node.h"
@@ -101,35 +105,12 @@ static void snode_drawstring(SpaceNode *snode, char *str, int okwidth)
/* ************** Socket callbacks *********** */
/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
-static uiBlock *socket_value_menu(void *sock_v)
-{
- bNodeSocket *sock= sock_v;
- uiBlock *block;
- char name[NODE_MAXSTR];
-
- /* don't add new block to a listbase if caller is LABEL button */
- block= uiNewBlock(NULL, "socket menu", UI_EMBOSS, UI_HELV, curarea->win);
-
- /* use this for a fake extra empy space around the buttons */
- uiDefBut(block, LABEL, 0, "", -4, -4, 188, 28, NULL, 0, 0, 0, 0, "");
-
- BLI_strncpy(name, sock->name, NODE_MAXSTR-1);
- strcat(name, " ");
- uiDefButF(block, NUMSLI, 0, name, 0,0,180,20, sock->ns.vec, 0.0, 1.0, 10, 0, "");
-
- uiBlockSetDirection(block, UI_TOP);
-
- return block;
-}
-
-/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
static uiBlock *socket_vector_menu(void *sock_v)
{
bNodeSocket *sock= sock_v;
uiBlock *block;
- /* don't add new block to a listbase if caller is LABEL button */
- block= uiNewBlock(NULL, "socket menu", UI_EMBOSS, UI_HELV, curarea->win);
+ block= uiNewBlock(&curarea->uiblocks, "socket menu", UI_EMBOSS, UI_HELV, curarea->win);
/* use this for a fake extra empy space around the buttons */
uiDefBut(block, LABEL, 0, "", -4, -4, 188, 68, NULL, 0, 0, 0, 0, "");
@@ -144,71 +125,138 @@ static uiBlock *socket_vector_menu(void *sock_v)
return block;
}
-static uiBlock *socket_color_menu(void *sock_v)
+/* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
+
+
+static void node_ID_title_cb(void *node_v, void *unused_v)
{
- bNodeSocket *sock= sock_v;
- uiBlock *block;
-
- /* don't add new block to a listbase if caller is LABEL button */
- block= uiNewBlock(NULL, "socket menu", UI_EMBOSS, UI_HELV, curarea->win);
-
- /* use this for a fake extra empy space around the buttons */
- uiDefBut(block, LABEL, 0, "", -4, -4, 188, 68, NULL, 0, 0, 0, 0, "");
+ bNode *node= node_v;
+
+ if(node->id) {
+ test_idbutton(node->id->name+2); /* library.c, verifies unique name */
+ BLI_strncpy(node->name, node->id->name+2, 21);
+
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWNODE, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+}
+
+static void node_mat_alone_cb(void *node_v, void *unused)
+{
+ bNode *node= node_v;
- uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, 0, "R ", 0,40,180,20, sock->ns.vec, 0.0, 1.0, 10, 0, "");
- uiDefButF(block, NUMSLI, 0, "G ", 0,20,180,20, sock->ns.vec+1, 0.0, 1.0, 10, 0, "");
- uiDefButF(block, NUMSLI, 0, "B ", 0,0,180,20, sock->ns.vec+2, 0.0, 1.0, 10, 0, "");
+ node->id= (ID *)copy_material((Material *)node->id);
- uiBlockSetDirection(block, UI_TOP);
-
- return block;
+ BIF_undo_push("Single user material");
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWNODE, 0);
+ allqueue(REDRAWOOPS, 0);
}
-static void node_ID_title_cb(void *node_v, void *unused_v)
+static void node_browse_mat_cb(void *ntree_v, void *node_v)
{
+ bNodeTree *ntree= ntree_v;
bNode *node= node_v;
+
+ if(node->menunr==32767 || node->menunr==0) { /* code for Add New */
+ if(node->id) {
+ /* make copy, but make sure it doesnt have the node tag nor nodes */
+ Material *ma= (Material *)node->id;
+ ma->id.us--;
+ ma= copy_material(ma);
+ ma->use_nodes= 0;
+ if(ma->nodetree) ntreeFreeTree(ma->nodetree);
+ ma->nodetree= NULL;
+ node->id= (ID *)ma;
+ }
+ else node->id= (ID *)add_material("MatNode");
+ }
+ else {
+ if(node->id) node->id->us--;
+ node->id= BLI_findlink(&G.main->mat, node->menunr-1);
+ id_us_plus(node->id);
+ }
+ BLI_strncpy(node->name, node->id->name+2, 21);
+
+ nodeSetActive(ntree, node);
- if(node->id)
- BLI_strncpy(node->name, node->id->name+2, 21);
-}
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWNODE, 0);
+ BIF_preview_changed(ID_MA);
-/* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
+ node->menunr= 0;
+}
-static int node_shader_buts_material(uiBlock *block, bNode *node, rctf *butr)
+static int node_shader_buts_material(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
uiBut *bt;
- float dx= (butr->xmax-butr->xmin)/3.0f;
+ short dx= (short)((butr->xmax-butr->xmin)/3.0f), has_us= (node->id && node->id->us>1);
+ char *strp;
uiBlockBeginAlign(block);
- bt= uiDefIDPoinBut(block, test_matpoin_but, ID_MA, B_NODE_EXEC, "",
- butr->xmin, butr->ymin+19.0f, butr->xmax-butr->xmin, 19.0f,
- &node->id, "");
- uiButSetFunc(bt, node_ID_title_cb, node, NULL);
-
- uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC, "Diff",
- butr->xmin, butr->ymin, dx, 19.0f,
- &node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse");
- uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC, "Spec",
- butr->xmin+dx, butr->ymin, dx, 19.0f,
- &node->custom1, 0, 0, 0, 0, "Material Node outputs Specular");
- uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC, "Neg Normal",
- butr->xmin+2.0f*dx, butr->ymin, dx, 19.0f,
- &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal");
+ if(has_us) uiBlockSetCol(block, TH_BUT_SETTING1);
+ else uiBlockSetCol(block, TH_BUT_SETTING2);
+
+ /* browse button */
+ IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), NULL, NULL);
+ node->menunr= 0;
+ bt= uiDefButS(block, MENU, B_NOP, strp,
+ butr->xmin, butr->ymin+19, 19, 19,
+ &node->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW");
+ uiButSetFunc(bt, node_browse_mat_cb, ntree, node);
+ if(strp) MEM_freeN(strp);
+
+ /* Add New button */
+ if(node->id==NULL) {
+ bt= uiDefBut(block, BUT, B_NOP, "Add New",
+ butr->xmin+19, butr->ymin+19, (short)(butr->xmax-butr->xmin-19.0f), 19,
+ NULL, 0.0, 0.0, 0, 0, "Add new Material");
+ uiButSetFunc(bt, node_browse_mat_cb, ntree, node);
+ }
+ else {
+ /* name button */
+ short width= (short)(butr->xmax-butr->xmin-19.0f - (has_us?19.0f:0.0f));
+ bt= uiDefBut(block, TEX, B_NOP, "MA:",
+ butr->xmin+19, butr->ymin+19, width, 19,
+ node->id->name+2, 0.0, 19.0, 0, 0, "Material name");
+ uiButSetFunc(bt, node_ID_title_cb, node, NULL);
+
+ /* user amount */
+ if(has_us) {
+ char str1[32];
+ sprintf(str1, "%d", node->id->us);
+ bt= uiDefBut(block, BUT, B_NOP, str1,
+ butr->xmax-19, butr->ymin+19, 19, 19,
+ NULL, 0, 0, 0, 0, "Displays number of users. Click to make a single-user copy.");
+ uiButSetFunc(bt, node_mat_alone_cb, node, NULL);
+ }
+
+ /* node options */
+ uiBlockSetCol(block, TH_AUTO);
+ uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC, "Diff",
+ butr->xmin, butr->ymin, dx, 19,
+ &node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse");
+ uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC, "Spec",
+ butr->xmin+dx, butr->ymin, dx, 19,
+ &node->custom1, 0, 0, 0, 0, "Material Node outputs Specular");
+ uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC, "Neg Normal",
+ butr->xmax-dx, butr->ymin, dx, 19,
+ &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal");
+ }
uiBlockEndAlign(block);
-
}
return 38;
}
-static int node_shader_buts_texture(uiBlock *block, bNode *node, rctf *butr)
+static int node_shader_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
uiBut *bt;
bt= uiDefIDPoinBut(block, test_texpoin_but, ID_TE, B_NODE_EXEC, "",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19.0f,
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19,
&node->id, "");
uiButSetFunc(bt, node_ID_title_cb, node, NULL);
@@ -216,20 +264,20 @@ static int node_shader_buts_texture(uiBlock *block, bNode *node, rctf *butr)
return 19;
}
-static int node_shader_buts_value(uiBlock *block, bNode *node, rctf *butr)
+static int node_shader_buts_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
bNodeSocket *sock= node->outputs.first; /* first socket stores value */
uiDefButF(block, NUM, B_NODE_EXEC, "",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20.0f,
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
sock->ns.vec, 0.0f, 1.0f, 10, 2, "");
}
return 20;
}
-static int node_shader_buts_rgb(uiBlock *block, bNode *node, rctf *butr)
+static int node_shader_buts_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
bNodeSocket *sock= node->outputs.first; /* first socket stores value */
@@ -238,13 +286,13 @@ static int node_shader_buts_rgb(uiBlock *block, bNode *node, rctf *butr)
uiBlockSetEmboss(block, UI_EMBOSSP);
uiDefButF(block, HSVCUBE, B_NODE_EXEC, "",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 12.0f,
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 12,
sock->ns.vec, 0.0f, 1.0f, 3, 0, "");
uiDefButF(block, HSVCUBE, B_NODE_EXEC, "",
- butr->xmin, butr->ymin+15.0f, butr->xmax-butr->xmin, butr->ymax-butr->ymin -15.0f -15.0f,
+ butr->xmin, butr->ymin+15, butr->xmax-butr->xmin, butr->ymax-butr->ymin -15 -15,
sock->ns.vec, 0.0f, 1.0f, 2, 0, "");
uiDefButF(block, COL, B_NOP, "",
- butr->xmin, butr->ymax-12.0f, butr->xmax-butr->xmin, 12.0f,
+ butr->xmin, butr->ymax-12, butr->xmax-butr->xmin, 12,
sock->ns.vec, 0.0, 0.0, -1, 0, "");
/* the -1 above prevents col button to popup a color picker */
@@ -258,30 +306,25 @@ static void node_but_title_cb(void *node_v, void *but_v)
bNode *node= node_v;
uiBut *bt= but_v;
BLI_strncpy(node->name, bt->drawstr, NODE_MAXSTR);
+
+ allqueue(REDRAWNODE, 0);
}
-static int node_shader_buts_mix_rgb(uiBlock *block, bNode *node, rctf *butr)
+static int node_shader_buts_mix_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
uiBut *bt;
- bNodeSocket *sock= node->inputs.first; /* first socket stores "fac" */
- uiBlockBeginAlign(block);
/* blend type */
bt=uiDefButS(block, MENU, B_NODE_EXEC, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Divide %x5|Difference %x6|Darken %x7|Lighten %x8",
- butr->xmin, butr->ymin+20.0f, butr->xmax-butr->xmin, 20.0f,
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
&node->custom1, 0, 0, 0, 0, "");
uiButSetFunc(bt, node_but_title_cb, node, bt);
- /* value */
- uiDefButF(block, NUM, B_NODE_EXEC, "",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20.0f,
- sock->ns.vec, 0.0f, 1.0f, 10, 2, "");
- uiBlockEndAlign(block);
}
- return 40;
+ return 20;
}
-static int node_shader_buts_valtorgb(uiBlock *block, bNode *node, rctf *butr)
+static int node_shader_buts_valtorgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block && (node->flag & NODE_OPTIONS)) {
if(node->storage) {
@@ -338,8 +381,6 @@ static void draw_nodespace_grid(SpaceNode *snode)
{
float start, step= 25.0f;
- /* window is 'pixel size', like buttons */
-
BIF_ThemeColorShade(TH_BACK, -10);
start= snode->v2d.cur.xmin -fmod(snode->v2d.cur.xmin, step);
@@ -355,6 +396,14 @@ static void draw_nodespace_grid(SpaceNode *snode)
glVertex2f(snode->v2d.cur.xmin, start);
glVertex2f(snode->v2d.cur.xmax, start);
}
+
+ /* X and Y axis */
+ BIF_ThemeColorShade(TH_BACK, -18);
+ glVertex2f(0.0f, snode->v2d.cur.ymin);
+ glVertex2f(0.0f, snode->v2d.cur.ymax);
+ glVertex2f(snode->v2d.cur.xmin, 0.0f);
+ glVertex2f(snode->v2d.cur.xmax, 0.0f);
+
glEnd();
}
@@ -520,7 +569,7 @@ static void node_update(bNode *node)
if((node->flag & NODE_OPTIONS) && node->typeinfo->butfunc) {
dy-= NODE_DYS/2;
node->butr.ymax= dy;
- node->butr.ymin= dy - (float)node->typeinfo->butfunc(NULL, node, NULL);
+ node->butr.ymin= dy - (float)node->typeinfo->butfunc(NULL, NULL, node, NULL);
dy= node->butr.ymin - NODE_DYS/2;
}
@@ -572,7 +621,7 @@ static int node_get_colorid(bNode *node)
return TH_NODE;
}
-static void node_basis_draw(SpaceNode *snode, bNode *node)
+static void node_basis_draw(ScrArea *sa, SpaceNode *snode, bNode *node)
{
bNodeSocket *sock;
rctf *rct= &node->totr;
@@ -645,21 +694,36 @@ static void node_basis_draw(SpaceNode *snode, bNode *node)
glDisable(GL_BLEND);
}
+ /* we make buttons for input sockets, if... */
+ if(node->flag & NODE_OPTIONS) {
+ if(node->inputs.first || node->typeinfo->butfunc) {
+ uiBlock *block= uiNewBlock(NULL, "node buttons", UI_EMBOSS, UI_HELV, sa->win);
+ BLI_addtail(&sa->uiblocks, block);
+ uiBlockSetFlag(block, UI_BLOCK_NO_HILITE);
+ node->block= block;
+ }
+ }
+
/* socket inputs, label buttons */
for(sock= node->inputs.first; sock; sock= sock->next) {
socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT);
- if(sock->type==SOCK_VALUE) {
- uiBut *bt= uiDefBut(snode->block, LABEL, B_NODE_EXEC, sock->name, sock->locx+5.0f, sock->locy-10.0f, node->width-NODE_DY, NODE_DY, sock, 0, 0, 0, 0, "");
- bt->block_func= socket_value_menu;
- }
- else if(sock->type==SOCK_VECTOR) {
- uiBut *bt= uiDefBut(snode->block, LABEL, B_NODE_EXEC, sock->name, sock->locx+5.0f, sock->locy-10.0f, node->width-NODE_DY, NODE_DY, sock, 0, 0, 0, 0, "");
- bt->block_func= socket_vector_menu;
- }
- else if(sock->type==SOCK_RGBA) {
- uiBut *bt= uiDefBut(snode->block, LABEL, B_NODE_EXEC, sock->name, sock->locx+5.0f, sock->locy-10.0f, node->width-NODE_DY, NODE_DY, sock, 0, 0, 0, 0, "");
- bt->block_func= socket_color_menu;
+ if(node->block && sock->link==NULL) {
+ if(sock->type==SOCK_VALUE) {
+ uiDefButF(node->block, NUM, B_NODE_EXEC, sock->name,
+ (short)node->locx+NODE_DYS, (short)(sock->locy)-7, (short)node->width-NODE_DY, 17,
+ sock->ns.vec, 0.0f, 1.0f, 10, 2, "");
+ }
+ else if(sock->type==SOCK_VECTOR) {
+ uiDefBlockBut(node->block, socket_vector_menu, sock, sock->name,
+ (short)node->locx+NODE_DYS, (short)sock->locy-7, (short)node->width-NODE_DY, 17,
+ "");
+ }
+ else if(node->block && sock->type==SOCK_RGBA) {
+ uiDefButF(node->block, COL, B_NODE_EXEC, "",
+ (short)(node->locx+NODE_DYS), (short)sock->locy-6, (short)(node->width-NODE_DY), 15,
+ sock->ns.vec, 0, 0, 0, 0, "");
+ }
}
else {
BIF_ThemeColor(TH_TEXT);
@@ -689,9 +753,12 @@ static void node_basis_draw(SpaceNode *snode, bNode *node)
node_draw_preview(node->preview, &node->prvr);
/* buttons */
- if(node->flag & NODE_OPTIONS)
- if(node->typeinfo->butfunc)
- node->typeinfo->butfunc(snode->block, node, &node->butr);
+ if(node->flag & NODE_OPTIONS) {
+ if(node->typeinfo->butfunc) {
+ node->typeinfo->butfunc(node->block, snode->nodetree, node, &node->butr);
+ }
+ uiDrawBlock(node->block);
+ }
}
@@ -724,17 +791,14 @@ void node_hidden_draw(SpaceNode *snode, bNode *node)
else
BIF_ThemeColorBlendShade(TH_TEXT, color_id, 0.4, 10);
- /* open/close entirely? */
+ /* open entirely? */
ui_draw_tria_icon(rct->xmin+9.0f, centy-6.0f, snode->aspect, 'h');
- if(node->flag & SELECT)
- BIF_ThemeColor(TH_TEXT_HI);
- else
- BIF_ThemeColor(TH_TEXT);
-
- ui_rasterpos_safe(rct->xmin+21.0f, centy-4.0f, snode->aspect);
- snode_drawstring(snode, node->name, (int)(rct->xmax - rct->xmin-18.0f -12.0f));
-
+ if(node->miniwidth>0.0f) {
+ ui_rasterpos_safe(rct->xmin+21.0f, centy-4.0f, snode->aspect);
+ snode_drawstring(snode, node->name, (int)(rct->xmax - rct->xmin-18.0f -12.0f));
+ }
+
/* scale widget thing */
BIF_ThemeColorShade(color_id, -10);
dx= 10.0f;
@@ -854,6 +918,9 @@ void drawnodespace(ScrArea *sa, void *spacedata)
bwin_clear_viewmat(sa->win); /* clear buttons view */
glLoadIdentity();
+ /* always free, blocks here have no unique identifier (1 block per node) */
+ uiFreeBlocks(&sa->uiblocks);
+
/* only set once */
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable(GL_MAP1_VERTEX_3);
@@ -866,7 +933,6 @@ void drawnodespace(ScrArea *sa, void *spacedata)
draw_nodespace_grid(snode);
/* nodes */
-
snode_set_context(snode);
if(snode->nodetree) {
@@ -885,34 +951,26 @@ void drawnodespace(ScrArea *sa, void *spacedata)
glDisable(GL_BLEND);
glDisable( GL_LINE_SMOOTH );
- /* not selected */
- snode->block= uiNewBlock(&sa->uiblocks, "node buttons1", UI_EMBOSS, UI_HELV, sa->win);
- uiBlockSetFlag(snode->block, UI_BLOCK_NO_HILITE);
-
+ /* not selected first */
for(node= snode->nodetree->nodes.first; node; node= node->next) {
+ node->block= NULL; /* were freed */
if(!(node->flag & SELECT)) {
if(node->flag & NODE_HIDDEN)
node_hidden_draw(snode, node);
else
- node_basis_draw(snode, node);
+ node_basis_draw(sa, snode, node);
}
}
- uiDrawBlock(snode->block);
/* selected */
- snode->block= uiNewBlock(&sa->uiblocks, "node buttons2", UI_EMBOSS, UI_HELV, sa->win);
- uiBlockSetFlag(snode->block, UI_BLOCK_NO_HILITE);
-
for(node= snode->nodetree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
if(node->flag & NODE_HIDDEN)
node_hidden_draw(snode, node);
else
- node_basis_draw(snode, node);
+ node_basis_draw(sa, snode, node);
}
}
-
- uiDrawBlock(snode->block);
}
/* restore viewport (not needed yet) */