[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44763] trunk/blender/source/blender/ editors/space_node: Node socket selection feature reimplemented from 2.49.

Lukas Toenne lukas.toenne at googlemail.com
Fri Mar 9 11:16:49 CET 2012


Revision: 44763
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44763
Author:   lukastoenne
Date:     2012-03-09 10:16:41 +0000 (Fri, 09 Mar 2012)
Log Message:
-----------
Node socket selection feature reimplemented from 2.49. Sockets can be selected as a sub-selection of nodes and are then preferred by the auto-connect operator. This makes it easier to create precise links over long distances as an alternative to the click & hold operator.
Socket selection is indicated by a simple white highlight circle.

Multiple inputs can be selected by holding SHIFTKEY (just like regular node select). Only one output socket can be selected at a time for each node, but several outputs in different nodes are allowed.

The auto-connect operator will prefer selected sockets on nodes for creating links. If either the output or input side have no selected sockets it will fall back to the previous behavior of chosing 'best' sockets first (colors, then vectors, then values). This could be improved in the future, but is out of scope here.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/space_node/node_draw.c
    trunk/blender/source/blender/editors/space_node/node_edit.c
    trunk/blender/source/blender/editors/space_node/node_intern.h
    trunk/blender/source/blender/editors/space_node/node_ops.c
    trunk/blender/source/blender/editors/space_node/node_select.c

Modified: trunk/blender/source/blender/editors/space_node/node_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_draw.c	2012-03-09 10:01:29 UTC (rev 44762)
+++ trunk/blender/source/blender/editors/space_node/node_draw.c	2012-03-09 10:16:41 UTC (rev 44763)
@@ -453,7 +453,7 @@
 }
 
 /* this might have some more generic use */
