Blender  V2.93
node_select.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stdlib.h>
25 
26 #include "DNA_node_types.h"
28 
29 #include "BLI_lasso_2d.h"
30 #include "BLI_listbase.h"
31 #include "BLI_math.h"
32 #include "BLI_rect.h"
33 #include "BLI_string.h"
34 #include "BLI_string_search.h"
35 #include "BLI_string_utf8.h"
36 #include "BLI_utildefines.h"
37 
38 #include "BKE_context.h"
39 #include "BKE_main.h"
40 #include "BKE_node.h"
41 #include "BKE_workspace.h"
42 
43 #include "ED_node.h" /* own include */
44 #include "ED_screen.h"
45 #include "ED_select_utils.h"
46 #include "ED_view3d.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_interface.h"
55 #include "UI_resources.h"
56 #include "UI_view2d.h"
57 
58 #include "DEG_depsgraph.h"
59 
60 #include "MEM_guardedalloc.h"
61 
62 #include "node_intern.h" /* own include */
63 
74  const Scene *scene,
75  const Object *ob)
76 {
77  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
78  if (win->scene != scene) {
79  continue;
80  }
81  const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
82  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
83  if (area->spacetype == SPACE_VIEW3D) {
84  const View3D *v3d = area->spacedata.first;
85 
87  return true;
88  }
89  }
90  }
91  }
92  return false;
93 }
94 
95 /* -------------------------------------------------------------------- */
99 static bNode *node_under_mouse_select(bNodeTree *ntree, int mx, int my)
100 {
101  bNode *node;
102 
103  for (node = ntree->nodes.last; node; node = node->prev) {
104  if (node->typeinfo->select_area_func) {
105  if (node->typeinfo->select_area_func(node, mx, my)) {
106  return node;
107  }
108  }
109  }
110  return NULL;
111 }
112 
113 static bNode *node_under_mouse_tweak(bNodeTree *ntree, int mx, int my)
114 {
115  bNode *node;
116 
117  for (node = ntree->nodes.last; node; node = node->prev) {
118  if (node->typeinfo->tweak_area_func) {
119  if (node->typeinfo->tweak_area_func(node, mx, my)) {
120  return node;
121  }
122  }
123  }
124  return NULL;
125 }
126 
127 static bool is_position_over_node_or_socket(SpaceNode *snode, float mouse[2])
128 {
129  if (node_under_mouse_tweak(snode->edittree, mouse[0], mouse[1])) {
130  return true;
131  }
132 
133  bNode *node;
134  bNodeSocket *sock;
135  if (node_find_indicated_socket(snode, &node, &sock, mouse, SOCK_IN | SOCK_OUT)) {
136  return true;
137  }
138 
139  return false;
140 }
141 
142 static bool is_event_over_node_or_socket(bContext *C, const wmEvent *event)
143 {
144  SpaceNode *snode = CTX_wm_space_node(C);
145  ARegion *region = CTX_wm_region(C);
146  float mouse[2];
147  UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &mouse[0], &mouse[1]);
148  return is_position_over_node_or_socket(snode, mouse);
149 }
150 
151 static void node_toggle(bNode *node)
152 {
153  nodeSetSelected(node, !(node->flag & SELECT));
154 }
155 
157 {
158  sock->flag |= SELECT;
159 
160  /* select node too */
161  if (node) {
162  node->flag |= SELECT;
163  }
164 }
165 
166 void node_socket_deselect(bNode *node, bNodeSocket *sock, const bool deselect_node)
167 {
168  sock->flag &= ~SELECT;
169 
170  if (node && deselect_node) {
171  bool sel = 0;
172 
173  /* if no selected sockets remain, also deselect the node */
174  for (sock = node->inputs.first; sock; sock = sock->next) {
175  if (sock->flag & SELECT) {
176  sel = 1;
177  break;
178  }
179  }
180  for (sock = node->outputs.first; sock; sock = sock->next) {
181  if (sock->flag & SELECT) {
182  sel = 1;
183  break;
184  }
185  }
186 
187  if (!sel) {
188  node->flag &= ~SELECT;
189  }
190  }
191 }
192 
193 static void node_socket_toggle(bNode *node, bNodeSocket *sock, int deselect_node)
194 {
195  if (sock->flag & SELECT) {
196  node_socket_deselect(node, sock, deselect_node);
197  }
198  else {
199  node_socket_select(node, sock);
200  }
201 }
202 
203 /* no undo here! */
205 {
206  bNode *node;
207 
208  for (node = snode->edittree->nodes.first; node; node = node->next) {
209  nodeSetSelected(node, false);
210  }
211 }
212 
213 void node_deselect_all_input_sockets(SpaceNode *snode, const bool deselect_nodes)
214 {
215  bNode *node;
216  bNodeSocket *sock;
217 
218  /* XXX not calling node_socket_deselect here each time, because this does iteration
219  * over all node sockets internally to check if the node stays selected.
220  * We can do that more efficiently here.
221  */
222 
223  for (node = snode->edittree->nodes.first; node; node = node->next) {
224  int sel = 0;
225 
226  for (sock = node->inputs.first; sock; sock = sock->next) {
227  sock->flag &= ~SELECT;
228  }
229 
230  /* if no selected sockets remain, also deselect the node */
231  if (deselect_nodes) {
232  for (sock = node->outputs.first; sock; sock = sock->next) {
233  if (sock->flag & SELECT) {
234  sel = 1;
235  break;
236  }
237  }
238 
239  if (!sel) {
240  node->flag &= ~SELECT;
241  }
242  }
243  }
244 }
245 
246 void node_deselect_all_output_sockets(SpaceNode *snode, const bool deselect_nodes)
247 {
248  bNode *node;
249  bNodeSocket *sock;
250 
251  /* XXX not calling node_socket_deselect here each time, because this does iteration
252  * over all node sockets internally to check if the node stays selected.
253  * We can do that more efficiently here.
254  */
255 
256  for (node = snode->edittree->nodes.first; node; node = node->next) {
257  bool sel = false;
258 
259  for (sock = node->outputs.first; sock; sock = sock->next) {
260  sock->flag &= ~SELECT;
261  }
262 
263  /* if no selected sockets remain, also deselect the node */
264  if (deselect_nodes) {
265  for (sock = node->inputs.first; sock; sock = sock->next) {
266  if (sock->flag & SELECT) {
267  sel = 1;
268  break;
269  }
270  }
271 
272  if (!sel) {
273  node->flag &= ~SELECT;
274  }
275  }
276  }
277 }
278 
281 /* -------------------------------------------------------------------- */
285 /* Return true if we need redraw, otherwise false. */
286 
287 static bool node_select_grouped_type(SpaceNode *snode, bNode *node_act)
288 {
289  bNode *node;
290  bool changed = false;
291 
292  for (node = snode->edittree->nodes.first; node; node = node->next) {
293  if ((node->flag & SELECT) == 0) {
294  if (node->type == node_act->type) {
295  nodeSetSelected(node, true);
296  changed = true;
297  }
298  }
299  }
300 
301  return changed;
302 }
303 
304 static bool node_select_grouped_color(SpaceNode *snode, bNode *node_act)
305 {
306  bNode *node;
307  bool changed = false;
308 
309  for (node = snode->edittree->nodes.first; node; node = node->next) {
310  if ((node->flag & SELECT) == 0) {
311  if (compare_v3v3(node->color, node_act->color, 0.005f)) {
312  nodeSetSelected(node, true);
313  changed = true;
314  }
315  }
316  }
317 
318  return changed;
319 }
320 
321 static bool node_select_grouped_name(SpaceNode *snode, bNode *node_act, const bool from_right)
322 {
323  bNode *node;
324  bool changed = false;
325  const uint delims[] = {'.', '-', '_', '\0'};
326  size_t pref_len_act, pref_len_curr;
327  const char *sep, *suf_act, *suf_curr;
328 
329  pref_len_act = BLI_str_partition_ex_utf8(
330  node_act->name, NULL, delims, &sep, &suf_act, from_right);
331 
332  /* Note: in case we are searching for suffix, and found none, use whole name as suffix. */
333  if (from_right && !(sep && suf_act)) {
334  pref_len_act = 0;
335  suf_act = node_act->name;
336  }
337 
338  for (node = snode->edittree->nodes.first; node; node = node->next) {
339  if (node->flag & SELECT) {
340  continue;
341  }
342  pref_len_curr = BLI_str_partition_ex_utf8(
343  node->name, NULL, delims, &sep, &suf_curr, from_right);
344 
345  /* Same as with active node name! */
346  if (from_right && !(sep && suf_curr)) {
347  pref_len_curr = 0;
348  suf_curr = node->name;
349  }
350 
351  if ((from_right && STREQ(suf_act, suf_curr)) ||
352  (!from_right && (pref_len_act == pref_len_curr) &&
353  STREQLEN(node_act->name, node->name, pref_len_act))) {
354  nodeSetSelected(node, true);
355  changed = true;
356  }
357  }
358 
359  return changed;
360 }
361 
362 enum {
367 };
368 
370 {
371  SpaceNode *snode = CTX_wm_space_node(C);
372  bNode *node_act = nodeGetActive(snode->edittree);
373 
374  if (node_act == NULL) {
375  return OPERATOR_CANCELLED;
376  }
377 
378  bNode *node;
379  bool changed = false;
380  const bool extend = RNA_boolean_get(op->ptr, "extend");
381  const int type = RNA_enum_get(op->ptr, "type");
382 
383  if (!extend) {
384  for (node = snode->edittree->nodes.first; node; node = node->next) {
385  nodeSetSelected(node, false);
386  }
387  }
388  nodeSetSelected(node_act, true);
389 
390  switch (type) {
392  changed = node_select_grouped_type(snode, node_act);
393  break;
395  changed = node_select_grouped_color(snode, node_act);
396  break;
398  changed = node_select_grouped_name(snode, node_act, false);
399  break;
401  changed = node_select_grouped_name(snode, node_act, true);
402  break;
403  default:
404  break;
405  }
406 
407  if (changed) {
408  ED_node_sort(snode->edittree);
410  return OPERATOR_FINISHED;
411  }
412 
413  return OPERATOR_CANCELLED;
414 }
415 
417 {
419  {NODE_SELECT_GROUPED_TYPE, "TYPE", 0, "Type", ""},
420  {NODE_SELECT_GROUPED_COLOR, "COLOR", 0, "Color", ""},
421  {NODE_SELECT_GROUPED_PREFIX, "PREFIX", 0, "Prefix", ""},
422  {NODE_SELECT_GROUPED_SUFIX, "SUFFIX", 0, "Suffix", ""},
423  {0, NULL, 0, NULL, NULL},
424  };
425 
426  /* identifiers */
427  ot->name = "Select Grouped";
428  ot->description = "Select nodes with similar properties";
429  ot->idname = "NODE_OT_select_grouped";
430 
431  /* api callbacks */
435 
436  /* flags */
438 
439  /* properties */
441  "extend",
442  false,
443  "Extend",
444  "Extend selection instead of deselecting everything first");
445  ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
446 }
447 
450 /* -------------------------------------------------------------------- */
455 {
456  Main *bmain = CTX_data_main(C);
457  SpaceNode *snode = CTX_wm_space_node(C);
458  const Object *ob = CTX_data_active_object(C);
459  const Scene *scene = CTX_data_scene(C);
460  const wmWindowManager *wm = CTX_wm_manager(C);
461  bool active_texture_changed = false;
462  bNode *tnode;
463 
464  for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
465  if (tnode != node) {
466  nodeSetSelected(tnode, false);
467  }
468  }
469  nodeSetSelected(node, true);
470 
471  ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
473 
474  ED_node_sort(snode->edittree);
475  if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
477  }
478 
480 }
481 
483  wmOperator *op,
484  const int mval[2],
485  bool wait_to_deselect_others)
486 {
487  Main *bmain = CTX_data_main(C);
488  SpaceNode *snode = CTX_wm_space_node(C);
489  ARegion *region = CTX_wm_region(C);
490  const Object *ob = CTX_data_active_object(C);
491  const Scene *scene = CTX_data_scene(C);
492  const wmWindowManager *wm = CTX_wm_manager(C);
493  bNode *node, *tnode;
494  bNodeSocket *sock = NULL;
495  bNodeSocket *tsock;
496  float cursor[2];
497  int ret_value = OPERATOR_CANCELLED;
498 
499  const bool extend = RNA_boolean_get(op->ptr, "extend");
500  /* always do socket_select when extending selection. */
501  const bool socket_select = extend || RNA_boolean_get(op->ptr, "socket_select");
502  const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
503 
504  /* These cases are never modal. */
505  if (extend || socket_select) {
506  wait_to_deselect_others = false;
507  }
508 
509  /* get mouse coordinates in view2d space */
510  UI_view2d_region_to_view(&region->v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
511 
512  /* first do socket selection, these generally overlap with nodes. */
513  if (socket_select) {
514  if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
515  /* NOTE: SOCK_IN does not take into account the extend case...
516  * This feature is not really used anyway currently? */
517  node_socket_toggle(node, sock, true);
518  ret_value = OPERATOR_FINISHED;
519  }
520  else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
521  if (sock->flag & SELECT) {
522  if (extend) {
523  node_socket_deselect(node, sock, true);
524  }
525  else {
526  ret_value = OPERATOR_FINISHED;
527  }
528  }
529  else {
530  /* Only allow one selected output per node, for sensible linking.
531  * Allow selecting outputs from different nodes though, if extend is true. */
532  if (node) {
533  for (tsock = node->outputs.first; tsock; tsock = tsock->next) {
534  if (tsock == sock) {
535  continue;
536  }
537  node_socket_deselect(node, tsock, true);
538  }
539  }
540  if (!extend) {
541  for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
542  if (tnode == node) {
543  continue;
544  }
545  for (tsock = tnode->outputs.first; tsock; tsock = tsock->next) {
546  node_socket_deselect(tnode, tsock, true);
547  }
548  }
549  }
550  node_socket_select(node, sock);
551  ret_value = OPERATOR_FINISHED;
552  }
553  }
554  }
555 
556  if (!sock) {
557  /* find the closest visible node */
558  node = node_under_mouse_select(snode->edittree, (int)cursor[0], (int)cursor[1]);
559 
560  if (extend) {
561  if (node != NULL) {
562  /* If node is selected but not active, we want to make it active,
563  * but not toggle (deselect) it. */
564  if (!((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0)) {
565  node_toggle(node);
566  }
567  ret_value = OPERATOR_FINISHED;
568  }
569  }
570  else if (deselect_all && node == NULL) {
571  /* Rather than deselecting others, users may want to drag to box-select (drag from empty
572  * space) or tweak-translate an already selected item. If these cases may apply, delay
573  * deselection. */
574  if (wait_to_deselect_others) {
575  ret_value = OPERATOR_RUNNING_MODAL;
576  }
577  else {
578  /* Deselect in empty space. */
579  for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
580  nodeSetSelected(tnode, false);
581  }
582  ret_value = OPERATOR_FINISHED;
583  }
584  }
585  else if (node != NULL) {
586  /* When clicking on an already selected node, we want to wait to deselect
587  * others and allow the user to start moving the node without that. */
588  if (wait_to_deselect_others && (node->flag & SELECT)) {
589  ret_value = OPERATOR_RUNNING_MODAL;
590  }
591  else {
592  nodeSetSelected(node, true);
593 
594  for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
595  if (tnode != node) {
596  nodeSetSelected(tnode, false);
597  }
598  }
599 
600  ret_value = OPERATOR_FINISHED;
601  }
602  }
603  }
604 
605  /* update node order */
606  if (ret_value != OPERATOR_CANCELLED) {
607  bool active_texture_changed = false;
608  if (node != NULL && ret_value != OPERATOR_RUNNING_MODAL) {
609  ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
610  }
612  ED_node_sort(snode->edittree);
613  if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
615  }
616 
618  }
619 
620  return ret_value;
621 }
622 
624 {
625  const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
626 
627  /* get settings from RNA properties for operator */
628  int mval[2];
629  mval[0] = RNA_int_get(op->ptr, "mouse_x");
630  mval[1] = RNA_int_get(op->ptr, "mouse_y");
631 
632  /* perform the select */
633  const int ret_value = node_mouse_select(C, op, mval, wait_to_deselect_others);
634 
635  /* allow tweak event to work too */
636  return ret_value | OPERATOR_PASS_THROUGH;
637 }
638 
640 {
641  PropertyRNA *prop;
642 
643  /* identifiers */
644  ot->name = "Select";
645  ot->idname = "NODE_OT_select";
646  ot->description = "Select the node under the cursor";
647 
648  /* api callbacks */
653 
654  /* flags */
656 
657  /* properties */
659  RNA_def_boolean(ot->srna, "extend", false, "Extend", "");
660  RNA_def_boolean(ot->srna, "socket_select", false, "Socket Select", "");
661  prop = RNA_def_boolean(ot->srna,
662  "deselect_all",
663  false,
664  "Deselect On Nothing",
665  "Deselect all when nothing under the cursor");
667 }
668 
671 /* -------------------------------------------------------------------- */
676 {
677  SpaceNode *snode = CTX_wm_space_node(C);
678  ARegion *region = CTX_wm_region(C);
679  rctf rectf;
680 
682  UI_view2d_region_to_view_rctf(&region->v2d, &rectf, &rectf);
683 
684  const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
685  const bool select = (sel_op != SEL_OP_SUB);
686  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
688  }
689 
690  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
691  bool is_inside;
692  if (node->type == NODE_FRAME) {
693  is_inside = BLI_rctf_inside_rctf(&rectf, &node->totr);
694  }
695  else {
696  is_inside = BLI_rctf_isect(&rectf, &node->totr, NULL);
697  }
698 
699  if (is_inside) {
701  }
702  }
703 
704  ED_node_sort(snode->edittree);
705 
707 
708  return OPERATOR_FINISHED;
709 }
710 
711 static int node_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
712 {
713  const bool tweak = RNA_boolean_get(op->ptr, "tweak");
714 
715  if (tweak && is_event_over_node_or_socket(C, event)) {
717  }
718 
719  return WM_gesture_box_invoke(C, op, event);
720 }
721 
723 {
724  /* identifiers */
725  ot->name = "Box Select";
726  ot->idname = "NODE_OT_select_box";
727  ot->description = "Use box selection to select nodes";
728 
729  /* api callbacks */
734 
736 
737  /* flags */
739 
740  /* properties */
742  "tweak",
743  0,
744  "Tweak",
745  "Only activate when mouse is not over a node (useful for tweak gesture)");
746 
749 }
750 
753 /* -------------------------------------------------------------------- */
758 {
759  SpaceNode *snode = CTX_wm_space_node(C);
760  ARegion *region = CTX_wm_region(C);
761  bNode *node;
762 
763  int x, y, radius;
764  float offset[2];
765 
766  float zoom = (float)(BLI_rcti_size_x(&region->winrct)) /
767  (float)(BLI_rctf_size_x(&region->v2d.cur));
768 
769  const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
771  const bool select = (sel_op != SEL_OP_SUB);
772  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
774  }
775 
776  /* get operator properties */
777  x = RNA_int_get(op->ptr, "x");
778  y = RNA_int_get(op->ptr, "y");
779  radius = RNA_int_get(op->ptr, "radius");
780 
781  UI_view2d_region_to_view(&region->v2d, x, y, &offset[0], &offset[1]);
782 
783  for (node = snode->edittree->nodes.first; node; node = node->next) {
784  if (BLI_rctf_isect_circle(&node->totr, offset, radius / zoom)) {
786  }
787  }
788 
790 
791  return OPERATOR_FINISHED;
792 }
793 
795 {
796  /* identifiers */
797  ot->name = "Circle Select";
798  ot->idname = "NODE_OT_select_circle";
799  ot->description = "Use circle selection to select nodes";
800 
801  /* api callbacks */
805 
807 
808  /* flags */
810 
811  /* properties */
814 }
815 
818 /* -------------------------------------------------------------------- */
822 static int node_lasso_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
823 {
824  const bool tweak = RNA_boolean_get(op->ptr, "tweak");
825 
826  if (tweak && is_event_over_node_or_socket(C, event)) {
828  }
829 
830  return WM_gesture_lasso_invoke(C, op, event);
831 }
832 
834  const int mcoords[][2],
835  const int mcoords_len,
836  eSelectOp sel_op)
837 {
838  SpaceNode *snode = CTX_wm_space_node(C);
839  bNode *node;
840 
841  ARegion *region = CTX_wm_region(C);
842 
843  rcti rect;
844  bool changed = false;
845 
846  const bool select = (sel_op != SEL_OP_SUB);
847  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
849  changed = true;
850  }
851 
852  /* get rectangle from operator */
853  BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
854 
855  /* do actual selection */
856  for (node = snode->edittree->nodes.first; node; node = node->next) {
857 
858  if (select && (node->flag & NODE_SELECT)) {
859  continue;
860  }
861 
862  int screen_co[2];
863  const float cent[2] = {BLI_rctf_cent_x(&node->totr), BLI_rctf_cent_y(&node->totr)};
864 
865  /* marker in screen coords */
867  &region->v2d, cent[0], cent[1], &screen_co[0], &screen_co[1]) &&
868  BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
869  BLI_lasso_is_point_inside(mcoords, mcoords_len, screen_co[0], screen_co[1], INT_MAX)) {
871  changed = true;
872  }
873  }
874 
875  if (changed) {
877  }
878 
879  return changed;
880 }
881 
883 {
884  int mcoords_len;
885  const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
886 
887  if (mcoords) {
888  const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
889 
890  do_lasso_select_node(C, mcoords, mcoords_len, sel_op);
891 
892  MEM_freeN((void *)mcoords);
893 
894  return OPERATOR_FINISHED;
895  }
896  return OPERATOR_PASS_THROUGH;
897 }
898 
900 {
901  /* identifiers */
902  ot->name = "Lasso Select";
903  ot->description = "Select nodes using lasso selection";
904  ot->idname = "NODE_OT_select_lasso";
905 
906  /* api callbacks */
912 
913  /* flags */
914  ot->flag = OPTYPE_UNDO;
915 
916  /* properties */
918  "tweak",
919  0,
920  "Tweak",
921  "Only activate when mouse is not over a node (useful for tweak gesture)");
922 
925 }
926 
929 /* -------------------------------------------------------------------- */
934 {
935  SpaceNode *snode = CTX_wm_space_node(C);
936  ListBase *node_lb = &snode->edittree->nodes;
937  int action = RNA_enum_get(op->ptr, "action");
938 
939  ED_node_select_all(node_lb, action);
940 
941  ED_node_sort(snode->edittree);
942 
944  return OPERATOR_FINISHED;
945 }
946 
948 {
949  /* identifiers */
950  ot->name = "(De)select All";
951  ot->description = "(De)select all nodes";
952  ot->idname = "NODE_OT_select_all";
953 
954  /* api callbacks */
957 
958  /* flags */
960 
962 }
963 
966 /* -------------------------------------------------------------------- */
971 {
972  SpaceNode *snode = CTX_wm_space_node(C);
973  bNodeLink *link;
974  bNode *node;
975 
976  for (node = snode->edittree->nodes.first; node; node = node->next) {
977  node->flag &= ~NODE_TEST;
978  }
979 
980  for (link = snode->edittree->links.first; link; link = link->next) {
981  if (nodeLinkIsHidden(link)) {
982  continue;
983  }
984  if (link->fromnode && link->tonode && (link->fromnode->flag & NODE_SELECT)) {
985  link->tonode->flag |= NODE_TEST;
986  }
987  }
988 
989  for (node = snode->edittree->nodes.first; node; node = node->next) {
990  if (node->flag & NODE_TEST) {
991  nodeSetSelected(node, true);
992  }
993  }
994 
995  ED_node_sort(snode->edittree);
996 
998  return OPERATOR_FINISHED;
999 }
1000 
1002 {
1003  /* identifiers */
1004  ot->name = "Select Linked To";
1005  ot->description = "Select nodes linked to the selected ones";
1006  ot->idname = "NODE_OT_select_linked_to";
1007 
1008  /* api callbacks */
1011 
1012  /* flags */
1014 }
1015 
1018 /* -------------------------------------------------------------------- */
1023 {
1024  SpaceNode *snode = CTX_wm_space_node(C);
1025  bNodeLink *link;
1026  bNode *node;
1027 
1028  for (node = snode->edittree->nodes.first; node; node = node->next) {
1029  node->flag &= ~NODE_TEST;
1030  }
1031 
1032  for (link = snode->edittree->links.first; link; link = link->next) {
1033  if (nodeLinkIsHidden(link)) {
1034  continue;
1035  }
1036  if (link->fromnode && link->tonode && (link->tonode->flag & NODE_SELECT)) {
1037  link->fromnode->flag |= NODE_TEST;
1038  }
1039  }
1040 
1041  for (node = snode->edittree->nodes.first; node; node = node->next) {
1042  if (node->flag & NODE_TEST) {
1043  nodeSetSelected(node, true);
1044  }
1045  }
1046 
1047  ED_node_sort(snode->edittree);
1048 
1050  return OPERATOR_FINISHED;
1051 }
1052 
1054 {
1055  /* identifiers */
1056  ot->name = "Select Linked From";
1057  ot->description = "Select nodes linked from the selected ones";
1058  ot->idname = "NODE_OT_select_linked_from";
1059 
1060  /* api callbacks */
1063 
1064  /* flags */
1066 }
1067 
1070 /* -------------------------------------------------------------------- */
1075 {
1076  SpaceNode *snode = CTX_wm_space_node(C);
1077  ARegion *region = CTX_wm_region(C);
1078  bNode **node_array;
1079  bNode *active = nodeGetActive(snode->edittree);
1080  int totnodes;
1081  const bool revert = RNA_boolean_get(op->ptr, "prev");
1082  const bool same_type = 1;
1083 
1084  ntreeGetDependencyList(snode->edittree, &node_array, &totnodes);
1085 
1086  if (totnodes > 1) {
1087  int a;
1088 
1089  for (a = 0; a < totnodes; a++) {
1090  if (node_array[a] == active) {
1091  break;
1092  }
1093  }
1094 
1095  if (same_type) {
1096  bNode *node = NULL;
1097 
1098  while (node == NULL) {
1099  if (revert) {
1100  a--;
1101  }
1102  else {
1103  a++;
1104  }
1105 
1106  if (a < 0 || a >= totnodes) {
1107  break;
1108  }
1109 
1110  node = node_array[a];
1111 
1112  if (node->type == active->type) {
1113  break;
1114  }
1115  node = NULL;
1116  }
1117  if (node) {
1118  active = node;
1119  }
1120  }
1121  else {
1122  if (revert) {
1123  if (a == 0) {
1124  active = node_array[totnodes - 1];
1125  }
1126  else {
1127  active = node_array[a - 1];
1128  }
1129  }
1130  else {
1131  if (a == totnodes - 1) {
1132  active = node_array[0];
1133  }
1134  else {
1135  active = node_array[a + 1];
1136  }
1137  }
1138  }
1139 
1141 
1142  /* is note outside view? */
1143  if (active->totr.xmax < region->v2d.cur.xmin || active->totr.xmin > region->v2d.cur.xmax ||
1144  active->totr.ymax < region->v2d.cur.ymin || active->totr.ymin > region->v2d.cur.ymax) {
1145  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
1146  space_node_view_flag(C, snode, region, NODE_SELECT, smooth_viewtx);
1147  }
1148  }
1149 
1150  if (node_array) {
1151  MEM_freeN(node_array);
1152  }
1153 
1154  return OPERATOR_FINISHED;
1155 }
1156 
1158 {
1159  /* identifiers */
1160  ot->name = "Activate Same Type Next/Prev";
1161  ot->description = "Activate and view same node type, step by step";
1162  ot->idname = "NODE_OT_select_same_type_step";
1163 
1164  /* api callbacks */
1167 
1168  /* flags */
1170 
1171  RNA_def_boolean(ot->srna, "prev", 0, "Previous", "");
1172 }
1173 
1176 /* -------------------------------------------------------------------- */
1180 static void node_find_create_label(const bNode *node, char *str, int maxlen)
1181 {
1182  if (node->label[0]) {
1183  BLI_snprintf(str, maxlen, "%s (%s)", node->name, node->label);
1184  }
1185  else {
1186  BLI_strncpy(str, node->name, maxlen);
1187  }
1188 }
1189 
1190 /* generic search invoke */
1191 static void node_find_update_fn(const struct bContext *C,
1192  void *UNUSED(arg),
1193  const char *str,
1194  uiSearchItems *items,
1195  const bool UNUSED(is_first))
1196 {
1197  SpaceNode *snode = CTX_wm_space_node(C);
1198 
1199  StringSearch *search = BLI_string_search_new();
1200 
1201  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1202  char name[256];
1203  node_find_create_label(node, name, ARRAY_SIZE(name));
1204  BLI_string_search_add(search, name, node);
1205  }
1206 
1207  bNode **filtered_nodes;
1208  int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_nodes);
1209 
1210  for (int i = 0; i < filtered_amount; i++) {
1211  bNode *node = filtered_nodes[i];
1212  char name[256];
1213  node_find_create_label(node, name, ARRAY_SIZE(name));
1214  if (!UI_search_item_add(items, name, node, ICON_NONE, 0, 0)) {
1215  break;
1216  }
1217  }
1218 
1219  MEM_freeN(filtered_nodes);
1220  BLI_string_search_free(search);
1221 }
1222 
1223 static void node_find_exec_fn(struct bContext *C, void *UNUSED(arg1), void *arg2)
1224 {
1225  SpaceNode *snode = CTX_wm_space_node(C);
1226  bNode *active = arg2;
1227 
1228  if (active) {
1229  ARegion *region = CTX_wm_region(C);
1231 
1232  /* is note outside view? */
1233  if (active->totr.xmax < region->v2d.cur.xmin || active->totr.xmin > region->v2d.cur.xmax ||
1234  active->totr.ymax < region->v2d.cur.ymin || active->totr.ymin > region->v2d.cur.ymax) {
1235  space_node_view_flag(C, snode, region, NODE_SELECT, U.smooth_viewtx);
1236  }
1237  }
1238 }
1239 
1240 static uiBlock *node_find_menu(bContext *C, ARegion *region, void *arg_op)
1241 {
1242  static char search[256] = "";
1243  uiBlock *block;
1244  uiBut *but;
1245  wmOperator *op = (wmOperator *)arg_op;
1246 
1247  block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
1250 
1251  but = uiDefSearchBut(block,
1252  search,
1253  0,
1254  ICON_VIEWZOOM,
1255  sizeof(search),
1256  10,
1257  10,
1259  UI_UNIT_Y,
1260  0,
1261  0,
1262  "");
1264  but, NULL, node_find_update_fn, op->type, false, NULL, node_find_exec_fn, NULL);
1266 
1267  /* fake button, it holds space for search items */
1268  uiDefBut(block,
1270  0,
1271  "",
1272  10,
1273  10 - UI_searchbox_size_y(),
1276  NULL,
1277  0,
1278  0,
1279  0,
1280  0,
1281  NULL);
1282 
1283  /* Move it downwards, mouse over button. */
1284  UI_block_bounds_set_popup(block, 0.3f * U.widget_unit, (const int[2]){0, -UI_UNIT_Y});
1285 
1286  return block;
1287 }
1288 
1289 static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1290 {
1292  return OPERATOR_CANCELLED;
1293 }
1294 
1296 {
1297  /* identifiers */
1298  ot->name = "Find Node";
1299  ot->description = "Search for a node by name and focus and select it";
1300  ot->idname = "NODE_OT_find_node";
1301 
1302  /* api callbacks */
1305 
1306  /* flags */
1308 
1309  RNA_def_boolean(ot->srna, "prev", 0, "Previous", "");
1310 }
1311 
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct SpaceNode * CTX_wm_space_node(const bContext *C)
Definition: context.c:854
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
bool nodeLinkIsHidden(const struct bNodeLink *link)
struct bNode * nodeGetActive(struct bNodeTree *ntree)
Definition: node.cc:3561
void nodeSetSelected(struct bNode *node, bool select)
Definition: node.cc:3664
#define NODE_FRAME
Definition: BKE_node.h:872
void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist, int *r_deplist_len)
Definition: node.cc:4107
struct bScreen * BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHook *hook) GETTER_ATTRS
void BLI_lasso_boundbox(struct rcti *rect, const int mcoords[][2], const unsigned int mcoords_len)
Definition: lasso_2d.c:31
bool BLI_lasso_is_point_inside(const int mcoords[][2], const unsigned int mcoords_len, const int sx, const int sy, const int error_value)
Definition: lasso_2d.c:54
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
MINLINE bool compare_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
Definition: BLI_rect.h:148
bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest)
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
Definition: BLI_rect.h:144
bool BLI_rctf_isect_circle(const struct rctf *rect, const float xy[2], const float radius)
bool BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b)
Definition: rct.c:221
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
void BLI_string_search_free(StringSearch *search)
void BLI_string_search_add(StringSearch *search, const char *str, void *user_data)
StringSearch * BLI_string_search_new(void)
int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data)
size_t BLI_str_partition_ex_utf8(const char *str, const char *end, const unsigned int delim[], const char **sep, const char **suf, const bool from_right) ATTR_NONNULL(1
unsigned int uint
Definition: BLI_sys_types.h:83
#define ARRAY_SIZE(arr)
#define STREQLEN(a, b, n)
#define UNUSED(x)
#define STREQ(a, b)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
#define NODE_TEST
@ SOCK_OUT
@ SOCK_IN
#define NODE_SELECT
#define NODE_ACTIVE
@ SPACE_VIEW3D
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_node_sort(struct bNodeTree *ntree)
Definition: node_draw.cc:253
void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node, bool *r_active_texture_changed)
Definition: node_edit.c:665
void ED_node_select_all(ListBase *lb, int action)
Definition: node_edit.c:1370
void ED_node_set_active_viewer_key(struct SpaceNode *snode)
Definition: space_node.c:225
bool ED_operator_node_active(struct bContext *C)
Definition: screen_ops.c:292
#define SEL_OP_USE_PRE_DESELECT(sel_op)
@ SEL_DESELECT
eSelectOp ED_select_op_modal(const eSelectOp sel_op, const bool is_first)
Definition: select_utils.c:77
eSelectOp
@ SEL_OP_SUB
bool ED_view3d_has_workbench_in_texture_color(const struct Scene *scene, const struct Object *ob, const struct View3D *v3d)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
#define UI_UNIT_Y
int UI_searchbox_size_x(void)
@ UI_EMBOSS
Definition: UI_interface.h:107
void UI_block_theme_style_set(uiBlock *block, char theme_style)
Definition: interface.c:3547
int UI_searchbox_size_y(void)
@ UI_BUT_ACTIVATE_ON_INIT
Definition: UI_interface.h:222
uiBut * uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:4687
void UI_block_bounds_set_popup(uiBlock *block, int addval, const int bounds_offset[2])
Definition: interface.c:598
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int state, const uint8_t name_prefix_offset)
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, const bool free_arg, uiButSearchArgFreeFn search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
Definition: interface.c:6613
void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg, void(*arg_free)(void *arg))
@ UI_BLOCK_SEARCH_MENU
Definition: UI_interface.h:152
@ UI_BLOCK_LOOP
Definition: UI_interface.h:140
@ UI_BLOCK_MOVEMOUSE_QUIT
Definition: UI_interface.h:148
uiBlock * UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, eUIEmbossType emboss)
uiBut * uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x, int y, short width, short height, float a1, float a2, const char *tip)
Definition: interface.c:6573
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.c:6067
@ UI_BTYPE_LABEL
Definition: UI_interface.h:358
@ UI_BLOCK_THEME_STYLE_POPUP
Definition: UI_interface.h:671
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.c:6077
void UI_view2d_region_to_view_rctf(const struct View2D *v2d, const struct rctf *rect_src, struct rctf *rect_dst) ATTR_NONNULL()
bool UI_view2d_view_to_region_clip(const struct View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL()
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
#define NC_NODE
Definition: WM_types.h:295
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define NA_SELECTED
Definition: WM_types.h:467
unsigned int U
Definition: btGjkEpa3.h:78
#define SELECT
OperationNode * node
Scene scene
bNodeTree * ntree
#define str(s)
static bool is_inside(int x, int y, int cols, int rows)
Definition: filesel.c:663
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
static unsigned a[3]
Definition: RandGen.cpp:92
static void area(int d1, int d2, int e1, int e2, float weights[2])
bool active
all scheduled work for the GPU.
int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, const float cursor[2], int in_out)
Definition: node_edit.c:1149
int space_node_view_flag(struct bContext *C, struct SpaceNode *snode, ARegion *region, const int node_flag, const int smooth_viewtx)
Definition: node_view.c:61
static int node_circleselect_exec(bContext *C, wmOperator *op)
Definition: node_select.c:757
static bNode * node_under_mouse_tweak(bNodeTree *ntree, int mx, int my)
Definition: node_select.c:113
void node_deselect_all(SpaceNode *snode)
Definition: node_select.c:204
static bool do_lasso_select_node(bContext *C, const int mcoords[][2], const int mcoords_len, eSelectOp sel_op)
Definition: node_select.c:833
static bool node_select_grouped_type(SpaceNode *snode, bNode *node_act)
Definition: node_select.c:287
void node_select_single(bContext *C, bNode *node)
Definition: node_select.c:454
static uiBlock * node_find_menu(bContext *C, ARegion *region, void *arg_op)
Definition: node_select.c:1240
void NODE_OT_select_grouped(wmOperatorType *ot)
Definition: node_select.c:416
static int node_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: node_select.c:711
void node_socket_select(bNode *node, bNodeSocket *sock)
Definition: node_select.c:156
void node_deselect_all_input_sockets(SpaceNode *snode, const bool deselect_nodes)
Definition: node_select.c:213
static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_select.c:1022
static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: node_select.c:1289
static bool has_workbench_in_texture_color(const wmWindowManager *wm, const Scene *scene, const Object *ob)
Definition: node_select.c:73
static int node_box_select_exec(bContext *C, wmOperator *op)
Definition: node_select.c:675
void NODE_OT_select_linked_to(wmOperatorType *ot)
Definition: node_select.c:1001
static void node_socket_toggle(bNode *node, bNodeSocket *sock, int deselect_node)
Definition: node_select.c:193
void NODE_OT_select_linked_from(wmOperatorType *ot)
Definition: node_select.c:1053
static bool is_event_over_node_or_socket(bContext *C, const wmEvent *event)
Definition: node_select.c:142
static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
Definition: node_select.c:1074
void node_deselect_all_output_sockets(SpaceNode *snode, const bool deselect_nodes)
Definition: node_select.c:246
void NODE_OT_select_box(wmOperatorType *ot)
Definition: node_select.c:722
static void node_toggle(bNode *node)
Definition: node_select.c:151
static void node_find_create_label(const bNode *node, char *str, int maxlen)
Definition: node_select.c:1180
static int node_mouse_select(bContext *C, wmOperator *op, const int mval[2], bool wait_to_deselect_others)
Definition: node_select.c:482
@ NODE_SELECT_GROUPED_COLOR
Definition: node_select.c:364
@ NODE_SELECT_GROUPED_PREFIX
Definition: node_select.c:365
@ NODE_SELECT_GROUPED_SUFIX
Definition: node_select.c:366
@ NODE_SELECT_GROUPED_TYPE
Definition: node_select.c:363
void NODE_OT_find_node(wmOperatorType *ot)
Definition: node_select.c:1295
static int node_select_exec(bContext *C, wmOperator *op)
Definition: node_select.c:623
void NODE_OT_select(wmOperatorType *ot)
Definition: node_select.c:639
static bool node_select_grouped_color(SpaceNode *snode, bNode *node_act)
Definition: node_select.c:304
static void node_find_update_fn(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items, const bool UNUSED(is_first))
Definition: node_select.c:1191
void NODE_OT_select_lasso(wmOperatorType *ot)
Definition: node_select.c:899
static int node_select_grouped_exec(bContext *C, wmOperator *op)
Definition: node_select.c:369
void NODE_OT_select_same_type_step(wmOperatorType *ot)
Definition: node_select.c:1157
static bNode * node_under_mouse_select(bNodeTree *ntree, int mx, int my)
Definition: node_select.c:99
static void node_find_exec_fn(struct bContext *C, void *UNUSED(arg1), void *arg2)
Definition: node_select.c:1223
static int node_lasso_select_exec(bContext *C, wmOperator *op)
Definition: node_select.c:882
void NODE_OT_select_circle(wmOperatorType *ot)
Definition: node_select.c:794
void node_socket_deselect(bNode *node, bNodeSocket *sock, const bool deselect_node)
Definition: node_select.c:166
static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_select.c:970
static bool is_position_over_node_or_socket(SpaceNode *snode, float mouse[2])
Definition: node_select.c:127
static int node_select_all_exec(bContext *C, wmOperator *op)
Definition: node_select.c:933
void NODE_OT_select_all(wmOperatorType *ot)
Definition: node_select.c:947
static int node_lasso_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: node_select.c:822
static bool node_select_grouped_name(SpaceNode *snode, bNode *node_act, const bool from_right)
Definition: node_select.c:321
static const EnumPropertyItem prop_select_grouped_types[]
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
struct bNodeTree * edittree
struct bNodeSocket * next
ListBase nodes
ListBase links
float color[3]
char name[64]
short type
struct bNode * next
ListBase outputs
ListBase areabase
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int mval[2]
Definition: WM_types.h:583
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct wmOperatorType * type
struct PointerRNA * ptr
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156
bool WM_gesture_is_modal_first(const wmGesture *gesture)
Definition: wm_gesture.c:124
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const int(* WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *r_mcoords_len))[2]
void WM_operator_properties_gesture_box(wmOperatorType *ot)
void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
void WM_operator_properties_generic_select(wmOperatorType *ot)
void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
void WM_operator_properties_gesture_circle(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
void WM_operator_properties_border_to_rctf(struct wmOperator *op, rctf *rect)
int WM_operator_smooth_viewtx_get(const wmOperator *op)
Definition: wm_operators.c:944
int WM_generic_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: wm_operators.c:905
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982
int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: wm_operators.c:838