Fix for #34739 and #35060, avoid ambiguity in compositor viewer nodes.
[blender.git] / source / blender / editors / space_node / drawnode.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb, Thomas Dinges
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_node/drawnode.c
29  *  \ingroup spnode
30  *  \brief lower level node drawing for nodes (boarders, headers etc), also node layout.
31  */
32
33 #include "BLI_blenlib.h"
34 #include "BLI_math.h"
35
36 #include "DNA_node_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_space_types.h"
39 #include "DNA_screen_types.h"
40
41 #include "BKE_context.h"
42 #include "BKE_curve.h"
43 #include "BKE_image.h"
44 #include "BKE_main.h"
45 #include "BKE_node.h"
46 #include "BKE_scene.h"
47 #include "BKE_tracking.h"
48
49 #include "BLF_api.h"
50 #include "BLF_translation.h"
51
52 #include "NOD_texture.h"
53
54 #include "BIF_gl.h"
55 #include "BIF_glutil.h"
56
57 #include "BLF_translation.h"
58 #include "MEM_guardedalloc.h"
59
60 #include "RNA_access.h"
61 #include "RNA_define.h"
62 #include "RNA_enum_types.h"
63
64 #include "ED_node.h"
65
66 #include "WM_api.h"
67 #include "WM_types.h"
68
69 #include "UI_resources.h"
70
71 #include "IMB_colormanagement.h"
72 #include "IMB_imbuf.h"
73 #include "IMB_imbuf_types.h"
74
75 #include "node_intern.h"  /* own include */
76 #include "NOD_composite.h"
77 #include "NOD_shader.h"
78 #include "NOD_texture.h"
79
80
81 /* ****************** SOCKET BUTTON DRAW FUNCTIONS ***************** */
82
83 static void node_socket_button_label(bContext *UNUSED(C), uiLayout *layout, PointerRNA *ptr, PointerRNA *UNUSED(node_ptr))
84 {
85         bNodeSocket *sock = (bNodeSocket *)ptr->data;
86         uiItemL(layout, sock->name, 0);
87 }
88
89 static void node_draw_input_default(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, int linked)
90 {
91         bNodeSocket *sock = (bNodeSocket *)ptr->data;
92         if (linked || (sock->flag & SOCK_HIDE_VALUE))
93                 node_socket_button_label(C, layout, ptr, node_ptr);
94         else
95                 sock->typeinfo->draw(C, layout, ptr, node_ptr);
96 }
97
98 static void node_draw_output_default(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, int UNUSED(linked))
99 {
100         node_socket_button_label(C, layout, ptr, node_ptr);
101 }
102
103
104 /* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */
105
106 #if 0 /* UNUSED */
107 static void node_draw_socket_new(bNodeSocket *sock, float size)
108 {
109         float x = sock->locx, y = sock->locy;
110         
111         /* 16 values of sin function */
112         static float si[16] = {
113                 0.00000000f, 0.39435585f, 0.72479278f, 0.93775213f,
114                 0.99871650f, 0.89780453f, 0.65137248f, 0.29936312f,
115                 -0.10116832f, -0.48530196f, -0.79077573f, -0.96807711f,
116                 -0.98846832f, -0.84864425f, -0.57126821f, -0.20129852f
117         };
118         /* 16 values of cos function */
119         static float co[16] = {
120                 1.00000000f, 0.91895781f, 0.68896691f, 0.34730525f,
121                 -0.05064916f, -0.44039415f, -0.75875812f, -0.95413925f,
122                 -0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
123                 0.15142777f, 0.52896401f, 0.82076344f, 0.97952994f,
124         };
125         int a;
126         
127         glColor3ub(180, 180, 180);
128         
129         glBegin(GL_POLYGON);
130         for (a = 0; a < 16; a++)
131                 glVertex2f(x + size * si[a], y + size * co[a]);
132         glEnd();
133         
134         glColor4ub(0, 0, 0, 150);
135         glEnable(GL_BLEND);
136         glEnable(GL_LINE_SMOOTH);
137         glBegin(GL_LINE_LOOP);
138         for (a = 0; a < 16; a++)
139                 glVertex2f(x + size * si[a], y + size * co[a]);
140         glEnd();
141         glDisable(GL_LINE_SMOOTH);
142         glDisable(GL_BLEND);
143 }
144 #endif
145
146 /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
147
148 static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
149 {
150         bNode *node = ptr->data;
151         /* first output stores value */
152         bNodeSocket *output = node->outputs.first;
153         PointerRNA sockptr;
154         RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, output, &sockptr);
155         
156         uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NONE);
157 }
158
159 static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
160 {
161         bNode *node = ptr->data;
162         /* first output stores value */
163         bNodeSocket *output = node->outputs.first;
164         PointerRNA sockptr;
165         uiLayout *col;
166         RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, output, &sockptr);
167         
168         col = uiLayoutColumn(layout, FALSE);
169         uiTemplateColorPicker(col, &sockptr, "default_value", 1, 0, 0, 0);
170         uiItemR(col, &sockptr, "default_value", 0, "", ICON_NONE);
171 }
172
173 static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
174 {       
175         uiLayout *row, *col;
176
177         bNodeTree *ntree = (bNodeTree *)ptr->id.data;
178
179         col = uiLayoutColumn(layout, FALSE);
180         row = uiLayoutRow(col, TRUE);
181         uiItemR(row, ptr, "blend_type", 0, "", ICON_NONE);
182         if (ntree->type == NTREE_COMPOSIT)
183                 uiItemR(row, ptr, "use_alpha", 0, "", ICON_IMAGE_RGB_ALPHA);
184
185         uiItemR(col, ptr, "use_clamp", 0, NULL, ICON_NONE);
186 }
187
188 static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
189 {
190         uiLayout *row;
191 #if 0
192         /* XXX no context access here .. */
193         bNode *node = ptr->data;
194         CurveMapping *cumap = node->storage;
195         
196         if (cumap) {
197                 cumap->flag |= CUMA_DRAW_CFRA;
198                 if (node->custom1 < node->custom2)
199                         cumap->sample[0] = (float)(CFRA - node->custom1) / (float)(node->custom2 - node->custom1);
200         }
201 #endif
202
203         uiTemplateCurveMapping(layout, ptr, "curve", 's', 0, 0);
204
205         row = uiLayoutRow(layout, TRUE);
206         uiItemR(row, ptr, "frame_start", 0, IFACE_("Sta"), ICON_NONE);
207         uiItemR(row, ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
208 }
209
210 static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
211 {
212         uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
213 }
214
215 static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
216 {
217         uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0, 0);
218 }
219
220 #define SAMPLE_FLT_ISNONE FLT_MAX
221 static float _sample_col[4] = {SAMPLE_FLT_ISNONE};  /* bad bad, 2.5 will do better?... no it won't... */
222 void ED_node_sample_set(const float col[4])
223 {
224         if (col) {
225                 copy_v4_v4(_sample_col, col);
226         }
227         else {
228                 copy_v4_fl(_sample_col, SAMPLE_FLT_ISNONE);
229         }
230 }
231
232 static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
233 {
234         bNode *node = ptr->data;
235         CurveMapping *cumap = node->storage;
236
237         if (_sample_col[0] != SAMPLE_FLT_ISNONE) {
238                 cumap->flag |= CUMA_DRAW_SAMPLE;
239                 copy_v3_v3(cumap->sample, _sample_col);
240         }
241         else {
242                 cumap->flag &= ~CUMA_DRAW_SAMPLE;
243         }
244
245         uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0, 0);
246 }
247
248 static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
249 {
250         bNode *node = ptr->data;
251         /* first output stores normal */
252         bNodeSocket *output = node->outputs.first;
253         PointerRNA sockptr;
254         RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, output, &sockptr);
255         
256         uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NONE);
257 }
258
259 #if 0 /* not used in 2.5x yet */
260 static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
261 {
262         Main *bmain = CTX_data_main(C);
263         bNodeTree *ntree = ntree_v;
264         bNode *node = node_v;
265         Tex *tex;
266         
267         if (node->menunr < 1) return;
268         
269         if (node->id) {
270                 node->id->us--;
271                 node->id = NULL;
272         }
273         tex = BLI_findlink(&bmain->tex, node->menunr - 1);
274
275         node->id = &tex->id;
276         id_us_plus(node->id);
277         BLI_strncpy(node->name, node->id->name + 2, sizeof(node->name));
278         
279         nodeSetActive(ntree, node);
280         
281         if (ntree->type == NTREE_TEXTURE)
282                 ntreeTexCheckCyclics(ntree);
283         
284         // allqueue(REDRAWBUTSSHADING, 0);
285         // allqueue(REDRAWNODE, 0);
286         NodeTagChanged(ntree, node); 
287         
288         node->menunr = 0;
289 }
290 #endif
291
292 static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
293 {
294         bNode *node = ptr->data;
295
296         short multi = (
297             node->id &&
298             ((Tex *)node->id)->use_nodes &&
299             (node->type != CMP_NODE_TEXTURE) &&
300             (node->type != TEX_NODE_TEXTURE)
301             );
302         
303         uiItemR(layout, ptr, "texture", 0, "", ICON_NONE);
304         
305         if (multi) {
306                 /* Number Drawing not optimal here, better have a list*/
307                 uiItemR(layout, ptr, "node_output", 0, "", ICON_NONE);
308         }
309 }
310
311 static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
312
313         uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
314         uiItemR(layout, ptr, "use_clamp", 0, NULL, ICON_NONE);
315 }
316
317 static int node_resize_area_default(bNode *node, int x, int y)
318 {
319         if (node->flag & NODE_HIDDEN) {
320                 rctf totr = node->totr;
321                 /* right part of node */
322                 totr.xmin = node->totr.xmax - 20.0f;
323                 if (BLI_rctf_isect_pt(&totr, x, y))
324                         return NODE_RESIZE_RIGHT;
325                 else
326                         return 0;
327         }
328         else {
329                 const float size = 10.0f;
330                 rctf totr = node->totr;
331                 int dir = 0;
332                 
333                 if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax)
334                         dir |= NODE_RESIZE_RIGHT;
335                 if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax)
336                         dir |= NODE_RESIZE_LEFT;
337                 return dir;
338         }
339 }
340
341 /* ****************** BUTTON CALLBACKS FOR COMMON NODES ***************** */
342
343
344 static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
345 {
346         uiTemplateIDBrowse(layout, C, ptr, "node_tree", NULL, NULL, NULL);
347 }
348
349 /* XXX Does a bounding box update by iterating over all children.
350  * Not ideal to do this in every draw call, but doing as transform callback doesn't work,
351  * since the child node totr rects are not updated properly at that point.
352  */
353 static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
354 {
355         const float margin = 1.5f * U.widget_unit;
356         NodeFrame *data = (NodeFrame *)node->storage;
357         int bbinit;
358         bNode *tnode;
359         rctf rect, noderect;
360         float xmax, ymax;
361         
362         /* init rect from current frame size */
363         node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
364         node_to_view(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
365         
366         /* frame can be resized manually only if shrinking is disabled or no children are attached */
367         data->flag |= NODE_FRAME_RESIZEABLE;
368         /* for shrinking bbox, initialize the rect from first child node */
369         bbinit = (data->flag & NODE_FRAME_SHRINK);
370         /* fit bounding box to all children */
371         for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) {
372                 if (tnode->parent != node)
373                         continue;
374                 
375                 /* add margin to node rect */
376                 noderect = tnode->totr;
377                 noderect.xmin -= margin;
378                 noderect.xmax += margin;
379                 noderect.ymin -= margin;
380                 noderect.ymax += margin;
381                 
382                 /* first child initializes frame */
383                 if (bbinit) {
384                         bbinit = 0;
385                         rect = noderect;
386                         data->flag &= ~NODE_FRAME_RESIZEABLE;
387                 }
388                 else
389                         BLI_rctf_union(&rect, &noderect);
390         }
391         
392         /* now adjust the frame size from view-space bounding box */
393         node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
394         node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax);
395         node->width = xmax - node->offsetx;
396         node->height = -ymax + node->offsety;
397         
398         node->totr = rect;
399 }
400
401 static void node_draw_frame_label(bNode *node, const float aspect)
402 {
403         /* XXX font id is crap design */
404         const int fontid = UI_GetStyle()->widgetlabel.uifont_id;
405         NodeFrame *data = (NodeFrame *)node->storage;
406         rctf *rct = &node->totr;
407         int color_id = node_get_colorid(node);
408         const char *label = nodeLabel(node);
409         /* XXX a bit hacky, should use separate align values for x and y */
410         float width, ascender;
411         float x, y;
412         const int font_size = data->label_size / aspect;
413
414         BLF_enable(fontid, BLF_ASPECT);
415         BLF_aspect(fontid, aspect, aspect, 1.0f);
416         BLF_size(fontid, MIN2(24, font_size), U.dpi); /* clamp otherwise it can suck up a LOT of memory */
417         
418         /* title color */
419         UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.8f, 10);
420
421         width = BLF_width(fontid, label);
422         ascender = BLF_ascender(fontid);
423         
424         /* 'x' doesn't need aspect correction */
425         x = BLI_rctf_cent_x(rct) - (0.5f * width);
426         y = rct->ymax - (((NODE_DY / 4) / aspect) + (ascender * aspect));
427
428         BLF_position(fontid, x, y, 0);
429         BLF_draw(fontid, label, BLF_DRAW_STR_DUMMY_MAX);
430
431         BLF_disable(fontid, BLF_ASPECT);
432 }
433
434 static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
435                             bNodeTree *UNUSED(ntree), bNode *node, bNodeInstanceKey UNUSED(key))
436 {
437         rctf *rct = &node->totr;
438         int color_id = node_get_colorid(node);
439         unsigned char color[4];
440         float alpha;
441         
442         /* skip if out of view */
443         if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == FALSE) {
444                 uiEndBlock(C, node->block);
445                 node->block = NULL;
446                 return;
447         }
448
449         UI_GetThemeColor4ubv(TH_NODE_FRAME, color);
450         alpha = (float)(color[3]) / 255.0f;
451         
452         /* shadow */
453         node_draw_shadow(snode, node, BASIS_RAD, alpha);
454         
455         /* body */
456         if (node->flag & NODE_CUSTOM_COLOR)
457                 glColor4f(node->color[0], node->color[1], node->color[2], alpha);
458         else
459                 UI_ThemeColor4(TH_NODE_FRAME);
460         glEnable(GL_BLEND);
461         uiSetRoundBox(UI_CNR_ALL);
462         uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
463         glDisable(GL_BLEND);
464
465         /* outline active and selected emphasis */
466         if (node->flag & SELECT) {
467                 glEnable(GL_BLEND);
468                 glEnable(GL_LINE_SMOOTH);
469                 
470                 if (node->flag & NODE_ACTIVE)
471                         UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
472                 else
473                         UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
474                 uiSetRoundBox(UI_CNR_ALL);
475                 uiDrawBox(GL_LINE_LOOP,
476                           rct->xmin, rct->ymin,
477                           rct->xmax, rct->ymax, BASIS_RAD);
478                 
479                 glDisable(GL_LINE_SMOOTH);
480                 glDisable(GL_BLEND);
481         }
482         
483         /* label */
484         node_draw_frame_label(node, snode->aspect);
485         
486         UI_ThemeClearColor(color_id);
487                 
488         uiEndBlock(C, node->block);
489         uiDrawBlock(C, node->block);
490         node->block = NULL;
491 }
492
493 static int node_resize_area_frame(bNode *node, int x, int y)
494 {
495         const float size = 10.0f;
496         NodeFrame *data = (NodeFrame *)node->storage;
497         rctf totr = node->totr;
498         int dir = 0;
499         
500         /* shrinking frame size is determined by child nodes */
501         if (!(data->flag & NODE_FRAME_RESIZEABLE))
502                 return 0;
503         
504         if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax)
505                 dir |= NODE_RESIZE_RIGHT;
506         if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax)
507                 dir |= NODE_RESIZE_LEFT;
508         if (x >= totr.xmin && x < totr.xmax && y >= totr.ymax - size && y < totr.ymax)
509                 dir |= NODE_RESIZE_TOP;
510         if (x >= totr.xmin && x < totr.xmax && y >= totr.ymin && y < totr.ymin + size)
511                 dir |= NODE_RESIZE_BOTTOM;
512         
513         return dir;
514 }
515
516 static void node_buts_frame_details(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
517 {
518         uiItemR(layout, ptr, "label_size", 0, IFACE_("Label Size"), ICON_NONE);
519         uiItemR(layout, ptr, "shrink", 0, IFACE_("Shrink"), ICON_NONE);
520 }
521
522
523 #define NODE_REROUTE_SIZE   8.0f
524
525 static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node)
526 {
527         bNodeSocket *nsock;
528         float locx, locy;
529         float size = NODE_REROUTE_SIZE;
530         
531         /* get "global" coords */
532         node_to_view(node, 0.0f, 0.0f, &locx, &locy);
533         
534         /* reroute node has exactly one input and one output, both in the same place */
535         nsock = node->outputs.first;
536         nsock->locx = locx;
537         nsock->locy = locy;
538
539         nsock = node->inputs.first;
540         nsock->locx = locx;
541         nsock->locy = locy;
542
543         node->width = size * 2;
544         node->totr.xmin = locx - size;
545         node->totr.xmax = locx + size;
546         node->totr.ymax = locy + size;
547         node->totr.ymin = locy - size;
548 }
549
550 static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(snode),
551                               bNodeTree *ntree, bNode *node, bNodeInstanceKey UNUSED(key))
552 {
553         bNodeSocket *sock;
554         char showname[128]; /* 128 used below */
555         rctf *rct = &node->totr;
556
557 #if 0   /* UNUSED */
558         float size = NODE_REROUTE_SIZE;
559 #endif
560         float socket_size = NODE_SOCKSIZE;
561
562         /* skip if out of view */
563         if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax ||
564             node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax)
565         {
566                 uiEndBlock(C, node->block);
567                 node->block = NULL;
568                 return;
569         }
570
571         /* XXX only kept for debugging
572          * selection state is indicated by socket outline below!
573          */
574 #if 0
575         /* body */
576         uiSetRoundBox(15);
577         UI_ThemeColor4(TH_NODE);
578         glEnable(GL_BLEND);
579         uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
580         glDisable(GL_BLEND);
581
582         /* outline active and selected emphasis */
583         if (node->flag & SELECT) {
584                 glEnable(GL_BLEND);
585                 glEnable(GL_LINE_SMOOTH);
586                 /* using different shades of TH_TEXT_HI for the empasis, like triangle */
587                 if (node->flag & NODE_ACTIVE)
588                         UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40);
589                 else
590                         UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120);
591                 uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
592
593                 glDisable(GL_LINE_SMOOTH);
594                 glDisable(GL_BLEND);
595         }
596 #endif
597
598         if (node->label[0] != '\0') {
599                 /* draw title (node label) */
600                 BLI_strncpy(showname, node->label, sizeof(showname));
601                 uiDefBut(node->block, LABEL, 0, showname,
602                          (int)(rct->xmin - NODE_DYS), (int)(rct->ymax),
603                          (short)512, (short)NODE_DY,
604                          NULL, 0, 0, 0, 0, NULL);
605         }
606
607         /* only draw input socket. as they all are placed on the same position.
608          * highlight also if node itself is selected, since we don't display the node body separately!
609          */
610         for (sock = node->inputs.first; sock; sock = sock->next) {
611                 node_socket_circle_draw(C, ntree, node, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT));
612         }
613
614         uiEndBlock(C, node->block);
615         uiDrawBlock(C, node->block);
616         node->block = NULL;
617 }
618
619 /* Special tweak area for reroute node.
620  * Since this node is quite small, we use a larger tweak area for grabbing than for selection.
621  */
622 static int node_tweak_area_reroute(bNode *node, int x, int y)
623 {
624         /* square of tweak radius */
625         static const float tweak_radius_sq = 576;  /* 24 * 24 */
626         
627         bNodeSocket *sock = node->inputs.first;
628         float dx = sock->locx - x;
629         float dy = sock->locy - y;
630         return (dx * dx + dy * dy <= tweak_radius_sq);
631 }
632
633 static void node_common_set_butfunc(bNodeType *ntype)
634 {
635         switch (ntype->type) {
636                 case NODE_GROUP:
637                         ntype->uifunc = node_uifunc_group;
638                         break;
639                 case NODE_FRAME:
640                         ntype->drawfunc = node_draw_frame;
641                         ntype->drawupdatefunc = node_update_frame;
642                         ntype->uifuncbut = node_buts_frame_details;
643                         ntype->resize_area_func = node_resize_area_frame;
644                         break;
645                 case NODE_REROUTE:
646                         ntype->drawfunc = node_draw_reroute;
647                         ntype->drawupdatefunc = node_update_reroute;
648                         ntype->tweak_area_func = node_tweak_area_reroute;
649                         break;
650         }
651 }
652
653 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
654
655 static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr,
656                                  PointerRNA *imaptr, PointerRNA *iuserptr)
657 {
658         uiLayout *col;
659         int source;
660
661         if (!imaptr->data)
662                 return;
663
664         col = uiLayoutColumn(layout, FALSE);
665         
666         uiItemR(col, imaptr, "source", 0, "", ICON_NONE);
667         
668         source = RNA_enum_get(imaptr, "source");
669
670         if (source == IMA_SRC_SEQUENCE) {
671                 /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
672                 Scene *scene = CTX_data_scene(C);
673                 ImageUser *iuser = iuserptr->data;
674                 char numstr[32];
675                 const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0, NULL);
676                 BLI_snprintf(numstr, sizeof(numstr), IFACE_("Frame: %d"), framenr);
677                 uiItemL(layout, numstr, ICON_NONE);
678         }
679
680         if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
681                 col = uiLayoutColumn(layout, TRUE);
682                 uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NONE);
683                 uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NONE);
684                 uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE);
685                 uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NONE);
686                 uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE);
687         }
688
689         col = uiLayoutColumn(layout, FALSE);
690
691         if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER)
692                 uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE);
693 }
694
695 static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr)
696 {
697         bNode *node = ptr->data;
698         uiLayout *col;
699         
700         uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL);
701         
702         if (!node->id) return;
703         
704         col = uiLayoutColumn(layout, FALSE);
705         uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NONE);
706         uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NONE);
707         uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NONE);
708 }
709
710 static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
711 {
712         uiLayout *row;
713         
714         uiItemL(layout, IFACE_("Location:"), ICON_NONE);
715         row = uiLayoutRow(layout, TRUE);
716         uiItemR(row, ptr, "translation", 0, "", ICON_NONE);
717         
718         uiItemL(layout, IFACE_("Rotation:"), ICON_NONE);
719         row = uiLayoutRow(layout, TRUE);
720         uiItemR(row, ptr, "rotation", 0, "", ICON_NONE);
721         
722         uiItemL(layout, IFACE_("Scale:"), ICON_NONE);
723         row = uiLayoutRow(layout, TRUE);
724         uiItemR(row, ptr, "scale", 0, "", ICON_NONE);
725         
726         row = uiLayoutRow(layout, TRUE);
727         uiItemR(row, ptr, "use_min", 0, IFACE_("Min"), ICON_NONE);
728         uiItemR(row, ptr, "min", 0, "", ICON_NONE);
729         
730         row = uiLayoutRow(layout, TRUE);
731         uiItemR(row, ptr, "use_max", 0, IFACE_("Max"), ICON_NONE);
732         uiItemR(row, ptr, "max", 0, "", ICON_NONE);
733 }
734
735 static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
736
737         uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
738 }
739
740 static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr)
741 {
742         PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
743         uiLayout *col;
744
745         col = uiLayoutColumn(layout, FALSE);
746
747         if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
748                 PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
749
750                 uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_textures", "", ICON_NONE);
751                 uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NONE);
752         }
753         else {
754                 uiItemR(col, ptr, "uv_layer", 0, IFACE_("UV"), ICON_NONE);
755                 uiItemR(col, ptr, "color_layer", 0, IFACE_("VCol"), ICON_NONE);
756         }
757 }
758
759 static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
760 {
761         uiItemR(layout, ptr, "attribute_name", 0, IFACE_("Name"), ICON_NONE);
762 }
763
764 static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
765 {
766         PointerRNA imaptr = RNA_pointer_get(ptr, "image");
767         PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
768
769         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
770         uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
771         uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
772
773         if (RNA_enum_get(ptr, "projection") == SHD_PROJ_BOX) {
774                 uiItemR(layout, ptr, "projection_blend", 0, "Blend", ICON_NONE);
775         }
776
777         /* note: image user properties used directly here, unlike compositor image node,
778          * which redefines them in the node struct RNA to get proper updates.
779          */
780         node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr);
781 }
782
783 static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr)
784 {
785         PointerRNA imaptr = RNA_pointer_get(ptr, "image");
786         PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
787
788         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
789         uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
790         uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
791
792         node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr);
793 }
794
795 static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
796 {
797         uiItemR(layout, ptr, "sun_direction", 0, "", ICON_NONE);
798         uiItemR(layout, ptr, "turbidity", 0, NULL, ICON_NONE);
799 }
800
801 static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
802 {
803         uiItemR(layout, ptr, "gradient_type", 0, "", ICON_NONE);
804 }
805
806 static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
807 {
808         uiItemR(layout, ptr, "turbulence_depth", 0, NULL, ICON_NONE);
809 }
810
811 static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
812 {
813         uiLayout *col;
814         
815         col = uiLayoutColumn(layout, TRUE);
816         uiItemR(col, ptr, "offset", 0, IFACE_("Offset"), ICON_NONE);
817         uiItemR(col, ptr, "offset_frequency", 0, IFACE_("Frequency"), ICON_NONE);
818         
819         col = uiLayoutColumn(layout, TRUE);
820         uiItemR(col, ptr, "squash", 0, IFACE_("Squash"), ICON_NONE);
821         uiItemR(col, ptr, "squash_frequency", 0, IFACE_("Frequency"), ICON_NONE);
822 }
823
824 static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
825 {
826         uiItemR(layout, ptr, "wave_type", 0, "", ICON_NONE);
827 }
828
829 static void node_shader_buts_tex_musgrave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
830 {
831         uiItemR(layout, ptr, "musgrave_type", 0, "", ICON_NONE);
832 }
833
834 static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
835 {
836         uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE);
837 }
838
839 static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
840 {
841         uiItemR(layout, ptr, "from_dupli", 0, NULL, 0);
842 }
843
844 static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRNA *ptr)
845 {
846         uiItemR(layout, ptr, "space", 0, "", 0);
847
848         if (RNA_enum_get(ptr, "space") == SHD_NORMAL_MAP_TANGENT) {
849                 PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
850
851                 if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
852                         PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
853                         uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
854                 }
855                 else
856                         uiItemR(layout, ptr, "uv_map", 0, "", 0);
857         }
858 }
859
860 static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *ptr)
861 {
862         uiLayout *split, *row;
863
864         split = uiLayoutSplit(layout, 0.0f, FALSE);
865
866         uiItemR(split, ptr, "direction_type", 0, "", 0);
867
868         row = uiLayoutRow(split, FALSE);
869
870         if (RNA_enum_get(ptr, "direction_type") == SHD_TANGENT_UVMAP) {
871                 PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
872
873                 if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
874                         PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
875                         uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_textures", "", ICON_NONE);
876                 }
877                 else
878                         uiItemR(row, ptr, "uv_map", 0, "", 0);
879         }
880         else
881                 uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, 0);
882 }
883
884 static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
885 {
886         uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
887 }
888
889 static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
890 {
891         uiLayout *row;
892
893         row = uiLayoutRow(layout, FALSE);
894         uiItemR(row, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
895
896         row = uiLayoutRow(layout, TRUE);
897
898         if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_INTERNAL)
899                 uiItemR(row, ptr, "script", 0, "", ICON_NONE);
900         else
901                 uiItemR(row, ptr, "filepath", 0, "", ICON_NONE);
902
903         uiItemO(row, "", ICON_FILE_REFRESH, "node.shader_script_update");
904 }
905
906 static void node_shader_buts_script_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
907 {
908         uiItemS(layout);
909
910         node_shader_buts_script(layout, C, ptr);
911
912 #if 0  /* not implemented yet */
913         if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_EXTERNAL)
914                 uiItemR(layout, ptr, "use_auto_update", 0, NULL, ICON_NONE);
915 #endif
916 }
917
918 /* only once called */
919 static void node_shader_set_butfunc(bNodeType *ntype)
920 {
921         switch (ntype->type) {
922                 case SH_NODE_MATERIAL:
923                 case SH_NODE_MATERIAL_EXT:
924                         ntype->uifunc = node_shader_buts_material;
925                         break;
926                 case SH_NODE_TEXTURE:
927                         ntype->uifunc = node_buts_texture;
928                         break;
929                 case SH_NODE_NORMAL:
930                         ntype->uifunc = node_buts_normal;
931                         break;
932                 case SH_NODE_CURVE_VEC:
933                         ntype->uifunc = node_buts_curvevec;
934                         break;
935                 case SH_NODE_CURVE_RGB:
936                         ntype->uifunc = node_buts_curvecol;
937                         break;
938                 case SH_NODE_MAPPING:
939                         ntype->uifunc = node_shader_buts_mapping;
940                         break;
941                 case SH_NODE_VALUE:
942                         ntype->uifunc = node_buts_value;
943                         break;
944                 case SH_NODE_RGB:
945                         ntype->uifunc = node_buts_rgb;
946                         break;
947                 case SH_NODE_MIX_RGB:
948                         ntype->uifunc = node_buts_mix_rgb;
949                         break;
950                 case SH_NODE_VALTORGB:
951                         ntype->uifunc = node_buts_colorramp;
952                         break;
953                 case SH_NODE_MATH: 
954                         ntype->uifunc = node_buts_math;
955                         break; 
956                 case SH_NODE_VECT_MATH: 
957                         ntype->uifunc = node_shader_buts_vect_math;
958                         break; 
959                 case SH_NODE_GEOMETRY:
960                         ntype->uifunc = node_shader_buts_geometry;
961                         break;
962                 case SH_NODE_ATTRIBUTE:
963                         ntype->uifunc = node_shader_buts_attribute;
964                         break;
965                 case SH_NODE_TEX_SKY:
966                         ntype->uifunc = node_shader_buts_tex_sky;
967                         break;
968                 case SH_NODE_TEX_IMAGE:
969                         ntype->uifunc = node_shader_buts_tex_image;
970                         break;
971                 case SH_NODE_TEX_ENVIRONMENT:
972                         ntype->uifunc = node_shader_buts_tex_environment;
973                         break;
974                 case SH_NODE_TEX_GRADIENT:
975                         ntype->uifunc = node_shader_buts_tex_gradient;
976                         break;
977                 case SH_NODE_TEX_MAGIC:
978                         ntype->uifunc = node_shader_buts_tex_magic;
979                         break;
980                 case SH_NODE_TEX_BRICK:
981                         ntype->uifunc = node_shader_buts_tex_brick;
982                         break;
983                 case SH_NODE_TEX_WAVE:
984                         ntype->uifunc = node_shader_buts_tex_wave;
985                         break;
986                 case SH_NODE_TEX_MUSGRAVE:
987                         ntype->uifunc = node_shader_buts_tex_musgrave;
988                         break;
989                 case SH_NODE_TEX_VORONOI:
990                         ntype->uifunc = node_shader_buts_tex_voronoi;
991                         break;
992                 case SH_NODE_TEX_COORD:
993                         ntype->uifunc = node_shader_buts_tex_coord;
994                         break;
995                 case SH_NODE_NORMAL_MAP:
996                         ntype->uifunc = node_shader_buts_normal_map;
997                         break;
998                 case SH_NODE_TANGENT:
999                         ntype->uifunc = node_shader_buts_tangent;
1000                         break;
1001                 case SH_NODE_BSDF_GLOSSY:
1002                 case SH_NODE_BSDF_GLASS:
1003                 case SH_NODE_BSDF_REFRACTION:
1004                         ntype->uifunc = node_shader_buts_glossy;
1005                         break;
1006                 case SH_NODE_SCRIPT:
1007                         ntype->uifunc = node_shader_buts_script;
1008                         ntype->uifuncbut = node_shader_buts_script_details;
1009                         break;
1010         }
1011 }
1012
1013 /* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
1014
1015 static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
1016 {
1017         bNode *node = ptr->data;
1018         PointerRNA imaptr, iuserptr;
1019         
1020         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
1021         
1022         if (!node->id) return;
1023         
1024         imaptr = RNA_pointer_get(ptr, "image");
1025         RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr);
1026         
1027         node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr);
1028 }
1029
1030 static void node_composit_buts_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
1031 {
1032         bNode *node = ptr->data;
1033         PointerRNA imaptr;
1034
1035         node_composit_buts_image(layout, C, ptr);
1036
1037         uiItemR(layout, ptr, "use_straight_alpha_output", 0, NULL, 0);
1038
1039         if (!node->id)
1040                 return;
1041
1042         imaptr = RNA_pointer_get(ptr, "image");
1043
1044         uiTemplateColorspaceSettings(layout, &imaptr, "colorspace_settings");
1045         uiItemR(layout, &imaptr, "alpha_mode", 0, NULL, 0);
1046 }
1047
1048 static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
1049 {
1050         bNode *node = ptr->data;
1051         uiLayout *col, *row;
1052         PointerRNA op_ptr;
1053         PointerRNA scn_ptr;
1054         PropertyRNA *prop;
1055         const char *layer_name;
1056         char scene_name[MAX_ID_NAME - 2];
1057         wmOperatorType *ot = WM_operatortype_find("RENDER_OT_render", 1);
1058
1059         BLI_assert(ot != 0);
1060
1061         uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
1062         
1063         if (!node->id) return;
1064
1065         col = uiLayoutColumn(layout, FALSE);
1066         row = uiLayoutRow(col, TRUE);
1067         uiItemR(row, ptr, "layer", 0, "", ICON_NONE);
1068         
1069         prop = RNA_struct_find_property(ptr, "layer");
1070         if (!(RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name)))
1071                 return;
1072         
1073         scn_ptr = RNA_pointer_get(ptr, "scene");
1074         RNA_string_get(&scn_ptr, "name", scene_name);
1075         
1076         WM_operator_properties_create_ptr(&op_ptr, ot);
1077         RNA_string_set(&op_ptr, "layer", layer_name);
1078         RNA_string_set(&op_ptr, "scene", scene_name);
1079         uiItemFullO_ptr(row, ot, "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
1080
1081 }
1082
1083
1084 static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1085 {
1086         uiLayout *col, *row;
1087         int reference;
1088         int filter;
1089         
1090         col = uiLayoutColumn(layout, FALSE);
1091         filter = RNA_enum_get(ptr, "filter_type");
1092         reference = RNA_boolean_get(ptr, "use_variable_size");
1093
1094         uiItemR(col, ptr, "filter_type", 0, "", ICON_NONE);
1095         if (filter != R_FILTER_FAST_GAUSS) {
1096                 uiItemR(col, ptr, "use_variable_size", 0, NULL, ICON_NONE);
1097                 if (!reference) {
1098                         uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NONE);
1099                 }
1100                 uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NONE);
1101         }
1102         
1103         uiItemR(col, ptr, "use_relative", 0, NULL, ICON_NONE);
1104         
1105         if (RNA_boolean_get(ptr, "use_relative")) {
1106                 uiItemL(col, IFACE_("Aspect Correction"), ICON_NONE);
1107                 row = uiLayoutRow(layout, TRUE);
1108                 uiItemR(row, ptr, "aspect_correction", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1109                 
1110                 col = uiLayoutColumn(layout, TRUE);
1111                 uiItemR(col, ptr, "factor_x", 0, IFACE_("X"), ICON_NONE);
1112                 uiItemR(col, ptr, "factor_y", 0, IFACE_("Y"), ICON_NONE);
1113         }
1114         else {
1115                 col = uiLayoutColumn(layout, TRUE);
1116                 uiItemR(col, ptr, "size_x", 0, IFACE_("X"), ICON_NONE);
1117                 uiItemR(col, ptr, "size_y", 0, IFACE_("Y"), ICON_NONE);
1118         }
1119 }
1120
1121 static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1122 {
1123         uiLayout *col;
1124         
1125         uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE);
1126         uiItemR(layout, ptr, "use_wrap", 0, NULL, ICON_NONE);
1127         
1128         col = uiLayoutColumn(layout, TRUE);
1129         uiItemL(col, IFACE_("Center:"), ICON_NONE);
1130         uiItemR(col, ptr, "center_x", 0, IFACE_("X"), ICON_NONE);
1131         uiItemR(col, ptr, "center_y", 0, IFACE_("Y"), ICON_NONE);
1132         
1133         uiItemS(layout);
1134         
1135         col = uiLayoutColumn(layout, TRUE);
1136         uiItemR(col, ptr, "distance", 0, NULL, ICON_NONE);
1137         uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE);
1138         
1139         uiItemS(layout);
1140         
1141         uiItemR(layout, ptr, "spin", 0, NULL, ICON_NONE);
1142         uiItemR(layout, ptr, "zoom", 0, NULL, ICON_NONE);
1143 }
1144
1145 static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1146 {       
1147         uiLayout *col;
1148         
1149         col = uiLayoutColumn(layout, TRUE);
1150         uiItemR(col, ptr, "iterations", 0, NULL, ICON_NONE);
1151         uiItemR(col, ptr, "sigma_color", 0, NULL, ICON_NONE);
1152         uiItemR(col, ptr, "sigma_space", 0, NULL, ICON_NONE);
1153 }
1154
1155 static void node_composit_buts_defocus(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1156 {
1157         uiLayout *sub, *col;
1158         
1159         col = uiLayoutColumn(layout, FALSE);
1160         uiItemL(col, IFACE_("Bokeh Type:"), ICON_NONE);
1161         uiItemR(col, ptr, "bokeh", 0, "", ICON_NONE);
1162         uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE);
1163
1164         uiItemR(layout, ptr, "use_gamma_correction", 0, NULL, ICON_NONE);
1165
1166         col = uiLayoutColumn(layout, FALSE);
1167         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer") == TRUE);
1168         uiItemR(col, ptr, "f_stop", 0, NULL, ICON_NONE);
1169
1170         uiItemR(layout, ptr, "blur_max", 0, NULL, ICON_NONE);
1171         uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE);
1172
1173         col = uiLayoutColumn(layout, FALSE);
1174         uiItemR(col, ptr, "use_preview", 0, NULL, ICON_NONE);
1175         
1176         col = uiLayoutColumn(layout, FALSE);
1177         uiItemR(col, ptr, "use_zbuffer", 0, NULL, ICON_NONE);
1178         sub = uiLayoutColumn(col, FALSE);
1179         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer") == FALSE);
1180         uiItemR(sub, ptr, "z_scale", 0, NULL, ICON_NONE);
1181 }
1182
1183 /* qdn: glare node */
1184 static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1185 {       
1186         uiItemR(layout, ptr, "glare_type", 0, "", ICON_NONE);
1187         uiItemR(layout, ptr, "quality", 0, "", ICON_NONE);
1188
1189         if (RNA_enum_get(ptr, "glare_type") != 1) {
1190                 uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE);
1191         
1192                 if (RNA_enum_get(ptr, "glare_type") != 0)
1193                         uiItemR(layout, ptr, "color_modulation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1194         }
1195         
1196         uiItemR(layout, ptr, "mix", 0, NULL, ICON_NONE);
1197         uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE);
1198
1199         if (RNA_enum_get(ptr, "glare_type") == 2) {
1200                 uiItemR(layout, ptr, "streaks", 0, NULL, ICON_NONE);
1201                 uiItemR(layout, ptr, "angle_offset", 0, NULL, ICON_NONE);
1202         }
1203         if (RNA_enum_get(ptr, "glare_type") == 0 || RNA_enum_get(ptr, "glare_type") == 2) {
1204                 uiItemR(layout, ptr, "fade", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1205                 
1206                 if (RNA_enum_get(ptr, "glare_type") == 0)
1207                         uiItemR(layout, ptr, "use_rotate_45", 0, NULL, ICON_NONE);
1208         }
1209         if (RNA_enum_get(ptr, "glare_type") == 1) {
1210                 uiItemR(layout, ptr, "size", 0, NULL, ICON_NONE);
1211         }
1212 }
1213
1214 static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1215 {       
1216         uiLayout *col;
1217
1218         col = uiLayoutColumn(layout, FALSE);
1219         uiItemR(col, ptr, "tonemap_type", 0, "", ICON_NONE);
1220         if (RNA_enum_get(ptr, "tonemap_type") == 0) {
1221                 uiItemR(col, ptr, "key", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1222                 uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE);
1223                 uiItemR(col, ptr, "gamma", 0, NULL, ICON_NONE);
1224         }
1225         else {
1226                 uiItemR(col, ptr, "intensity", 0, NULL, ICON_NONE);
1227                 uiItemR(col, ptr, "contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1228                 uiItemR(col, ptr, "adaptation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1229                 uiItemR(col, ptr, "correction", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1230         }
1231 }
1232
1233 static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1234 {
1235         uiLayout *col;
1236
1237         col = uiLayoutColumn(layout, FALSE);
1238         uiItemR(col, ptr, "use_projector", 0, NULL, ICON_NONE);
1239
1240         col = uiLayoutColumn(col, FALSE);
1241         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector") == FALSE);
1242         uiItemR(col, ptr, "use_jitter", 0, NULL, ICON_NONE);
1243         uiItemR(col, ptr, "use_fit", 0, NULL, ICON_NONE);
1244 }
1245
1246 static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1247 {
1248         uiLayout *col;
1249         
1250         col = uiLayoutColumn(layout, FALSE);
1251         uiItemR(col, ptr, "samples", 0, NULL, ICON_NONE);
1252         uiItemR(col, ptr, "factor", 0, IFACE_("Blur"), ICON_NONE);
1253         
1254         col = uiLayoutColumn(layout, TRUE);
1255         uiItemL(col, IFACE_("Speed:"), ICON_NONE);
1256         uiItemR(col, ptr, "speed_min", 0, IFACE_("Min"), ICON_NONE);
1257         uiItemR(col, ptr, "speed_max", 0, IFACE_("Max"), ICON_NONE);
1258
1259         uiItemR(layout, ptr, "use_curved", 0, NULL, ICON_NONE);
1260 }
1261
1262 static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1263 {
1264         uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
1265 }
1266
1267 static void node_composit_buts_flip(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1268 {
1269         uiItemR(layout, ptr, "axis", 0, "", ICON_NONE);
1270 }
1271
1272 static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1273 {
1274         uiLayout *col;
1275
1276         uiItemR(layout, ptr, "use_crop_size", 0, NULL, ICON_NONE);
1277         uiItemR(layout, ptr, "relative", 0, NULL, ICON_NONE);
1278
1279         col = uiLayoutColumn(layout, TRUE);
1280         if (RNA_boolean_get(ptr, "relative")) {
1281                 uiItemR(col, ptr, "rel_min_x", 0, IFACE_("Left"), ICON_NONE);
1282                 uiItemR(col, ptr, "rel_max_x", 0, IFACE_("Right"), ICON_NONE);
1283                 uiItemR(col, ptr, "rel_min_y", 0, IFACE_("Up"), ICON_NONE);
1284                 uiItemR(col, ptr, "rel_max_y", 0, IFACE_("Down"), ICON_NONE);
1285         }
1286         else {
1287                 uiItemR(col, ptr, "min_x", 0, IFACE_("Left"), ICON_NONE);
1288                 uiItemR(col, ptr, "max_x", 0, IFACE_("Right"), ICON_NONE);
1289                 uiItemR(col, ptr, "min_y", 0, IFACE_("Up"), ICON_NONE);
1290                 uiItemR(col, ptr, "max_y", 0, IFACE_("Down"), ICON_NONE);
1291         }
1292 }
1293
1294 static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1295 {
1296         uiLayout *row, *col;
1297         
1298         col = uiLayoutColumn(layout, FALSE);
1299         row = uiLayoutRow(col, FALSE);
1300         uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1301         uiItemR(col, ptr, "factor", 0, NULL, ICON_NONE);
1302 }
1303
1304 static void node_composit_buts_double_edge_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1305 {
1306         uiLayout *col;
1307
1308         col = uiLayoutColumn(layout, FALSE);
1309
1310         uiItemL(col, IFACE_("Inner Edge:"), ICON_NONE);
1311         uiItemR(col, ptr, "inner_mode", 0, "", ICON_NONE);
1312         uiItemL(col, IFACE_("Buffer Edge:"), ICON_NONE);
1313         uiItemR(col, ptr, "edge_mode", 0, "", ICON_NONE);
1314 }
1315
1316 static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1317 {
1318         uiLayout *col;
1319
1320         col = uiLayoutColumn(layout, TRUE);
1321         uiItemR(col, ptr, "use_clamp", 0, NULL, ICON_NONE);
1322 }
1323
1324 static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1325 {
1326         uiLayout *sub, *col;
1327         
1328         col = uiLayoutColumn(layout, TRUE);
1329         uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE);
1330         uiItemR(col, ptr, "size", 0, NULL, ICON_NONE);
1331         
1332         col = uiLayoutColumn(layout, TRUE);
1333         uiItemR(col, ptr, "use_min", 0, NULL, ICON_NONE);
1334         sub = uiLayoutColumn(col, FALSE);
1335         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
1336         uiItemR(sub, ptr, "min", 0, "", ICON_NONE);
1337         
1338         col = uiLayoutColumn(layout, TRUE);
1339         uiItemR(col, ptr, "use_max", 0, NULL, ICON_NONE);
1340         sub = uiLayoutColumn(col, FALSE);
1341         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
1342         uiItemR(sub, ptr, "max", 0, "", ICON_NONE);
1343 }
1344
1345 static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1346 {       
1347         uiLayout *col;
1348         
1349         col = uiLayoutColumn(layout, TRUE);
1350         uiItemR(col, ptr, "use_premultiply", 0, NULL, ICON_NONE);
1351         uiItemR(col, ptr, "premul", 0, NULL, ICON_NONE);
1352 }
1353
1354 static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1355 {       
1356         uiLayout *col;
1357         
1358         col = uiLayoutColumn(layout, TRUE);
1359         uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NONE);
1360 }
1361
1362
1363 static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1364 {
1365         uiLayout *col;
1366         
1367         col = uiLayoutColumn(layout, FALSE);
1368         uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1369         uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1370         uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1371 }
1372
1373 static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1374 {
1375         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1376         uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE);
1377         switch (RNA_enum_get(ptr, "mode")) {
1378                 case CMP_NODE_DILATEERODE_DISTANCE_THRESH:
1379                         uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE);
1380                         break;
1381                 case CMP_NODE_DILATEERODE_DISTANCE_FEATHER:
1382                         uiItemR(layout, ptr, "falloff", 0, NULL, ICON_NONE);
1383                         break;
1384         }
1385 }
1386
1387 static void node_composit_buts_inpaint(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1388 {
1389         uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE);
1390 }
1391
1392 static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1393 {
1394         uiLayout *col;
1395
1396         col = uiLayoutColumn(layout, FALSE);
1397         uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE);
1398         uiItemR(col, ptr, "threshold_neighbour", 0, NULL, ICON_NONE);
1399 }
1400
1401 static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1402 {
1403         uiLayout *col;
1404         
1405         col = uiLayoutColumn(layout, TRUE);
1406         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1407         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1408 }
1409
1410 static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1411 {
1412         uiLayout *col, *row;
1413         
1414         col = uiLayoutColumn(layout, TRUE);
1415
1416         uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
1417         row = uiLayoutRow(layout, FALSE);
1418         uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1419
1420         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1421         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1422 }
1423
1424 static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1425 {
1426         uiLayout *row, *col;
1427         
1428         uiItemL(layout, IFACE_("Despill Channel:"), ICON_NONE);
1429         row = uiLayoutRow(layout, FALSE);
1430         uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1431
1432         col = uiLayoutColumn(layout, FALSE);
1433         uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NONE);
1434
1435         if (RNA_enum_get(ptr, "limit_method") == 0) {
1436                 uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
1437                 row = uiLayoutRow(col, FALSE);
1438                 uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1439         }
1440
1441         uiItemR(col, ptr, "ratio", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1442         uiItemR(col, ptr, "use_unspill", 0, NULL, ICON_NONE);
1443         if (RNA_boolean_get(ptr, "use_unspill") == TRUE) {
1444                 uiItemR(col, ptr, "unspill_red", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1445                 uiItemR(col, ptr, "unspill_green", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1446                 uiItemR(col, ptr, "unspill_blue", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1447         }
1448 }
1449
1450 static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1451 {
1452         uiLayout *col;
1453         
1454         col = uiLayoutColumn(layout, FALSE);
1455         uiItemR(col, ptr, "tolerance", 0, NULL, ICON_NONE);
1456         uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE);
1457         
1458         col = uiLayoutColumn(layout, TRUE);
1459         /*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);  Removed for now */
1460         uiItemR(col, ptr, "gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1461         /*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, ICON_NONE);  Removed for now*/
1462 }
1463
1464 static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1465 {
1466         uiLayout *col;
1467         
1468         col = uiLayoutColumn(layout, TRUE);
1469         uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1470         uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1471         uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1472 }
1473
1474 static void node_composit_buts_channel_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1475 {       
1476         uiLayout *col, *row;
1477
1478         uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
1479         row = uiLayoutRow(layout, FALSE);
1480         uiItemR(row, ptr, "color_space", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1481
1482         col = uiLayoutColumn(layout, FALSE);
1483         uiItemL(col, IFACE_("Key Channel:"), ICON_NONE);
1484         row = uiLayoutRow(col, FALSE);
1485         uiItemR(row, ptr, "matte_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1486
1487         col = uiLayoutColumn(layout, FALSE);
1488
1489         uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NONE);
1490         if (RNA_enum_get(ptr, "limit_method") == 0) {
1491                 uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
1492                 row = uiLayoutRow(col, FALSE);
1493                 uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1494         }
1495
1496         uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1497         uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1498 }
1499
1500 static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1501 {
1502         uiLayout *col;
1503         
1504         col = uiLayoutColumn(layout, TRUE);
1505         uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1506         uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1507 }
1508
1509 static void node_composit_buts_map_uv(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1510 {
1511         uiItemR(layout, ptr, "alpha", 0, NULL, ICON_NONE);
1512 }
1513
1514 static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1515 {
1516         uiItemR(layout, ptr, "index", 0, NULL, ICON_NONE);
1517         uiItemR(layout, ptr, "use_antialiasing", 0, NULL, ICON_NONE);
1518 }
1519
1520 /* draw function for file output node sockets, displays only sub-path and format, no value button */
1521 static void node_draw_input_file_output(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, int UNUSED(linked))
1522 {
1523         bNodeTree *ntree = ptr->id.data;
1524         bNodeSocket *sock = ptr->data;
1525         uiLayout *row;
1526         PointerRNA inputptr, imfptr;
1527         int imtype;
1528         
1529         row = uiLayoutRow(layout, FALSE);
1530         
1531         imfptr = RNA_pointer_get(node_ptr, "format");
1532         imtype = RNA_enum_get(&imfptr, "file_format");
1533         if (imtype == R_IMF_IMTYPE_MULTILAYER) {
1534                 NodeImageMultiFileSocket *input = sock->storage;
1535                 RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr);
1536                 
1537                 uiItemL(row, input->layer, ICON_NONE);
1538         }
1539         else {
1540                 NodeImageMultiFileSocket *input = sock->storage;
1541                 PropertyRNA *imtype_prop;
1542                 const char *imtype_name;
1543                 uiBlock *block;
1544                 RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr);
1545                 
1546                 uiItemL(row, input->path, ICON_NONE);
1547                 
1548                 if (!RNA_boolean_get(&inputptr, "use_node_format"))
1549                         imfptr = RNA_pointer_get(&inputptr, "format");
1550                 
1551                 imtype_prop = RNA_struct_find_property(&imfptr, "file_format");
1552                 RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop,
1553                                        RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name);
1554                 block = uiLayoutGetBlock(row);
1555                 uiBlockSetEmboss(block, UI_EMBOSSP);
1556                 uiItemL(row, imtype_name, ICON_NONE);
1557                 uiBlockSetEmboss(block, UI_EMBOSSN);
1558         }
1559 }
1560 static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1561 {
1562         PointerRNA imfptr = RNA_pointer_get(ptr, "format");
1563         int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER);
1564         
1565         if (multilayer)
1566                 uiItemL(layout, IFACE_("Path:"), ICON_NONE);
1567         else
1568                 uiItemL(layout, IFACE_("Base Path:"), ICON_NONE);
1569         uiItemR(layout, ptr, "base_path", 0, "", ICON_NONE);
1570 }
1571 static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
1572 {
1573         PointerRNA imfptr = RNA_pointer_get(ptr, "format");
1574         PointerRNA active_input_ptr, op_ptr;
1575         uiLayout *row, *col;
1576         int active_index;
1577         int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER);
1578         
1579         node_composit_buts_file_output(layout, C, ptr);
1580         uiTemplateImageSettings(layout, &imfptr, FALSE);
1581         
1582         uiItemS(layout);
1583         
1584         uiItemO(layout, IFACE_("Add Input"), ICON_ZOOMIN, "NODE_OT_output_file_add_socket");
1585         
1586         row = uiLayoutRow(layout, FALSE);
1587         col = uiLayoutColumn(row, TRUE);
1588         
1589         active_index = RNA_int_get(ptr, "active_input_index");
1590         /* using different collection properties if multilayer format is enabled */
1591         if (multilayer) {
1592                 uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "layer_slots", ptr, "active_input_index", 0, 0, 0);
1593                 RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "layer_slots"),
1594                                                    active_index, &active_input_ptr);
1595         }
1596         else {
1597                 uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "file_slots", ptr, "active_input_index", 0, 0, 0);
1598                 RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"),
1599                                                    active_index, &active_input_ptr);
1600         }
1601         /* XXX collection lookup does not return the ID part of the pointer, setting this manually here */
1602         active_input_ptr.id.data = ptr->id.data;
1603         
1604         col = uiLayoutColumn(row, TRUE);
1605         op_ptr = uiItemFullO(col, "NODE_OT_output_file_move_active_socket", "",
1606                              ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS);
1607         RNA_enum_set(&op_ptr, "direction", 1);
1608         op_ptr = uiItemFullO(col, "NODE_OT_output_file_move_active_socket", "",
1609                              ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS);
1610         RNA_enum_set(&op_ptr, "direction", 2);
1611         
1612         if (active_input_ptr.data) {
1613                 if (multilayer) {
1614                         col = uiLayoutColumn(layout, TRUE);
1615                         
1616                         uiItemL(col, IFACE_("Layer:"), ICON_NONE);
1617                         row = uiLayoutRow(col, FALSE);
1618                         uiItemR(row, &active_input_ptr, "name", 0, "", ICON_NONE);
1619                         uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "",
1620                                     ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY);
1621                 }
1622                 else {
1623                         col = uiLayoutColumn(layout, TRUE);
1624                         
1625                         uiItemL(col, IFACE_("File Path:"), ICON_NONE);
1626                         row = uiLayoutRow(col, FALSE);
1627                         uiItemR(row, &active_input_ptr, "path", 0, "", ICON_NONE);
1628                         uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "",
1629                                     ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY);
1630                         
1631                         /* format details for individual files */
1632                         imfptr = RNA_pointer_get(&active_input_ptr, "format");
1633                         
1634                         col = uiLayoutColumn(layout, TRUE);
1635                         uiItemL(col, IFACE_("Format:"), ICON_NONE);
1636                         uiItemR(col, &active_input_ptr, "use_node_format", 0, NULL, ICON_NONE);
1637                         
1638                         col = uiLayoutColumn(layout, FALSE);
1639                         uiLayoutSetActive(col, RNA_boolean_get(&active_input_ptr, "use_node_format") == FALSE);
1640                         uiTemplateImageSettings(col, &imfptr, FALSE);
1641                 }
1642         }
1643 }
1644
1645 static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1646 {
1647         uiItemR(layout, ptr, "space", 0, "", ICON_NONE);
1648
1649         if (RNA_enum_get(ptr, "space") == CMP_SCALE_RENDERPERCENT) {
1650                 uiLayout *row;
1651                 uiItemR(layout, ptr, "frame_method", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1652                 row = uiLayoutRow(layout, TRUE);
1653                 uiItemR(row, ptr, "offset_x", 0, "X", ICON_NONE);
1654                 uiItemR(row, ptr, "offset_y", 0, "Y", ICON_NONE);
1655         }
1656 }
1657
1658 static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1659 {
1660         uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
1661 }
1662
1663 static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1664 {
1665         uiLayout *col;
1666         
1667         col = uiLayoutColumn(layout, FALSE);
1668         uiItemR(col, ptr, "invert_rgb", 0, NULL, ICON_NONE);
1669         uiItemR(col, ptr, "invert_alpha", 0, NULL, ICON_NONE);
1670 }
1671
1672 static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1673 {
1674         uiItemR(layout, ptr, "mapping", 0, "", ICON_NONE);
1675 }
1676
1677 static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1678 {
1679         uiItemR(layout, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1680 }
1681
1682 static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1683 {
1684         uiLayout *split, *col, *row;
1685         
1686         uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NONE);
1687         
1688         if (RNA_enum_get(ptr, "correction_method") == 0) {
1689         
1690                 split = uiLayoutSplit(layout, 0.0f, FALSE);
1691                 col = uiLayoutColumn(split, FALSE);
1692                 uiTemplateColorPicker(col, ptr, "lift", 1, 1, 0, 1);
1693                 row = uiLayoutRow(col, FALSE);
1694                 uiItemR(row, ptr, "lift", 0, NULL, ICON_NONE);
1695                 
1696                 col = uiLayoutColumn(split, FALSE);
1697                 uiTemplateColorPicker(col, ptr, "gamma", 1, 1, 1, 1);
1698                 row = uiLayoutRow(col, FALSE);
1699                 uiItemR(row, ptr, "gamma", 0, NULL, ICON_NONE);
1700                 
1701                 col = uiLayoutColumn(split, FALSE);
1702                 uiTemplateColorPicker(col, ptr, "gain", 1, 1, 1, 1);
1703                 row = uiLayoutRow(col, FALSE);
1704                 uiItemR(row, ptr, "gain", 0, NULL, ICON_NONE);
1705
1706         }
1707         else {
1708                 
1709                 split = uiLayoutSplit(layout, 0.0f, FALSE);
1710                 col = uiLayoutColumn(split, FALSE);
1711                 uiTemplateColorPicker(col, ptr, "offset", 1, 1, 0, 1);
1712                 row = uiLayoutRow(col, FALSE);
1713                 uiItemR(row, ptr, "offset", 0, NULL, ICON_NONE);
1714                 
1715                 col = uiLayoutColumn(split, FALSE);
1716                 uiTemplateColorPicker(col, ptr, "power", 1, 1, 0, 1);
1717                 row = uiLayoutRow(col, FALSE);
1718                 uiItemR(row, ptr, "power", 0, NULL, ICON_NONE);
1719                 
1720                 col = uiLayoutColumn(split, FALSE);
1721                 uiTemplateColorPicker(col, ptr, "slope", 1, 1, 0, 1);
1722                 row = uiLayoutRow(col, FALSE);
1723                 uiItemR(row, ptr, "slope", 0, NULL, ICON_NONE);
1724         }
1725
1726 }
1727 static void node_composit_buts_colorbalance_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1728 {
1729         uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NONE);
1730
1731         if (RNA_enum_get(ptr, "correction_method") == 0) {
1732
1733                 uiTemplateColorPicker(layout, ptr, "lift", 1, 1, 0, 1);
1734                 uiItemR(layout, ptr, "lift", 0, NULL, ICON_NONE);
1735
1736                 uiTemplateColorPicker(layout, ptr, "gamma", 1, 1, 1, 1);
1737                 uiItemR(layout, ptr, "gamma", 0, NULL, ICON_NONE);
1738
1739                 uiTemplateColorPicker(layout, ptr, "gain", 1, 1, 1, 1);
1740                 uiItemR(layout, ptr, "gain", 0, NULL, ICON_NONE);
1741         }
1742         else {
1743                 uiTemplateColorPicker(layout, ptr, "offset", 1, 1, 0, 1);
1744                 uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE);
1745
1746                 uiTemplateColorPicker(layout, ptr, "power", 1, 1, 0, 1);
1747                 uiItemR(layout, ptr, "power", 0, NULL, ICON_NONE);
1748
1749                 uiTemplateColorPicker(layout, ptr, "slope", 1, 1, 0, 1);
1750                 uiItemR(layout, ptr, "slope", 0, NULL, ICON_NONE);
1751         }
1752 }
1753
1754
1755 static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1756 {
1757         bNode *node = ptr->data;
1758         CurveMapping *cumap = node->storage;
1759
1760         if (_sample_col[0] != SAMPLE_FLT_ISNONE) {
1761                 cumap->flag |= CUMA_DRAW_SAMPLE;
1762                 copy_v3_v3(cumap->sample, _sample_col);
1763         }
1764         else {
1765                 cumap->flag &= ~CUMA_DRAW_SAMPLE;
1766         }
1767
1768         uiTemplateCurveMapping(layout, ptr, "mapping", 'h', 0, 0);
1769 }
1770
1771 static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1772
1773         uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
1774 }
1775
1776 static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr)
1777 {
1778         uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
1779 }
1780
1781 static void node_composit_buts_movieclip_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
1782 {
1783         bNode *node = ptr->data;
1784         PointerRNA clipptr;
1785
1786         uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
1787
1788         if (!node->id)
1789                 return;
1790
1791         clipptr = RNA_pointer_get(ptr, "clip");
1792
1793         uiTemplateColorspaceSettings(layout, &clipptr, "colorspace_settings");
1794 }
1795
1796 static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, PointerRNA *ptr)
1797 {
1798         bNode *node = ptr->data;
1799
1800         uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
1801
1802         if (!node->id)
1803                 return;
1804
1805         uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
1806 }
1807
1808 static void node_composit_buts_translate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1809 {
1810         uiItemR(layout, ptr, "use_relative", 0, NULL, ICON_NONE);
1811         uiItemR(layout, ptr, "wrap_axis", 0, NULL, ICON_NONE);
1812 }
1813
1814 static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1815 {
1816         uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
1817 }
1818
1819 static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr)
1820 {
1821         bNode *node = ptr->data;
1822
1823         uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
1824
1825         if (!node->id)
1826                 return;
1827
1828         uiItemR(layout, ptr, "distortion_type", 0, "", ICON_NONE);
1829 }
1830
1831 static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1832 {
1833         uiLayout *row;
1834         
1835         row = uiLayoutRow(layout, FALSE);
1836         uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
1837         uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
1838         uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE);
1839
1840         row = uiLayoutRow(layout, FALSE);
1841         uiItemL(row, "", ICON_NONE);
1842         uiItemL(row, IFACE_("Saturation"), ICON_NONE);
1843         uiItemL(row, IFACE_("Contrast"), ICON_NONE);
1844         uiItemL(row, IFACE_("Gamma"), ICON_NONE);
1845         uiItemL(row, IFACE_("Gain"), ICON_NONE);
1846         uiItemL(row, IFACE_("Lift"), ICON_NONE);
1847
1848         row = uiLayoutRow(layout, FALSE);
1849         uiItemL(row, IFACE_("Master"), ICON_NONE);
1850         uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
1851         uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
1852         uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
1853         uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
1854         uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
1855
1856         row = uiLayoutRow(layout, FALSE);
1857         uiItemL(row, IFACE_("Highlights"), ICON_NONE);
1858         uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
1859         uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
1860         uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
1861         uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
1862         uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
1863
1864         row = uiLayoutRow(layout, FALSE);
1865         uiItemL(row, IFACE_("Midtones"), ICON_NONE);
1866         uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
1867         uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
1868         uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
1869         uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
1870         uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
1871
1872         row = uiLayoutRow(layout, FALSE);
1873         uiItemL(row, IFACE_("Shadows"), ICON_NONE);
1874         uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, "", ICON_NONE);
1875         uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, "", ICON_NONE);
1876         uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, "", ICON_NONE);
1877         uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, "", ICON_NONE);
1878         uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, "", ICON_NONE);
1879
1880         row = uiLayoutRow(layout, FALSE);
1881         uiItemR(row, ptr, "midtones_start", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1882         uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1883 }
1884
1885 static void node_composit_buts_colorcorrection_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1886 {
1887         uiLayout *row;
1888         
1889         row = uiLayoutRow(layout, FALSE);
1890         uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
1891         uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
1892         uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE);
1893         row = layout;
1894         uiItemL(row, IFACE_("Saturation"), ICON_NONE);
1895         uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1896         uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1897         uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1898         uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1899
1900         uiItemL(row, IFACE_("Contrast"), ICON_NONE);
1901         uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1902         uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1903         uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1904         uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1905
1906         uiItemL(row, IFACE_("Gamma"), ICON_NONE);
1907         uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1908         uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1909         uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1910         uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1911
1912         uiItemL(row, IFACE_("Gain"), ICON_NONE);
1913         uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1914         uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1915         uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1916         uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1917         
1918         uiItemL(row, IFACE_("Lift"), ICON_NONE);
1919         uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1920         uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1921         uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1922         uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1923
1924         row = uiLayoutRow(layout, FALSE);
1925         uiItemR(row, ptr, "midtones_start", 0, NULL, ICON_NONE);
1926         uiItemR(row, ptr, "midtones_end", 0, NULL, ICON_NONE);
1927 }
1928
1929 static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1930 {
1931         uiItemR(layout, ptr, "check", 0, NULL, ICON_NONE);
1932 }
1933
1934 static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1935 {
1936         uiLayout *row;
1937         
1938         row = uiLayoutRow(layout, TRUE);
1939         uiItemR(row, ptr, "x", 0, NULL, ICON_NONE);
1940         uiItemR(row, ptr, "y", 0, NULL, ICON_NONE);
1941         
1942         row = uiLayoutRow(layout, TRUE);
1943         uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1944         uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1945
1946         uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE);
1947         uiItemR(layout, ptr, "mask_type", 0, NULL, ICON_NONE);
1948 }
1949
1950 static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1951 {
1952         uiItemR(layout, ptr, "flaps", 0, NULL, ICON_NONE);
1953         uiItemR(layout, ptr, "angle", 0, NULL, ICON_NONE);
1954         uiItemR(layout, ptr, "rounding", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1955         uiItemR(layout, ptr, "catadioptric", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1956         uiItemR(layout, ptr, "shift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1957 }
1958
1959 static void node_composit_buts_bokehblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1960 {
1961         uiItemR(layout, ptr, "use_variable_size", 0, NULL, ICON_NONE);
1962         // uiItemR(layout, ptr, "f_stop", 0, NULL, ICON_NONE);  // UNUSED
1963         uiItemR(layout, ptr, "blur_max", 0, NULL, ICON_NONE);
1964 }
1965
1966 static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
1967 {
1968 //      node_composit_backdrop_canvas(snode, backdrop, node, x, y);
1969         if (node->custom1 == 0) {
1970                 const float backdropWidth = backdrop->x;
1971                 const float backdropHeight = backdrop->y;
1972                 const float cx  = x + snode->zoom * backdropWidth * node->custom3;
1973                 const float cy = y + snode->zoom * backdropHeight * node->custom4;
1974
1975                 glColor3f(1.0, 1.0, 1.0);
1976
1977                 glBegin(GL_LINES);
1978                 glVertex2f(cx - 25, cy - 25);
1979                 glVertex2f(cx + 25, cy + 25);
1980                 glVertex2f(cx + 25, cy - 25);
1981                 glVertex2f(cx - 25, cy + 25);
1982                 glEnd();
1983         }
1984 }
1985
1986 static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
1987 {
1988         NodeBoxMask *boxmask = node->storage;
1989         const float backdropWidth = backdrop->x;
1990         const float backdropHeight = backdrop->y;
1991         const float aspect = backdropWidth / backdropHeight;
1992         const float rad = DEG2RADF(-boxmask->rotation);
1993         const float cosine = cosf(rad);
1994         const float sine = sinf(rad);
1995         const float halveBoxWidth = backdropWidth * (boxmask->width / 2.0f);
1996         const float halveBoxHeight = backdropHeight * (boxmask->height / 2.0f) * aspect;
1997
1998         float cx, cy, x1, x2, x3, x4;
1999         float y1, y2, y3, y4;
2000
2001
2002         /* keep this, saves us from a version patch */
2003         if (snode->zoom == 0.0f) snode->zoom = 1.0f;
2004
2005         glColor3f(1.0, 1.0, 1.0);
2006
2007         cx  = x + snode->zoom * backdropWidth * boxmask->x;
2008         cy = y + snode->zoom * backdropHeight * boxmask->y;
2009
2010         x1 = cx - (cosine * halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2011         x2 = cx - (cosine * -halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2012         x3 = cx - (cosine * -halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2013         x4 = cx - (cosine * halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2014         y1 = cy - (-sine * halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2015         y2 = cy - (-sine * -halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2016         y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2017         y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2018
2019         glBegin(GL_LINE_LOOP);
2020         glVertex2f(x1, y1);
2021         glVertex2f(x2, y2);
2022         glVertex2f(x3, y3);
2023         glVertex2f(x4, y4);
2024         glEnd();
2025 }
2026
2027 static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
2028 {
2029         NodeEllipseMask *ellipsemask = node->storage;
2030         const float backdropWidth = backdrop->x;
2031         const float backdropHeight = backdrop->y;
2032         const float aspect = backdropWidth / backdropHeight;
2033         const float rad = DEG2RADF(-ellipsemask->rotation);
2034         const float cosine = cosf(rad);
2035         const float sine = sinf(rad);
2036         const float halveBoxWidth = backdropWidth * (ellipsemask->width / 2.0f);
2037         const float halveBoxHeight = backdropHeight * (ellipsemask->height / 2.0f) * aspect;
2038
2039         float cx, cy, x1, x2, x3, x4;
2040         float y1, y2, y3, y4;
2041
2042
2043         /* keep this, saves us from a version patch */
2044         if (snode->zoom == 0.0f) snode->zoom = 1.0f;
2045
2046         glColor3f(1.0, 1.0, 1.0);
2047
2048         cx  = x + snode->zoom * backdropWidth * ellipsemask->x;
2049         cy = y + snode->zoom * backdropHeight * ellipsemask->y;
2050
2051         x1 = cx - (cosine * halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2052         x2 = cx - (cosine * -halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2053         x3 = cx - (cosine * -halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2054         x4 = cx - (cosine * halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2055         y1 = cy - (-sine * halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2056         y2 = cy - (-sine * -halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2057         y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2058         y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2059
2060         glBegin(GL_LINE_LOOP);
2061
2062         glVertex2f(x1, y1);
2063         glVertex2f(x2, y2);
2064         glVertex2f(x3, y3);
2065         glVertex2f(x4, y4);
2066         glEnd();
2067 }
2068
2069 static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2070 {
2071         uiLayout *row;
2072         row = uiLayoutRow(layout, TRUE);
2073         uiItemR(row, ptr, "x", 0, NULL, ICON_NONE);
2074         uiItemR(row, ptr, "y", 0, NULL, ICON_NONE);
2075         row = uiLayoutRow(layout, TRUE);
2076         uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2077         uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2078
2079         uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE);
2080         uiItemR(layout, ptr, "mask_type", 0, NULL, ICON_NONE);
2081 }
2082
2083 static void node_composit_buts_composite(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2084 {
2085         uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
2086 }
2087
2088 static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2089 {
2090         uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
2091 }
2092
2093 static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2094 {
2095         uiLayout *col;
2096         
2097         uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
2098         uiItemR(layout, ptr, "tile_order", 0, NULL, ICON_NONE);
2099         if (RNA_enum_get(ptr, "tile_order") == 0) {
2100                 col = uiLayoutColumn(layout, TRUE);
2101                 uiItemR(col, ptr, "center_x", 0, NULL, ICON_NONE);
2102                 uiItemR(col, ptr, "center_y", 0, NULL, ICON_NONE);
2103         }
2104 }
2105
2106 static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
2107 {
2108         bNode *node = ptr->data;
2109
2110         uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL);
2111         uiItemR(layout, ptr, "use_antialiasing", 0, NULL, ICON_NONE);
2112         uiItemR(layout, ptr, "use_feather", 0, NULL, ICON_NONE);
2113
2114         uiItemR(layout, ptr, "size_source", 0, "", ICON_NONE);
2115
2116         if (node->custom1 & (CMP_NODEFLAG_MASK_FIXED | CMP_NODEFLAG_MASK_FIXED_SCENE)) {
2117                 uiItemR(layout, ptr, "size_x", 0, NULL, ICON_NONE);
2118                 uiItemR(layout, ptr, "size_y", 0, NULL, ICON_NONE);
2119         }
2120
2121         uiItemR(layout, ptr, "use_motion_blur", 0, NULL, ICON_NONE);
2122         if (node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) {
2123                 uiItemR(layout, ptr, "motion_blur_samples", 0, NULL, ICON_NONE);
2124                 uiItemR(layout, ptr, "motion_blur_shutter", 0, NULL, ICON_NONE);
2125         }
2126 }
2127
2128 static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, PointerRNA *ptr)
2129 {
2130         bNode *node = ptr->data;
2131
2132         uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL);
2133
2134         if (node->id) {
2135                 MovieClip *clip = (MovieClip *) node->id;
2136                 uiLayout *col;
2137                 PointerRNA tracking_ptr;
2138
2139                 RNA_pointer_create(&clip->id, &RNA_MovieTracking, &clip->tracking, &tracking_ptr);
2140
2141                 col = uiLayoutColumn(layout, TRUE);
2142                 uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
2143         }
2144 }
2145
2146 static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2147 {
2148         /* bNode *node = ptr->data; */ /* UNUSED */
2149
2150         uiItemR(layout, ptr, "blur_pre", 0, NULL, ICON_NONE);
2151         uiItemR(layout, ptr, "screen_balance", 0, NULL, ICON_NONE);
2152         uiItemR(layout, ptr, "despill_factor", 0, NULL, ICON_NONE);
2153         uiItemR(layout, ptr, "despill_balance", 0, NULL, ICON_NONE);
2154         uiItemR(layout, ptr, "edge_kernel_radius", 0, NULL, ICON_NONE);
2155         uiItemR(layout, ptr, "edge_kernel_tolerance", 0, NULL, ICON_NONE);
2156         uiItemR(layout, ptr, "clip_black", 0, NULL, ICON_NONE);
2157         uiItemR(layout, ptr, "clip_white", 0, NULL, ICON_NONE);
2158         uiItemR(layout, ptr, "dilate_distance", 0, NULL, ICON_NONE);
2159         uiItemR(layout, ptr, "feather_falloff", 0, NULL, ICON_NONE);
2160         uiItemR(layout, ptr, "feather_distance", 0, NULL, ICON_NONE);
2161         uiItemR(layout, ptr, "blur_post", 0, NULL, ICON_NONE);
2162 }
2163
2164 static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRNA *ptr)
2165 {
2166         bNode *node = ptr->data;
2167
2168         uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
2169
2170         if (node->id) {
2171                 MovieClip *clip = (MovieClip *) node->id;
2172                 MovieTracking *tracking = &clip->tracking;
2173                 MovieTrackingObject *object;
2174                 uiLayout *col;
2175                 PointerRNA tracking_ptr;
2176                 NodeTrackPosData *data = node->storage;
2177
2178                 RNA_pointer_create(&clip->id, &RNA_MovieTracking, tracking, &tracking_ptr);
2179
2180                 col = uiLayoutColumn(layout, FALSE);
2181                 uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
2182
2183                 object = BKE_tracking_object_get_named(tracking, data->tracking_object);
2184                 if (object) {
2185                         PointerRNA object_ptr;
2186
2187                         RNA_pointer_create(&clip->id, &RNA_MovieTrackingObject, object, &object_ptr);
2188
2189                         uiItemPointerR(col, ptr, "track_name", &object_ptr, "tracks", "", ICON_ANIM_DATA);
2190                 }
2191                 else {
2192                         uiItemR(layout, ptr, "track_name", 0, "", ICON_ANIM_DATA);
2193                 }
2194
2195                 uiItemR(layout, ptr, "position", 0, NULL, ICON_NONE);
2196
2197                 if (node->custom1 == 2) {
2198                         uiItemR(layout, ptr, "frame_relative", 0, NULL, ICON_NONE);
2199                 }
2200         }
2201 }
2202
2203 /* only once called */
2204 static void node_composit_set_butfunc(bNodeType *ntype)
2205 {
2206         switch (ntype->type) {
2207                 case CMP_NODE_IMAGE:
2208                         ntype->uifunc = node_composit_buts_image;
2209                         ntype->uifuncbut = node_composit_buts_image_details;
2210                         break;
2211                 case CMP_NODE_R_LAYERS:
2212                         ntype->uifunc = node_composit_buts_renderlayers;
2213                         break;
2214                 case CMP_NODE_NORMAL:
2215                         ntype->uifunc = node_buts_normal;
2216                         break;
2217                 case CMP_NODE_CURVE_VEC:
2218                         ntype->uifunc = node_buts_curvevec;
2219                         break;
2220                 case CMP_NODE_CURVE_RGB:
2221                         ntype->uifunc = node_buts_curvecol;
2222                         break;
2223                 case CMP_NODE_VALUE:
2224                         ntype->uifunc = node_buts_value;
2225                         break;
2226                 case CMP_NODE_RGB:
2227                         ntype->uifunc = node_buts_rgb;
2228                         break;
2229                 case CMP_NODE_FLIP:
2230                         ntype->uifunc = node_composit_buts_flip;
2231                         break;
2232                 case CMP_NODE_SPLITVIEWER:
2233                         ntype->uifunc = node_composit_buts_splitviewer;
2234                         break;
2235                 case CMP_NODE_MIX_RGB:
2236                         ntype->uifunc = node_buts_mix_rgb;
2237                         break;
2238                 case CMP_NODE_VALTORGB:
2239                         ntype->uifunc = node_buts_colorramp;
2240                         break;
2241                 case CMP_NODE_CROP:
2242                         ntype->uifunc = node_composit_buts_crop;
2243                         break;
2244                 case CMP_NODE_BLUR:
2245                         ntype->uifunc = node_composit_buts_blur;
2246                         break;
2247                 case CMP_NODE_DBLUR:
2248                         ntype->uifunc = node_composit_buts_dblur;
2249                         break;
2250                 case CMP_NODE_BILATERALBLUR:
2251                         ntype->uifunc = node_composit_buts_bilateralblur;
2252                         break;
2253                 case CMP_NODE_DEFOCUS:
2254                         ntype->uifunc = node_composit_buts_defocus;
2255                         break;
2256                 case CMP_NODE_GLARE:
2257                         ntype->uifunc = node_composit_buts_glare;
2258                         break;
2259                 case CMP_NODE_TONEMAP:
2260                         ntype->uifunc = node_composit_buts_tonemap;
2261                         break;
2262                 case CMP_NODE_LENSDIST:
2263                         ntype->uifunc = node_composit_buts_lensdist;
2264                         break;
2265                 case CMP_NODE_VECBLUR:
2266                         ntype->uifunc = node_composit_buts_vecblur;
2267                         break;
2268                 case CMP_NODE_FILTER:
2269                         ntype->uifunc = node_composit_buts_filter;
2270                         break;
2271                 case CMP_NODE_MAP_VALUE:
2272                         ntype->uifunc = node_composit_buts_map_value;
2273                         break;
2274                 case CMP_NODE_MAP_RANGE:
2275                         ntype->uifunc = node_composit_buts_map_range;
2276                         break;
2277                 case CMP_NODE_TIME:
2278                         ntype->uifunc = node_buts_time;
2279                         break;
2280                 case CMP_NODE_ALPHAOVER:
2281                         ntype->uifunc = node_composit_buts_alphaover;
2282                         break;
2283                 case CMP_NODE_HUE_SAT:
2284                         ntype->uifunc = node_composit_buts_hue_sat;
2285                         break;
2286                 case CMP_NODE_TEXTURE:
2287                         ntype->uifunc = node_buts_texture;
2288                         break;
2289                 case CMP_NODE_DILATEERODE:
2290                         ntype->uifunc = node_composit_buts_dilateerode;
2291                         break;
2292                 case CMP_NODE_INPAINT:
2293                         ntype->uifunc = node_composit_buts_inpaint;
2294                         break;
2295                 case CMP_NODE_DESPECKLE:
2296                         ntype->uifunc = node_composit_buts_despeckle;
2297                         break;
2298                 case CMP_NODE_OUTPUT_FILE:
2299                         ntype->uifunc = node_composit_buts_file_output;
2300                         ntype->uifuncbut = node_composit_buts_file_output_details;
2301                         ntype->drawinputfunc = node_draw_input_file_output;
2302                         break;
2303                 case CMP_NODE_DIFF_MATTE:
2304                         ntype->uifunc = node_composit_buts_diff_matte;
2305                         break;
2306                 case CMP_NODE_DIST_MATTE:
2307                         ntype->uifunc = node_composit_buts_distance_matte;
2308                         break;
2309                 case CMP_NODE_COLOR_SPILL:
2310                         ntype->uifunc = node_composit_buts_color_spill;
2311                         break;
2312                 case CMP_NODE_CHROMA_MATTE:
2313                         ntype->uifunc = node_composit_buts_chroma_matte;
2314                         break;
2315                 case CMP_NODE_COLOR_MATTE:
2316                         ntype->uifunc = node_composit_buts_color_matte;
2317                         break;
2318                 case CMP_NODE_SCALE:
2319                         ntype->uifunc = node_composit_buts_scale;
2320                         break;
2321                 case CMP_NODE_ROTATE:
2322                         ntype->uifunc = node_composit_buts_rotate;
2323                         break;
2324                 case CMP_NODE_CHANNEL_MATTE:
2325                         ntype->uifunc = node_composit_buts_channel_matte;
2326                         break;
2327                 case CMP_NODE_LUMA_MATTE:
2328                         ntype->uifunc = node_composit_buts_luma_matte;
2329                         break;
2330                 case CMP_NODE_MAP_UV:
2331                         ntype->uifunc = node_composit_buts_map_uv;
2332                         break;
2333                 case CMP_NODE_ID_MASK:
2334                         ntype->uifunc = node_composit_buts_id_mask;
2335                         break;
2336                 case CMP_NODE_DOUBLEEDGEMASK:
2337                         ntype->uifunc = node_composit_buts_double_edge_mask;
2338                         break;
2339                 case CMP_NODE_MATH:
2340                         ntype->uifunc = node_buts_math;
2341                         break;
2342                 case CMP_NODE_INVERT:
2343                         ntype->uifunc = node_composit_buts_invert;
2344                         break;
2345                 case CMP_NODE_PREMULKEY:
2346                         ntype->uifunc = node_composit_buts_premulkey;
2347                         break;
2348                 case CMP_NODE_VIEW_LEVELS:
2349                         ntype->uifunc = node_composit_buts_view_levels;
2350                         break;
2351                 case CMP_NODE_COLORBALANCE:
2352                         ntype->uifunc = node_composit_buts_colorbalance;
2353                         ntype->uifuncbut = node_composit_buts_colorbalance_but;
2354                         break;
2355                 case CMP_NODE_HUECORRECT:
2356                         ntype->uifunc = node_composit_buts_huecorrect;
2357                         break;
2358                 case CMP_NODE_ZCOMBINE:
2359                         ntype->uifunc = node_composit_buts_zcombine;
2360                         break;
2361                 case CMP_NODE_COMBYCCA:
2362                 case CMP_NODE_SEPYCCA:
2363                         ntype->uifunc = node_composit_buts_ycc;
2364                         break;
2365                 case CMP_NODE_MOVIECLIP:
2366                         ntype->uifunc = node_composit_buts_movieclip;
2367                         ntype->uifuncbut = node_composit_buts_movieclip_details;
2368                         break;
2369                 case CMP_NODE_STABILIZE2D:
2370                         ntype->uifunc = node_composit_buts_stabilize2d;
2371                         break;
2372                 case CMP_NODE_TRANSFORM:
2373                         ntype->uifunc = node_composit_buts_transform;
2374                         break;
2375                 case CMP_NODE_TRANSLATE:
2376                         ntype->uifunc = node_composit_buts_translate;
2377                         break;
2378                 case CMP_NODE_MOVIEDISTORTION:
2379                         ntype->uifunc = node_composit_buts_moviedistortion;
2380                         break;
2381                 case CMP_NODE_COLORCORRECTION:
2382                         ntype->uifunc = node_composit_buts_colorcorrection;
2383                         ntype->uifuncbut = node_composit_buts_colorcorrection_but;
2384                         break;
2385                 case CMP_NODE_SWITCH:
2386                         ntype->uifunc = node_composit_buts_switch;
2387                         break;
2388                 case CMP_NODE_MASK_BOX:
2389                         ntype->uifunc = node_composit_buts_boxmask;
2390                         ntype->uibackdropfunc = node_composit_backdrop_boxmask;
2391                         break;
2392                 case CMP_NODE_MASK_ELLIPSE:
2393                         ntype->uifunc = node_composit_buts_ellipsemask;
2394                         ntype->uibackdropfunc = node_composit_backdrop_ellipsemask;
2395                         break;
2396                 case CMP_NODE_BOKEHIMAGE:
2397                         ntype->uifunc = node_composit_buts_bokehimage;
2398                         break;
2399                 case CMP_NODE_BOKEHBLUR:
2400                         ntype->uifunc = node_composit_buts_bokehblur;
2401                         break;
2402                 case CMP_NODE_VIEWER:
2403                         ntype->uifunc = node_composit_buts_viewer;
2404                         ntype->uifuncbut = node_composit_buts_viewer_but;
2405                         ntype->uibackdropfunc = node_composit_backdrop_viewer;
2406                         break;
2407                 case CMP_NODE_COMPOSITE:
2408                         ntype->uifunc = node_composit_buts_composite;
2409                         break;
2410                 case CMP_NODE_MASK:
2411                         ntype->uifunc = node_composit_buts_mask;
2412                         break;
2413                 case CMP_NODE_KEYINGSCREEN:
2414                         ntype->uifunc = node_composit_buts_keyingscreen;
2415                         break;
2416                 case CMP_NODE_KEYING:
2417                         ntype->uifunc = node_composit_buts_keying;
2418                         break;
2419                 case CMP_NODE_TRACKPOS:
2420                         ntype->uifunc = node_composit_buts_trackpos;
2421                         break;
2422         }
2423 }
2424
2425 /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
2426
2427 static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2428 {
2429         uiLayout *col;
2430         
2431         col = uiLayoutColumn(layout, TRUE);
2432         uiItemR(col, ptr, "offset", 0, IFACE_("Offset"), ICON_NONE);
2433         uiItemR(col, ptr, "offset_frequency", 0, IFACE_("Frequency"), ICON_NONE);
2434         
2435         col = uiLayoutColumn(layout, TRUE);
2436         uiItemR(col, ptr, "squash", 0, IFACE_("Squash"), ICON_NONE);
2437         uiItemR(col, ptr, "squash_frequency", 0, IFACE_("Frequency"), ICON_NONE);
2438 }
2439
2440 static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2441 {
2442         PointerRNA tex_ptr;
2443         bNode *node = ptr->data;
2444         ID *id = ptr->id.data;
2445         Tex *tex = (Tex *)node->storage;
2446         uiLayout *col, *row;
2447         
2448         RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr);
2449
2450         col = uiLayoutColumn(layout, FALSE);
2451
2452         switch (tex->type) {
2453                 case TEX_BLEND:
2454                         uiItemR(col, &tex_ptr, "progression", 0, "", ICON_NONE);
2455                         row = uiLayoutRow(col, FALSE);
2456                         uiItemR(row, &tex_ptr, "use_flip_axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2457                         break;
2458
2459                 case TEX_MARBLE:
2460                         row = uiLayoutRow(col, FALSE);
2461                         uiItemR(row, &tex_ptr, "marble_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2462                         row = uiLayoutRow(col, FALSE);
2463                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2464                         row = uiLayoutRow(col, FALSE);
2465                         uiItemR(row, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
2466                         row = uiLayoutRow(col, FALSE);
2467                         uiItemR(row, &tex_ptr, "noise_basis_2", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2468                         break;
2469
2470                 case TEX_MAGIC:
2471                         uiItemR(col, &tex_ptr, "noise_depth", 0, NULL, ICON_NONE);
2472                         break;
2473
2474                 case TEX_STUCCI:
2475                         row = uiLayoutRow(col, FALSE);
2476                         uiItemR(row, &tex_ptr, "stucci_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2477                         row = uiLayoutRow(col, FALSE);
2478                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2479                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
2480                         break;
2481
2482                 case TEX_WOOD:
2483                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
2484                         uiItemR(col, &tex_ptr, "wood_type", 0, "", ICON_NONE);
2485                         row = uiLayoutRow(col, FALSE);
2486                         uiItemR(row, &tex_ptr, "noise_basis_2", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2487                         row = uiLayoutRow(col, FALSE);
2488                         uiLayoutSetActive(row, !(ELEM(tex->stype, TEX_BAND, TEX_RING)));
2489                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2490                         break;
2491                         
2492                 case TEX_CLOUDS:
2493                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
2494                         row = uiLayoutRow(col, FALSE);
2495                         uiItemR(row, &tex_ptr, "cloud_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2496                         row = uiLayoutRow(col, FALSE);
2497                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2498                         uiItemR(col, &tex_ptr, "noise_depth", UI_ITEM_R_EXPAND, IFACE_("Depth"), ICON_NONE);
2499                         break;
2500                         
2501                 case TEX_DISTNOISE:
2502                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
2503                         uiItemR(col, &tex_ptr, "noise_distortion", 0, "", ICON_NONE);
2504                         break;
2505
2506                 case TEX_MUSGRAVE:
2507                         uiItemR(col, &tex_ptr, "musgrave_type", 0, "", ICON_NONE);
2508                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
2509                         break;
2510                 case TEX_VORONOI:
2511                         uiItemR(col, &tex_ptr, "distance_metric", 0, "", ICON_NONE);
2512                         if (tex->vn_distm == TEX_MINKOVSKY) {
2513                                 uiItemR(col, &tex_ptr, "minkovsky_exponent", 0, NULL, ICON_NONE);
2514                         }
2515                         uiItemR(col, &tex_ptr, "color_mode", 0, "", ICON_NONE);
2516                         break;
2517         }
2518 }
2519
2520 static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
2521 {
2522         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
2523 }
2524
2525 static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2526 {
2527         uiItemR(layout, ptr, "filepath", 0, "", ICON_NONE);
2528 }
2529
2530 /* only once called */
2531 static void node_texture_set_butfunc(bNodeType *ntype)
2532 {
2533         if (ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX) {
2534                 ntype->uifunc = node_texture_buts_proc;
2535         }
2536         else {
2537                 switch (ntype->type) {
2538
2539                         case TEX_NODE_MATH:
2540                                 ntype->uifunc = node_buts_math;
2541                                 break;
2542
2543                         case TEX_NODE_MIX_RGB:
2544                                 ntype->uifunc = node_buts_mix_rgb;
2545                                 break;
2546
2547                         case TEX_NODE_VALTORGB:
2548                                 ntype->uifunc = node_buts_colorramp;
2549                                 break;
2550
2551                         case TEX_NODE_CURVE_RGB:
2552                                 ntype->uifunc = node_buts_curvecol;
2553                                 break;
2554
2555                         case TEX_NODE_CURVE_TIME:
2556                                 ntype->uifunc = node_buts_time;
2557                                 break;
2558
2559                         case TEX_NODE_TEXTURE:
2560                                 ntype->uifunc = node_buts_texture;
2561                                 break;
2562
2563                         case TEX_NODE_BRICKS:
2564                                 ntype->uifunc = node_texture_buts_bricks;
2565                                 break;
2566
2567                         case TEX_NODE_IMAGE:
2568                                 ntype->uifunc = node_texture_buts_image;
2569                                 break;
2570
2571                         case TEX_NODE_OUTPUT:
2572                                 ntype->uifunc = node_texture_buts_output;
2573                                 break;
2574                 }
2575         }
2576 }
2577
2578 /* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */
2579
2580 static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
2581 {
2582         bNodeTree *ntree = ptr->id.data;
2583         ED_node_tag_update_nodetree(bmain, ntree);
2584 }
2585
2586 static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocketTemplate *stemp)
2587 {
2588         StructRNA *srna = ntype->ext.srna;
2589         PropertyRNA *prop = RNA_struct_type_find_property(srna, stemp->identifier);
2590         
2591         if (prop)
2592                 RNA_def_property_update_runtime(prop, node_property_update_default);
2593 }
2594
2595 static void node_template_properties_update(bNodeType *ntype)
2596 {
2597         bNodeSocketTemplate *stemp;
2598         
2599         if (ntype->inputs) {
2600                 for (stemp = ntype->inputs; stemp->type >= 0; ++stemp)
2601                         node_socket_template_properties_update(ntype, stemp);
2602         }
2603         if (ntype->outputs) {
2604                 for (stemp = ntype->outputs; stemp->type >= 0; ++stemp)
2605                         node_socket_template_properties_update(ntype, stemp);
2606         }
2607 }
2608
2609 static void node_socket_undefined_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *UNUSED(ptr), PointerRNA *UNUSED(node_ptr))
2610 {
2611         uiItemL(layout, "Undefined Socket Type", ICON_ERROR);
2612 }
2613
2614 static void node_socket_undefined_draw_color(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PointerRNA *UNUSED(node_ptr), float *r_color)
2615 {
2616         r_color[0] = 1.0f;
2617         r_color[1] = 0.0f;
2618         r_color[2] = 0.0f;
2619         r_color[3] = 1.0f;
2620 }
2621
2622 static void node_socket_undefined_interface_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *UNUSED(ptr))
2623 {
2624         uiItemL(layout, "Undefined Socket Type", ICON_ERROR);
2625 }
2626
2627 static void node_socket_undefined_interface_draw_color(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), float *r_color)
2628 {
2629         r_color[0] = 1.0f;
2630         r_color[1] = 0.0f;
2631         r_color[2] = 0.0f;
2632         r_color[3] = 1.0f;
2633 }
2634
2635 void ED_node_init_butfuncs(void)
2636 {
2637         /* Fallback types for undefined tree, nodes, sockets
2638          * Defined in blenkernel, but not registered in type hashes.
2639          */
2640         /*extern bNodeTreeType NodeTreeTypeUndefined;*/
2641         extern bNodeType NodeTypeUndefined;
2642         extern bNodeSocketType NodeSocketTypeUndefined;
2643         
2644         /* default ui functions */
2645         NodeTypeUndefined.drawfunc = node_draw_default;
2646         NodeTypeUndefined.drawupdatefunc = node_update_default;
2647         NodeTypeUndefined.select_area_func = node_select_area_default;
2648         NodeTypeUndefined.tweak_area_func = node_tweak_area_default;
2649         NodeTypeUndefined.uifunc = NULL;
2650         NodeTypeUndefined.uifuncbut = NULL;
2651         NodeTypeUndefined.drawinputfunc = node_draw_input_default;
2652         NodeTypeUndefined.drawoutputfunc = node_draw_output_default;
2653         NodeTypeUndefined.resize_area_func = node_resize_area_default;
2654         
2655         NodeSocketTypeUndefined.draw = node_socket_undefined_draw;
2656         NodeSocketTypeUndefined.draw_color = node_socket_undefined_draw_color;
2657         NodeSocketTypeUndefined.interface_draw = node_socket_undefined_interface_draw;
2658         NodeSocketTypeUndefined.interface_draw_color = node_socket_undefined_interface_draw_color;
2659         
2660         /* node type ui functions */
2661         NODE_TYPES_BEGIN(ntype)
2662                 /* default ui functions */
2663                 ntype->drawfunc = node_draw_default;
2664                 ntype->drawupdatefunc = node_update_default;
2665                 ntype->select_area_func = node_select_area_default;
2666                 ntype->tweak_area_func = node_tweak_area_default;
2667                 ntype->uifunc = NULL;
2668                 ntype->uifuncbut = NULL;
2669                 ntype->drawinputfunc = node_draw_input_default;
2670                 ntype->drawoutputfunc = node_draw_output_default;
2671                 ntype->resize_area_func = node_resize_area_default;
2672                 
2673                 node_common_set_butfunc(ntype);
2674                 
2675                 node_composit_set_butfunc(ntype);
2676                 node_shader_set_butfunc(ntype);
2677                 node_texture_set_butfunc(ntype);
2678                 
2679                 /* define update callbacks for socket properties */
2680                 node_template_properties_update(ntype);
2681         NODE_TYPES_END
2682         
2683         /* tree type icons */
2684         ntreeType_Composite->ui_icon = ICON_RENDERLAYERS;
2685         ntreeType_Shader->ui_icon = ICON_MATERIAL;
2686         ntreeType_Texture->ui_icon = ICON_TEXTURE;
2687 }
2688
2689 void ED_init_custom_node_type(bNodeType *ntype)
2690 {
2691         /* default ui functions */
2692         ntype->drawfunc = node_draw_default;
2693         ntype->drawupdatefunc = node_update_default;
2694         ntype->drawinputfunc = node_draw_input_default;
2695         ntype->drawoutputfunc = node_draw_output_default;
2696         ntype->resize_area_func = node_resize_area_default;
2697         ntype->select_area_func = node_select_area_default;
2698         ntype->tweak_area_func = node_tweak_area_default;
2699 }
2700
2701 void ED_init_custom_node_socket_type(bNodeSocketType *stype)
2702 {
2703         /* default ui functions */
2704         stype->draw = node_socket_button_label;
2705 }
2706
2707 /* maps standard socket integer type to a color */
2708 static const float std_node_socket_colors[][4] = {
2709         {0.63, 0.63, 0.63, 1.0},    /* SOCK_FLOAT */
2710         {0.39, 0.39, 0.78, 1.0},    /* SOCK_VECTOR */
2711         {0.78, 0.78, 0.16, 1.0},    /* SOCK_RGBA */
2712         {0.39, 0.78, 0.39, 1.0},    /* SOCK_SHADER */
2713         {0.70, 0.65, 0.19, 1.0},    /* SOCK_BOOLEAN */
2714         {0.0, 0.0, 0.0, 1.0},       /*__SOCK_MESH (deprecated) */
2715         {0.06, 0.52, 0.15, 1.0},    /* SOCK_INT */
2716         {1.0, 1.0, 1.0, 1.0},       /* SOCK_STRING */
2717 };
2718
2719 /* common color callbacks for standard types */
2720 static void std_node_socket_draw_color(bContext *UNUSED(C), PointerRNA *ptr, PointerRNA *UNUSED(node_ptr), float *r_color)
2721 {
2722         bNodeSocket *sock = ptr->data;
2723         int type = sock->typeinfo->type;
2724         copy_v4_v4(r_color, std_node_socket_colors[type]);
2725 }
2726 static void std_node_socket_interface_draw_color(bContext *UNUSED(C), PointerRNA *ptr, float *r_color)
2727 {
2728         bNodeSocket *sock = ptr->data;
2729         int type = sock->typeinfo->type;
2730         copy_v4_v4(r_color, std_node_socket_colors[type]);
2731 }
2732
2733 static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr)
2734 {
2735         bNodeSocket *sock = ptr->data;
2736         int type = sock->typeinfo->type;
2737         /*int subtype = sock->typeinfo->subtype;*/
2738         
2739         switch (type) {
2740                 case SOCK_FLOAT:
2741                 case SOCK_INT:
2742                 case SOCK_BOOLEAN:
2743                         uiItemR(layout, ptr, "default_value", 0, sock->name, 0);
2744                         break;
2745                 case SOCK_VECTOR:
2746                         uiTemplateComponentMenu(layout, ptr, "default_value", sock->name);
2747                         break;
2748                 case SOCK_RGBA: {
2749                         uiLayout *row = uiLayoutRow(layout, false);
2750                         uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
2751                         /* draw the socket name right of the actual button */
2752                         uiItemR(row, ptr, "default_value", 0, "", 0);
2753                         uiItemL(row, sock->name, 0);
2754                         break;
2755                 }
2756                 case SOCK_STRING: {
2757                         uiLayout *row = uiLayoutRow(layout, true);
2758                         /* draw the socket name right of the actual button */
2759                         uiItemR(row, ptr, "default_value", 0, "", 0);
2760                         uiItemL(row, sock->name, 0);
2761                         break;
2762                 }
2763                 
2764                 default:
2765                         node_socket_button_label(C, layout, ptr, node_ptr);
2766                         break;
2767         }
2768 }
2769
2770 static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *ptr)
2771 {
2772         bNodeSocket *sock = ptr->data;
2773         int type = sock->typeinfo->type;
2774         /*int subtype = sock->typeinfo->subtype;*/
2775         
2776         switch (type) {
2777                 case SOCK_FLOAT: {
2778                         uiLayout *row;
2779                         uiItemR(layout, ptr, "default_value", 0, NULL, 0);
2780                         row = uiLayoutRow(layout, true);
2781                         uiItemR(row, ptr, "min_value", 0, "Min", 0);
2782                         uiItemR(row, ptr, "max_value", 0, "Max", 0);
2783                         break;
2784                 }
2785                 case SOCK_INT: {
2786                         uiLayout *row;
2787                         uiItemR(layout, ptr, "default_value", 0, NULL, 0);
2788                         row = uiLayoutRow(layout, true);
2789                         uiItemR(row, ptr, "min_value", 0, "Min", 0);
2790                         uiItemR(row, ptr, "max_value", 0, "Max", 0);
2791                         break;
2792                 }
2793                 case SOCK_BOOLEAN: {
2794                         uiItemR(layout, ptr, "default_value", 0, NULL, 0);
2795                         break;
2796                 }
2797                 case SOCK_VECTOR: {
2798                         uiLayout *row;
2799                         uiItemR(layout, ptr, "default_value", UI_ITEM_R_EXPAND, NULL, 0);
2800                         row = uiLayoutRow(layout, true);
2801                         uiItemR(row, ptr, "min_value", 0, "Min", 0);
2802                         uiItemR(row, ptr, "max_value", 0, "Max", 0);
2803                         break;
2804                 }
2805                 case SOCK_RGBA: {
2806                         uiItemR(layout, ptr, "default_value", 0, NULL, 0);
2807                         break;
2808                 }
2809                 case SOCK_STRING: {
2810                         uiItemR(layout, ptr, "default_value", 0, NULL, 0);
2811                         break;
2812                 }
2813         }
2814 }
2815
2816 void ED_init_standard_node_socket_type(bNodeSocketType *stype)
2817 {
2818         stype->draw = std_node_socket_draw;
2819         stype->draw_color = std_node_socket_draw_color;
2820         stype->interface_draw = std_node_socket_interface_draw;
2821         stype->interface_draw_color = std_node_socket_interface_draw_color;
2822 }
2823
2824 static void node_socket_virtual_draw_color(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PointerRNA *UNUSED(node_ptr), float *r_color)
2825 {
2826         /* alpha = 0, empty circle */
2827         zero_v4(r_color);
2828 }
2829
2830 void ED_init_node_socket_type_virtual(bNodeSocketType *stype)
2831 {
2832         stype->draw = node_socket_button_label;
2833         stype->draw_color = node_socket_virtual_draw_color;
2834 }
2835
2836 /* ************** Generic drawing ************** */
2837
2838 void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeInstanceKey parent_key)
2839 {
2840         bNodeInstanceKey active_viewer_key = (snode->nodetree ? snode->nodetree->active_viewer_key : NODE_INSTANCE_KEY_NONE);
2841         Image *ima;
2842         void *lock;
2843         ImBuf *ibuf;
2844         
2845         if (!(snode->flag & SNODE_BACKDRAW) || !ED_node_is_compositor(snode))
2846                 return;
2847         
2848         if (parent_key.value != active_viewer_key.value)
2849                 return;
2850         
2851         ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
2852         ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
2853         if (ibuf) {
2854                 float x, y; 
2855                 
2856                 glMatrixMode(GL_PROJECTION);
2857                 glPushMatrix();
2858                 glMatrixMode(GL_MODELVIEW);
2859                 glPushMatrix();
2860                 
2861                 /* keep this, saves us from a version patch */
2862                 if (snode->zoom == 0.0f) snode->zoom = 1.0f;
2863                 
2864                 /* somehow the offset has to be calculated inverse */
2865                 
2866                 glaDefine2DArea(&ar->winrct);
2867                 /* ortho at pixel level curarea */
2868                 wmOrtho2(-GLA_PIXEL_OFS, ar->winx - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, ar->winy - GLA_PIXEL_OFS);
2869                 
2870                 x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
2871                 y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof;
2872                 
2873                 if (ibuf->rect || ibuf->rect_float) {
2874                         unsigned char *display_buffer = NULL;
2875                         void *cache_handle = NULL;
2876                         
2877                         if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B)) {
2878                                 int ofs;
2879                                 
2880                                 display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
2881                                 
2882 #ifdef __BIG_ENDIAN__
2883                                 if      (snode->flag & SNODE_SHOW_R) ofs = 2;
2884                                 else if (snode->flag & SNODE_SHOW_G) ofs = 1;
2885                                 else                                 ofs = 0;
2886 #else
2887                                 if      (snode->flag & SNODE_SHOW_R) ofs = 1;
2888                                 else if (snode->flag & SNODE_SHOW_G) ofs = 2;
2889                                 else                                 ofs = 3;
2890 #endif
2891                                 
2892                                 glPixelZoom(snode->zoom, snode->zoom);
2893                                 /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
2894                                 
2895                                 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT,
2896                                                   display_buffer + ofs);
2897                                 
2898                                 glPixelZoom(1.0f, 1.0f);
2899                         }
2900                         else if (snode->flag & SNODE_SHOW_ALPHA) {
2901                                 display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
2902                                 
2903                                 glPixelZoom(snode->zoom, snode->zoom);
2904                                 /* swap bytes, so alpha is most significant one, then just draw it as luminance int */
2905 #ifdef __BIG_ENDIAN__
2906                                 glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
2907 #endif
2908                                 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, display_buffer);
2909                                 
2910 #ifdef __BIG_ENDIAN__
2911                                 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
2912 #endif
2913                                 glPixelZoom(1.0f, 1.0f);
2914                         }
2915                         else if (snode->flag & SNODE_USE_ALPHA) {
2916                                 glEnable(GL_BLEND);
2917                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2918                                 glPixelZoom(snode->zoom, snode->zoom);
2919                                 
2920                                 glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
2921                                 
2922                                 glPixelZoom(1.0f, 1.0f);
2923                                 glDisable(GL_BLEND);
2924                         }
2925                         else {
2926                                 glPixelZoom(snode->zoom, snode->zoom);
2927                                 
2928                                 glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
2929                                 
2930                                 glPixelZoom(1.0f, 1.0f);
2931                         }
2932                         
2933                         if (cache_handle)
2934                                 IMB_display_buffer_release(cache_handle);
2935                 }
2936                 
2937                 /** @note draw selected info on backdrop */
2938                 if (snode->edittree) {
2939                         bNode *node = snode->edittree->nodes.first;
2940                         rctf *viewer_border = &snode->nodetree->viewer_border;
2941                         while (node) {
2942                                 if (node->flag & NODE_SELECT) {
2943                                         if (node->typeinfo->uibackdropfunc) {
2944                                                 node->typeinfo->uibackdropfunc(snode, ibuf, node, x, y);
2945                                         }
2946                                 }
2947                                 node = node->next;
2948                         }
2949                         
2950                         if ((snode->nodetree->flag & NTREE_VIEWER_BORDER) &&
2951                                 viewer_border->xmin < viewer_border->xmax &&
2952                                 viewer_border->ymin < viewer_border->ymax)
2953                         {
2954                                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2955                                 setlinestyle(3);
2956                                 cpack(0x4040FF);
2957                                 
2958                                 glRectf(x + snode->zoom * viewer_border->xmin * ibuf->x,
2959                                         y + snode->zoom * viewer_border->ymin * ibuf->y,
2960                                         x + snode->zoom * viewer_border->xmax * ibuf->x,
2961                                         y + snode->zoom * viewer_border->ymax * ibuf->y);
2962                                 
2963                                 setlinestyle(0);
2964                                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2965                         }
2966                 }
2967                 
2968                 glMatrixMode(GL_PROJECTION);
2969                 glPopMatrix();
2970                 glMatrixMode(GL_MODELVIEW);
2971                 glPopMatrix();
2972         }
2973         
2974         BKE_image_release_ibuf(ima, ibuf, lock);
2975 }
2976
2977
2978 /* if v2d not NULL, it clips and returns 0 if not visible */
2979 int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
2980 {
2981         float dist, vec[4][2];
2982         float deltax, deltay;
2983         int toreroute, fromreroute;
2984         /* in v0 and v3 we put begin/end points */
2985         if (link->fromsock) {
2986                 vec[0][0] = link->fromsock->locx;
2987                 vec[0][1] = link->fromsock->locy;
2988                 fromreroute = (link->fromnode && link->fromnode->type == NODE_REROUTE);
2989         }
2990         else {
2991                 if (snode == NULL) return 0;
2992                 copy_v2_v2(vec[0], snode->cursor);
2993                 fromreroute = 0;
2994         }
2995         if (link->tosock) {
2996                 vec[3][0] = link->tosock->locx;
2997                 vec[3][1] = link->tosock->locy;
2998                 toreroute = (link->tonode && link->tonode->type == NODE_REROUTE);
2999         }
3000         else {
3001                 if (snode == NULL) return 0;
3002                 copy_v2_v2(vec[3], snode->cursor);
3003                 toreroute = 0;
3004         }
3005
3006         dist = UI_GetThemeValue(TH_NODE_CURVING) * 0.10f * ABS(vec[0][0] - vec[3][0]);
3007         deltax = vec[3][0] - vec[0][0];
3008         deltay = vec[3][1] - vec[0][1];
3009         /* check direction later, for top sockets */
3010         if (fromreroute) {
3011                 if (ABS(deltax) > ABS(deltay)) {
3012                         vec[1][1] = vec[0][1];
3013                         vec[1][0] = vec[0][0] + (deltax > 0 ? dist : -dist);
3014                 }
3015                 else {
3016                         vec[1][0] = vec[0][0];
3017                         vec[1][1] = vec[0][1] + (deltay > 0 ? dist : -dist);
3018                 }
3019         }
3020         else {
3021                 vec[1][0] = vec[0][0] + dist;
3022                 vec[1][1] = vec[0][1];
3023         }
3024         if (toreroute) {
3025                 if (ABS(deltax) > ABS(deltay)) {
3026                         vec[2][1] = vec[3][1];
3027                         vec[2][0] = vec[3][0] + (deltax > 0 ? -dist : dist);
3028                 }
3029                 else {
3030                         vec[2][0] = vec[3][0];
3031                         vec[2][1] = vec[3][1] + (deltay > 0 ? -dist : dist);
3032                 }
3033
3034         }
3035         else {
3036                 vec[2][0] = vec[3][0] - dist;
3037                 vec[2][1] = vec[3][1];
3038         }
3039         if (v2d && min_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
3040                 /* clipped */
3041         }
3042         else if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
3043                 /* clipped */
3044         }
3045         else {
3046                 /* always do all three, to prevent data hanging around */
3047                 BKE_curve_forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0],
3048                                               coord_array[0] + 0, resol, sizeof(float) * 2);
3049                 BKE_curve_forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1],
3050                                               coord_array[0] + 1, resol, sizeof(float) * 2);
3051                 
3052                 return 1;
3053         }
3054         return 0;
3055 }
3056
3057 #define LINK_RESOL  24
3058 #define LINK_ARROW  12  /* position of arrow on the link, LINK_RESOL/2 */
3059 #define ARROW_SIZE 7
3060 void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
3061                            int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3)
3062 {
3063         float coord_array[LINK_RESOL + 1][2];
3064         
3065         if (node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
3066                 float dist, spline_step = 0.0f;
3067                 int i;
3068                 int drawarrow;
3069                 /* store current linewidth */
3070                 float linew;
3071                 float arrow[2], arrow1[2], arrow2[2];
3072                 glGetFloatv(GL_LINE_WIDTH, &linew);
3073                 
3074                 /* we can reuse the dist variable here to increment the GL curve eval amount*/
3075                 dist = 1.0f / (float)LINK_RESOL;
3076                 
3077                 glEnable(GL_LINE_SMOOTH);
3078                 
3079                 drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) &&
3080                              (link->fromnode && (link->fromnode->type == NODE_REROUTE)));
3081
3082                 if (drawarrow) {
3083                         /* draw arrow in line segment LINK_ARROW */
3084                         float d_xy[2], len;
3085
3086                         sub_v2_v2v2(d_xy, coord_array[LINK_ARROW], coord_array[LINK_ARROW - 1]);
3087                         len = len_v2(d_xy);
3088                         mul_v2_fl(d_xy, ARROW_SIZE / len);
3089                         arrow1[0] = coord_array[LINK_ARROW][0] - d_xy[0] + d_xy[1];
3090                         arrow1[1] = coord_array[LINK_ARROW][1] - d_xy[1] - d_xy[0];
3091                         arrow2[0] = coord_array[LINK_ARROW][0] - d_xy[0] - d_xy[1];
3092                         arrow2[1] = coord_array[LINK_ARROW][1] - d_xy[1] + d_xy[0];
3093                         arrow[0] = coord_array[LINK_ARROW][0];
3094                         arrow[1] = coord_array[LINK_ARROW][1];
3095                 }
3096                 if (do_triple) {
3097                         UI_ThemeColorShadeAlpha(th_col3, -80, -120);
3098                         glLineWidth(4.0f);
3099                         
3100                         glBegin(GL_LINE_STRIP);
3101                         for (i = 0; i <= LINK_RESOL; i++) {
3102                                 glVertex2fv(coord_array[i]);
3103                         }
3104                         glEnd();
3105                         if (drawarrow) {
3106                                 glBegin(GL_LINE_STRIP);
3107                                 glVertex2fv(arrow1);
3108                                 glVertex2fv(arrow);
3109                                 glVertex2fv(arrow);
3110                                 glVertex2fv(arrow2);
3111                                 glEnd();
3112                         }
3113                 }
3114                 
3115                 /* XXX using GL_LINES for shaded node lines is a workaround
3116                  * for Intel hardware, this breaks with GL_LINE_STRIP and
3117                  * changing color in begin/end blocks.
3118                  */
3119                 glLineWidth(1.5f);
3120                 if (do_shaded) {
3121                         glBegin(GL_LINES);
3122                         for (i = 0; i < LINK_RESOL; i++) {
3123                                 UI_ThemeColorBlend(th_col1, th_col2, spline_step);
3124                                 glVertex2fv(coord_array[i]);
3125                                 
3126                                 UI_ThemeColorBlend(th_col1, th_col2, spline_step + dist);
3127                                 glVertex2fv(coord_array[i + 1]);
3128                                 
3129                                 spline_step += dist;
3130                         }
3131                         glEnd();
3132                 }
3133                 else {
3134                         UI_ThemeColor(th_col1);
3135                         glBegin(GL_LINE_STRIP);
3136                         for (i = 0; i <= LINK_RESOL; i++) {
3137                                 glVertex2fv(coord_array[i]);
3138                         }
3139                         glEnd();
3140                 }
3141                 
3142                 if (drawarrow) {
3143                         glBegin(GL_LINE_STRIP);
3144                         glVertex2fv(arrow1);
3145                         glVertex2fv(arrow);
3146                         glVertex2fv(arrow);
3147                         glVertex2fv(arrow2);
3148                         glEnd();
3149                 }
3150                 
3151                 glDisable(GL_LINE_SMOOTH);
3152                 
3153                 /* restore previuos linewidth */
3154                 glLineWidth(1.0f);
3155         }
3156 }
3157
3158 #if 0 /* not used in 2.5x yet */
3159 static void node_link_straight_points(View2D *UNUSED(v2d), SpaceNode *snode, bNodeLink *link, float coord_array[][2])
3160 {
3161         if (link->fromsock) {
3162                 coord_array[0][0] = link->fromsock->locx;
3163                 coord_array[0][1] = link->fromsock->locy;
3164         }
3165         else {
3166                 if (snode == NULL) return;
3167                 coord_array[0][0] = snode->mx;
3168                 coord_array[0][1] = snode->my;
3169         }
3170         if (link->tosock) {
3171                 coord_array[1][0] = link->tosock->locx;
3172                 coord_array[1][1] = link->tosock->locy;
3173         }
3174         else {
3175                 if (snode == NULL) return;
3176                 coord_array[1][0] = snode->mx;
3177                 coord_array[1][1] = snode->my;
3178         }
3179 }
3180
3181 void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link,
3182                              int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3)
3183 {
3184         float coord_array[2][2];
3185         float linew;
3186         int i;
3187         
3188         node_link_straight_points(v2d, snode, link, coord_array);
3189         
3190         /* store current linewidth */
3191         glGetFloatv(GL_LINE_WIDTH, &linew);
3192         
3193         glEnable(GL_LINE_SMOOTH);
3194         
3195         if (do_triple) {
3196                 UI_ThemeColorShadeAlpha(th_col3, -80, -120);
3197                 glLineWidth(4.0f);