NodeEditor: Connect Viewer To Socket Selection
authorJeroen Bakker <j.bakker@atmind.nl>
Fri, 22 Mar 2019 16:03:02 +0000 (17:03 +0100)
committerJeroen Bakker <j.bakker@atmind.nl>
Fri, 22 Mar 2019 16:03:28 +0000 (17:03 +0100)
Request from the Spring team. When compositing the CTRL-Shift Click on a
node cycles the viewnode with an output socket. When you have many
render layers you spend time cycling to the desired socket. This patch
allows the user to CTRL-Shift Click on a socket to connect directly to
that socket.

Reviewed By: brecht

Maniphest Tasks: T62785

Differential Revision: https://developer.blender.org/D4564

source/blender/editors/space_node/node_ops.c
source/blender/editors/space_node/node_relationships.c
source/blender/editors/space_node/node_select.c

index ed3190b06feca9148cac8616fa5e62c9659968c7..517e4df1dc1673d2b1df173f4cf927335e9a0e0a 100644 (file)
@@ -136,7 +136,9 @@ void ED_operatormacros_node(void)
        ot = WM_operatortype_append_macro("NODE_OT_select_link_viewer", "Link Viewer",
                                          "Select node and link it to a viewer node",
                                          OPTYPE_UNDO);
-       WM_operatortype_macro_define(ot, "NODE_OT_select");
+       mot = WM_operatortype_macro_define(ot, "NODE_OT_select");
+       RNA_boolean_set(mot->ptr, "extend", false);
+       RNA_boolean_set(mot->ptr, "socket_select", true);
        WM_operatortype_macro_define(ot, "NODE_OT_link_viewer");
 
        ot = WM_operatortype_append_macro("NODE_OT_translate_attach", "Move and Attach",
index d81c764af81073de4e63f6245bc6bb136a60afb1..1aaf0baae6d6af8d285e6f07a03782b1235a46de 100644 (file)
@@ -438,6 +438,17 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
                }
        }
 
+       if (tonode) {
+               /* Find a selected socket that overrides the socket to connect to */
+               for (bNodeSocket *sock2 = tonode->outputs.first; sock2; sock2 = sock2->next) {
+                       if (!nodeSocketIsHidden(sock2) && sock2->flag & SELECT) {
+                               sock = sock2;
+                               break;
+                       }
+               }
+       }
+
+
        /* find a socket starting from the first socket */
        if (!sock) {
                for (sock = tonode->outputs.first; sock; sock = sock->next)
index fc80d20dcba655d033d7067fc3197e2e863281e9..a329958db5ee6f6d7cf31f00316ac44317de2f51 100644 (file)
@@ -410,72 +410,83 @@ void node_select_single(bContext *C, bNode *node)
        WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
 }
 
-static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], short extend)
+static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], bool extend, bool socket_select)
 {
        bNode *node, *tnode;
-       bNodeSocket *sock, *tsock;
+       bNodeSocket *sock = NULL;
+       bNodeSocket *tsock;
        float cursor[2];
-       int selected = 0;
+       bool selected = false;
 
        /* get mouse coordinates in view2d space */
        UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
 
-       if (extend) {
-               /* first do socket selection, these generally overlap with nodes.
-                * socket selection only in extend mode.
-                */
+       /* first do socket selection, these generally overlap with nodes. */
+       if (socket_select) {
                if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
                        node_socket_toggle(node, sock, 1);
-                       selected = 1;
+                       selected = true;
                }
                else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
                        if (sock->flag & SELECT) {
-                               node_socket_deselect(node, sock, 1);
+                               if (extend) {
+                                       node_socket_deselect(node, sock, 1);
+                               }
+                               else {
+                                       selected = true;
+                               }
                        }
                        else {
                                /* only allow one selected output per node, for sensible linking.
-                                * allows selecting outputs from different nodes though.
-                                */
+                                * allows selecting outputs from different nodes though. */
                                if (node) {
                                        for (tsock = node->outputs.first; tsock; tsock = tsock->next)
                                                node_socket_deselect(node, tsock, 1);
                                }
+                               if (extend) {
+                                       /* only allow one selected output per node, for sensible linking.
+                                        * allows selecting outputs from different nodes though. */
+                                       for (tsock = node->outputs.first; tsock; tsock = tsock->next) {
+                                               if (tsock != sock) {
+                                                       node_socket_deselect(node, tsock, 1);
+                                               }
+                                       }
+                               }
                                node_socket_select(node, sock);
+                               selected = true;
                        }
-                       selected = 1;
                }
-               else {
+       }
+
+       if (!sock) {
+               if (extend) {
                        /* find the closest visible node */
                        node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
 
                        if (node) {
                                if ((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0) {
-                                       /* if node is selected but not active make it active
-                                        * before it'll be desleected
-                                        */
+                                       /* if node is selected but not active make it active */
                                        ED_node_set_active(bmain, snode->edittree, node);
                                }
                                else {
                                        node_toggle(node);
                                        ED_node_set_active(bmain, snode->edittree, node);
                                }
-
-                               selected = 1;
+                               selected = true;
                        }
                }
-       }
-       else {  /* extend == 0 */
-
-               /* find the closest visible node */
-               node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
+               else {
+                       /* find the closest visible node */
+                       node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
 
-               if (node) {
-                       for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
-                               nodeSetSelected(tnode, false);
+                       if (node) {
+                               for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
+                                       nodeSetSelected(tnode, false);
+                               }
+                               nodeSetSelected(node, true);
+                               ED_node_set_active(bmain, snode->edittree, node);
+                               selected = true;
                        }
-                       nodeSetSelected(node, true);
-                       ED_node_set_active(bmain, snode->edittree, node);
-                       selected = 1;
                }
        }
 
@@ -495,15 +506,18 @@ static int node_select_exec(bContext *C, wmOperator *op)
        ARegion *ar = CTX_wm_region(C);
        int mval[2];
        short extend;
+       bool socket_select;
 
        /* get settings from RNA properties for operator */
        mval[0] = RNA_int_get(op->ptr, "mouse_x");
        mval[1] = RNA_int_get(op->ptr, "mouse_y");
 
        extend = RNA_boolean_get(op->ptr, "extend");
+       /* always do socket_select when extending selection. */
+       socket_select = extend || RNA_boolean_get(op->ptr, "socket_select");
 
        /* perform the select */
-       if (node_mouse_select(bmain, snode, ar, mval, extend)) {
+       if (node_mouse_select(bmain, snode, ar, mval, extend, socket_select)) {
                /* send notifiers */
                WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
 
@@ -543,7 +557,8 @@ void NODE_OT_select(wmOperatorType *ot)
        /* properties */
        RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX);
        RNA_def_int(ot->srna, "mouse_y", 0, INT_MIN, INT_MAX, "Mouse Y", "", INT_MIN, INT_MAX);
-       RNA_def_boolean(ot->srna, "extend", 0, "Extend", "");
+       RNA_def_boolean(ot->srna, "extend", false, "Extend", "");
+       RNA_def_boolean(ot->srna, "socket_select", false, "Socket Select", "");
 }
 
 /** \} */