-static void node_circle_draw(float x, float y, float size, char *col)
+static void node_circle_draw(float x, float y, float size, char *col, int highlight)
 {
 	/* 16 values of sin function */
 	static float si[16] = {
@@ -478,7 +478,13 @@
 		glVertex2f(x+size*si[a], y+size*co[a]);
 	glEnd();
 	
-	glColor4ub(0, 0, 0, 150);
+	if (highlight) {
+		UI_ThemeColor(TH_TEXT_HI);
+		glLineWidth(1.5f);
+	}
+	else {
+		glColor4ub(0, 0, 0, 150);
+	}
 	glEnable(GL_BLEND);
 	glEnable( GL_LINE_SMOOTH );
 	glBegin(GL_LINE_LOOP);
@@ -487,12 +493,13 @@
 	glEnd();
 	glDisable( GL_LINE_SMOOTH );
 	glDisable(GL_BLEND);
+	glLineWidth(1.0f);
 }
 
 void node_socket_circle_draw(bNodeTree *UNUSED(ntree), bNodeSocket *sock, float size)
 {
 	bNodeSocketType *stype = ntreeGetSocketType(sock->type);
-	node_circle_draw(sock->locx, sock->locy, size, stype->ui_color);
+	node_circle_draw(sock->locx, sock->locy, size, stype->ui_color, (sock->flag & SELECT));
 }
 
 /* **************  Socket callbacks *********** */

Modified: trunk/blender/source/blender/editors/space_node/node_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_edit.c	2012-03-09 10:01:29 UTC (rev 44762)
+++ trunk/blender/source/blender/editors/space_node/node_edit.c	2012-03-09 10:16:41 UTC (rev 44763)
@@ -1801,12 +1801,15 @@
 
 /* checks snode->mouse position, and returns found node/socket */
 /* type is SOCK_IN and/or SOCK_OUT */
-static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out)
+int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out)
 {
 	bNode *node;
 	bNodeSocket *sock;
 	rctf rect;
 	
+	*nodep= NULL;
+	*sockp= NULL;
+	
 	/* check if we click in a socket */
 	for(node= snode->edittree->nodes.first; node; node= node->next) {
 		
@@ -1883,43 +1886,6 @@
 	return 0;
 }
 
-static int node_socket_hilights(SpaceNode *snode, int in_out)
-{
-	bNode *node;
-	bNodeSocket *sock, *tsock, *socksel= NULL;
-	short redraw= 0;
-	
-	if(snode->edittree==NULL) return 0;
-	
-	/* deselect sockets */
-	for(node= snode->edittree->nodes.first; node; node= node->next) {
-		for(sock= node->inputs.first; sock; sock= sock->next) {
-			if(sock->flag & SELECT) {
-				sock->flag &= ~SELECT;
-				redraw++;
-				socksel= sock;
-			}
-		}
-		for(sock= node->outputs.first; sock; sock= sock->next) {
-			if(sock->flag & SELECT) {
-				sock->flag &= ~SELECT;
-				redraw++;
-				socksel= sock;
-			}
-		}
-	}
-	
-	// XXX mousepos should be set here!
-	
-	if(find_indicated_socket(snode, &node, &tsock, in_out)) {
-		tsock->flag |= SELECT;
-		if(redraw==1 && tsock==socksel) redraw= 0;
-		else redraw= 1;
-	}
-	
-	return redraw;
-}
-
 static int outside_group_rect(SpaceNode *snode)
 {
 	bNode *gnode= node_tree_get_editgroup(snode->nodetree);
@@ -1966,11 +1932,19 @@
 {
 	bNodeSocket *sock;
 	
-	/* first try to find a socket with a matching name */
+	/* first look for selected output */
 	for (sock=node->outputs.first; sock; sock=sock->next) {
-
 		if (!socket_is_available(ntree, sock, allow_multiple))
 			continue;
+		
+		if (sock->flag & SELECT)
+			return sock;
+	}
+	
+	/* try to find a socket with a matching name */
+	for (sock=node->outputs.first; sock; sock=sock->next) {
+		if (!socket_is_available(ntree, sock, allow_multiple))
+			continue;
 
 		/* check for same types */
 		if (sock->type == sock_target->type) {
@@ -2028,15 +2002,36 @@
 	return NULL;
 }
 
+static int snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, bNodeSocket *sock_to, int replace)
+{
+	bNodeTree *ntree = snode->edittree;
+	bNodeLink *link;
+	
+	/* then we can connect */
+	if (replace)
+		nodeRemSocketLinks(ntree, sock_to);
+	
+	link = nodeAddLink(ntree, node_fr, sock_fr, node_to, sock_to);
+	/* validate the new link */
+	ntreeUpdateTree(ntree);
+	if (!(link->flag & NODE_LINK_VALID)) {
+		nodeRemLink(ntree, link);
+		return 0;
+	}
+	
+	snode_update(snode, node_to);
+	return 1;
+}
+
 void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace)
 {
+	bNodeTree *ntree = snode->edittree;
 	ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list");
 	bNodeListItem *nli;
 	bNode *node;
-	bNodeLink *link;
 	int i, numlinks=0;
 	
-	for(node= snode->edittree->nodes.first; node; node= node->next) {
+	for(node= ntree->nodes.first; node; node= node->next) {
 		if(node->flag & NODE_SELECT) {
 			nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item");
 			nli->node = node;
@@ -2050,43 +2045,57 @@
 	for (nli=nodelist->first; nli; nli=nli->next) {
 		bNode *node_fr, *node_to;
 		bNodeSocket *sock_fr, *sock_to;
+		int has_selected_inputs = 0;
 		
 		if (nli->next == NULL) break;
 		
 		node_fr = nli->node;
 		node_to = nli->next->node;
 		
-		/* check over input sockets first */
-		for (i=0; i<BLI_countlist(&node_to->inputs); i++) {
+		/* if there are selected sockets, connect those */
+		for (sock_to = node_to->inputs.first; sock_to; sock_to=sock_to->next) {
+			if (sock_to->flag & SELECT) {
+				has_selected_inputs = 1;
+				
+				if (!socket_is_available(ntree, sock_to, replace))
+					continue;
+				
+				/* check for an appropriate output socket to connect from */
+				sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
+				if (!sock_fr)
+					continue;
+	
+				if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace))
+					++numlinks;
+			}
+		}
+		
+		if (!has_selected_inputs) {
+			/* no selected inputs, connect by finding suitable match */
+			int num_inputs = BLI_countlist(&node_to->inputs);
 			
-			/* find the best guess input socket */
-			sock_to = best_socket_input(snode->edittree, node_to, i, replace);
-			if (!sock_to) continue;
-			
-			/* check for an appropriate output socket to connect from */
-			sock_fr = best_socket_output(snode->edittree, node_fr, sock_to, allow_multiple);
-			if (!sock_fr) continue;
-			
-			/* then we can connect */
-			if (replace)
-				nodeRemSocketLinks(snode->edittree, sock_to);
-			
-			link = nodeAddLink(snode->edittree, node_fr, sock_fr, node_to, sock_to);
-			/* validate the new link */
-			ntreeUpdateTree(snode->edittree);
-			if (!(link->flag & NODE_LINK_VALID)) {
-				nodeRemLink(snode->edittree, link);
-				continue;
+			for (i=0; i<num_inputs; i++) {
+				
+				/* find the best guess input socket */
+				sock_to = best_socket_input(ntree, node_to, i, replace);
+				if (!sock_to)
+					continue;
+				
+				/* check for an appropriate output socket to connect from */
+				sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
+				if (!sock_fr)
+					continue;
+	
+				if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) {
+					++numlinks;
+					break;
+				}
 			}
-			
-			snode_update(snode, node_to);
-			++numlinks;
-			break;
 		}
 	}
 	
 	if (numlinks > 0) {
-		ntreeUpdateTree(snode->edittree);
+		ntreeUpdateTree(ntree);
 	}
 	
 	BLI_freelistN(nodelist);
@@ -2148,6 +2157,7 @@
 	SpaceNode *snode= CTX_wm_space_node(C);
 	bNodeTree *ntree= snode->edittree;
 	bNode *node, *newnode, *lastnode;
+	bNodeSocket *sock;
 	bNodeLink *link, *newlink, *lastlink;
 	int keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
 	
@@ -2212,6 +2222,12 @@
 			
 			node->flag &= ~(NODE_SELECT|NODE_ACTIVE);
 			newnode->flag |= NODE_SELECT;
+		
+			/* deselect old node sockets */
+			for (sock=node->inputs.first; sock; sock=sock->next)
+				sock->flag &= ~SELECT;
+			for (sock=node->outputs.first; sock; sock=sock->next)
+				sock->flag &= ~SELECT;
 		}
 		
 		/* make sure we don't copy new nodes again! */
@@ -2306,7 +2322,10 @@
 		case MOUSEMOVE:
 			
 			if(in_out==SOCK_OUT) {
-				if(find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
+				/* only target socket becomes hilighted */
+				node_deselect_all_input_sockets(snode, 0);
+				
+				if(node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
 					if(nodeFindLink(snode->edittree, sock, tsock)==NULL) {
 						if( link->tosock!= tsock && (!tnode || (tnode!=node && link->tonode!=tnode)) ) {
 							link->tonode= tnode;
@@ -2319,6 +2338,9 @@
 							ntreeUpdateTree(snode->edittree);
 						}
 					}
+					
+					/* hilight target socket */
+					tsock->flag |= SELECT;
 				}
 				else {
 					if (link->tonode || link->tosock) {
@@ -2333,7 +2355,10 @@
 				}
 			}
 			else {
-				if(find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
+				/* only target socket becomes hilighted */
+				node_deselect_all_output_sockets(snode, 0);
+				
+				if(node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
 					if(nodeFindLink(snode->edittree, sock, tsock)==NULL) {
 						if(nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) {
 							if( link->fromsock!= tsock && (!tnode || (tnode!=node && link->fromnode!=tnode)) ) {
@@ -2348,6 +2373,9 @@
 							}
 						}
 					}
+					
+					/* hilight target socket */
+					tsock->flag |= SELECT;
 				}
 				else {
 					if (link->tonode || link->tosock) {
@@ -2360,8 +2388,7 @@
 					}
 				}
 			}
-			/* hilight target sockets only */
-			node_socket_hilights(snode, in_out==SOCK_OUT?SOCK_IN:SOCK_OUT);
+			
 			ED_region_tag_redraw(ar);
 			break;
 			
@@ -2376,6 +2403,10 @@
 				if(in_out==SOCK_OUT)
 					node_remove_extra_links(snode, link->tosock, link);
 				
+				/* deselect sockets after successful linking */
+				node_deselect_all_input_sockets(snode, 0);
+				node_deselect_all_output_sockets(snode, 0);
+				
 				/* when linking to group outputs, update the socket type */
 				/* XXX this should all be part of a generic update system */
 				if (!link->tonode) {
@@ -2400,6 +2431,10 @@
 					}
 					snode->edittree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
 				}
+				
+				/* deselect sockets after successful linking */
+				node_deselect_all_input_sockets(snode, 0);
+				node_deselect_all_output_sockets(snode, 0);
 			}
 			else
 				nodeRemLink(snode->edittree, link);
@@ -2421,11 +2456,12 @@
 static int node_link_init(SpaceNode *snode, bNodeLinkDrag *nldrag)
 {
 	bNodeLink *link;
+	int in_out = 0;
 
 	/* output indicated? */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list