e7be750928d69b99d82531fe4bc96bf6f3ff3ed6
[blender.git] / source / blender / editors / space_node / node_select.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) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation, Nathan Letwory
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_node/node_select.c
28  *  \ingroup spnode
29  */
30
31
32 #include <stdio.h>
33
34 #include "BLI_listbase.h"
35
36 #include "DNA_node_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "BKE_context.h"
40 #include "BKE_main.h"
41 #include "BKE_node.h"
42
43 #include "BLI_rect.h"
44 #include "BLI_utildefines.h"
45
46 #include "ED_node.h"
47 #include "ED_screen.h"
48 #include "ED_types.h"
49
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52
53 #include "WM_api.h"
54 #include "WM_types.h"
55
56 #include "UI_view2d.h"
57  
58 #include "node_intern.h"
59
60 /* ****** helpers ****** */
61
62 static bNode *node_under_mouse_select(bNodeTree *ntree, int mx, int my)
63 {
64         bNode *node;
65         
66         for (node=ntree->nodes.last; node; node=node->prev) {
67                 if (node->typeinfo->select_area_func) {
68                         if (node->typeinfo->select_area_func(node, mx, my))
69                                 return node;
70                 }
71         }
72         return NULL;
73 }
74
75 static bNode *node_under_mouse_tweak(bNodeTree *ntree, int mx, int my)
76 {
77         bNode *node;
78         
79         for (node=ntree->nodes.last; node; node=node->prev) {
80                 if (node->typeinfo->tweak_area_func) {
81                         if (node->typeinfo->tweak_area_func(node, mx, my))
82                                 return node;
83                 }
84         }
85         return NULL;
86 }
87
88 void node_select(bNode *node)
89 {
90         node->flag |= SELECT;
91 }
92
93 void node_deselect(bNode *node)
94 {
95         bNodeSocket *sock;
96         
97         node->flag &= ~SELECT;
98         
99         /* deselect sockets too */
100         for (sock=node->inputs.first; sock; sock=sock->next)
101                 sock->flag &= ~SELECT;
102         for (sock=node->outputs.first; sock; sock=sock->next)
103                 sock->flag &= ~SELECT;
104 }
105
106 static void node_toggle(bNode *node)
107 {
108         if (node->flag & SELECT)
109                 node_deselect(node);
110         else
111                 node_select(node);
112 }
113
114 void node_socket_select(bNode *node, bNodeSocket *sock)
115 {
116         sock->flag |= SELECT;
117         
118         /* select node too */
119         if (node)
120                 node->flag |= SELECT;
121 }
122
123 void node_socket_deselect(bNode *node, bNodeSocket *sock, int deselect_node)
124 {
125         sock->flag &= ~SELECT;
126         
127         if (node && deselect_node) {
128                 int sel=0;
129                 
130                 /* if no selected sockets remain, also deselect the node */
131                 for (sock=node->inputs.first; sock; sock=sock->next) {
132                         if (sock->flag & SELECT) {
133                                 sel = 1;
134                                 break;
135                         }
136                 }
137                 for (sock=node->outputs.first; sock; sock=sock->next) {
138                         if (sock->flag & SELECT) {
139                                 sel = 1;
140                                 break;
141                         }
142                 }
143                 
144                 if (!sel)
145                         node->flag &= ~SELECT;
146         }
147 }
148
149 static void node_socket_toggle(bNode *node, bNodeSocket *sock, int deselect_node)
150 {
151         if (sock->flag & SELECT)
152                 node_socket_deselect(node, sock, deselect_node);
153         else
154                 node_socket_select(node, sock);
155 }
156
157 /* no undo here! */
158 void node_deselect_all(SpaceNode *snode)
159 {
160         bNode *node;
161         
162         for (node= snode->edittree->nodes.first; node; node= node->next)
163                 node_deselect(node);
164 }
165
166 void node_deselect_all_input_sockets(SpaceNode *snode, int deselect_nodes)
167 {
168         bNode *node;
169         bNodeSocket *sock;
170         
171         /* XXX not calling node_socket_deselect here each time, because this does iteration
172          * over all node sockets internally to check if the node stays selected.
173          * We can do that more efficiently here.
174          */
175         
176         for (node= snode->edittree->nodes.first; node; node= node->next) {
177                 int sel=0;
178                 
179                 for (sock= node->inputs.first; sock; sock=sock->next)
180                         sock->flag &= ~SELECT;
181                 
182                 /* if no selected sockets remain, also deselect the node */
183                 if (deselect_nodes) {
184                         for (sock= node->outputs.first; sock; sock=sock->next) {
185                                 if (sock->flag & SELECT) {
186                                         sel = 1;
187                                         break;
188                                 }
189                         }
190                         
191                         if (!sel)
192                                 node->flag &= ~SELECT;
193                 }
194         }
195         
196         for (sock= snode->edittree->outputs.first; sock; sock=sock->next)
197                 sock->flag &= ~SELECT;
198 }
199
200 void node_deselect_all_output_sockets(SpaceNode *snode, int deselect_nodes)
201 {
202         bNode *node;
203         bNodeSocket *sock;
204         
205         /* XXX not calling node_socket_deselect here each time, because this does iteration
206          * over all node sockets internally to check if the node stays selected.
207          * We can do that more efficiently here.
208          */
209         
210         for (node= snode->edittree->nodes.first; node; node= node->next) {
211                 int sel=0;
212                 
213                 for (sock= node->outputs.first; sock; sock=sock->next)
214                         sock->flag &= ~SELECT;
215                 
216                 /* if no selected sockets remain, also deselect the node */
217                 if (deselect_nodes) {
218                         for (sock= node->inputs.first; sock; sock=sock->next) {
219                                 if (sock->flag & SELECT) {
220                                         sel = 1;
221                                         break;
222                                 }
223                         }
224                         
225                         if (!sel)
226                                 node->flag &= ~SELECT;
227                 }
228         }
229         
230         for (sock= snode->edittree->inputs.first; sock; sock=sock->next)
231                 sock->flag &= ~SELECT;
232 }
233
234 /* return 1 if we need redraw otherwise zero. */
235 int node_select_same_type(SpaceNode *snode)
236 {
237         bNode *nac, *p;
238         int redraw;
239
240         /* search for the active node. */
241         for (nac= snode->edittree->nodes.first; nac; nac= nac->next) {
242                 if (nac->flag & SELECT)
243                         break;
244         }
245
246         /* no active node, return. */
247         if (!nac)
248                 return(0);
249
250         redraw= 0;
251         for (p= snode->edittree->nodes.first; p; p= p->next) {
252                 if (p->type != nac->type && p->flag & SELECT) {
253                         /* if it's selected but different type, unselect */
254                         redraw= 1;
255                         node_deselect(p);
256                 }
257                 else if (p->type == nac->type && (!(p->flag & SELECT))) {
258                         /* if it's the same type and is not selected, select! */
259                         redraw= 1;
260                         node_select(p);
261                 }
262         }
263         return(redraw);
264 }
265
266 /* return 1 if we need redraw, otherwise zero.
267  * dir can be 0 == next or 0 != prev.
268  */
269 int node_select_same_type_np(SpaceNode *snode, int dir)
270 {
271         bNode *nac, *p, *tnode;
272
273         /* search the active one. */
274         for (nac= snode->edittree->nodes.first; nac; nac= nac->next) {
275                 if (nac->flag & SELECT)
276                         break;
277         }
278
279         /* no active node, return. */
280         if (!nac)
281                 return(0);
282
283         if (dir == 0)
284                 p= nac->next;
285         else
286                 p= nac->prev;
287
288         while (p) {
289                 /* Now search the next with the same type. */
290                 if (p->type == nac->type)
291                         break;
292
293                 if (dir == 0)
294                         p= p->next;
295                 else
296                         p= p->prev;
297         }
298
299         if (p) {
300                 for (tnode=snode->edittree->nodes.first; tnode; tnode=tnode->next)
301                         if (tnode!=p)
302                                 node_deselect(tnode);
303                 node_select(p);
304                 return(1);
305         }
306         return(0);
307 }
308
309 void node_select_single(bContext *C, bNode *node)
310 {
311         Main *bmain= CTX_data_main(C);
312         SpaceNode *snode= CTX_wm_space_node(C);
313         bNode *tnode;
314         
315         for (tnode=snode->edittree->nodes.first; tnode; tnode=tnode->next)
316                 if (tnode!=node)
317                         node_deselect(tnode);
318         node_select(node);
319         
320         ED_node_set_active(bmain, snode->edittree, node);
321         
322         ED_node_sort(snode->edittree);
323         
324         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
325 }
326
327 /* ****** Click Select ****** */
328  
329 static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], short extend)
330 {
331         bNode *node, *tnode;
332         bNodeSocket *sock, *tsock;
333         float mx, my;
334         int selected = 0;
335         
336         /* get mouse coordinates in view2d space */
337         UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &mx, &my);
338         /* node_find_indicated_socket uses snode->mx/my */
339         snode->mx = mx;
340         snode->my = my;
341         
342         if (extend) {
343                 /* first do socket selection, these generally overlap with nodes.
344                  * socket selection only in extend mode.
345                  */
346                 if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
347                         node_socket_toggle(node, sock, 1);
348                         selected = 1;
349                 }
350                 else if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
351                         if (sock->flag & SELECT) {
352                                 node_socket_deselect(node, sock, 1);
353                         }
354                         else {
355                                 /* only allow one selected output per node, for sensible linking.
356                                  * allows selecting outputs from different nodes though.
357                                  */
358                                 if (node) {
359                                         for (tsock=node->outputs.first; tsock; tsock=tsock->next)
360                                                 node_socket_deselect(node, tsock, 1);
361                                 }
362                                 node_socket_select(node, sock);
363                         }
364                         selected = 1;
365                 }
366                 else {
367                         /* find the closest visible node */
368                         node = node_under_mouse_select(snode->edittree, mx, my);
369                         
370                         if (node) {
371                                 node_toggle(node);
372                                 
373                                 ED_node_set_active(bmain, snode->edittree, node);
374                                 selected = 1;
375                         }
376                 }
377         }
378         else {  /* extend==0 */
379                 
380                 /* find the closest visible node */
381                 node = node_under_mouse_select(snode->edittree, mx, my);
382                 
383                 if (node) {
384                         for (tnode=snode->edittree->nodes.first; tnode; tnode=tnode->next)
385                                 node_deselect(tnode);
386                         node_select(node);
387                         ED_node_set_active(bmain, snode->edittree, node);
388                         selected = 1;
389                 }
390         }
391         
392         /* update node order */
393         if (selected)
394                 ED_node_sort(snode->edittree);
395         
396         return selected;
397 }
398
399 static int node_select_exec(bContext *C, wmOperator *op)
400 {
401         Main *bmain= CTX_data_main(C);
402         SpaceNode *snode= CTX_wm_space_node(C);
403         ARegion *ar= CTX_wm_region(C);
404         int mval[2];
405         short extend;
406         
407         /* get settings from RNA properties for operator */
408         mval[0] = RNA_int_get(op->ptr, "mouse_x");
409         mval[1] = RNA_int_get(op->ptr, "mouse_y");
410         
411         extend = RNA_boolean_get(op->ptr, "extend");
412         
413         /* perform the select */
414         if (node_mouse_select(bmain, snode, ar, mval, extend)) {
415                 /* send notifiers */
416                 WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
417                 
418                 /* allow tweak event to work too */
419                 return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
420         }
421         else {
422                 /* allow tweak event to work too */
423                 return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
424         }
425 }
426
427 static int node_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
428 {
429         RNA_int_set(op->ptr, "mouse_x", event->mval[0]);
430         RNA_int_set(op->ptr, "mouse_y", event->mval[1]);
431
432         return node_select_exec(C, op);
433 }
434
435
436 void NODE_OT_select(wmOperatorType *ot)
437 {
438         /* identifiers */
439         ot->name = "Select";
440         ot->idname = "NODE_OT_select";
441         ot->description = "Select the node under the cursor";
442         
443         /* api callbacks */
444         ot->invoke = node_select_invoke;
445         ot->poll = ED_operator_node_active;
446         
447         /* flags */
448         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
449         
450         /* properties */
451         RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX);
452         RNA_def_int(ot->srna, "mouse_y", 0, INT_MIN, INT_MAX, "Mouse Y", "", INT_MIN, INT_MAX);
453         RNA_def_boolean(ot->srna, "extend", 0, "Extend", "");
454 }
455
456 /* ****** Border Select ****** */
457
458 static int node_borderselect_exec(bContext *C, wmOperator *op)
459 {
460         SpaceNode *snode= CTX_wm_space_node(C);
461         ARegion *ar= CTX_wm_region(C);
462         bNode *node;
463         rcti rect;
464         rctf rectf;
465         int gesture_mode= RNA_int_get(op->ptr, "gesture_mode");
466         int extend= RNA_boolean_get(op->ptr, "extend");
467         
468         rect.xmin = RNA_int_get(op->ptr, "xmin");
469         rect.ymin = RNA_int_get(op->ptr, "ymin");
470         UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
471         
472         rect.xmax = RNA_int_get(op->ptr, "xmax");
473         rect.ymax = RNA_int_get(op->ptr, "ymax");
474         UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
475         
476         for (node= snode->edittree->nodes.first; node; node= node->next) {
477                 if (BLI_isect_rctf(&rectf, &node->totr, NULL)) {
478                         if (gesture_mode==GESTURE_MODAL_SELECT)
479                                 node_select(node);
480                         else
481                                 node_deselect(node);
482                 }
483                 else if (!extend) {
484                         node_deselect(node);
485                 }
486         }
487         
488         ED_node_sort(snode->edittree);
489         
490         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
491
492         return OPERATOR_FINISHED;
493 }
494
495 static int node_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
496 {
497         int tweak = RNA_boolean_get(op->ptr, "tweak");
498         
499         if (tweak) {
500                 /* prevent initiating the border select if the mouse is over a node */
501                 /* this allows border select on empty space, but drag-translate on nodes */
502                 SpaceNode *snode= CTX_wm_space_node(C);
503                 ARegion *ar= CTX_wm_region(C);
504                 float mx, my;
505
506                 UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
507                 
508                 if (node_under_mouse_tweak(snode->edittree, mx, my))
509                         return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
510         }
511         
512         return WM_border_select_invoke(C, op, event);
513 }
514
515 void NODE_OT_select_border(wmOperatorType *ot)
516 {
517         /* identifiers */
518         ot->name = "Border Select";
519         ot->idname = "NODE_OT_select_border";
520         ot->description = "Use box selection to select nodes";
521         
522         /* api callbacks */
523         ot->invoke = node_border_select_invoke;
524         ot->exec = node_borderselect_exec;
525         ot->modal = WM_border_select_modal;
526         ot->cancel = WM_border_select_cancel;
527         
528         ot->poll = ED_operator_node_active;
529         
530         /* flags */
531         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
532         
533         /* rna */
534         WM_operator_properties_gesture_border(ot, TRUE);
535         RNA_def_boolean(ot->srna, "tweak", 0, "Tweak", "Only activate when mouse is not over a node - useful for tweak gesture");
536 }
537
538 /* ****** Select/Deselect All ****** */
539
540 static int node_select_all_exec(bContext *C, wmOperator *UNUSED(op))
541 {
542         SpaceNode *snode = CTX_wm_space_node(C);
543         bNode *first = snode->edittree->nodes.first;
544         bNode *node;
545         int count= 0;
546
547         for (node=first; node; node=node->next)
548                 if (node->flag & NODE_SELECT)
549                         count++;
550
551         if (count) {
552                 for (node=first; node; node=node->next)
553                         node_deselect(node);
554         }
555         else {
556                 for (node=first; node; node=node->next)
557                         node_select(node);
558         }
559         
560         ED_node_sort(snode->edittree);
561         
562         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
563         return OPERATOR_FINISHED;
564 }
565
566 void NODE_OT_select_all(wmOperatorType *ot)
567 {
568         /* identifiers */
569         ot->name = "(De)select All";
570         ot->description = "(De)select all nodes";
571         ot->idname = "NODE_OT_select_all";
572         
573         /* api callbacks */
574         ot->exec = node_select_all_exec;
575         ot->poll = ED_operator_node_active;
576         
577         /* flags */
578         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
579 }
580
581 /* ****** Select Linked To ****** */
582
583 static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
584 {
585         SpaceNode *snode = CTX_wm_space_node(C);
586         bNodeLink *link;
587         bNode *node;
588         
589         for (node=snode->edittree->nodes.first; node; node=node->next)
590                 node->flag &= ~NODE_TEST;
591
592         for (link=snode->edittree->links.first; link; link=link->next) {
593                 if (link->fromnode && link->tonode && (link->fromnode->flag & NODE_SELECT))
594                         link->tonode->flag |= NODE_TEST;
595         }
596         
597         for (node=snode->edittree->nodes.first; node; node=node->next) {
598                 if (node->flag & NODE_TEST)
599                         node_select(node);
600         }
601         
602         ED_node_sort(snode->edittree);
603         
604         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
605         return OPERATOR_FINISHED;
606 }
607
608 void NODE_OT_select_linked_to(wmOperatorType *ot)
609 {
610         /* identifiers */
611         ot->name = "Select Linked To";
612         ot->description = "Select nodes linked to the selected ones";
613         ot->idname = "NODE_OT_select_linked_to";
614         
615         /* api callbacks */
616         ot->exec = node_select_linked_to_exec;
617         ot->poll = ED_operator_node_active;
618         
619         /* flags */
620         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
621 }
622
623 /* ****** Select Linked From ****** */
624
625 static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
626 {
627         SpaceNode *snode = CTX_wm_space_node(C);
628         bNodeLink *link;
629         bNode *node;
630         
631         for (node=snode->edittree->nodes.first; node; node=node->next)
632                 node->flag &= ~NODE_TEST;
633
634         for (link=snode->edittree->links.first; link; link=link->next) {
635                 if (link->fromnode && link->tonode && (link->tonode->flag & NODE_SELECT))
636                         link->fromnode->flag |= NODE_TEST;
637         }
638         
639         for (node=snode->edittree->nodes.first; node; node=node->next) {
640                 if (node->flag & NODE_TEST)
641                         node_select(node);
642         }
643         
644         ED_node_sort(snode->edittree);
645         
646         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
647         return OPERATOR_FINISHED;
648 }
649
650 void NODE_OT_select_linked_from(wmOperatorType *ot)
651 {
652         /* identifiers */
653         ot->name = "Select Linked From";
654         ot->description = "Select nodes linked from the selected ones";
655         ot->idname = "NODE_OT_select_linked_from";
656         
657         /* api callbacks */
658         ot->exec = node_select_linked_from_exec;
659         ot->poll = ED_operator_node_active;
660         
661         /* flags */
662         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
663 }
664
665 /* ****** Select Same Type ****** */
666
667 static int node_select_same_type_exec(bContext *C, wmOperator *UNUSED(op))
668 {
669         SpaceNode *snode = CTX_wm_space_node(C);
670
671         node_select_same_type(snode);
672
673         ED_node_sort(snode->edittree);
674
675         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
676         return OPERATOR_FINISHED;
677 }
678
679 void NODE_OT_select_same_type(wmOperatorType *ot)
680 {
681         /* identifiers */
682         ot->name = "Select Same Type";
683         ot->description = "Select all the nodes of the same type";
684         ot->idname = "NODE_OT_select_same_type";
685         
686         /* api callbacks */
687         ot->exec = node_select_same_type_exec;
688         ot->poll = ED_operator_node_active;
689         
690         /* flags */
691         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
692 }
693
694 /* ****** Select The Next/Prev Node Of The Same Type ****** */
695
696 static int node_select_same_type_next_exec(bContext *C, wmOperator *UNUSED(op))
697 {
698         SpaceNode *snode = CTX_wm_space_node(C);
699
700         node_select_same_type_np(snode, 0);
701
702         ED_node_sort(snode->edittree);
703
704         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
705
706         return OPERATOR_FINISHED;
707 }
708
709 void NODE_OT_select_same_type_next(wmOperatorType *ot)
710 {
711         /* identifiers */
712         ot->name = "Select Same Type Next";
713         ot->description = "Select the next node of the same type";
714         ot->idname = "NODE_OT_select_same_type_next";
715         
716         /* api callbacks */
717         ot->exec = node_select_same_type_next_exec;
718         ot->poll = ED_operator_node_active;
719         
720         /* flags */
721         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
722 }
723
724 static int node_select_same_type_prev_exec(bContext *C, wmOperator *UNUSED(op))
725 {
726         SpaceNode *snode = CTX_wm_space_node(C);
727
728         node_select_same_type_np(snode, 1);
729
730         ED_node_sort(snode->edittree);
731
732         WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL);
733         return OPERATOR_FINISHED;
734 }
735
736 void NODE_OT_select_same_type_prev(wmOperatorType *ot)
737 {
738         /* identifiers */
739         ot->name = "Select Same Type Prev";
740         ot->description = "Select the prev node of the same type";
741         ot->idname = "NODE_OT_select_same_type_prev";
742         
743         /* api callbacks */
744         ot->exec = node_select_same_type_prev_exec;
745         ot->poll = ED_operator_node_active;
746         
747         /* flags */
748         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
749 }