style cleanup
[blender.git] / source / blender / editors / space_node / node_relationships.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Nathan Letwory
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_node/node_relationships.c
29  *  \ingroup spnode
30  */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_node_types.h"
35 #include "DNA_object_types.h"
36
37 #include "BLI_math.h"
38 #include "BLI_blenlib.h"
39
40 #include "BKE_context.h"
41 #include "BKE_main.h"
42 #include "BKE_node.h"
43
44 #include "ED_node.h"  /* own include */
45 #include "ED_screen.h"
46 #include "ED_render.h"
47
48 #include "RNA_access.h"
49 #include "RNA_define.h"
50
51 #include "WM_api.h"
52 #include "WM_types.h"
53
54 #include "UI_view2d.h"
55
56 #include "node_intern.h"  /* own include */
57
58 /* ****************** Add *********************** */
59
60
61 typedef struct bNodeListItem {
62         struct bNodeListItem *next, *prev;
63         struct bNode *node;
64 } bNodeListItem;
65
66 static int sort_nodes_locx(void *a, void *b)
67 {
68         bNodeListItem *nli1 = (bNodeListItem *)a;
69         bNodeListItem *nli2 = (bNodeListItem *)b;
70         bNode *node1 = nli1->node;
71         bNode *node2 = nli2->node;
72
73         if (node1->locx > node2->locx)
74                 return 1;
75         else
76                 return 0;
77 }
78
79 static int socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, int allow_used)
80 {
81         if (nodeSocketIsHidden(sock))
82                 return 0;
83
84         if (!allow_used && (sock->flag & SOCK_IN_USE))
85                 return 0;
86
87         return 1;
88 }
89
90 static bNodeSocket *best_socket_output(bNodeTree *ntree, bNode *node, bNodeSocket *sock_target, int allow_multiple)
91 {
92         bNodeSocket *sock;
93
94         /* first look for selected output */
95         for (sock = node->outputs.first; sock; sock = sock->next) {
96                 if (!socket_is_available(ntree, sock, allow_multiple))
97                         continue;
98
99                 if (sock->flag & SELECT)
100                         return sock;
101         }
102
103         /* try to find a socket with a matching name */
104         for (sock = node->outputs.first; sock; sock = sock->next) {
105                 if (!socket_is_available(ntree, sock, allow_multiple))
106                         continue;
107
108                 /* check for same types */
109                 if (sock->type == sock_target->type) {
110                         if (strcmp(sock->name, sock_target->name) == 0)
111                                 return sock;
112                 }
113         }
114
115         /* otherwise settle for the first available socket of the right type */
116         for (sock = node->outputs.first; sock; sock = sock->next) {
117
118                 if (!socket_is_available(ntree, sock, allow_multiple))
119                         continue;
120
121                 /* check for same types */
122                 if (sock->type == sock_target->type) {
123                         return sock;
124                 }
125         }
126
127         return NULL;
128 }
129
130 /* this is a bit complicated, but designed to prioritize finding
131  * sockets of higher types, such as image, first */
132 static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace)
133 {
134         bNodeSocket *sock;
135         int socktype, maxtype = 0;
136         int a = 0;
137
138         for (sock = node->inputs.first; sock; sock = sock->next) {
139                 maxtype = MAX2(sock->type, maxtype);
140         }
141
142         /* find sockets of higher 'types' first (i.e. image) */
143         for (socktype = maxtype; socktype >= 0; socktype--) {
144                 for (sock = node->inputs.first; sock; sock = sock->next) {
145
146                         if (!socket_is_available(ntree, sock, replace)) {
147                                 a++;
148                                 continue;
149                         }
150
151                         if (sock->type == socktype) {
152                                 /* increment to make sure we don't keep finding
153                                  * the same socket on every attempt running this function */
154                                 a++;
155                                 if (a > num)
156                                         return sock;
157                         }
158                 }
159         }
160
161         return NULL;
162 }
163
164 static int snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, bNodeSocket *sock_to, int replace)
165 {
166         bNodeTree *ntree = snode->edittree;
167         bNodeLink *link;
168
169         /* then we can connect */
170         if (replace)
171                 nodeRemSocketLinks(ntree, sock_to);
172
173         link = nodeAddLink(ntree, node_fr, sock_fr, node_to, sock_to);
174         /* validate the new link */
175         ntreeUpdateTree(ntree);
176         if (!(link->flag & NODE_LINK_VALID)) {
177                 nodeRemLink(ntree, link);
178                 return 0;
179         }
180
181         snode_update(snode, node_to);
182         return 1;
183 }
184
185 static void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace)
186 {
187         bNodeTree *ntree = snode->edittree;
188         ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list");
189         bNodeListItem *nli;
190         bNode *node;
191         int i, numlinks = 0;
192
193         for (node = ntree->nodes.first; node; node = node->next) {
194                 if (node->flag & NODE_SELECT) {
195                         nli = MEM_mallocN(sizeof(bNodeListItem), "temporary node list item");
196                         nli->node = node;
197                         BLI_addtail(nodelist, nli);
198                 }
199         }
200
201         /* sort nodes left to right */
202         BLI_sortlist(nodelist, sort_nodes_locx);
203
204         for (nli = nodelist->first; nli; nli = nli->next) {
205                 bNode *node_fr, *node_to;
206                 bNodeSocket *sock_fr, *sock_to;
207                 int has_selected_inputs = 0;
208
209                 if (nli->next == NULL) break;
210
211                 node_fr = nli->node;
212                 node_to = nli->next->node;
213
214                 /* if there are selected sockets, connect those */
215                 for (sock_to = node_to->inputs.first; sock_to; sock_to = sock_to->next) {
216                         if (sock_to->flag & SELECT) {
217                                 has_selected_inputs = 1;
218
219                                 if (!socket_is_available(ntree, sock_to, replace))
220                                         continue;
221
222                                 /* check for an appropriate output socket to connect from */
223                                 sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
224                                 if (!sock_fr)
225                                         continue;
226
227                                 if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) {
228                                         numlinks++;
229                                 }
230                         }
231                 }
232
233                 if (!has_selected_inputs) {
234                         /* no selected inputs, connect by finding suitable match */
235                         int num_inputs = BLI_countlist(&node_to->inputs);
236
237                         for (i = 0; i < num_inputs; i++) {
238
239                                 /* find the best guess input socket */
240                                 sock_to = best_socket_input(ntree, node_to, i, replace);
241                                 if (!sock_to)
242                                         continue;
243
244                                 /* check for an appropriate output socket to connect from */
245                                 sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple);
246                                 if (!sock_fr)
247                                         continue;
248
249                                 if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) {
250                                         numlinks++;
251                                         break;
252                                 }
253                         }
254                 }
255         }
256
257         if (numlinks > 0) {
258                 ntreeUpdateTree(ntree);
259         }
260
261         BLI_freelistN(nodelist);
262         MEM_freeN(nodelist);
263 }
264
265 /* *************************** link viewer op ******************** */
266
267 static int node_link_viewer(const bContext *C, bNode *tonode)
268 {
269         SpaceNode *snode = CTX_wm_space_node(C);
270         bNode *node;
271         bNodeLink *link;
272         bNodeSocket *sock;
273
274         /* context check */
275         if (tonode == NULL || tonode->outputs.first == NULL)
276                 return OPERATOR_CANCELLED;
277         if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
278                 return OPERATOR_CANCELLED;
279
280         /* get viewer */
281         for (node = snode->edittree->nodes.first; node; node = node->next)
282                 if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
283                         if (node->flag & NODE_DO_OUTPUT)
284                                 break;
285         /* no viewer, we make one active */
286         if (node == NULL) {
287                 for (node = snode->edittree->nodes.first; node; node = node->next) {
288                         if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
289                                 node->flag |= NODE_DO_OUTPUT;
290                                 break;
291                         }
292                 }
293         }
294
295         sock = NULL;
296
297         /* try to find an already connected socket to cycle to the next */
298         if (node) {
299                 link = NULL;
300                 for (link = snode->edittree->links.first; link; link = link->next)
301                         if (link->tonode == node && link->fromnode == tonode)
302                                 if (link->tosock == node->inputs.first)
303                                         break;
304                 if (link) {
305                         /* unlink existing connection */
306                         sock = link->fromsock;
307                         nodeRemLink(snode->edittree, link);
308
309                         /* find a socket after the previously connected socket */
310                         for (sock = sock->next; sock; sock = sock->next)
311                                 if (!nodeSocketIsHidden(sock))
312                                         break;
313                 }
314         }
315
316         /* find a socket starting from the first socket */
317         if (!sock) {
318                 for (sock = tonode->outputs.first; sock; sock = sock->next)
319                         if (!nodeSocketIsHidden(sock))
320                                 break;
321         }
322
323         if (sock) {
324                 /* add a new viewer if none exists yet */
325                 if (!node) {
326                         Main *bmain = CTX_data_main(C);
327                         Scene *scene = CTX_data_scene(C);
328                         bNodeTemplate ntemp;
329
330                         ntemp.type = CMP_NODE_VIEWER;
331                         /* XXX location is a quick hack, just place it next to the linked socket */
332                         node = node_add_node(snode, bmain, scene, &ntemp, sock->locx + 100, sock->locy);
333                         if (!node)
334                                 return OPERATOR_CANCELLED;
335
336                         link = NULL;
337                 }
338                 else {
339                         /* get link to viewer */
340                         for (link = snode->edittree->links.first; link; link = link->next)
341                                 if (link->tonode == node && link->tosock == node->inputs.first)
342                                         break;
343                 }
344
345                 if (link == NULL) {
346                         nodeAddLink(snode->edittree, tonode, sock, node, node->inputs.first);
347                 }
348                 else {
349                         link->fromnode = tonode;
350                         link->fromsock = sock;
351                         /* make sure the dependency sorting is updated */
352                         snode->edittree->update |= NTREE_UPDATE_LINKS;
353                 }
354                 ntreeUpdateTree(snode->edittree);
355                 snode_update(snode, node);
356         }
357
358         return OPERATOR_FINISHED;
359 }
360
361
362 static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op))
363 {
364         SpaceNode *snode = CTX_wm_space_node(C);
365         bNode *node;
366
367         node = editnode_get_active(snode->edittree);
368
369         if (!node)
370                 return OPERATOR_CANCELLED;
371
372         ED_preview_kill_jobs(C);
373
374         if (node_link_viewer(C, node) == OPERATOR_CANCELLED)
375                 return OPERATOR_CANCELLED;
376
377         snode_notify(C, snode);
378
379         return OPERATOR_FINISHED;
380 }
381
382
383 void NODE_OT_link_viewer(wmOperatorType *ot)
384 {
385         /* identifiers */
386         ot->name = "Link to Viewer Node";
387         ot->description = "Link to viewer node";
388         ot->idname = "NODE_OT_link_viewer";
389
390         /* api callbacks */
391         ot->exec = node_active_link_viewer;
392         ot->poll = composite_node_active;
393
394         /* flags */
395         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
396 }
397
398
399 /* *************************** add link op ******************** */
400
401 static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeLink *link)
402 {
403         bNodeLink *tlink;
404         bNodeSocket *sock;
405
406         if (tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) {
407
408                 for (tlink = snode->edittree->links.first; tlink; tlink = tlink->next) {
409                         if (link != tlink && tlink->tosock == link->tosock)
410                                 break;
411                 }
412                 if (tlink) {
413                         /* try to move the existing link to the next available socket */
414                         if (tlink->tonode) {
415                                 /* is there a free input socket with the target type? */
416                                 for (sock = tlink->tonode->inputs.first; sock; sock = sock->next) {
417                                         if (sock->type == tlink->tosock->type)
418                                                 if (nodeCountSocketLinks(snode->edittree, sock) < sock->limit)
419                                                         break;
420                                 }
421                                 if (sock) {
422                                         tlink->tosock = sock;
423                                         sock->flag &= ~SOCK_HIDDEN;
424                                 }
425                                 else {
426                                         nodeRemLink(snode->edittree, tlink);
427                                 }
428                         }
429                         else
430                                 nodeRemLink(snode->edittree, tlink);
431
432                         snode->edittree->update |= NTREE_UPDATE_LINKS;
433                 }
434         }
435 }
436
437 static int outside_group_rect(SpaceNode *snode)
438 {
439         bNode *gnode = node_tree_get_editgroup(snode->nodetree);
440         if (gnode) {
441                 return (snode->cursor[0] <  gnode->totr.xmin ||
442                         snode->cursor[0] >= gnode->totr.xmax ||
443                         snode->cursor[1] <  gnode->totr.ymin ||
444                         snode->cursor[1] >= gnode->totr.ymax);
445         }
446         return 0;
447 }
448
449 /* loop that adds a nodelink, called by function below  */
450 /* in_out = starting socket */
451 static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
452 {
453         SpaceNode *snode = CTX_wm_space_node(C);
454         ARegion *ar = CTX_wm_region(C);
455         bNodeLinkDrag *nldrag = op->customdata;
456         bNodeTree *ntree = snode->edittree;
457         bNode *tnode;
458         bNodeSocket *tsock = NULL;
459         bNodeLink *link;
460         LinkData *linkdata;
461         int in_out;
462
463         in_out = nldrag->in_out;
464
465         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
466                                  &snode->cursor[0], &snode->cursor[1]);
467
468         switch (event->type) {
469                 case MOUSEMOVE:
470
471                         if (in_out == SOCK_OUT) {
472                                 if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
473                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
474                                                 link = linkdata->data;
475
476                                                 /* skip if this is already the target socket */
477                                                 if (link->tosock == tsock)
478                                                         continue;
479                                                 /* skip if socket is on the same node as the fromsock */
480                                                 if (tnode && link->fromnode == tnode)
481                                                         continue;
482
483                                                 /* attach links to the socket */
484                                                 link->tonode = tnode;
485                                                 link->tosock = tsock;
486                                                 /* add it to the node tree temporarily */
487                                                 if (BLI_findindex(&ntree->links, link) < 0)
488                                                         BLI_addtail(&ntree->links, link);
489
490                                                 ntree->update |= NTREE_UPDATE_LINKS;
491                                         }
492                                         ntreeUpdateTree(ntree);
493                                 }
494                                 else {
495                                         int do_update = FALSE;
496                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
497                                                 link = linkdata->data;
498
499                                                 if (link->tonode || link->tosock) {
500                                                         BLI_remlink(&ntree->links, link);
501                                                         link->prev = link->next = NULL;
502                                                         link->tonode = NULL;
503                                                         link->tosock = NULL;
504
505                                                         ntree->update |= NTREE_UPDATE_LINKS;
506                                                         do_update = TRUE;
507                                                 }
508                                         }
509                                         if (do_update) {
510                                                 ntreeUpdateTree(ntree);
511                                         }
512                                 }
513                         }
514                         else {
515                                 if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
516                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
517                                                 link = linkdata->data;
518
519                                                 /* skip if this is already the target socket */
520                                                 if (link->fromsock == tsock)
521                                                         continue;
522                                                 /* skip if socket is on the same node as the fromsock */
523                                                 if (tnode && link->tonode == tnode)
524                                                         continue;
525
526                                                 /* attach links to the socket */
527                                                 link->fromnode = tnode;
528                                                 link->fromsock = tsock;
529                                                 /* add it to the node tree temporarily */
530                                                 if (BLI_findindex(&ntree->links, link) < 0)
531                                                         BLI_addtail(&ntree->links, link);
532
533                                                 ntree->update |= NTREE_UPDATE_LINKS;
534                                         }
535                                         ntreeUpdateTree(ntree);
536                                 }
537                                 else {
538                                         int do_update = FALSE;
539                                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
540                                                 link = linkdata->data;
541
542                                                 if (link->fromnode || link->fromsock) {
543                                                         BLI_remlink(&ntree->links, link);
544                                                         link->prev = link->next = NULL;
545                                                         link->fromnode = NULL;
546                                                         link->fromsock = NULL;
547
548                                                         ntree->update |= NTREE_UPDATE_LINKS;
549                                                         do_update = TRUE;
550                                                 }
551                                         }
552                                         if (do_update) {
553                                                 ntreeUpdateTree(ntree);
554                                         }
555                                 }
556                         }
557
558                         ED_region_tag_redraw(ar);
559                         break;
560
561                 case LEFTMOUSE:
562                 case RIGHTMOUSE:
563                 case MIDDLEMOUSE: {
564                         for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
565                                 link = linkdata->data;
566
567                                 if (link->tosock && link->fromsock) {
568                                         /* send changed events for original tonode and new */
569                                         if (link->tonode)
570                                                 snode_update(snode, link->tonode);
571
572                                         /* we might need to remove a link */
573                                         if (in_out == SOCK_OUT)
574                                                 node_remove_extra_links(snode, link->tosock, link);
575
576                                         /* when linking to group outputs, update the socket type */
577                                         /* XXX this should all be part of a generic update system */
578                                         if (!link->tonode) {
579                                                 if (link->tosock->type != link->fromsock->type)
580                                                         nodeSocketSetType(link->tosock, link->fromsock->type);
581                                         }
582                                 }
583                                 else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
584                                         /* automatically add new group socket */
585                                         if (link->tonode && link->tosock) {
586                                                 link->fromsock = node_group_expose_socket(ntree, link->tosock, SOCK_IN);
587                                                 link->fromnode = NULL;
588                                                 if (BLI_findindex(&ntree->links, link) < 0)
589                                                         BLI_addtail(&ntree->links, link);
590
591                                                 ntree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS;
592                                         }
593                                         else if (link->fromnode && link->fromsock) {
594                                                 link->tosock = node_group_expose_socket(ntree, link->fromsock, SOCK_OUT);
595                                                 link->tonode = NULL;
596                                                 if (BLI_findindex(&ntree->links, link) < 0)
597                                                         BLI_addtail(&ntree->links, link);
598
599                                                 ntree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
600                                         }
601                                 }
602                                 else
603                                         nodeRemLink(ntree, link);
604                         }
605
606                         ntreeUpdateTree(ntree);
607                         snode_notify(C, snode);
608                         snode_dag_update(C, snode);
609
610                         BLI_remlink(&snode->linkdrag, nldrag);
611                         /* links->data pointers are either held by the tree or freed already */
612                         BLI_freelistN(&nldrag->links);
613                         MEM_freeN(nldrag);
614
615                         return OPERATOR_FINISHED;
616                 }
617         }
618
619         return OPERATOR_RUNNING_MODAL;
620 }
621
622 /* return 1 when socket clicked */
623 static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
624 {
625         bNode *node;
626         bNodeSocket *sock;
627         bNodeLink *link, *link_next, *oplink;
628         bNodeLinkDrag *nldrag = NULL;
629         LinkData *linkdata;
630         int num_links;
631
632         /* output indicated? */
633         if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
634                 nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
635
636                 num_links = nodeCountSocketLinks(snode->edittree, sock);
637                 if (num_links > 0 && (num_links >= sock->limit || detach)) {
638                         /* dragged links are fixed on input side */
639                         nldrag->in_out = SOCK_IN;
640                         /* detach current links and store them in the operator data */
641                         for (link = snode->edittree->links.first; link; link = link_next) {
642                                 link_next = link->next;
643                                 if (link->fromsock == sock) {
644                                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
645                                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
646                                         *oplink = *link;
647                                         oplink->next = oplink->prev = NULL;
648                                         BLI_addtail(&nldrag->links, linkdata);
649                                         nodeRemLink(snode->edittree, link);
650                                 }
651                         }
652                 }
653                 else {
654                         /* dragged links are fixed on output side */
655                         nldrag->in_out = SOCK_OUT;
656                         /* create a new link */
657                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
658                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
659                         oplink->fromnode = node;
660                         oplink->fromsock = sock;
661                         BLI_addtail(&nldrag->links, linkdata);
662                 }
663         }
664         /* or an input? */
665         else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
666                 nldrag = MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
667
668                 num_links = nodeCountSocketLinks(snode->edittree, sock);
669                 if (num_links > 0 && (num_links >= sock->limit || detach)) {
670                         /* dragged links are fixed on output side */
671                         nldrag->in_out = SOCK_OUT;
672                         /* detach current links and store them in the operator data */
673                         for (link = snode->edittree->links.first; link; link = link_next) {
674                                 link_next = link->next;
675                                 if (link->tosock == sock) {
676                                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
677                                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
678                                         *oplink = *link;
679                                         oplink->next = oplink->prev = NULL;
680                                         BLI_addtail(&nldrag->links, linkdata);
681                                         nodeRemLink(snode->edittree, link);
682
683                                         /* send changed event to original link->tonode */
684                                         if (node)
685                                                 snode_update(snode, node);
686                                 }
687                         }
688                 }
689                 else {
690                         /* dragged links are fixed on input side */
691                         nldrag->in_out = SOCK_IN;
692                         /* create a new link */
693                         linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
694                         linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
695                         oplink->tonode = node;
696                         oplink->tosock = sock;
697                         BLI_addtail(&nldrag->links, linkdata);
698                 }
699         }
700
701         return nldrag;
702 }
703
704 static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
705 {
706         SpaceNode *snode = CTX_wm_space_node(C);
707         ARegion *ar = CTX_wm_region(C);
708         bNodeLinkDrag *nldrag;
709         int detach = RNA_boolean_get(op->ptr, "detach");
710
711         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
712                                  &snode->cursor[0], &snode->cursor[1]);
713
714         ED_preview_kill_jobs(C);
715
716         nldrag = node_link_init(snode, detach);
717
718         if (nldrag) {
719                 op->customdata = nldrag;
720                 BLI_addtail(&snode->linkdrag, nldrag);
721
722                 /* add modal handler */
723                 WM_event_add_modal_handler(C, op);
724
725                 return OPERATOR_RUNNING_MODAL;
726         }
727         else
728                 return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
729 }
730
731 static int node_link_cancel(bContext *C, wmOperator *op)
732 {
733         SpaceNode *snode = CTX_wm_space_node(C);
734         bNodeLinkDrag *nldrag = op->customdata;
735
736         BLI_remlink(&snode->linkdrag, nldrag);
737
738         BLI_freelistN(&nldrag->links);
739         MEM_freeN(nldrag);
740
741         return OPERATOR_CANCELLED;
742 }
743
744 void NODE_OT_link(wmOperatorType *ot)
745 {
746         /* identifiers */
747         ot->name = "Link Nodes";
748         ot->idname = "NODE_OT_link";
749         ot->description = "Use the mouse to create a link between two nodes";
750
751         /* api callbacks */
752         ot->invoke = node_link_invoke;
753         ot->modal = node_link_modal;
754 //      ot->exec = node_link_exec;
755         ot->poll = ED_operator_node_active;
756         ot->cancel = node_link_cancel;
757
758         /* flags */
759         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
760
761         RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links");
762 }
763
764 /* ********************** Make Link operator ***************** */
765
766 /* makes a link between selected output and input sockets */
767 static int node_make_link_exec(bContext *C, wmOperator *op)
768 {
769         SpaceNode *snode = CTX_wm_space_node(C);
770         int replace = RNA_boolean_get(op->ptr, "replace");
771
772         ED_preview_kill_jobs(C);
773
774         snode_autoconnect(snode, 1, replace);
775
776         /* deselect sockets after linking */
777         node_deselect_all_input_sockets(snode, 0);
778         node_deselect_all_output_sockets(snode, 0);
779
780         ntreeUpdateTree(snode->edittree);
781         snode_notify(C, snode);
782         snode_dag_update(C, snode);
783
784         return OPERATOR_FINISHED;
785 }
786
787 void NODE_OT_link_make(wmOperatorType *ot)
788 {
789         /* identifiers */
790         ot->name = "Make Links";
791         ot->description = "Makes a link between selected output in input sockets";
792         ot->idname = "NODE_OT_link_make";
793
794         /* callbacks */
795         ot->exec = node_make_link_exec;
796         ot->poll = ED_operator_node_active; // XXX we need a special poll which checks that there are selected input/output sockets
797
798         /* flags */
799         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
800
801         RNA_def_boolean(ot->srna, "replace", 0, "Replace", "Replace socket connections with the new links");
802 }
803
804 /* ********************** Cut Link operator ***************** */
805 static int cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot)
806 {
807         float coord_array[NODE_LINK_RESOL + 1][2];
808         int i, b;
809
810         if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
811
812                 for (i = 0; i < tot - 1; i++)
813                         for (b = 0; b < NODE_LINK_RESOL; b++)
814                                 if (isect_line_line_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0)
815                                         return 1;
816         }
817         return 0;
818 }
819
820 static int cut_links_exec(bContext *C, wmOperator *op)
821 {
822         SpaceNode *snode = CTX_wm_space_node(C);
823         ARegion *ar = CTX_wm_region(C);
824         float mcoords[256][2];
825         int i = 0;
826
827         RNA_BEGIN(op->ptr, itemptr, "path")
828         {
829                 float loc[2];
830
831                 RNA_float_get_array(&itemptr, "loc", loc);
832                 UI_view2d_region_to_view(&ar->v2d, (int)loc[0], (int)loc[1],
833                                          &mcoords[i][0], &mcoords[i][1]);
834                 i++;
835                 if (i >= 256) break;
836         }
837         RNA_END;
838
839         if (i > 1) {
840                 int found = FALSE;
841                 bNodeLink *link, *next;
842
843                 for (link = snode->edittree->links.first; link; link = next) {
844                         next = link->next;
845
846                         if (cut_links_intersect(link, mcoords, i)) {
847
848                                 if (found == FALSE) {
849                                         ED_preview_kill_jobs(C);
850                                         found = TRUE;
851                                 }
852
853                                 snode_update(snode, link->tonode);
854                                 nodeRemLink(snode->edittree, link);
855                         }
856                 }
857
858                 if (found) {
859                         ntreeUpdateTree(snode->edittree);
860                         snode_notify(C, snode);
861                         snode_dag_update(C, snode);
862
863                         return OPERATOR_FINISHED;
864                 }
865                 else {
866                         return OPERATOR_CANCELLED;
867                 }
868
869         }
870
871         return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
872 }
873
874 void NODE_OT_links_cut(wmOperatorType *ot)
875 {
876         PropertyRNA *prop;
877
878         ot->name = "Cut links";
879         ot->idname = "NODE_OT_links_cut";
880         ot->description = "Use the mouse to cut (remove) some links";
881
882         ot->invoke = WM_gesture_lines_invoke;
883         ot->modal = WM_gesture_lines_modal;
884         ot->exec = cut_links_exec;
885         ot->cancel = WM_gesture_lines_cancel;
886
887         ot->poll = ED_operator_node_active;
888
889         /* flags */
890         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
891
892         prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
893         RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
894         /* internal */
895         RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
896 }
897
898 /* ********************** Detach links operator ***************** */
899
900 static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
901 {
902         SpaceNode *snode = CTX_wm_space_node(C);
903         bNodeTree *ntree = snode->edittree;
904         bNode *node;
905
906         ED_preview_kill_jobs(C);
907
908         for (node = ntree->nodes.first; node; node = node->next) {
909                 if (node->flag & SELECT) {
910                         nodeInternalRelink(ntree, node);
911                 }
912         }
913
914         ntreeUpdateTree(ntree);
915
916         snode_notify(C, snode);
917         snode_dag_update(C, snode);
918
919         return OPERATOR_FINISHED;
920 }
921
922 void NODE_OT_links_detach(wmOperatorType *ot)
923 {
924         ot->name = "Detach Links";
925         ot->idname = "NODE_OT_links_detach";
926         ot->description = "Remove all links to selected nodes, and try to connect neighbor nodes together";
927
928         ot->exec = detach_links_exec;
929         ot->poll = ED_operator_node_active;
930
931         /* flags */
932         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
933 }
934
935
936 /* ****************** Show Cyclic Dependencies Operator  ******************* */
937
938 static int node_show_cycles_exec(bContext *C, wmOperator *UNUSED(op))
939 {
940         SpaceNode *snode = CTX_wm_space_node(C);
941
942         /* this is just a wrapper around this call... */
943         ntreeUpdateTree(snode->nodetree);
944         snode_notify(C, snode);
945
946         return OPERATOR_FINISHED;
947 }
948
949 void NODE_OT_show_cyclic_dependencies(wmOperatorType *ot)
950 {
951         /* identifiers */
952         ot->name = "Show Cyclic Dependencies";
953         ot->description = "Sort the nodes and show the cyclic dependencies between the nodes";
954         ot->idname = "NODE_OT_show_cyclic_dependencies";
955
956         /* callbacks */
957         ot->exec = node_show_cycles_exec;
958         ot->poll = ED_operator_node_active;
959
960         /* flags */
961         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
962 }
963
964 /* ****************** Set Parent ******************* */
965
966 static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
967 {
968         SpaceNode *snode = CTX_wm_space_node(C);
969         bNodeTree *ntree = snode->edittree;
970         bNode *frame = nodeGetActive(ntree), *node;
971         if (!frame || frame->type != NODE_FRAME)
972                 return OPERATOR_CANCELLED;
973
974         for (node = ntree->nodes.first; node; node = node->next) {
975                 if (node == frame)
976                         continue;
977                 if (node->flag & NODE_SELECT) {
978                         nodeDetachNode(node);
979                         nodeAttachNode(node, frame);
980                 }
981         }
982
983         ED_node_sort(ntree);
984         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
985
986         return OPERATOR_FINISHED;
987 }
988
989 void NODE_OT_parent_set(wmOperatorType *ot)
990 {
991         /* identifiers */
992         ot->name = "Make Parent";
993         ot->description = "Attach selected nodes";
994         ot->idname = "NODE_OT_parent_set";
995
996         /* api callbacks */
997         ot->exec = node_parent_set_exec;
998         ot->poll = ED_operator_node_active;
999
1000         /* flags */
1001         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1002 }
1003
1004 /* ****************** Clear Parent ******************* */
1005
1006 static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
1007 {
1008         SpaceNode *snode = CTX_wm_space_node(C);
1009         bNodeTree *ntree = snode->edittree;
1010         bNode *node;
1011
1012         for (node = ntree->nodes.first; node; node = node->next) {
1013                 if (node->flag & NODE_SELECT) {
1014                         nodeDetachNode(node);
1015                 }
1016         }
1017
1018         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1019
1020         return OPERATOR_FINISHED;
1021 }
1022
1023 void NODE_OT_parent_clear(wmOperatorType *ot)
1024 {
1025         /* identifiers */
1026         ot->name = "Clear Parent";
1027         ot->description = "Detach selected nodes";
1028         ot->idname = "NODE_OT_parent_clear";
1029
1030         /* api callbacks */
1031         ot->exec = node_parent_clear_exec;
1032         ot->poll = ED_operator_node_active;
1033
1034         /* flags */
1035         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1036 }
1037
1038 /* ****************** Join Nodes ******************* */
1039
1040 /* tags for depth-first search */
1041 #define NODE_JOIN_DONE          1
1042 #define NODE_JOIN_IS_DESCENDANT 2
1043
1044 static void node_join_attach_recursive(bNode *node, bNode *frame)
1045 {
1046         node->done |= NODE_JOIN_DONE;
1047
1048         if (node == frame) {
1049                 node->done |= NODE_JOIN_IS_DESCENDANT;
1050         }
1051         else if (node->parent) {
1052                 /* call recursively */
1053                 if (!(node->parent->done & NODE_JOIN_DONE))
1054                         node_join_attach_recursive(node->parent, frame);
1055
1056                 /* in any case: if the parent is a descendant, so is the child */
1057                 if (node->parent->done & NODE_JOIN_IS_DESCENDANT)
1058                         node->done |= NODE_JOIN_IS_DESCENDANT;
1059                 else if (node->flag & NODE_TEST) {
1060                         /* if parent is not an decendant of the frame, reattach the node */
1061                         nodeDetachNode(node);
1062                         nodeAttachNode(node, frame);
1063                         node->done |= NODE_JOIN_IS_DESCENDANT;
1064                 }
1065         }
1066         else if (node->flag & NODE_TEST) {
1067                 nodeAttachNode(node, frame);
1068                 node->done |= NODE_JOIN_IS_DESCENDANT;
1069         }
1070 }
1071
1072 static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
1073 {
1074         SpaceNode *snode = CTX_wm_space_node(C);
1075         Main *bmain = CTX_data_main(C);
1076         Scene *scene = CTX_data_scene(C);
1077         bNodeTree *ntree = snode->edittree;
1078         bNode *node, *frame;
1079         bNodeTemplate ntemp;
1080
1081         /* XXX save selection: node_add_node call below sets the new frame as single active+selected node */
1082         for (node = ntree->nodes.first; node; node = node->next) {
1083                 if (node->flag & NODE_SELECT)
1084                         node->flag |= NODE_TEST;
1085                 else
1086                         node->flag &= ~NODE_TEST;
1087         }
1088
1089         ntemp.main = bmain;
1090         ntemp.scene = scene;
1091         ntemp.type = NODE_FRAME;
1092         frame = node_add_node(snode, bmain, scene, &ntemp, 0.0f, 0.0f);
1093
1094         /* reset tags */
1095         for (node = ntree->nodes.first; node; node = node->next)
1096                 node->done = 0;
1097
1098         for (node = ntree->nodes.first; node; node = node->next) {
1099                 if (!(node->done & NODE_JOIN_DONE))
1100                         node_join_attach_recursive(node, frame);
1101         }
1102
1103         /* restore selection */
1104         for (node = ntree->nodes.first; node; node = node->next) {
1105                 if (node->flag & NODE_TEST)
1106                         node->flag |= NODE_SELECT;
1107         }
1108
1109         ED_node_sort(ntree);
1110         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1111
1112         return OPERATOR_FINISHED;
1113 }
1114
1115 void NODE_OT_join(wmOperatorType *ot)
1116 {
1117         /* identifiers */
1118         ot->name = "Join Nodes";
1119         ot->description = "Attach selected nodes to a new common frame";
1120         ot->idname = "NODE_OT_join";
1121
1122         /* api callbacks */
1123         ot->exec = node_join_exec;
1124         ot->poll = ED_operator_node_active;
1125
1126         /* flags */
1127         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1128 }
1129
1130 /* ****************** Attach ******************* */
1131
1132 static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
1133 {
1134         SpaceNode *snode = CTX_wm_space_node(C);
1135         bNodeTree *ntree = snode->edittree;
1136         bNode *frame;
1137
1138         /* check nodes front to back */
1139         for (frame = ntree->nodes.last; frame; frame = frame->prev) {
1140                 /* skip selected, those are the nodes we want to attach */
1141                 if ((frame->type != NODE_FRAME) || (frame->flag & NODE_SELECT))
1142                         continue;
1143                 if (BLI_in_rctf(&frame->totr, snode->cursor[0], snode->cursor[1]))
1144                         break;
1145         }
1146         if (frame) {
1147                 bNode *node, *parent;
1148                 for (node = ntree->nodes.last; node; node = node->prev) {
1149                         if (node->flag & NODE_SELECT) {
1150                                 if (node->parent == NULL) {
1151                                         /* disallow moving a parent into its child */
1152                                         if (nodeAttachNodeCheck(frame, node) == FALSE) {
1153                                                 /* attach all unparented nodes */
1154                                                 nodeAttachNode(node, frame);
1155                                         }
1156                                 }
1157                                 else {
1158                                         /* attach nodes which share parent with the frame */
1159                                         for (parent = frame->parent; parent; parent = parent->parent) {
1160                                                 if (parent == node->parent) {
1161                                                         break;
1162                                                 }
1163                                         }
1164
1165                                         if (parent) {
1166                                                 /* disallow moving a parent into its child */
1167                                                 if (nodeAttachNodeCheck(frame, node) == FALSE) {
1168                                                         nodeDetachNode(node);
1169                                                         nodeAttachNode(node, frame);
1170                                                 }
1171                                         }
1172                                 }
1173                         }
1174                 }
1175         }
1176
1177         ED_node_sort(ntree);
1178         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1179
1180         return OPERATOR_FINISHED;
1181 }
1182
1183 static int node_attach_invoke(bContext *C, wmOperator *op, wmEvent *event)
1184 {
1185         ARegion *ar = CTX_wm_region(C);
1186         SpaceNode *snode = CTX_wm_space_node(C);
1187
1188         /* convert mouse coordinates to v2d space */
1189         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
1190
1191         return node_attach_exec(C, op);
1192 }
1193
1194 void NODE_OT_attach(wmOperatorType *ot)
1195 {
1196         /* identifiers */
1197         ot->name = "Attach Nodes";
1198         ot->description = "Attach active node to a frame";
1199         ot->idname = "NODE_OT_attach";
1200
1201         /* api callbacks */
1202         ot->exec = node_attach_exec;
1203         ot->invoke = node_attach_invoke;
1204         ot->poll = ED_operator_node_active;
1205
1206         /* flags */
1207         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1208 }
1209
1210 /* ****************** Detach ******************* */
1211
1212 /* tags for depth-first search */
1213 #define NODE_DETACH_DONE            1
1214 #define NODE_DETACH_IS_DESCENDANT   2
1215
1216 static void node_detach_recursive(bNode *node)
1217 {
1218         node->done |= NODE_DETACH_DONE;
1219
1220         if (node->parent) {
1221                 /* call recursively */
1222                 if (!(node->parent->done & NODE_DETACH_DONE))
1223                         node_detach_recursive(node->parent);
1224
1225                 /* in any case: if the parent is a descendant, so is the child */
1226                 if (node->parent->done & NODE_DETACH_IS_DESCENDANT)
1227                         node->done |= NODE_DETACH_IS_DESCENDANT;
1228                 else if (node->flag & NODE_SELECT) {
1229                         /* if parent is not a decendant of a selected node, detach */
1230                         nodeDetachNode(node);
1231                         node->done |= NODE_DETACH_IS_DESCENDANT;
1232                 }
1233         }
1234         else if (node->flag & NODE_SELECT) {
1235                 node->done |= NODE_DETACH_IS_DESCENDANT;
1236         }
1237 }
1238
1239
1240 /* detach the root nodes in the current selection */
1241 static int node_detach_exec(bContext *C, wmOperator *UNUSED(op))
1242 {
1243         SpaceNode *snode = CTX_wm_space_node(C);
1244         bNodeTree *ntree = snode->edittree;
1245         bNode *node;
1246
1247         /* reset tags */
1248         for (node = ntree->nodes.first; node; node = node->next)
1249                 node->done = 0;
1250         /* detach nodes recursively
1251          * relative order is preserved here!
1252          */
1253         for (node = ntree->nodes.first; node; node = node->next) {
1254                 if (!(node->done & NODE_DETACH_DONE))
1255                         node_detach_recursive(node);
1256         }
1257
1258         ED_node_sort(ntree);
1259         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1260
1261         return OPERATOR_FINISHED;
1262 }
1263
1264 void NODE_OT_detach(wmOperatorType *ot)
1265 {
1266         /* identifiers */
1267         ot->name = "Detach Nodes";
1268         ot->description = "Detach selected nodes from parents";
1269         ot->idname = "NODE_OT_detach";
1270
1271         /* api callbacks */
1272         ot->exec = node_detach_exec;
1273         ot->poll = ED_operator_node_active;
1274
1275         /* flags */
1276         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1277 }
1278
1279 /* *********************  automatic node insert on dragging ******************* */
1280
1281
1282 /* prevent duplicate testing code below */
1283 static SpaceNode *ed_node_link_conditions(ScrArea *sa, bNode **select)
1284 {
1285         SpaceNode *snode = sa ? sa->spacedata.first : NULL;
1286         bNode *node;
1287         bNodeLink *link;
1288
1289         /* no unlucky accidents */
1290         if (sa == NULL || sa->spacetype != SPACE_NODE) return NULL;
1291
1292         *select = NULL;
1293
1294         for (node = snode->edittree->nodes.first; node; node = node->next) {
1295                 if (node->flag & SELECT) {
1296                         if (*select)
1297                                 break;
1298                         else
1299                                 *select = node;
1300                 }
1301         }
1302         /* only one selected */
1303         if (node || *select == NULL) return NULL;
1304
1305         /* correct node */
1306         if ((*select)->inputs.first == NULL || (*select)->outputs.first == NULL) return NULL;
1307
1308         /* test node for links */
1309         for (link = snode->edittree->links.first; link; link = link->next) {
1310                 if (link->tonode == *select || link->fromnode == *select)
1311                         return NULL;
1312         }
1313
1314         return snode;
1315 }
1316
1317 /* test == 0, clear all intersect flags */
1318 void ED_node_link_intersect_test(ScrArea *sa, int test)
1319 {
1320         bNode *select;
1321         SpaceNode *snode = ed_node_link_conditions(sa, &select);
1322         bNodeLink *link, *selink = NULL;
1323         float mcoords[6][2];
1324
1325         if (snode == NULL) return;
1326
1327         /* clear flags */
1328         for (link = snode->edittree->links.first; link; link = link->next)
1329                 link->flag &= ~NODE_LINKFLAG_HILITE;
1330
1331         if (test == 0) return;
1332
1333         /* okay, there's 1 node, without links, now intersect */
1334         mcoords[0][0] = select->totr.xmin;
1335         mcoords[0][1] = select->totr.ymin;
1336         mcoords[1][0] = select->totr.xmax;
1337         mcoords[1][1] = select->totr.ymin;
1338         mcoords[2][0] = select->totr.xmax;
1339         mcoords[2][1] = select->totr.ymax;
1340         mcoords[3][0] = select->totr.xmin;
1341         mcoords[3][1] = select->totr.ymax;
1342         mcoords[4][0] = select->totr.xmin;
1343         mcoords[4][1] = select->totr.ymin;
1344         mcoords[5][0] = select->totr.xmax;
1345         mcoords[5][1] = select->totr.ymax;
1346
1347         /* we only tag a single link for intersect now */
1348         /* idea; use header dist when more? */
1349         for (link = snode->edittree->links.first; link; link = link->next) {
1350
1351                 if (cut_links_intersect(link, mcoords, 5)) { /* intersect code wants edges */
1352                         if (selink)
1353                                 break;
1354                         selink = link;
1355                 }
1356         }
1357
1358         if (link == NULL && selink)
1359                 selink->flag |= NODE_LINKFLAG_HILITE;
1360 }
1361
1362 /* assumes sockets in list */
1363 static bNodeSocket *socket_best_match(ListBase *sockets)
1364 {
1365         bNodeSocket *sock;
1366         int type, maxtype = 0;
1367
1368         /* find type range */
1369         for (sock = sockets->first; sock; sock = sock->next)
1370                 maxtype = MAX2(sock->type, maxtype);
1371
1372         /* try all types, starting from 'highest' (i.e. colors, vectors, values) */
1373         for (type = maxtype; type >= 0; --type) {
1374                 for (sock = sockets->first; sock; sock = sock->next) {
1375                         if (!nodeSocketIsHidden(sock) && type == sock->type) {
1376                                 return sock;
1377                         }
1378                 }
1379         }
1380
1381         /* no visible sockets, unhide first of highest type */
1382         for (type = maxtype; type >= 0; --type) {
1383                 for (sock = sockets->first; sock; sock = sock->next) {
1384                         if (type == sock->type) {
1385                                 sock->flag &= ~SOCK_HIDDEN;
1386                                 return sock;
1387                         }
1388                 }
1389         }
1390
1391         return NULL;
1392 }
1393
1394 /* assumes link with NODE_LINKFLAG_HILITE set */
1395 void ED_node_link_insert(ScrArea *sa)
1396 {
1397         bNode *node, *select;
1398         SpaceNode *snode = ed_node_link_conditions(sa, &select);
1399         bNodeLink *link;
1400         bNodeSocket *sockto;
1401
1402         if (snode == NULL) return;
1403
1404         /* get the link */
1405         for (link = snode->edittree->links.first; link; link = link->next)
1406                 if (link->flag & NODE_LINKFLAG_HILITE)
1407                         break;
1408
1409         if (link) {
1410                 node = link->tonode;
1411                 sockto = link->tosock;
1412
1413                 link->tonode = select;
1414                 link->tosock = socket_best_match(&select->inputs);
1415                 link->flag &= ~NODE_LINKFLAG_HILITE;
1416
1417                 nodeAddLink(snode->edittree, select, socket_best_match(&select->outputs), node, sockto);
1418                 ntreeUpdateTree(snode->edittree);   /* needed for pointers */
1419                 snode_update(snode, select);
1420                 ED_node_changed_update(snode->id, select);
1421         }
1422 }