From 8e0fe8bff72e2dc2926618577eaffdd3417a8304 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Mon, 5 Sep 2011 21:01:50 +0000 Subject: Merged the particles-2010 branch with node improvements into trunk. This branch adds mostly organizational improvements to the node system by renaming the node folders and files. A couple of internal features have been added too. Detailed information can be found on the wiki page: http://wiki.blender.org/index.php/User:Phonybone/Particles2010 --- source/blender/editors/space_node/node_draw.c | 679 +++++++------------------- 1 file changed, 166 insertions(+), 513 deletions(-) (limited to 'source/blender/editors/space_node/node_draw.c') diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 950b3c72fe7..ec118bb3ca2 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -70,8 +70,8 @@ #include "RNA_access.h" -#include "CMP_node.h" -#include "SHD_node.h" +#include "NOD_composite.h" +#include "NOD_shader.h" #include "node_intern.h" @@ -81,6 +81,15 @@ // XXX interface.h extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select); +/* XXX update functions for node editor are a mess, needs a clear concept */ +void ED_node_tree_update(SpaceNode *snode, Scene *scene) +{ + snode_set_context(snode, scene); + + if(snode->nodetree && snode->nodetree->id.us==0) + snode->nodetree->id.us= 1; +} + void ED_node_changed_update(ID *id, bNode *node) { bNodeTree *nodetree, *edittree; @@ -123,24 +132,25 @@ static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup) return 0; } +typedef struct NodeUpdateCalldata { + bNodeTree *ntree; + bNode *node; +} NodeUpdateCalldata; +static void node_generic_update_cb(void *calldata, ID *owner_id, bNodeTree *ntree) +{ + NodeUpdateCalldata *cd= (NodeUpdateCalldata*)calldata; + /* check if nodetree uses the group stored in calldata */ + if (has_nodetree(ntree, cd->ntree)) + ED_node_changed_update(owner_id, cd->node); +} void ED_node_generic_update(Main *bmain, bNodeTree *ntree, bNode *node) { - Material *ma; - Tex *tex; - Scene *sce; - + bNodeTreeType *tti= ntreeGetType(ntree->type); + NodeUpdateCalldata cd; + cd.ntree = ntree; + cd.node = node; /* look through all datablocks, to support groups */ - for(ma=bmain->mat.first; ma; ma=ma->id.next) - if(ma->nodetree && ma->use_nodes && has_nodetree(ma->nodetree, ntree)) - ED_node_changed_update(&ma->id, node); - - for(tex=bmain->tex.first; tex; tex=tex->id.next) - if(tex->nodetree && tex->use_nodes && has_nodetree(tex->nodetree, ntree)) - ED_node_changed_update(&tex->id, node); - - for(sce=bmain->scene.first; sce; sce=sce->id.next) - if(sce->nodetree && sce->use_nodes && has_nodetree(sce->nodetree, ntree)) - ED_node_changed_update(&sce->id, node); + tti->foreach_nodetree(bmain, &cd, node_generic_update_cb); if(ntree->type == NTREE_TEXTURE) ntreeTexCheckCyclics(ntree); @@ -204,14 +214,19 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree) } /* based on settings in node, sets drawing rect info. each redraw! */ -static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) +static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) { uiLayout *layout; PointerRNA ptr; bNodeSocket *nsock; - float dy= node->locy; + float locx, locy; + float dy= locy; int buty; + /* get "global" coords */ + nodeSpaceCoords(node, &locx, &locy); + dy= locy; + /* header */ dy-= NODE_DY; @@ -222,14 +237,14 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) /* output sockets */ for(nsock= node->outputs.first; nsock; nsock= nsock->next) { if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - nsock->locx= node->locx + node->width; + nsock->locx= locx + node->width; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; } } - node->prvr.xmin= node->locx + NODE_DYS; - node->prvr.xmax= node->locx + node->width- NODE_DYS; + node->prvr.xmin= locx + NODE_DYS; + node->prvr.xmax= locx + node->width- NODE_DYS; /* preview rect? */ if(node->flag & NODE_PREVIEW) { @@ -286,21 +301,22 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) node->butr.ymax= 0; RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); - + layout= uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, - node->locx+NODE_DYS, dy, node->butr.xmax, NODE_DY, U.uistyles.first); - + locx+NODE_DYS, dy, node->butr.xmax, NODE_DY, U.uistyles.first); + node->typeinfo->uifunc(layout, (bContext *)C, &ptr); + uiBlockEndAlign(node->block); uiBlockLayoutResolve(node->block, NULL, &buty); - + dy= buty - NODE_DYS/2; } /* input sockets */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) { if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - nsock->locx= node->locx; + nsock->locx= locx; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; } @@ -310,19 +326,23 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) if(node->inputs.first || (node->flag & (NODE_OPTIONS|NODE_PREVIEW))==0 ) dy-= NODE_DYS/2; - node->totr.xmin= node->locx; - node->totr.xmax= node->locx + node->width; - node->totr.ymax= node->locy; - node->totr.ymin= MIN2(dy, node->locy-2*NODE_DY); + node->totr.xmin= locx; + node->totr.xmax= locx + node->width; + node->totr.ymax= locy; + node->totr.ymin= MIN2(dy, locy-2*NODE_DY); } /* based on settings in node, sets drawing rect info. each redraw! */ static void node_update_hidden(bNode *node) { bNodeSocket *nsock; + float locx, locy; float rad, drad, hiddenrad= HIDDEN_RAD; int totin=0, totout=0, tot; + /* get "global" coords */ + nodeSpaceCoords(node, &locx, &locy); + /* calculate minimal radius */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) @@ -336,9 +356,9 @@ static void node_update_hidden(bNode *node) hiddenrad += 5.0f*(float)(tot-4); } - node->totr.xmin= node->locx; - node->totr.xmax= node->locx + 3*hiddenrad + node->miniwidth; - node->totr.ymax= node->locy + (hiddenrad - 0.5f*NODE_DY); + node->totr.xmin= locx; + node->totr.xmax= locx + 3*hiddenrad + node->miniwidth; + node->totr.ymax= locy + (hiddenrad - 0.5f*NODE_DY); node->totr.ymin= node->totr.ymax - 2*hiddenrad; /* output sockets */ @@ -364,6 +384,14 @@ static void node_update_hidden(bNode *node) } } +void node_update_default(const bContext *C, bNodeTree *ntree, bNode *node) +{ + if(node->flag & NODE_HIDDEN) + node_update_hidden(node); + else + node_update_basis(C, ntree, node); +} + static int node_get_colorid(bNode *node) { if(node->typeinfo->nclass==NODE_CLASS_INPUT) @@ -383,138 +411,42 @@ static int node_get_colorid(bNode *node) return TH_NODE; } -/* based on settings in node, sets drawing rect info. each redraw! */ -/* note: this assumes only 1 group at a time is drawn (linked data) */ -/* in node->totr the entire boundbox for the group is stored */ -static void node_update_group(const bContext *C, bNodeTree *UNUSED(ntree), bNode *gnode) -{ - bNodeTree *ngroup= (bNodeTree *)gnode->id; - bNode *node; - bNodeSocket *sock, *gsock; - rctf *rect= &gnode->totr; - float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; - int counter; - int dy; - - rect->xmin = rect->xmax = gnode->locx; - rect->ymin = rect->ymax = gnode->locy; - - /* center them, is a bit of abuse of locx and locy though */ - for(node= ngroup->nodes.first; node; node= node->next) { - node->locx+= gnode->locx; - node->locy+= gnode->locy; - - if(node->flag & NODE_HIDDEN) - node_update_hidden(node); - else - node_update(C, ngroup, node); - node->locx-= gnode->locx; - node->locy-= gnode->locy; - } - counter= 1; - for(node= ngroup->nodes.first; node; node= node->next) { - if(counter) { - *rect= node->totr; - counter= 0; - } - else - BLI_union_rctf(rect, &node->totr); - } - - /* add some room for links to group sockets */ - rect->xmin -= 4*NODE_DY; - rect->xmax += 4*NODE_DY; - rect->ymin-= NODE_DY; - rect->ymax+= NODE_DY; - - /* input sockets */ - dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->inputs)-1); - for(gsock=ngroup->inputs.first, sock=gnode->inputs.first; gsock; gsock=gsock->next, sock=sock->next) { - gsock->locx = rect->xmin; - sock->locx = rect->xmin - node_group_frame; - sock->locy = gsock->locy = dy; - - /* prevent long socket lists from growing out of the group box */ - if (dy-3*NODE_DYS < rect->ymin) - rect->ymin = dy-3*NODE_DYS; - if (dy+3*NODE_DYS > rect->ymax) - rect->ymax = dy+3*NODE_DYS; - - dy -= 2*NODE_DY; - } - - /* output sockets */ - dy = 0.5f*(rect->ymin+rect->ymax) + NODE_DY*(BLI_countlist(&gnode->outputs)-1); - for(gsock=ngroup->outputs.first, sock=gnode->outputs.first; gsock; gsock=gsock->next, sock=sock->next) { - gsock->locx = rect->xmax; - sock->locx = rect->xmax + node_group_frame; - sock->locy = gsock->locy = dy - NODE_DYS; - - /* prevent long socket lists from growing out of the group box */ - if (dy-3*NODE_DYS < rect->ymin) - rect->ymin = dy-3*NODE_DYS; - if (dy+3*NODE_DYS > rect->ymax) - rect->ymax = dy+3*NODE_DYS; - - dy -= 2*NODE_DY; - } -} - /* note: in cmp_util.c is similar code, for node_compo_pass_on() */ /* note: in node_edit.c is similar code, for untangle node */ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) { - bNodeSocket *valsock= NULL, *colsock= NULL, *vecsock= NULL; - bNodeSocket *sock; + static int types[]= { SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA }; bNodeLink link= {NULL}; - int a; + int i; - /* connect the first value buffer in with first value out */ - /* connect the first RGBA buffer in with first RGBA out */ + /* connect the first input of each type with first output of the same type */ - /* test the inputs */ - for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { - if(nodeCountSocketLinks(snode->edittree, sock)) { - if(sock->type==SOCK_VALUE && valsock==NULL) valsock= sock; - if(sock->type==SOCK_VECTOR && vecsock==NULL) vecsock= sock; - if(sock->type==SOCK_RGBA && colsock==NULL) colsock= sock; - } - } - - /* outputs, draw lines */ glEnable(GL_BLEND); glEnable( GL_LINE_SMOOTH ); - if(valsock || colsock || vecsock) { - for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if(nodeCountSocketLinks(snode->edittree, sock)) { - link.tosock= sock; - - if(sock->type==SOCK_VALUE && valsock) { - link.fromsock= valsock; - node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); - valsock= NULL; - } - if(sock->type==SOCK_VECTOR && vecsock) { - link.fromsock= vecsock; - node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); - vecsock= NULL; - } - if(sock->type==SOCK_RGBA && colsock) { - link.fromsock= colsock; - node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); - colsock= NULL; - } + link.fromnode = link.tonode = node; + for (i=0; i < 3; ++i) { + /* find input socket */ + for (link.fromsock=node->inputs.first; link.fromsock; link.fromsock=link.fromsock->next) + if (link.fromsock->type==types[i] && nodeCountSocketLinks(snode->edittree, link.fromsock)) + break; + if (link.fromsock) { + for (link.tosock=node->outputs.first; link.tosock; link.tosock=link.tosock->next) + if (link.tosock->type==types[i] && nodeCountSocketLinks(snode->edittree, link.tosock)) + break; + + if (link.tosock) { + node_draw_link_bezier(v2d, snode, &link, TH_REDALERT, 0, TH_WIRE, 0, TH_WIRE); } } } + glDisable(GL_BLEND); glDisable( GL_LINE_SMOOTH ); } -/* nice AA filled circle */ /* this might have some more generic use */ -static void circle_draw(float x, float y, float size, int col[3]) +static void node_circle_draw(float x, float y, float size, char *col) { /* 16 values of sin function */ static float si[16] = { @@ -550,37 +482,10 @@ static void circle_draw(float x, float y, float size, int col[3]) glDisable(GL_BLEND); } -static void socket_circle_draw(bNodeSocket *sock, float size) -{ - int col[3]; - - if(sock->type==-1) { - col[0]= 0; col[1]= 0; col[2]= 0; - } - else if(sock->type==SOCK_VALUE) { - col[0]= 160; col[1]= 160; col[2]= 160; - } - else if(sock->type==SOCK_VECTOR) { - col[0]= 100; col[1]= 100; col[2]= 200; - } - else if(sock->type==SOCK_RGBA) { - col[0]= 200; col[1]= 200; col[2]= 40; - } - else { - col[0]= 100; col[1]= 200; col[2]= 100; - } - - circle_draw(sock->locx, sock->locy, size, col); -} - -static void node_sync_cb(bContext *UNUSED(C), void *snode_v, void *node_v) +void node_socket_circle_draw(bNodeTree *UNUSED(ntree), bNodeSocket *sock, float size) { - SpaceNode *snode= snode_v; - - if(snode->treetype==NTREE_SHADER) { - nodeShaderSynchronizeID(node_v, 1); - // allqueue(REDRAWBUTSSHADING, 0); - } + bNodeSocketType *stype = ntreeGetSocketType(sock->type); + node_circle_draw(sock->locx, sock->locy, size, stype->ui_color); } /* ************** Socket callbacks *********** */ @@ -639,83 +544,6 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) } -typedef struct SocketVectorMenuArgs { - PointerRNA ptr; - int x, y, width; - uiButHandleFunc cb; - void *arg1, *arg2; -} SocketVectorMenuArgs; - -/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ -static uiBlock *socket_vector_menu(bContext *C, ARegion *ar, void *args_v) -{ - SocketVectorMenuArgs *args= (SocketVectorMenuArgs*)args_v; - uiBlock *block; - uiLayout *layout; - - block= uiBeginBlock(C, ar, "socket menu", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); - - layout= uiLayoutColumn(uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, args->x, args->y+2, args->width, NODE_DY, U.uistyles.first), 0); - - uiItemR(layout, &args->ptr, "default_value", UI_ITEM_R_EXPAND, "", ICON_NONE); - - return block; -} - -static void node_draw_socket_button(bNodeTree *ntree, bNodeSocket *sock, const char *name, - uiBlock *block, int x, int y, int width, - uiButHandleFunc cb, void *arg1, void *arg2) -{ - uiBut *bt= NULL; - PointerRNA ptr; - int labelw; - SocketVectorMenuArgs *args; - - RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); - - switch (sock->type) { - case SOCK_VALUE: - bt=uiDefButR(block, NUM, B_NODE_EXEC, name, - x, y+1, width, NODE_DY-2, - &ptr, "default_value", 0, sock->ns.min, sock->ns.max, -1, -1, NULL); - if (cb) - uiButSetFunc(bt, cb, arg1, arg2); - break; - - case SOCK_VECTOR: - args= MEM_callocN(sizeof(SocketVectorMenuArgs), "SocketVectorMenuArgs"); - - args->ptr = ptr; - args->x = x; - args->y = y; - args->width = width; - args->cb = cb; - args->arg1 = arg1; - args->arg2 = arg2; - - uiDefBlockButN(block, socket_vector_menu, args, name, - x, y+1, width, NODE_DY-2, - ""); - break; - - case SOCK_RGBA: - labelw= width - 40; - - bt=uiDefButR(block, COL, B_NODE_EXEC, "", - x, y+2, (labelw>0 ? 40 : width), NODE_DY-2, - &ptr, "default_value", 0, sock->ns.min, sock->ns.max, -1, -1, NULL); - if (cb) - uiButSetFunc(bt, cb, arg1, arg2); - - if (name[0]!='\0' && labelw>0) - uiDefBut(block, LABEL, 0, name, - x + 40, y+2, labelw, NODE_DY-2, - NULL, 0, 0, 0, 0, ""); - break; - } -} - static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) { bNodeSocket *sock; @@ -809,13 +637,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN else UI_ThemeColor(TH_TEXT); */ - if (node->label[0]!='\0') - BLI_strncpy(showname, node->label, sizeof(showname)); - else if (node->typeinfo->labelfunc) - BLI_strncpy(showname, node->typeinfo->labelfunc(node), sizeof(showname)); - else - BLI_strncpy(showname, node->typeinfo->name, sizeof(showname)); - + BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); + //if(node->flag & NODE_MUTED) // sprintf(showname, "[%s]", showname); @@ -855,37 +678,45 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* socket inputs, buttons */ for(sock= node->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - socket_circle_draw(sock, socket_size); - - if(node->block && sock->link==NULL) { - node_draw_socket_button(ntree, sock, sock->name, node->block, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY, node_sync_cb, snode, node); - } - else { - uiDefBut(node->block, LABEL, 0, sock->name, (short)(sock->locx+7), (short)(sock->locy-9.0f), - (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); - } + bNodeSocketType *stype= ntreeGetSocketType(sock->type); + + if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + continue; + + node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); + + if (sock->link) { + uiDefBut(node->block, LABEL, 0, sock->name, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY, NODE_DY, + NULL, 0, 0, 0, 0, ""); + } + else { + if (stype->buttonfunc) + stype->buttonfunc(C, node->block, ntree, node, sock, sock->name, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY); } } /* socket outputs */ for(sock= node->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { - float slen; - int ofs= 0; - - socket_circle_draw(sock, socket_size); - - UI_ThemeColor(TH_TEXT); - slen= snode->aspect*UI_GetStringWidth(sock->name); - while(slen > node->width) { - ofs++; - slen= snode->aspect*UI_GetStringWidth(sock->name+ofs); - } - - uiDefBut(node->block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), - (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); + PointerRNA sockptr; + float slen; + int ofs; + + RNA_pointer_create((ID*)ntree, &RNA_NodeSocket, sock, &sockptr); + + if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + continue; + + node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); + + ofs= 0; + UI_ThemeColor(TH_TEXT); + slen= snode->aspect*UI_GetStringWidth(sock->name); + while(slen > node->width) { + ofs++; + slen= snode->aspect*UI_GetStringWidth(sock->name+ofs); } + uiDefBut(node->block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), + (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); } /* preview */ @@ -956,12 +787,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b UI_ThemeColor(TH_TEXT); if(node->miniwidth>0.0f) { - if (node->label[0]!='\0') - BLI_strncpy(showname, node->label, sizeof(showname)); - else if (node->typeinfo->labelfunc) - BLI_strncpy(showname, node->typeinfo->labelfunc(node), sizeof(showname)); - else - BLI_strncpy(showname, node->typeinfo->name, sizeof(showname)); + BLI_strncpy(showname, nodeLabel(node), sizeof(showname)); //if(node->flag & NODE_MUTED) // sprintf(showname, "[%s]", showname); @@ -984,12 +810,12 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b /* sockets */ for(sock= node->inputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock, socket_size); + node_socket_circle_draw(snode->nodetree, sock, socket_size); } for(sock= node->outputs.first; sock; sock= sock->next) { if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) - socket_circle_draw(sock, socket_size); + node_socket_circle_draw(snode->nodetree, sock, socket_size); } uiEndBlock(C, node->block); @@ -997,7 +823,43 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b node->block= NULL; } -static void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree) +void node_draw_default(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) +{ + if(node->flag & NODE_HIDDEN) + node_draw_hidden(C, ar, snode, node); + else + node_draw_basis(C, ar, snode, ntree, node); +} + +static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) +{ + if (node->typeinfo->drawupdatefunc) + node->typeinfo->drawupdatefunc(C, ntree, node); +} + +void node_update_nodetree(const bContext *C, bNodeTree *ntree, float offsetx, float offsety) +{ + bNode *node; + + for(node= ntree->nodes.first; node; node= node->next) { + /* XXX little hack */ + node->locx += offsetx; + node->locy += offsety; + + node_update(C, ntree, node); + + node->locx -= offsetx; + node->locy -= offsety; + } +} + +static void node_draw(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) +{ + if (node->typeinfo->drawfunc) + node->typeinfo->drawfunc(C, ar, snode, ntree, node); +} + +void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree) { bNode *node; bNodeLink *link; @@ -1013,212 +875,11 @@ static void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); - /* not selected first */ - for(a=0, node= ntree->nodes.first; node; node= node->next, a++) { + /* draw nodes, last nodes in front */ + for(a=0, node= ntree->nodes.first; node; node=node->next, a++) { node->nr= a; /* index of node in list, used for exec event code */ - if(!(node->flag & SELECT)) { - if(node->flag & NODE_GROUP_EDIT); - else if(node->flag & NODE_HIDDEN) - node_draw_hidden(C, ar, snode, node); - else - node_draw_basis(C, ar, snode, ntree, node); - } - } - - /* selected */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->flag & SELECT) { - if(node->flag & NODE_GROUP_EDIT); - else if(node->flag & NODE_HIDDEN) - node_draw_hidden(C, ar, snode, node); - else - node_draw_basis(C, ar, snode, ntree, node); - } - } -} - -static void group_verify_cb(bContext *UNUSED(C), void *UNUSED(snode_v), void *ngroup_v) -{ - bNodeTree *ngroup= (bNodeTree*)ngroup_v; - - nodeGroupVerify(ngroup); -} - -/* groups are, on creation, centered around 0,0 */ -static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *gnode) -{ - bNodeTree *ngroup= (bNodeTree *)gnode->id; - bNodeSocket *sock; - uiLayout *layout; - PointerRNA ptr; - uiBut *bt; - rctf rect= gnode->totr; - float socket_size= NODE_SOCKSIZE*U.dpi/72; - float node_group_frame= U.dpi*NODE_GROUP_FRAME/72; - float group_header= 26*U.dpi/72; - float arrowbutw= 0.8f*UI_UNIT_X; - /* layout stuff for buttons on group left frame */ - float col1= 6, colw1= 0.6f*node_group_frame; - float col2= col1 + colw1+6; - float col3= node_group_frame - arrowbutw - 6; - /* layout stuff for buttons on group right frame */ - float cor1= 6; - float cor2= cor1 + arrowbutw + 6; - float cor3= cor2 + arrowbutw + 6, corw3= node_group_frame - cor3-6; - - int index; - - /* backdrop header */ - glEnable(GL_BLEND); - uiSetRoundBox(3); - UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); - uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymax, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); - - /* backdrop body */ - UI_ThemeColorShadeAlpha(TH_BACK, -8, -70); - uiSetRoundBox(0); - uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, BASIS_RAD); - - /* input column */ - UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); - uiSetRoundBox(8); - uiDrawBox(GL_POLYGON, rect.xmin-node_group_frame, rect.ymin, rect.xmin, rect.ymax, BASIS_RAD); - - /* output column */ - UI_ThemeColorShadeAlpha(TH_BACK, 10, -50); - uiSetRoundBox(4); - uiDrawBox(GL_POLYGON, rect.xmax, rect.ymin, rect.xmax+node_group_frame, rect.ymax, BASIS_RAD); - - /* input column separator */ - glColor4ub(200, 200, 200, 140); - glBegin(GL_LINES); - glVertex2f(rect.xmin, rect.ymin); - glVertex2f(rect.xmin, rect.ymax); - glEnd(); - - /* output column separator */ - glColor4ub(200, 200, 200, 140); - glBegin(GL_LINES); - glVertex2f(rect.xmax, rect.ymin); - glVertex2f(rect.xmax, rect.ymax); - glEnd(); - - /* group node outline */ - uiSetRoundBox(15); - glColor4ub(200, 200, 200, 140); - glEnable( GL_LINE_SMOOTH ); - uiDrawBox(GL_LINE_LOOP, rect.xmin-node_group_frame, rect.ymin, rect.xmax+node_group_frame, rect.ymax+group_header, BASIS_RAD); - glDisable( GL_LINE_SMOOTH ); - glDisable(GL_BLEND); - - /* backdrop title */ - UI_ThemeColor(TH_TEXT_HI); - - layout = uiBlockLayout(gnode->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, (short)(rect.xmin+15), (short)(rect.ymax+group_header), - MIN2((int)(rect.xmax - rect.xmin-18.0f), node_group_frame+20), group_header, U.uistyles.first); - RNA_pointer_create(&ntree->id, &RNA_Node, gnode, &ptr); - uiTemplateIDBrowse(layout, (bContext*)C, &ptr, "node_tree", NULL, NULL, NULL); - uiBlockLayoutResolve(gnode->block, NULL, NULL); - - /* draw the internal tree nodes and links */ - node_draw_nodetree(C, ar, snode, ngroup); - - /* group sockets */ - for(sock=ngroup->inputs.first, index=0; sock; sock=sock->next, ++index) { - float locx= sock->locx - node_group_frame; - - socket_circle_draw(sock, socket_size); - /* small hack to use socket_circle_draw function with offset */ - sock->locx -= node_group_frame; - socket_circle_draw(sock, socket_size); - sock->locx += node_group_frame; - - bt = uiDefBut(gnode->block, TEX, 0, "", - locx+col1, sock->locy+1, colw1, NODE_DY, - sock->name, 0, 31, 0, 0, ""); - uiButSetFunc(bt, group_verify_cb, snode, ngroup); - - node_draw_socket_button(ngroup, sock, "", gnode->block, - locx+col1, sock->locy-NODE_DY, colw1, - NULL, NULL, NULL); - - uiBlockSetDirection(gnode->block, UI_TOP); - uiBlockBeginAlign(gnode->block); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_up", 0, ICON_TRIA_UP, - locx+col2, sock->locy, arrowbutw, arrowbutw, ""); - if (!sock->prev) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_IN); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_down", 0, ICON_TRIA_DOWN, - locx+col2, sock->locy-arrowbutw, arrowbutw, arrowbutw, ""); - if (!sock->next) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_IN); - uiBlockEndAlign(gnode->block); - uiBlockSetDirection(gnode->block, 0); - - uiBlockSetEmboss(gnode->block, UI_EMBOSSN); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X, - locx+col3, sock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, ""); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_IN); - uiBlockSetEmboss(gnode->block, UI_EMBOSS); - } - - for(sock=ngroup->outputs.first, index=0; sock; sock=sock->next, ++index) { - float locx= sock->locx; - - socket_circle_draw(sock, socket_size); - /* small hack to use socket_circle_draw function with offset */ - sock->locx += node_group_frame; - socket_circle_draw(sock, socket_size); - sock->locx -= node_group_frame; - - uiBlockSetEmboss(gnode->block, UI_EMBOSSN); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X, - locx+col1, sock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, ""); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_OUT); - uiBlockSetEmboss(gnode->block, UI_EMBOSS); - - uiBlockSetDirection(gnode->block, UI_TOP); - uiBlockBeginAlign(gnode->block); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_up", 0, ICON_TRIA_UP, - locx+cor2, sock->locy, arrowbutw, arrowbutw, ""); - if (!sock->prev) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_OUT); - bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_move_down", 0, ICON_TRIA_DOWN, - locx+cor2, sock->locy-arrowbutw, arrowbutw, arrowbutw, ""); - if (!sock->next) - uiButSetFlag(bt, UI_BUT_DISABLED); - RNA_int_set(uiButGetOperatorPtrRNA(bt), "index", index); - RNA_enum_set(uiButGetOperatorPtrRNA(bt), "in_out", SOCK_OUT); - uiBlockEndAlign(gnode->block); - uiBlockSetDirection(gnode->block, 0); - - if (sock->link) { - bt = uiDefBut(gnode->block, TEX, 0, "", - locx+cor3, sock->locy-NODE_DYS+1, corw3, NODE_DY, - sock->name, 0, 31, 0, 0, ""); - uiButSetFunc(bt, group_verify_cb, snode, ngroup); - } - else { - bt = uiDefBut(gnode->block, TEX, 0, "", - locx+cor3, sock->locy+1, corw3, NODE_DY, - sock->name, 0, 31, 0, 0, ""); - uiButSetFunc(bt, group_verify_cb, snode, ngroup); - - node_draw_socket_button(ngroup, sock, "", gnode->block, locx+cor3, sock->locy-NODE_DY, corw3, NULL, NULL, NULL); - } + node_draw(C, ar, snode, ntree, node); } - - uiEndBlock(C, gnode->block); - uiDrawBlock(C, gnode->block); - gnode->block= NULL; } void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) @@ -1260,27 +921,19 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) if(node->flag & NODE_GROUP_EDIT) node_uiblocks_init(C, (bNodeTree *)node->id); } - - node_uiblocks_init(C, snode->nodetree); + node_uiblocks_init(C, snode->nodetree); - /* for now, we set drawing coordinates on each redraw */ - for(node= snode->nodetree->nodes.first; node; node= node->next) { - if(node->flag & NODE_GROUP_EDIT) - node_update_group(C, snode->nodetree, node); - else if(node->flag & NODE_HIDDEN) - node_update_hidden(node); - else - node_update(C, snode->nodetree, node); - } - + node_update_nodetree(C, snode->nodetree, 0.0f, 0.0f); node_draw_nodetree(C, ar, snode, snode->nodetree); - + + #if 0 /* active group */ for(node= snode->nodetree->nodes.first; node; node= node->next) { if(node->flag & NODE_GROUP_EDIT) node_draw_group(C, ar, snode, snode->nodetree, node); } + #endif } /* temporary links */ -- cgit v1.2.3