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