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