Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_node / space_node.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
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_node/space_node.c
28  *  \ingroup spnode
29  */
30
31 #include "DNA_gpencil_types.h"
32 #include "DNA_lamp_types.h"
33 #include "DNA_material_types.h"
34 #include "DNA_node_types.h"
35 #include "DNA_world_types.h"
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_math.h"
41
42 #include "BKE_context.h"
43 #include "BKE_library.h"
44 #include "BKE_scene.h"
45 #include "BKE_screen.h"
46 #include "BKE_node.h"
47
48 #include "ED_space_api.h"
49 #include "ED_node.h"
50 #include "ED_render.h"
51 #include "ED_screen.h"
52 #include "WM_api.h"
53 #include "WM_types.h"
54
55 #include "UI_resources.h"
56 #include "UI_view2d.h"
57
58 #include "RNA_access.h"
59
60 #include "WM_api.h"
61
62 #include "node_intern.h"  /* own include */
63
64
65 /* ******************** tree path ********************* */
66
67 void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from)
68 {
69         bNodeTreePath *path, *path_next;
70         for (path = snode->treepath.first; path; path = path_next) {
71                 path_next = path->next;
72                 MEM_freeN(path);
73         }
74         BLI_listbase_clear(&snode->treepath);
75         
76         if (ntree) {
77                 path = MEM_callocN(sizeof(bNodeTreePath), "node tree path");
78                 path->nodetree = ntree;
79                 path->parent_key = NODE_INSTANCE_KEY_BASE;
80                 
81                 /* copy initial offset from bNodeTree */
82                 copy_v2_v2(path->view_center, ntree->view_center);
83                 
84                 if (id)
85                         BLI_strncpy(path->node_name, id->name + 2, sizeof(path->node_name));
86                 
87                 BLI_addtail(&snode->treepath, path);
88                 
89                 id_us_ensure_real(&ntree->id);
90         }
91         
92         /* update current tree */
93         snode->nodetree = snode->edittree = ntree;
94         snode->id = id;
95         snode->from = from;
96         
97         ED_node_set_active_viewer_key(snode);
98         
99         WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
100 }
101
102 void ED_node_tree_push(SpaceNode *snode, bNodeTree *ntree, bNode *gnode)
103 {
104         bNodeTreePath *path = MEM_callocN(sizeof(bNodeTreePath), "node tree path");
105         bNodeTreePath *prev_path = snode->treepath.last;
106         path->nodetree = ntree;
107         if (gnode) {
108                 if (prev_path)
109                         path->parent_key = BKE_node_instance_key(prev_path->parent_key, prev_path->nodetree, gnode);
110                 else
111                         path->parent_key = NODE_INSTANCE_KEY_BASE;
112                 
113                 BLI_strncpy(path->node_name, gnode->name, sizeof(path->node_name));
114         }
115         else
116                 path->parent_key = NODE_INSTANCE_KEY_BASE;
117         
118         /* copy initial offset from bNodeTree */
119         copy_v2_v2(path->view_center, ntree->view_center);
120         
121         BLI_addtail(&snode->treepath, path);
122         
123         id_us_ensure_real(&ntree->id);
124         
125         /* update current tree */
126         snode->edittree = ntree;
127         
128         ED_node_set_active_viewer_key(snode);
129         
130         WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
131 }
132
133 void ED_node_tree_pop(SpaceNode *snode)
134 {
135         bNodeTreePath *path = snode->treepath.last;
136         
137         /* don't remove root */
138         if (path == snode->treepath.first)
139                 return;
140         
141         BLI_remlink(&snode->treepath, path);
142         MEM_freeN(path);
143         
144         /* update current tree */
145         path = snode->treepath.last;
146         snode->edittree = path->nodetree;
147         
148         ED_node_set_active_viewer_key(snode);
149         
150         /* listener updates the View2D center from edittree */
151         WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
152 }
153
154 int ED_node_tree_depth(SpaceNode *snode)
155 {
156         return BLI_listbase_count(&snode->treepath);
157 }
158
159 bNodeTree *ED_node_tree_get(SpaceNode *snode, int level)
160 {
161         bNodeTreePath *path;
162         int i;
163         for (path = snode->treepath.last, i = 0; path; path = path->prev, ++i) {
164                 if (i == level)
165                         return path->nodetree;
166         }
167         return NULL;
168 }
169
170 int ED_node_tree_path_length(SpaceNode *snode)
171 {
172         bNodeTreePath *path;
173         int length = 0;
174         int i;
175         for (path = snode->treepath.first, i = 0; path; path = path->next, ++i) {
176                 length += strlen(path->node_name);
177                 if (i > 0)
178                         length += 1;    /* for separator char */
179         }
180         return length;
181 }
182
183 void ED_node_tree_path_get(SpaceNode *snode, char *value)
184 {
185         bNodeTreePath *path;
186         int i;
187         
188         value[0] = '\0';
189         for (path = snode->treepath.first, i = 0; path; path = path->next, ++i) {
190                 if (i == 0) {
191                         strcpy(value, path->node_name);
192                         value += strlen(path->node_name);
193                 }
194                 else {
195                         sprintf(value, "/%s", path->node_name);
196                         value += strlen(path->node_name) + 1;
197                 }
198         }
199 }
200
201 void ED_node_tree_path_get_fixedbuf(SpaceNode *snode, char *value, int max_length)
202 {
203         bNodeTreePath *path;
204         int size, i;
205         
206         value[0] = '\0';
207         for (path = snode->treepath.first, i = 0; path; path = path->next, ++i) {
208                 if (i == 0) {
209                         size = BLI_strncpy_rlen(value, path->node_name, max_length);
210                 }
211                 else {
212                         size = BLI_snprintf_rlen(value, max_length, "/%s", path->node_name);
213                 }
214                 max_length -= size;
215                 if (max_length <= 0)
216                         break;
217                 value += size;
218         }
219 }
220
221 void ED_node_set_active_viewer_key(SpaceNode *snode)
222 {
223         bNodeTreePath *path = snode->treepath.last;
224         if (snode->nodetree && path) {
225                 snode->nodetree->active_viewer_key = path->parent_key;
226         }
227 }
228
229 void snode_group_offset(SpaceNode *snode, float *x, float *y)
230 {
231         bNodeTreePath *path = snode->treepath.last;
232         
233         if (path && path->prev) {
234                 float dcenter[2];
235                 sub_v2_v2v2(dcenter, path->view_center, path->prev->view_center);
236                 *x = dcenter[0];
237                 *y = dcenter[1];
238         }
239         else
240                 *x = *y = 0.0f;
241 }
242
243 /* ******************** manage regions ********************* */
244
245 ARegion *node_has_buttons_region(ScrArea *sa)
246 {
247         ARegion *ar, *arnew;
248
249         ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
250         if (ar) return ar;
251
252         /* add subdiv level; after header */
253         ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
254
255         /* is error! */
256         if (ar == NULL) return NULL;
257
258         arnew = MEM_callocN(sizeof(ARegion), "buttons for node");
259
260         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
261         arnew->regiontype = RGN_TYPE_UI;
262         arnew->alignment = RGN_ALIGN_RIGHT;
263
264         arnew->flag = RGN_FLAG_HIDDEN;
265
266         return arnew;
267 }
268
269 ARegion *node_has_tools_region(ScrArea *sa)
270 {
271         ARegion *ar, *arnew;
272         
273         ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
274         if (ar) return ar;
275         
276         /* add subdiv level; after header */
277         ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
278         
279         /* is error! */
280         if (ar == NULL) return NULL;
281         
282         arnew = MEM_callocN(sizeof(ARegion), "node tools");
283         
284         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
285         arnew->regiontype = RGN_TYPE_TOOLS;
286         arnew->alignment = RGN_ALIGN_LEFT;
287         
288         arnew->flag = RGN_FLAG_HIDDEN;
289         
290         return arnew;
291 }
292
293 /* ******************** default callbacks for node space ***************** */
294
295 static SpaceLink *node_new(const bContext *UNUSED(C))
296 {
297         ARegion *ar;
298         SpaceNode *snode;
299
300         snode = MEM_callocN(sizeof(SpaceNode), "initnode");
301         snode->spacetype = SPACE_NODE;
302
303         snode->flag = SNODE_SHOW_GPENCIL | SNODE_USE_ALPHA;
304
305         /* backdrop */
306         snode->zoom = 1.0f;
307
308         /* select the first tree type for valid type */
309         NODE_TREE_TYPES_BEGIN (treetype)
310         {
311                 strcpy(snode->tree_idname, treetype->idname);
312                 break;
313         }
314         NODE_TREE_TYPES_END;
315
316         /* header */
317         ar = MEM_callocN(sizeof(ARegion), "header for node");
318
319         BLI_addtail(&snode->regionbase, ar);
320         ar->regiontype = RGN_TYPE_HEADER;
321         ar->alignment = RGN_ALIGN_BOTTOM;
322
323         /* buttons/list view */
324         ar = MEM_callocN(sizeof(ARegion), "buttons for node");
325
326         BLI_addtail(&snode->regionbase, ar);
327         ar->regiontype = RGN_TYPE_UI;
328         ar->alignment = RGN_ALIGN_RIGHT;
329
330         /* toolbar */
331         ar = MEM_callocN(sizeof(ARegion), "node tools");
332
333         BLI_addtail(&snode->regionbase, ar);
334         ar->regiontype = RGN_TYPE_TOOLS;
335         ar->alignment = RGN_ALIGN_LEFT;
336
337         ar->flag = RGN_FLAG_HIDDEN;
338
339         /* main region */
340         ar = MEM_callocN(sizeof(ARegion), "main region for node");
341
342         BLI_addtail(&snode->regionbase, ar);
343         ar->regiontype = RGN_TYPE_WINDOW;
344
345         ar->v2d.tot.xmin =  -12.8f * U.widget_unit;
346         ar->v2d.tot.ymin =  -12.8f * U.widget_unit;
347         ar->v2d.tot.xmax = 38.4f * U.widget_unit;
348         ar->v2d.tot.ymax = 38.4f * U.widget_unit;
349
350         ar->v2d.cur =  ar->v2d.tot;
351
352         ar->v2d.min[0] = 1.0f;
353         ar->v2d.min[1] = 1.0f;
354
355         ar->v2d.max[0] = 32000.0f;
356         ar->v2d.max[1] = 32000.0f;
357
358         ar->v2d.minzoom = 0.09f;
359         ar->v2d.maxzoom = 2.31f;
360
361         ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
362         ar->v2d.keepzoom = V2D_LIMITZOOM | V2D_KEEPASPECT;
363         ar->v2d.keeptot = 0;
364
365         return (SpaceLink *)snode;
366 }
367
368 static void node_free(SpaceLink *sl)
369 {
370         SpaceNode *snode = (SpaceNode *)sl;
371         bNodeTreePath *path, *path_next;
372
373         for (path = snode->treepath.first; path; path = path_next) {
374                 path_next = path->next;
375                 MEM_freeN(path);
376         }
377 }
378
379
380 /* spacetype; init callback */
381 static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
382 {
383
384 }
385
386 static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, const Scene *scene)
387 {
388         /* note, ED_area_tag_refresh will re-execute compositor */
389         SpaceNode *snode = sa->spacedata.first;
390         /* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */
391         short shader_type = BKE_scene_use_new_shading_nodes(scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT;
392
393         /* preview renders */
394         switch (wmn->category) {
395                 case NC_SCENE:
396                         switch (wmn->data) {
397                                 case ND_NODES:
398                                 {
399                                         ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
400                                         bNodeTreePath *path = snode->treepath.last;
401                                         /* shift view to node tree center */
402                                         if (ar && path)
403                                                 UI_view2d_center_set(&ar->v2d, path->view_center[0], path->view_center[1]);
404                                         
405                                         ED_area_tag_refresh(sa);
406                                         break;
407                                 }
408                                 case ND_FRAME:
409                                         ED_area_tag_refresh(sa);
410                                         break;
411                                 case ND_COMPO_RESULT:
412                                         ED_area_tag_redraw(sa);
413                                         break;
414                                 case ND_TRANSFORM_DONE:
415                                         if (ED_node_is_compositor(snode)) {
416                                                 if (snode->flag & SNODE_AUTO_RENDER) {
417                                                         snode->recalc = 1;
418                                                         ED_area_tag_refresh(sa);
419                                                 }
420                                         }
421                                         break;
422                                 case ND_LAYER_CONTENT:
423                                         ED_area_tag_refresh(sa);
424                                         break;
425                         }
426                         break;
427
428                 /* future: add ID checks? */
429                 case NC_MATERIAL:
430                         if (ED_node_is_shader(snode)) {
431                                 if (wmn->data == ND_SHADING)
432                                         ED_area_tag_refresh(sa);
433                                 else if (wmn->data == ND_SHADING_DRAW)
434                                         ED_area_tag_refresh(sa);
435                                 else if (wmn->data == ND_SHADING_LINKS)
436                                         ED_area_tag_refresh(sa);
437                                 else if (wmn->action == NA_ADDED && snode->edittree)
438                                         nodeSetActiveID(snode->edittree, ID_MA, wmn->reference);
439
440                         }
441                         break;
442                 case NC_TEXTURE:
443                         if (ED_node_is_shader(snode) || ED_node_is_texture(snode)) {
444                                 if (wmn->data == ND_NODES)
445                                         ED_area_tag_refresh(sa);
446                         }
447                         break;
448                 case NC_WORLD:
449                         if (ED_node_is_shader(snode) && shader_type == SNODE_SHADER_WORLD) {
450                                 ED_area_tag_refresh(sa);
451                         }
452                         break;
453                 case NC_OBJECT:
454                         if (ED_node_is_shader(snode)) {
455                                 if (wmn->data == ND_OB_SHADING)
456                                         ED_area_tag_refresh(sa);
457                         }
458                         break;
459                 case NC_SPACE:
460                         if (wmn->data == ND_SPACE_NODE)
461                                 ED_area_tag_refresh(sa);
462                         else if (wmn->data == ND_SPACE_NODE_VIEW)
463                                 ED_area_tag_redraw(sa);
464                         break;
465                 case NC_NODE:
466                         if (wmn->action == NA_EDITED)
467                                 ED_area_tag_refresh(sa);
468                         else if (wmn->action == NA_SELECTED)
469                                 ED_area_tag_redraw(sa);
470                         break;
471                 case NC_SCREEN:
472                         switch (wmn->data) {
473                                 case ND_ANIMPLAY:
474                                         ED_area_tag_refresh(sa);
475                                         break;
476                         }
477                         break;
478                 case NC_MASK:
479                         if (wmn->action == NA_EDITED) {
480                                 if (snode->nodetree && snode->nodetree->type == NTREE_COMPOSIT) {
481                                         ED_area_tag_refresh(sa);
482                                 }
483                         }
484                         break;
485
486                 case NC_IMAGE:
487                         if (wmn->action == NA_EDITED) {
488                                 if (ED_node_is_compositor(snode)) {
489                                         /* note that nodeUpdateID is already called by BKE_image_signal() on all
490                                          * scenes so really this is just to know if the images is used in the compo else
491                                          * painting on images could become very slow when the compositor is open. */
492                                         if (nodeUpdateID(snode->nodetree, wmn->reference))
493                                                 ED_area_tag_refresh(sa);
494                                 }
495                         }
496                         break;
497
498                 case NC_MOVIECLIP:
499                         if (wmn->action == NA_EDITED) {
500                                 if (ED_node_is_compositor(snode)) {
501                                         if (nodeUpdateID(snode->nodetree, wmn->reference))
502                                                 ED_area_tag_refresh(sa);
503                                 }
504                         }
505                         break;
506
507                 case NC_LINESTYLE:
508                         if (ED_node_is_shader(snode) && shader_type == SNODE_SHADER_LINESTYLE) {
509                                 ED_area_tag_refresh(sa);
510                         }
511                         break;
512                 case NC_WM:
513                         if (wmn->data == ND_UNDO) {
514                                 ED_area_tag_refresh(sa);
515                         }
516                         break;
517                 case NC_GPENCIL:
518                         if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
519                                 ED_area_tag_redraw(sa);
520                         }
521                         break;
522         }
523 }
524
525 static void node_area_refresh(const struct bContext *C, ScrArea *sa)
526 {
527         /* default now: refresh node is starting preview */
528         SpaceNode *snode = sa->spacedata.first;
529         
530         snode_set_context(C);
531
532         if (snode->nodetree) {
533                 if (snode->nodetree->type == NTREE_SHADER) {
534                         if (GS(snode->id->name) == ID_MA) {
535                                 Material *ma = (Material *)snode->id;
536                                 if (ma->use_nodes)
537                                         ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
538                         }
539                         else if (GS(snode->id->name) == ID_LA) {
540                                 Lamp *la = (Lamp *)snode->id;
541                                 if (la->use_nodes)
542                                         ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
543                         }
544                         else if (GS(snode->id->name) == ID_WO) {
545                                 World *wo = (World *)snode->id;
546                                 if (wo->use_nodes)
547                                         ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
548                         }
549                 }
550                 else if (snode->nodetree->type == NTREE_COMPOSIT) {
551                         Scene *scene = (Scene *)snode->id;
552                         if (scene->use_nodes) {
553                                 /* recalc is set on 3d view changes for auto compo */
554                                 if (snode->recalc) {
555                                         snode->recalc = 0;
556                                         node_render_changed_exec((struct bContext *)C, NULL);
557                                 }
558                                 else {
559                                         ED_node_composite_job(C, snode->nodetree, scene);
560                                 }
561                         }
562                 }
563                 else if (snode->nodetree->type == NTREE_TEXTURE) {
564                         Tex *tex = (Tex *)snode->id;
565                         if (tex->use_nodes) {
566                                 ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER);
567                         }
568                 }
569         }
570 }
571
572 static SpaceLink *node_duplicate(SpaceLink *sl)
573 {
574         SpaceNode *snode = (SpaceNode *)sl;
575         SpaceNode *snoden = MEM_dupallocN(snode);
576
577         BLI_duplicatelist(&snoden->treepath, &snode->treepath);
578
579         /* clear or remove stuff from old */
580         BLI_listbase_clear(&snoden->linkdrag);
581
582         /* Note: no need to set node tree user counts,
583          * the editor only keeps at least 1 (id_us_ensure_real),
584          * which is already done by the original SpaceNode.
585          */
586
587         return (SpaceLink *)snoden;
588 }
589
590
591 /* add handlers, stuff you only do once or on area/region changes */
592 static void node_buttons_region_init(wmWindowManager *wm, ARegion *ar)
593 {
594         wmKeyMap *keymap;
595
596         ED_region_panels_init(wm, ar);
597
598         keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0);
599         WM_event_add_keymap_handler(&ar->handlers, keymap);
600 }
601
602 static void node_buttons_region_draw(const bContext *C, ARegion *ar)
603 {
604         ED_region_panels(C, ar, NULL, -1, true);
605 }
606
607 /* add handlers, stuff you only do once or on area/region changes */
608 static void node_toolbar_region_init(wmWindowManager *wm, ARegion *ar)
609 {
610         wmKeyMap *keymap;
611
612         ED_region_panels_init(wm, ar);
613
614         keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0);
615         WM_event_add_keymap_handler(&ar->handlers, keymap);
616 }
617
618 static void node_toolbar_region_draw(const bContext *C, ARegion *ar)
619 {
620         ED_region_panels(C, ar, NULL, -1, true);
621 }
622
623 static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
624 {
625         SpaceNode *snode = sa->spacedata.first;
626
627         /* convert mouse coordinates to v2d space */
628         UI_view2d_region_to_view(&ar->v2d, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin,
629                                  &snode->cursor[0], &snode->cursor[1]);
630         
631         /* here snode->cursor is used to detect the node edge for sizing */
632         node_set_cursor(win, snode, snode->cursor);
633
634         /* XXX snode->cursor is in placing new nodes space */
635         snode->cursor[0] /= UI_DPI_FAC;
636         snode->cursor[1] /= UI_DPI_FAC;
637         
638 }
639
640 /* Initialize main region, setting handlers. */
641 static void node_main_region_init(wmWindowManager *wm, ARegion *ar)
642 {
643         wmKeyMap *keymap;
644         ListBase *lb;
645
646         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
647
648         /* manipulators stay in the background for now - quick patchjob to make sure nodes themselves work */
649         if (ar->manipulator_map == NULL) {
650                 ar->manipulator_map = WM_manipulatormap_new_from_type(
651                         &(const struct wmManipulatorMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW});
652         }
653
654         WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
655
656         /* own keymaps */
657         keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0);
658         WM_event_add_keymap_handler(&ar->handlers, keymap);
659
660         keymap = WM_keymap_find(wm->defaultconf, "Node Editor", SPACE_NODE, 0);
661         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
662
663         /* add drop boxes */
664         lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW);
665
666         WM_event_add_dropbox_handler(&ar->handlers, lb);
667 }
668
669 static void node_main_region_draw(const bContext *C, ARegion *ar)
670 {
671         drawnodespace(C, ar);
672 }
673
674
675 /* ************* dropboxes ************* */
676
677 static int node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
678 {
679         if (drag->type == WM_DRAG_ID) {
680                 ID *id = drag->poin;
681                 if (GS(id->name) == ID_IM)
682                         return 1;
683         }
684         else if (drag->type == WM_DRAG_PATH) {
685                 if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE))   /* rule might not work? */
686                         return 1;
687         }
688         return 0;
689 }
690
691 static int node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
692 {
693         if (drag->type == WM_DRAG_ID) {
694                 ID *id = drag->poin;
695                 if (GS(id->name) == ID_MSK)
696                         return 1;
697         }
698         return 0;
699 }
700
701 static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
702 {
703         ID *id = drag->poin;
704
705         RNA_string_set(drop->ptr, "name", id->name + 2);
706 }
707
708 static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
709 {
710         ID *id = drag->poin;
711
712         if (id) {
713                 RNA_string_set(drop->ptr, "name", id->name + 2);
714                 RNA_struct_property_unset(drop->ptr, "filepath");
715         }
716         else if (drag->path[0]) {
717                 RNA_string_set(drop->ptr, "filepath", drag->path);
718                 RNA_struct_property_unset(drop->ptr, "name");
719         }
720 }
721
722 /* this region dropbox definition */
723 static void node_dropboxes(void)
724 {
725         ListBase *lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW);
726
727         WM_dropbox_add(lb, "NODE_OT_add_file", node_ima_drop_poll, node_id_path_drop_copy);
728         WM_dropbox_add(lb, "NODE_OT_add_mask", node_mask_drop_poll, node_id_drop_copy);
729
730 }
731
732 /* ************* end drop *********** */
733
734
735 /* add handlers, stuff you only do once or on area/region changes */
736 static void node_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
737 {
738         ED_region_header_init(ar);
739 }
740
741 static void node_header_region_draw(const bContext *C, ARegion *ar)
742 {
743         /* find and set the context */
744         snode_set_context(C);
745
746         ED_region_header(C, ar);
747 }
748
749 /* used for header + main region */
750 static void node_region_listener(
751         bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
752         wmNotifier *wmn, const Scene *UNUSED(scene))
753 {
754         wmManipulatorMap *mmap = ar->manipulator_map;
755
756         /* context changes */
757         switch (wmn->category) {
758                 case NC_SPACE:
759                         switch (wmn->data) {
760                                 case ND_SPACE_NODE:
761                                         ED_region_tag_redraw(ar);
762                                         break;
763                                 case ND_SPACE_NODE_VIEW:
764                                         WM_manipulatormap_tag_refresh(mmap);
765                                         break;
766                         }
767                         break;
768                 case NC_SCREEN:
769                         if (wmn->data == ND_LAYOUTSET || wmn->action == NA_EDITED) {
770                                 WM_manipulatormap_tag_refresh(mmap);
771                         }
772                         switch (wmn->data) {
773                                 case ND_SCREENCAST:
774                                 case ND_ANIMPLAY:
775                                 case ND_LAYER:
776                                         ED_region_tag_redraw(ar);
777                                         break;
778                         }
779                         break;
780                 case NC_WM:
781                         if (wmn->data == ND_JOB)
782                                 ED_region_tag_redraw(ar);
783                         break;
784                 case NC_SCENE:
785                         ED_region_tag_redraw(ar);
786                         if (wmn->data == ND_RENDER_RESULT) {
787                                 WM_manipulatormap_tag_refresh(mmap);
788                         }
789                         break;
790                 case NC_NODE:
791                         ED_region_tag_redraw(ar);
792                         if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
793                                 WM_manipulatormap_tag_refresh(mmap);
794                         }
795                         break;
796                 case NC_MATERIAL:
797                 case NC_TEXTURE:
798                 case NC_WORLD:
799                 case NC_LINESTYLE:
800                         ED_region_tag_redraw(ar);
801                         break;
802                 case NC_OBJECT:
803                         if (wmn->data == ND_OB_SHADING)
804                                 ED_region_tag_redraw(ar);
805                         break;
806                 case NC_ID:
807                         if (wmn->action == NA_RENAME)
808                                 ED_region_tag_redraw(ar);
809                         break;
810                 case NC_GPENCIL:
811                         if (wmn->action == NA_EDITED)
812                                 ED_region_tag_redraw(ar);
813                         else if (wmn->data & ND_GPENCIL_EDITMODE)
814                                 ED_region_tag_redraw(ar);
815                         break;
816         }
817 }
818
819 const char *node_context_dir[] = {"selected_nodes", "active_node", NULL};
820
821 static int node_context(const bContext *C, const char *member, bContextDataResult *result)
822 {
823         SpaceNode *snode = CTX_wm_space_node(C);
824
825         if (CTX_data_dir(member)) {
826                 CTX_data_dir_set(result, node_context_dir);
827                 return 1;
828         }
829         else if (CTX_data_equals(member, "selected_nodes")) {
830                 bNode *node;
831
832                 if (snode->edittree) {
833                         for (node = snode->edittree->nodes.last; node; node = node->prev) {
834                                 if (node->flag & NODE_SELECT) {
835                                         CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node);
836                                 }
837                         }
838                 }
839                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
840                 return 1;
841         }
842         else if (CTX_data_equals(member, "active_node")) {
843                 if (snode->edittree) {
844                         bNode *node = nodeGetActive(snode->edittree);
845                         CTX_data_pointer_set(result, &snode->edittree->id, &RNA_Node, node);
846                 }
847
848                 CTX_data_type_set(result, CTX_DATA_TYPE_POINTER);
849                 return 1;
850         }
851         else if (CTX_data_equals(member, "node_previews")) {
852                 if (snode->nodetree) {
853                         CTX_data_pointer_set(result, &snode->nodetree->id, &RNA_NodeInstanceHash, snode->nodetree->previews);
854                 }
855
856                 CTX_data_type_set(result, CTX_DATA_TYPE_POINTER);
857                 return 1;
858         }
859
860         return 0;
861 }
862
863 static void node_widgets(void)
864 {
865         /* create the widgetmap for the area here */
866         wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(
867                 &(const struct wmManipulatorMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW});
868         WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_transform);
869 }
870
871 static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
872 {
873         SpaceNode *snode = (SpaceNode *)slink;
874
875         if (GS(old_id->name) == ID_SCE) {
876                 if (snode->id == old_id) {
877                         /* nasty DNA logic for SpaceNode:
878                          * ideally should be handled by editor code, but would be bad level call
879                          */
880                         BLI_freelistN(&snode->treepath);
881
882                         /* XXX Untested in case new_id != NULL... */
883                         snode->id = new_id;
884                         snode->from = NULL;
885                         snode->nodetree = NULL;
886                         snode->edittree = NULL;
887                 }
888         }
889         else if (GS(old_id->name) == ID_OB) {
890                 if (snode->from == old_id) {
891                         if (new_id == NULL) {
892                                 snode->flag &= ~SNODE_PIN;
893                         }
894                         snode->from = new_id;
895                 }
896         }
897         else if (GS(old_id->name) == ID_GD) {
898                 if ((ID *)snode->gpd == old_id) {
899                         snode->gpd = (bGPdata *)new_id;
900                         id_us_min(old_id);
901                         id_us_plus(new_id);
902                 }
903         }
904         else if (GS(old_id->name) == ID_NT) {
905                 bNodeTreePath *path, *path_next;
906
907                 for (path = snode->treepath.first; path; path = path->next) {
908                         if ((ID *)path->nodetree == old_id) {
909                                 path->nodetree = (bNodeTree *)new_id;
910                                 id_us_min(old_id);
911                                 id_us_plus(new_id);
912                         }
913                         if (path == snode->treepath.first) {
914                                 /* first nodetree in path is same as snode->nodetree */
915                                 snode->nodetree = path->nodetree;
916                         }
917                         if (path->nodetree == NULL) {
918                                 break;
919                         }
920                 }
921
922                 /* remaining path entries are invalid, remove */
923                 for (; path; path = path_next) {
924                         path_next = path->next;
925
926                         BLI_remlink(&snode->treepath, path);
927                         MEM_freeN(path);
928                 }
929
930                 /* edittree is just the last in the path,
931                  * set this directly since the path may have been shortened above */
932                 if (snode->treepath.last) {
933                         path = snode->treepath.last;
934                         snode->edittree = path->nodetree;
935                 }
936                 else {
937                         snode->edittree = NULL;
938                 }
939         }
940 }
941
942 /* only called once, from space/spacetypes.c */
943 void ED_spacetype_node(void)
944 {
945         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype node");
946         ARegionType *art;
947
948         st->spaceid = SPACE_NODE;
949         strncpy(st->name, "Node", BKE_ST_MAXNAME);
950
951         st->new = node_new;
952         st->free = node_free;
953         st->init = node_init;
954         st->duplicate = node_duplicate;
955         st->operatortypes = node_operatortypes;
956         st->keymap = node_keymap;
957         st->listener = node_area_listener;
958         st->refresh = node_area_refresh;
959         st->context = node_context;
960         st->dropboxes = node_dropboxes;
961         st->manipulators = node_widgets;
962         st->id_remap = node_id_remap;
963
964         /* regions: main window */
965         art = MEM_callocN(sizeof(ARegionType), "spacetype node region");
966         art->regionid = RGN_TYPE_WINDOW;
967         art->init = node_main_region_init;
968         art->draw = node_main_region_draw;
969         art->listener = node_region_listener;
970         art->cursor = node_cursor;
971         art->event_cursor = true;
972         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_GPENCIL;
973
974         BLI_addhead(&st->regiontypes, art);
975
976         /* regions: header */
977         art = MEM_callocN(sizeof(ARegionType), "spacetype node region");
978         art->regionid = RGN_TYPE_HEADER;
979         art->prefsizey = HEADERY;
980         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
981         art->listener = node_region_listener;
982         art->init = node_header_region_init;
983         art->draw = node_header_region_draw;
984
985         BLI_addhead(&st->regiontypes, art);
986
987         /* regions: listview/buttons */
988         art = MEM_callocN(sizeof(ARegionType), "spacetype node region");
989         art->regionid = RGN_TYPE_UI;
990         art->prefsizex = 180; // XXX
991         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
992         art->listener = node_region_listener;
993         art->init = node_buttons_region_init;
994         art->draw = node_buttons_region_draw;
995         BLI_addhead(&st->regiontypes, art);
996
997         node_buttons_register(art);
998
999         /* regions: toolbar */
1000         art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
1001         art->regionid = RGN_TYPE_TOOLS;
1002         art->prefsizex = 160; /* XXX */
1003         art->prefsizey = 50; /* XXX */
1004         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
1005         art->listener = node_region_listener;
1006         art->init = node_toolbar_region_init;
1007         art->draw = node_toolbar_region_draw;
1008         BLI_addhead(&st->regiontypes, art);
1009         
1010         node_toolbar_register(art);
1011
1012         BKE_spacetype_register(st);
1013 }
1014