Merge branch 'blender-v2.93-release'
[blender.git] / source / blender / editors / space_node / drawnode.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup spnode
22  * \brief lower level node drawing for nodes (boarders, headers etc), also node layout.
23  */
24
25 #include "BLI_blenlib.h"
26 #include "BLI_math.h"
27 #include "BLI_system.h"
28 #include "BLI_threads.h"
29
30 #include "DNA_node_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_screen_types.h"
33 #include "DNA_space_types.h"
34 #include "DNA_text_types.h"
35 #include "DNA_userdef_types.h"
36
37 #include "BKE_context.h"
38 #include "BKE_curve.h"
39 #include "BKE_image.h"
40 #include "BKE_main.h"
41 #include "BKE_node.h"
42 #include "BKE_tracking.h"
43
44 #include "BLF_api.h"
45 #include "BLT_translation.h"
46
47 #include "BIF_glutil.h"
48
49 #include "GPU_batch.h"
50 #include "GPU_batch_presets.h"
51 #include "GPU_framebuffer.h"
52 #include "GPU_immediate.h"
53 #include "GPU_matrix.h"
54 #include "GPU_platform.h"
55 #include "GPU_state.h"
56
57 #include "DRW_engine.h"
58
59 #include "RNA_access.h"
60 #include "RNA_define.h"
61
62 #include "ED_node.h"
63 #include "ED_space_api.h"
64
65 #include "WM_api.h"
66 #include "WM_types.h"
67
68 #include "UI_resources.h"
69 #include "UI_view2d.h"
70
71 #include "IMB_colormanagement.h"
72 #include "IMB_imbuf_types.h"
73
74 #include "NOD_composite.h"
75 #include "NOD_geometry.h"
76 #include "NOD_shader.h"
77 #include "NOD_texture.h"
78 #include "node_intern.h" /* own include */
79
80 /* Default flags for uiItemR(). Name is kept short since this is used a lot in this file. */
81 #define DEFAULT_FLAGS UI_ITEM_R_SPLIT_EMPTY_NAME
82
83 /* ****************** SOCKET BUTTON DRAW FUNCTIONS ***************** */
84
85 static void node_socket_button_label(bContext *UNUSED(C),
86                                      uiLayout *layout,
87                                      PointerRNA *UNUSED(ptr),
88                                      PointerRNA *UNUSED(node_ptr),
89                                      const char *text)
90 {
91   uiItemL(layout, text, 0);
92 }
93
94 /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
95
96 static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
97 {
98   bNode *node = ptr->data;
99   /* first output stores value */
100   bNodeSocket *output = node->outputs.first;
101   PointerRNA sockptr;
102   RNA_pointer_create(ptr->owner_id, &RNA_NodeSocket, output, &sockptr);
103
104   uiItemR(layout, &sockptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE);
105 }
106
107 static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
108 {
109   bNode *node = ptr->data;
110   /* first output stores value */
111   bNodeSocket *output = node->outputs.first;
112   PointerRNA sockptr;
113   uiLayout *col;
114   RNA_pointer_create(ptr->owner_id, &RNA_NodeSocket, output, &sockptr);
115
116   col = uiLayoutColumn(layout, false);
117   uiTemplateColorPicker(col, &sockptr, "default_value", 1, 0, 0, 0);
118   uiItemR(col, &sockptr, "default_value", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
119 }
120
121 static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
122 {
123   bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
124
125   uiLayout *col = uiLayoutColumn(layout, false);
126   uiLayout *row = uiLayoutRow(col, true);
127   uiItemR(row, ptr, "blend_type", DEFAULT_FLAGS, "", ICON_NONE);
128   if (ELEM(ntree->type, NTREE_COMPOSIT, NTREE_TEXTURE)) {
129     uiItemR(row, ptr, "use_alpha", DEFAULT_FLAGS, "", ICON_IMAGE_RGB_ALPHA);
130   }
131
132   uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
133 }
134
135 static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
136 {
137 #if 0
138   /* XXX no context access here .. */
139   bNode *node = ptr->data;
140   CurveMapping *cumap = node->storage;
141
142   if (cumap) {
143     cumap->flag |= CUMA_DRAW_CFRA;
144     if (node->custom1 < node->custom2) {
145       cumap->sample[0] = (float)(CFRA - node->custom1) / (float)(node->custom2 - node->custom1);
146     }
147   }
148 #endif
149
150   uiTemplateCurveMapping(layout, ptr, "curve", 's', false, false, false, false);
151
152   uiLayout *row = uiLayoutRow(layout, true);
153   uiItemR(row, ptr, "frame_start", DEFAULT_FLAGS, IFACE_("Sta"), ICON_NONE);
154   uiItemR(row, ptr, "frame_end", DEFAULT_FLAGS, IFACE_("End"), ICON_NONE);
155 }
156
157 static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
158 {
159   uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
160 }
161
162 static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
163 {
164   uiTemplateCurveMapping(layout, ptr, "mapping", 'v', false, false, false, false);
165 }
166
167 #define SAMPLE_FLT_ISNONE FLT_MAX
168 /* bad bad, 2.5 will do better?... no it won't... */
169 static float _sample_col[4] = {SAMPLE_FLT_ISNONE};
170 void ED_node_sample_set(const float col[4])
171 {
172   if (col) {
173     copy_v4_v4(_sample_col, col);
174   }
175   else {
176     copy_v4_fl(_sample_col, SAMPLE_FLT_ISNONE);
177   }
178 }
179
180 static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
181 {
182   bNode *node = ptr->data;
183   CurveMapping *cumap = node->storage;
184
185   if (_sample_col[0] != SAMPLE_FLT_ISNONE) {
186     cumap->flag |= CUMA_DRAW_SAMPLE;
187     copy_v3_v3(cumap->sample, _sample_col);
188   }
189   else {
190     cumap->flag &= ~CUMA_DRAW_SAMPLE;
191   }
192
193   /* "Tone" (Standard/Film-like) only used in the Compositor. */
194   bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
195   uiTemplateCurveMapping(
196       layout, ptr, "mapping", 'c', false, false, false, (ntree->type == NTREE_COMPOSIT));
197 }
198
199 static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
200 {
201   bNode *node = ptr->data;
202   /* first output stores normal */
203   bNodeSocket *output = node->outputs.first;
204   PointerRNA sockptr;
205   RNA_pointer_create(ptr->owner_id, &RNA_NodeSocket, output, &sockptr);
206
207   uiItemR(layout, &sockptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE);
208 }
209
210 static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
211 {
212   bNode *node = ptr->data;
213
214   short multi = (node->id && ((Tex *)node->id)->use_nodes && (node->type != CMP_NODE_TEXTURE) &&
215                  (node->type != TEX_NODE_TEXTURE));
216
217   uiItemR(layout, ptr, "texture", DEFAULT_FLAGS, "", ICON_NONE);
218
219   if (multi) {
220     /* Number Drawing not optimal here, better have a list*/
221     uiItemR(layout, ptr, "node_output", DEFAULT_FLAGS, "", ICON_NONE);
222   }
223 }
224
225 static void node_shader_buts_clamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
226 {
227   uiItemR(layout, ptr, "clamp_type", DEFAULT_FLAGS, "", ICON_NONE);
228 }
229
230 static void node_shader_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
231 {
232   uiItemR(layout, ptr, "interpolation_type", DEFAULT_FLAGS, "", ICON_NONE);
233   if (!ELEM(RNA_enum_get(ptr, "interpolation_type"),
234             NODE_MAP_RANGE_SMOOTHSTEP,
235             NODE_MAP_RANGE_SMOOTHERSTEP)) {
236     uiItemR(layout, ptr, "clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
237   }
238 }
239
240 static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
241 {
242   uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
243   uiItemR(layout, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
244 }
245
246 static int node_resize_area_default(bNode *node, int x, int y)
247 {
248   if (node->flag & NODE_HIDDEN) {
249     rctf totr = node->totr;
250     /* right part of node */
251     totr.xmin = node->totr.xmax - 20.0f;
252     if (BLI_rctf_isect_pt(&totr, x, y)) {
253       return NODE_RESIZE_RIGHT;
254     }
255
256     return 0;
257   }
258
259   const float size = NODE_RESIZE_MARGIN;
260   rctf totr = node->totr;
261   int dir = 0;
262
263   if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax) {
264     dir |= NODE_RESIZE_RIGHT;
265   }
266   if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax) {
267     dir |= NODE_RESIZE_LEFT;
268   }
269   return dir;
270 }
271
272 /* ****************** BUTTON CALLBACKS FOR COMMON NODES ***************** */
273
274 static void node_draw_buttons_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
275 {
276   uiTemplateIDBrowse(
277       layout, C, ptr, "node_tree", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, NULL);
278 }
279
280 /* XXX Does a bounding box update by iterating over all children.
281  * Not ideal to do this in every draw call, but doing as transform callback doesn't work,
282  * since the child node totr rects are not updated properly at that point.
283  */
284 static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
285 {
286   const float margin = 1.5f * U.widget_unit;
287   NodeFrame *data = (NodeFrame *)node->storage;
288
289   /* init rect from current frame size */
290   rctf rect;
291   node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
292   node_to_view(
293       node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
294
295   /* frame can be resized manually only if shrinking is disabled or no children are attached */
296   data->flag |= NODE_FRAME_RESIZEABLE;
297   /* for shrinking bbox, initialize the rect from first child node */
298   bool bbinit = (data->flag & NODE_FRAME_SHRINK);
299   /* fit bounding box to all children */
300   LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
301     if (tnode->parent != node) {
302       continue;
303     }
304
305     /* add margin to node rect */
306     rctf noderect = tnode->totr;
307     noderect.xmin -= margin;
308     noderect.xmax += margin;
309     noderect.ymin -= margin;
310     noderect.ymax += margin;
311
312     /* first child initializes frame */
313     if (bbinit) {
314       bbinit = 0;
315       rect = noderect;
316       data->flag &= ~NODE_FRAME_RESIZEABLE;
317     }
318     else {
319       BLI_rctf_union(&rect, &noderect);
320     }
321   }
322
323   /* now adjust the frame size from view-space bounding box */
324   node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
325   float xmax, ymax;
326   node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax);
327   node->width = xmax - node->offsetx;
328   node->height = -ymax + node->offsety;
329
330   node->totr = rect;
331 }
332
333 static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float aspect)
334 {
335   /* XXX font id is crap design */
336   const int fontid = UI_style_get()->widgetlabel.uifont_id;
337   NodeFrame *data = (NodeFrame *)node->storage;
338   const int font_size = data->label_size / aspect;
339
340   char label[MAX_NAME];
341   nodeLabel(ntree, node, label, sizeof(label));
342
343   BLF_enable(fontid, BLF_ASPECT);
344   BLF_aspect(fontid, aspect, aspect, 1.0f);
345   /* clamp otherwise it can suck up a LOT of memory */
346   BLF_size(fontid, MIN2(24, font_size), U.dpi);
347
348   /* title color */
349   int color_id = node_get_colorid(node);
350   uchar color[3];
351   UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color);
352   BLF_color3ubv(fontid, color);
353
354   const float margin = (float)(NODE_DY / 4);
355   const float width = BLF_width(fontid, label, sizeof(label));
356   const float ascender = BLF_ascender(fontid);
357   const int label_height = ((margin / aspect) + (ascender * aspect));
358
359   /* 'x' doesn't need aspect correction */
360   rctf *rct = &node->totr;
361   /* XXX a bit hacky, should use separate align values for x and y */
362   float x = BLI_rctf_cent_x(rct) - (0.5f * width);
363   float y = rct->ymax - label_height;
364
365   BLF_position(fontid, x, y, 0);
366   BLF_draw(fontid, label, BLF_DRAW_STR_DUMMY_MAX);
367
368   /* draw text body */
369   if (node->id) {
370     Text *text = (Text *)node->id;
371     const int line_height_max = BLF_height_max(fontid);
372     const float line_spacing = (line_height_max * aspect);
373     const float line_width = (BLI_rctf_size_x(rct) - margin) / aspect;
374
375     /* 'x' doesn't need aspect correction */
376     x = rct->xmin + margin;
377     y = rct->ymax - (label_height + line_spacing);
378     /* early exit */
379     int y_min = y + ((margin * 2) - (y - rct->ymin));
380
381     BLF_enable(fontid, BLF_CLIPPING | BLF_WORD_WRAP);
382     BLF_clipping(fontid,
383                  rct->xmin,
384                  /* round to avoid clipping half-way through a line */
385                  y - (floorf(((y - rct->ymin) - (margin * 2)) / line_spacing) * line_spacing),
386                  rct->xmin + line_width,
387                  rct->ymax);
388
389     BLF_wordwrap(fontid, line_width);
390
391     LISTBASE_FOREACH (TextLine *, line, &text->lines) {
392       struct ResultBLF info;
393       if (line->line[0]) {
394         BLF_position(fontid, x, y, 0);
395         BLF_draw_ex(fontid, line->line, line->len, &info);
396         y -= line_spacing * info.lines;
397       }
398       else {
399         y -= line_spacing;
400       }
401       if (y < y_min) {
402         break;
403       }
404     }
405
406     BLF_disable(fontid, BLF_CLIPPING | BLF_WORD_WRAP);
407   }
408
409   BLF_disable(fontid, BLF_ASPECT);
410 }
411
412 static void node_draw_frame(const bContext *C,
413                             ARegion *region,
414                             SpaceNode *snode,
415                             bNodeTree *ntree,
416                             bNode *node,
417                             bNodeInstanceKey UNUSED(key))
418 {
419
420   /* skip if out of view */
421   if (BLI_rctf_isect(&node->totr, &region->v2d.cur, NULL) == false) {
422     UI_block_end(C, node->block);
423     node->block = NULL;
424     return;
425   }
426
427   float color[4];
428   UI_GetThemeColor4fv(TH_NODE_FRAME, color);
429   const float alpha = color[3];
430
431   /* shadow */
432   node_draw_shadow(snode, node, BASIS_RAD, alpha);
433
434   /* body */
435   if (node->flag & NODE_CUSTOM_COLOR) {
436     rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], alpha);
437   }
438   else {
439     UI_GetThemeColor4fv(TH_NODE_FRAME, color);
440   }
441
442   const rctf *rct = &node->totr;
443   UI_draw_roundbox_corner_set(UI_CNR_ALL);
444   UI_draw_roundbox_aa(rct, true, BASIS_RAD, color);
445
446   /* outline active and selected emphasis */
447   if (node->flag & SELECT) {
448     if (node->flag & NODE_ACTIVE) {
449       UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -40, color);
450     }
451     else {
452       UI_GetThemeColorShadeAlpha4fv(TH_SELECT, 0, -40, color);
453     }
454
455     UI_draw_roundbox_aa(rct, false, BASIS_RAD, color);
456   }
457
458   /* label */
459   if (node->label[0] != '\0') {
460     node_draw_frame_label(ntree, node, snode->runtime->aspect);
461   }
462
463   UI_block_end(C, node->block);
464   UI_block_draw(C, node->block);
465   node->block = NULL;
466 }
467
468 static int node_resize_area_frame(bNode *node, int x, int y)
469 {
470   const float size = 10.0f;
471   NodeFrame *data = (NodeFrame *)node->storage;
472   rctf totr = node->totr;
473   int dir = 0;
474
475   /* shrinking frame size is determined by child nodes */
476   if (!(data->flag & NODE_FRAME_RESIZEABLE)) {
477     return 0;
478   }
479
480   if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax) {
481     dir |= NODE_RESIZE_RIGHT;
482   }
483   if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax) {
484     dir |= NODE_RESIZE_LEFT;
485   }
486   if (x >= totr.xmin && x < totr.xmax && y >= totr.ymax - size && y < totr.ymax) {
487     dir |= NODE_RESIZE_TOP;
488   }
489   if (x >= totr.xmin && x < totr.xmax && y >= totr.ymin && y < totr.ymin + size) {
490     dir |= NODE_RESIZE_BOTTOM;
491   }
492
493   return dir;
494 }
495
496 static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
497 {
498   uiItemR(layout, ptr, "label_size", DEFAULT_FLAGS, IFACE_("Label Size"), ICON_NONE);
499   uiItemR(layout, ptr, "shrink", DEFAULT_FLAGS, IFACE_("Shrink"), ICON_NONE);
500   uiItemR(layout, ptr, "text", DEFAULT_FLAGS, NULL, ICON_NONE);
501 }
502
503 #define NODE_REROUTE_SIZE 8.0f
504
505 static void node_draw_reroute_prepare(const bContext *UNUSED(C),
506                                       bNodeTree *UNUSED(ntree),
507                                       bNode *node)
508 {
509   /* get "global" coords */
510   float locx, locy;
511   node_to_view(node, 0.0f, 0.0f, &locx, &locy);
512
513   /* reroute node has exactly one input and one output, both in the same place */
514   bNodeSocket *nsock = node->outputs.first;
515   nsock->locx = locx;
516   nsock->locy = locy;
517
518   nsock = node->inputs.first;
519   nsock->locx = locx;
520   nsock->locy = locy;
521
522   const float size = NODE_REROUTE_SIZE;
523   node->width = size * 2;
524   node->totr.xmin = locx - size;
525   node->totr.xmax = locx + size;
526   node->totr.ymax = locy + size;
527   node->totr.ymin = locy - size;
528 }
529
530 static void node_draw_reroute(const bContext *C,
531                               ARegion *region,
532                               SpaceNode *UNUSED(snode),
533                               bNodeTree *ntree,
534                               bNode *node,
535                               bNodeInstanceKey UNUSED(key))
536 {
537   char showname[128]; /* 128 used below */
538   rctf *rct = &node->totr;
539
540   /* skip if out of view */
541   if (node->totr.xmax < region->v2d.cur.xmin || node->totr.xmin > region->v2d.cur.xmax ||
542       node->totr.ymax < region->v2d.cur.ymin || node->totr.ymin > region->v2d.cur.ymax) {
543     UI_block_end(C, node->block);
544     node->block = NULL;
545     return;
546   }
547
548   /* XXX only kept for debugging
549    * selection state is indicated by socket outline below!
550    */
551 #if 0
552   float size = NODE_REROUTE_SIZE;
553
554   /* body */
555   float debug_color[4];
556   UI_draw_roundbox_corner_set(UI_CNR_ALL);
557   UI_GetThemeColor4fv(TH_NODE, debug_color);
558   UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color);
559
560   /* outline active and selected emphasis */
561   if (node->flag & SELECT) {
562     GPU_blend(GPU_BLEND_ALPHA);
563     GPU_line_smooth(true);
564     /* Using different shades of #TH_TEXT_HI for the emphasis, like triangle. */
565     if (node->flag & NODE_ACTIVE) {
566       UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, 0, -40, debug_color);
567     }
568     else {
569       UI_GetThemeColorShadeAlpha4fv(TH_TEXT_HI, -20, -120, debug_color);
570     }
571     UI_draw_roundbox_4fv(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color);
572
573     GPU_line_smooth(false);
574     GPU_blend(GPU_BLEND_NONE);
575   }
576 #endif
577
578   if (node->label[0] != '\0') {
579     /* draw title (node label) */
580     BLI_strncpy(showname, node->label, sizeof(showname));
581     uiDefBut(node->block,
582              UI_BTYPE_LABEL,
583              0,
584              showname,
585              (int)(rct->xmin - NODE_DYS),
586              (int)(rct->ymax),
587              (short)512,
588              (short)NODE_DY,
589              NULL,
590              0,
591              0,
592              0,
593              0,
594              NULL);
595   }
596
597   /* only draw input socket. as they all are placed on the same position.
598    * highlight also if node itself is selected, since we don't display the node body separately!
599    */
600   node_draw_sockets(&region->v2d, C, ntree, node, false, node->flag & SELECT);
601
602   UI_block_end(C, node->block);
603   UI_block_draw(C, node->block);
604   node->block = NULL;
605 }
606
607 /* Special tweak area for reroute node.
608  * Since this node is quite small, we use a larger tweak area for grabbing than for selection.
609  */
610 static int node_tweak_area_reroute(bNode *node, int x, int y)
611 {
612   /* square of tweak radius */
613   const float tweak_radius_sq = square_f(24.0f);
614
615   bNodeSocket *sock = node->inputs.first;
616   float dx = sock->locx - x;
617   float dy = sock->locy - y;
618   return (dx * dx + dy * dy <= tweak_radius_sq);
619 }
620
621 static void node_common_set_butfunc(bNodeType *ntype)
622 {
623   switch (ntype->type) {
624     case NODE_GROUP:
625       ntype->draw_buttons = node_draw_buttons_group;
626       break;
627     case NODE_FRAME:
628       ntype->draw_nodetype = node_draw_frame;
629       ntype->draw_nodetype_prepare = node_draw_frame_prepare;
630       ntype->draw_buttons_ex = node_buts_frame_ex;
631       ntype->resize_area_func = node_resize_area_frame;
632       break;
633     case NODE_REROUTE:
634       ntype->draw_nodetype = node_draw_reroute;
635       ntype->draw_nodetype_prepare = node_draw_reroute_prepare;
636       ntype->tweak_area_func = node_tweak_area_reroute;
637       break;
638   }
639 }
640
641 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
642
643 static void node_buts_image_user(uiLayout *layout,
644                                  bContext *C,
645                                  PointerRNA *ptr,
646                                  PointerRNA *imaptr,
647                                  PointerRNA *iuserptr,
648                                  const bool show_layer_selection,
649                                  const bool show_color_management)
650 {
651   if (!imaptr->data) {
652     return;
653   }
654
655   uiLayout *col = uiLayoutColumn(layout, false);
656
657   uiItemR(col, imaptr, "source", DEFAULT_FLAGS, "", ICON_NONE);
658
659   const int source = RNA_enum_get(imaptr, "source");
660
661   if (source == IMA_SRC_SEQUENCE) {
662     /* don't use iuser->framenr directly
663      * because it may not be updated if auto-refresh is off */
664     Scene *scene = CTX_data_scene(C);
665     ImageUser *iuser = iuserptr->data;
666     /* Image *ima = imaptr->data; */ /* UNUSED */
667
668     char numstr[32];
669     const int framenr = BKE_image_user_frame_get(iuser, CFRA, NULL);
670     BLI_snprintf(numstr, sizeof(numstr), IFACE_("Frame: %d"), framenr);
671     uiItemL(layout, numstr, ICON_NONE);
672   }
673
674   if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
675     col = uiLayoutColumn(layout, true);
676     uiItemR(col, ptr, "frame_duration", DEFAULT_FLAGS, NULL, ICON_NONE);
677     uiItemR(col, ptr, "frame_start", DEFAULT_FLAGS, NULL, ICON_NONE);
678     uiItemR(col, ptr, "frame_offset", DEFAULT_FLAGS, NULL, ICON_NONE);
679     uiItemR(col, ptr, "use_cyclic", DEFAULT_FLAGS, NULL, ICON_NONE);
680     uiItemR(col, ptr, "use_auto_refresh", DEFAULT_FLAGS, NULL, ICON_NONE);
681   }
682
683   if (show_layer_selection && RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER &&
684       RNA_boolean_get(ptr, "has_layers")) {
685     col = uiLayoutColumn(layout, false);
686     uiItemR(col, ptr, "layer", DEFAULT_FLAGS, NULL, ICON_NONE);
687   }
688
689   if (show_color_management) {
690     uiLayout *split = uiLayoutSplit(layout, 0.5f, true);
691     PointerRNA colorspace_settings_ptr = RNA_pointer_get(imaptr, "colorspace_settings");
692     uiItemL(split, IFACE_("Color Space"), ICON_NONE);
693     uiItemR(split, &colorspace_settings_ptr, "name", DEFAULT_FLAGS, "", ICON_NONE);
694
695     /* Avoid losing changes image is painted. */
696     if (BKE_image_is_dirty(imaptr->data)) {
697       uiLayoutSetEnabled(split, false);
698     }
699   }
700 }
701
702 static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
703 {
704   uiItemR(layout, ptr, "vector_type", DEFAULT_FLAGS, NULL, ICON_NONE);
705 }
706
707 static void node_shader_buts_vector_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
708 {
709   uiItemR(layout, ptr, "rotation_type", DEFAULT_FLAGS, NULL, ICON_NONE);
710   uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, NULL, 0);
711 }
712
713 static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
714 {
715   uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE);
716 }
717
718 static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
719 {
720   uiItemR(layout, ptr, "vector_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
721   uiItemR(layout, ptr, "convert_from", DEFAULT_FLAGS, "", ICON_NONE);
722   uiItemR(layout, ptr, "convert_to", DEFAULT_FLAGS, "", ICON_NONE);
723 }
724
725 static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
726 {
727   uiItemR(layout, ptr, "attribute_type", DEFAULT_FLAGS, IFACE_("Type"), ICON_NONE);
728   uiItemR(layout, ptr, "attribute_name", DEFAULT_FLAGS, IFACE_("Name"), ICON_NONE);
729 }
730
731 static void node_shader_buts_wireframe(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
732 {
733   uiItemR(layout, ptr, "use_pixel_size", DEFAULT_FLAGS, NULL, 0);
734 }
735
736 static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
737 {
738   PointerRNA imaptr = RNA_pointer_get(ptr, "image");
739   PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
740
741   uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
742   uiTemplateID(layout,
743                C,
744                ptr,
745                "image",
746                "IMAGE_OT_new",
747                "IMAGE_OT_open",
748                NULL,
749                UI_TEMPLATE_ID_FILTER_ALL,
750                false,
751                NULL);
752   uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, "", ICON_NONE);
753   uiItemR(layout, ptr, "projection", DEFAULT_FLAGS, "", ICON_NONE);
754
755   if (RNA_enum_get(ptr, "projection") == SHD_PROJ_BOX) {
756     uiItemR(layout, ptr, "projection_blend", DEFAULT_FLAGS, "Blend", ICON_NONE);
757   }
758
759   uiItemR(layout, ptr, "extension", DEFAULT_FLAGS, "", ICON_NONE);
760
761   /* note: image user properties used directly here, unlike compositor image node,
762    * which redefines them in the node struct RNA to get proper updates.
763    */
764   node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false, true);
765 }
766
767 static void node_shader_buts_tex_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
768 {
769   PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
770   uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0);
771 }
772
773 static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr)
774 {
775   PointerRNA imaptr = RNA_pointer_get(ptr, "image");
776   PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
777
778   uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
779   uiTemplateID(layout,
780                C,
781                ptr,
782                "image",
783                "IMAGE_OT_new",
784                "IMAGE_OT_open",
785                NULL,
786                UI_TEMPLATE_ID_FILTER_ALL,
787                false,
788                NULL);
789
790   uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, "", ICON_NONE);
791   uiItemR(layout, ptr, "projection", DEFAULT_FLAGS, "", ICON_NONE);
792
793   node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false, true);
794 }
795
796 static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
797 {
798   PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
799   uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0);
800
801   uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, IFACE_("Interpolation"), ICON_NONE);
802   uiItemR(layout, ptr, "projection", DEFAULT_FLAGS, IFACE_("Projection"), ICON_NONE);
803 }
804
805 static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
806 {
807   uiItemR(layout, ptr, "sky_type", DEFAULT_FLAGS, "", ICON_NONE);
808
809   if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_PREETHAM) {
810     uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE);
811     uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE);
812   }
813   if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_HOSEK) {
814     uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE);
815     uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE);
816     uiItemR(layout, ptr, "ground_albedo", DEFAULT_FLAGS, NULL, ICON_NONE);
817   }
818   if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) {
819     uiItemR(layout, ptr, "sun_disc", DEFAULT_FLAGS, NULL, 0);
820
821     uiLayout *col;
822     if (RNA_boolean_get(ptr, "sun_disc")) {
823       col = uiLayoutColumn(layout, true);
824       uiItemR(col, ptr, "sun_size", DEFAULT_FLAGS, NULL, ICON_NONE);
825       uiItemR(col, ptr, "sun_intensity", DEFAULT_FLAGS, NULL, ICON_NONE);
826     }
827
828     col = uiLayoutColumn(layout, true);
829     uiItemR(col, ptr, "sun_elevation", DEFAULT_FLAGS, NULL, ICON_NONE);
830     uiItemR(col, ptr, "sun_rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
831
832     uiItemR(layout, ptr, "altitude", DEFAULT_FLAGS, NULL, ICON_NONE);
833
834     col = uiLayoutColumn(layout, true);
835     uiItemR(col, ptr, "air_density", DEFAULT_FLAGS, NULL, ICON_NONE);
836     uiItemR(col, ptr, "dust_density", DEFAULT_FLAGS, NULL, ICON_NONE);
837     uiItemR(col, ptr, "ozone_density", DEFAULT_FLAGS, NULL, ICON_NONE);
838   }
839 }
840
841 static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
842 {
843   uiItemR(layout, ptr, "gradient_type", DEFAULT_FLAGS, "", ICON_NONE);
844 }
845
846 static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
847 {
848   uiItemR(layout, ptr, "turbulence_depth", DEFAULT_FLAGS, NULL, ICON_NONE);
849 }
850
851 static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
852 {
853   uiLayout *col;
854
855   col = uiLayoutColumn(layout, true);
856   uiItemR(col, ptr, "offset", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, IFACE_("Offset"), ICON_NONE);
857   uiItemR(col, ptr, "offset_frequency", DEFAULT_FLAGS, IFACE_("Frequency"), ICON_NONE);
858
859   col = uiLayoutColumn(layout, true);
860   uiItemR(col, ptr, "squash", DEFAULT_FLAGS, IFACE_("Squash"), ICON_NONE);
861   uiItemR(col, ptr, "squash_frequency", DEFAULT_FLAGS, IFACE_("Frequency"), ICON_NONE);
862 }
863
864 static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
865 {
866   uiItemR(layout, ptr, "wave_type", DEFAULT_FLAGS, "", ICON_NONE);
867   int type = RNA_enum_get(ptr, "wave_type");
868   if (type == SHD_WAVE_BANDS) {
869     uiItemR(layout, ptr, "bands_direction", DEFAULT_FLAGS, "", ICON_NONE);
870   }
871   else { /* SHD_WAVE_RINGS */
872     uiItemR(layout, ptr, "rings_direction", DEFAULT_FLAGS, "", ICON_NONE);
873   }
874
875   uiItemR(layout, ptr, "wave_profile", DEFAULT_FLAGS, "", ICON_NONE);
876 }
877
878 static void node_shader_buts_tex_musgrave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
879 {
880   uiItemR(layout, ptr, "musgrave_dimensions", DEFAULT_FLAGS, "", ICON_NONE);
881   uiItemR(layout, ptr, "musgrave_type", DEFAULT_FLAGS, "", ICON_NONE);
882 }
883
884 static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
885 {
886   uiItemR(layout, ptr, "voronoi_dimensions", DEFAULT_FLAGS, "", ICON_NONE);
887   uiItemR(layout, ptr, "feature", DEFAULT_FLAGS, "", ICON_NONE);
888   int feature = RNA_enum_get(ptr, "feature");
889   if (!ELEM(feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS) &&
890       RNA_enum_get(ptr, "voronoi_dimensions") != 1) {
891     uiItemR(layout, ptr, "distance", DEFAULT_FLAGS, "", ICON_NONE);
892   }
893 }
894
895 static void node_shader_buts_tex_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
896 {
897   uiItemR(layout, ptr, "noise_dimensions", DEFAULT_FLAGS, "", ICON_NONE);
898 }
899
900 static void node_shader_buts_tex_pointdensity(uiLayout *layout,
901                                               bContext *UNUSED(C),
902                                               PointerRNA *ptr)
903 {
904   bNode *node = ptr->data;
905   NodeShaderTexPointDensity *shader_point_density = node->storage;
906   Object *ob = (Object *)node->id;
907
908   PointerRNA ob_ptr, obdata_ptr;
909   RNA_id_pointer_create((ID *)ob, &ob_ptr);
910   RNA_id_pointer_create(ob ? (ID *)ob->data : NULL, &obdata_ptr);
911
912   uiItemR(layout, ptr, "point_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
913   uiItemR(layout, ptr, "object", DEFAULT_FLAGS, NULL, ICON_NONE);
914
915   if (node->id && shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
916     PointerRNA dataptr;
917     RNA_id_pointer_create((ID *)node->id, &dataptr);
918     uiItemPointerR(layout, ptr, "particle_system", &dataptr, "particle_systems", NULL, ICON_NONE);
919   }
920
921   uiItemR(layout, ptr, "space", DEFAULT_FLAGS, NULL, ICON_NONE);
922   uiItemR(layout, ptr, "radius", DEFAULT_FLAGS, NULL, ICON_NONE);
923   uiItemR(layout, ptr, "interpolation", DEFAULT_FLAGS, NULL, ICON_NONE);
924   uiItemR(layout, ptr, "resolution", DEFAULT_FLAGS, NULL, ICON_NONE);
925   if (shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
926     uiItemR(layout, ptr, "particle_color_source", DEFAULT_FLAGS, NULL, ICON_NONE);
927   }
928   else {
929     uiItemR(layout, ptr, "vertex_color_source", DEFAULT_FLAGS, NULL, ICON_NONE);
930     if (shader_point_density->ob_color_source == SHD_POINTDENSITY_COLOR_VERTWEIGHT) {
931       if (ob_ptr.data) {
932         uiItemPointerR(
933             layout, ptr, "vertex_attribute_name", &ob_ptr, "vertex_groups", "", ICON_NONE);
934       }
935     }
936     if (shader_point_density->ob_color_source == SHD_POINTDENSITY_COLOR_VERTCOL) {
937       if (obdata_ptr.data) {
938         uiItemPointerR(
939             layout, ptr, "vertex_attribute_name", &obdata_ptr, "vertex_colors", "", ICON_NONE);
940       }
941     }
942   }
943 }
944
945 static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
946 {
947   uiItemR(layout, ptr, "object", DEFAULT_FLAGS, NULL, 0);
948   uiItemR(layout, ptr, "from_instancer", DEFAULT_FLAGS, NULL, 0);
949 }
950
951 static void node_shader_buts_bump(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
952 {
953   uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, NULL, 0);
954 }
955
956 static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *ptr)
957 {
958   uiItemR(layout, ptr, "from_instancer", DEFAULT_FLAGS, NULL, 0);
959
960   if (!RNA_boolean_get(ptr, "from_instancer")) {
961     PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
962
963     if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
964       PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
965       uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
966     }
967   }
968 }
969
970 static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, PointerRNA *ptr)
971 {
972   PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
973   if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
974     PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
975
976     if (U.experimental.use_sculpt_vertex_colors &&
977         RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
978       uiItemPointerR(
979           layout, ptr, "layer_name", &dataptr, "sculpt_vertex_colors", "", ICON_GROUP_VCOL);
980     }
981     else {
982       uiItemPointerR(layout, ptr, "layer_name", &dataptr, "vertex_colors", "", ICON_GROUP_VCOL);
983     }
984   }
985   else {
986     uiItemL(layout, "No mesh in active object.", ICON_ERROR);
987   }
988 }
989
990 static void node_shader_buts_uvalongstroke(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
991 {
992   uiItemR(layout, ptr, "use_tips", DEFAULT_FLAGS, NULL, 0);
993 }
994
995 static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRNA *ptr)
996 {
997   uiItemR(layout, ptr, "space", DEFAULT_FLAGS, "", 0);
998
999   if (RNA_enum_get(ptr, "space") == SHD_SPACE_TANGENT) {
1000     PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
1001
1002     if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
1003       PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
1004       uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
1005     }
1006     else {
1007       uiItemR(layout, ptr, "uv_map", DEFAULT_FLAGS, "", 0);
1008     }
1009   }
1010 }
1011
1012 static void node_shader_buts_displacement(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1013 {
1014   uiItemR(layout, ptr, "space", DEFAULT_FLAGS, "", 0);
1015 }
1016
1017 static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *ptr)
1018 {
1019   uiLayout *split, *row;
1020
1021   split = uiLayoutSplit(layout, 0.0f, false);
1022
1023   uiItemR(split, ptr, "direction_type", DEFAULT_FLAGS, "", 0);
1024
1025   row = uiLayoutRow(split, false);
1026
1027   if (RNA_enum_get(ptr, "direction_type") == SHD_TANGENT_UVMAP) {
1028     PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
1029
1030     if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
1031       PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
1032       uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE);
1033     }
1034     else {
1035       uiItemR(row, ptr, "uv_map", DEFAULT_FLAGS, "", 0);
1036     }
1037   }
1038   else {
1039     uiItemR(row, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, 0);
1040   }
1041 }
1042
1043 static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1044 {
1045   uiItemR(layout, ptr, "distribution", DEFAULT_FLAGS, "", ICON_NONE);
1046 }
1047
1048 static void node_shader_buts_principled(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1049 {
1050   uiItemR(layout, ptr, "distribution", DEFAULT_FLAGS, "", ICON_NONE);
1051   uiItemR(layout, ptr, "subsurface_method", DEFAULT_FLAGS, "", ICON_NONE);
1052 }
1053
1054 static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1055 {
1056   uiItemR(layout, ptr, "distribution", DEFAULT_FLAGS, "", ICON_NONE);
1057 }
1058
1059 static void node_shader_buts_subsurface(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1060 {
1061   uiItemR(layout, ptr, "falloff", DEFAULT_FLAGS, "", ICON_NONE);
1062 }
1063
1064 static void node_shader_buts_toon(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1065 {
1066   uiItemR(layout, ptr, "component", DEFAULT_FLAGS, "", ICON_NONE);
1067 }
1068
1069 static void node_shader_buts_hair(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1070 {
1071   uiItemR(layout, ptr, "component", DEFAULT_FLAGS, "", ICON_NONE);
1072 }
1073
1074 static void node_shader_buts_principled_hair(uiLayout *layout,
1075                                              bContext *UNUSED(C),
1076                                              PointerRNA *ptr)
1077 {
1078   uiItemR(layout, ptr, "parametrization", DEFAULT_FLAGS, "", ICON_NONE);
1079 }
1080
1081 static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1082 {
1083   uiLayout *row;
1084
1085   row = uiLayoutRow(layout, false);
1086   uiItemR(row, ptr, "mode", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1087
1088   row = uiLayoutRow(layout, true);
1089
1090   if (RNA_enum_get(ptr, "mode") == NODE_IES_INTERNAL) {
1091     uiItemR(row, ptr, "ies", DEFAULT_FLAGS, "", ICON_NONE);
1092   }
1093   else {
1094     uiItemR(row, ptr, "filepath", DEFAULT_FLAGS, "", ICON_NONE);
1095   }
1096 }
1097
1098 static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1099 {
1100   uiLayout *row;
1101
1102   row = uiLayoutRow(layout, false);
1103   uiItemR(row, ptr, "mode", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1104
1105   row = uiLayoutRow(layout, true);
1106
1107   if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_INTERNAL) {
1108     uiItemR(row, ptr, "script", DEFAULT_FLAGS, "", ICON_NONE);
1109   }
1110   else {
1111     uiItemR(row, ptr, "filepath", DEFAULT_FLAGS, "", ICON_NONE);
1112   }
1113
1114   uiItemO(row, "", ICON_FILE_REFRESH, "node.shader_script_update");
1115 }
1116
1117 static void node_shader_buts_script_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
1118 {
1119   uiItemS(layout);
1120
1121   node_shader_buts_script(layout, C, ptr);
1122
1123 #if 0 /* not implemented yet */
1124   if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_EXTERNAL) {
1125     uiItemR(layout, ptr, "use_auto_update", DEFAULT_FLAGS, NULL, ICON_NONE);
1126   }
1127 #endif
1128 }
1129
1130 static void node_buts_output_shader(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1131 {
1132   uiItemR(layout, ptr, "target", DEFAULT_FLAGS, "", ICON_NONE);
1133 }
1134
1135 static void node_buts_output_linestyle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1136 {
1137   uiLayout *row, *col;
1138
1139   col = uiLayoutColumn(layout, false);
1140   row = uiLayoutRow(col, true);
1141   uiItemR(row, ptr, "blend_type", DEFAULT_FLAGS, "", ICON_NONE);
1142   uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
1143 }
1144
1145 static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1146 {
1147   uiItemR(layout, ptr, "samples", DEFAULT_FLAGS, NULL, ICON_NONE);
1148 }
1149
1150 static void node_shader_buts_ambient_occlusion(uiLayout *layout,
1151                                                bContext *UNUSED(C),
1152                                                PointerRNA *ptr)
1153 {
1154   uiItemR(layout, ptr, "samples", DEFAULT_FLAGS, NULL, ICON_NONE);
1155   uiItemR(layout, ptr, "inside", DEFAULT_FLAGS, NULL, ICON_NONE);
1156   uiItemR(layout, ptr, "only_local", DEFAULT_FLAGS, NULL, ICON_NONE);
1157 }
1158
1159 static void node_shader_buts_white_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1160 {
1161   uiItemR(layout, ptr, "noise_dimensions", DEFAULT_FLAGS, "", ICON_NONE);
1162 }
1163
1164 static void node_shader_buts_output_aov(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1165 {
1166   uiItemR(layout, ptr, "name", DEFAULT_FLAGS, NULL, ICON_NONE);
1167 }
1168
1169 /* only once called */
1170 static void node_shader_set_butfunc(bNodeType *ntype)
1171 {
1172   switch (ntype->type) {
1173     case SH_NODE_NORMAL:
1174       ntype->draw_buttons = node_buts_normal;
1175       break;
1176     case SH_NODE_CURVE_VEC:
1177       ntype->draw_buttons = node_buts_curvevec;
1178       break;
1179     case SH_NODE_CURVE_RGB:
1180       ntype->draw_buttons = node_buts_curvecol;
1181       break;
1182     case SH_NODE_MAPPING:
1183       ntype->draw_buttons = node_shader_buts_mapping;
1184       break;
1185     case SH_NODE_VALUE:
1186       ntype->draw_buttons = node_buts_value;
1187       break;
1188     case SH_NODE_RGB:
1189       ntype->draw_buttons = node_buts_rgb;
1190       break;
1191     case SH_NODE_MIX_RGB:
1192       ntype->draw_buttons = node_buts_mix_rgb;
1193       break;
1194     case SH_NODE_VALTORGB:
1195       ntype->draw_buttons = node_buts_colorramp;
1196       break;
1197     case SH_NODE_CLAMP:
1198       ntype->draw_buttons = node_shader_buts_clamp;
1199       break;
1200     case SH_NODE_MAP_RANGE:
1201       ntype->draw_buttons = node_shader_buts_map_range;
1202       break;
1203     case SH_NODE_MATH:
1204       ntype->draw_buttons = node_buts_math;
1205       break;
1206     case SH_NODE_VECTOR_MATH:
1207       ntype->draw_buttons = node_shader_buts_vect_math;
1208       break;
1209     case SH_NODE_VECTOR_ROTATE:
1210       ntype->draw_buttons = node_shader_buts_vector_rotate;
1211       break;
1212     case SH_NODE_VECT_TRANSFORM:
1213       ntype->draw_buttons = node_shader_buts_vect_transform;
1214       break;
1215     case SH_NODE_ATTRIBUTE:
1216       ntype->draw_buttons = node_shader_buts_attribute;
1217       break;
1218     case SH_NODE_WIREFRAME:
1219       ntype->draw_buttons = node_shader_buts_wireframe;
1220       break;
1221     case SH_NODE_TEX_SKY:
1222       ntype->draw_buttons = node_shader_buts_tex_sky;
1223       break;
1224     case SH_NODE_TEX_IMAGE:
1225       ntype->draw_buttons = node_shader_buts_tex_image;
1226       ntype->draw_buttons_ex = node_shader_buts_tex_image_ex;
1227       break;
1228     case SH_NODE_TEX_ENVIRONMENT:
1229       ntype->draw_buttons = node_shader_buts_tex_environment;
1230       ntype->draw_buttons_ex = node_shader_buts_tex_environment_ex;
1231       break;
1232     case SH_NODE_TEX_GRADIENT:
1233       ntype->draw_buttons = node_shader_buts_tex_gradient;
1234       break;
1235     case SH_NODE_TEX_MAGIC:
1236       ntype->draw_buttons = node_shader_buts_tex_magic;
1237       break;
1238     case SH_NODE_TEX_BRICK:
1239       ntype->draw_buttons = node_shader_buts_tex_brick;
1240       break;
1241     case SH_NODE_TEX_WAVE:
1242       ntype->draw_buttons = node_shader_buts_tex_wave;
1243       break;
1244     case SH_NODE_TEX_MUSGRAVE:
1245       ntype->draw_buttons = node_shader_buts_tex_musgrave;
1246       break;
1247     case SH_NODE_TEX_VORONOI:
1248       ntype->draw_buttons = node_shader_buts_tex_voronoi;
1249       break;
1250     case SH_NODE_TEX_NOISE:
1251       ntype->draw_buttons = node_shader_buts_tex_noise;
1252       break;
1253     case SH_NODE_TEX_POINTDENSITY:
1254       ntype->draw_buttons = node_shader_buts_tex_pointdensity;
1255       break;
1256     case SH_NODE_TEX_COORD:
1257       ntype->draw_buttons = node_shader_buts_tex_coord;
1258       break;
1259     case SH_NODE_BUMP:
1260       ntype->draw_buttons = node_shader_buts_bump;
1261       break;
1262     case SH_NODE_NORMAL_MAP:
1263       ntype->draw_buttons = node_shader_buts_normal_map;
1264       break;
1265     case SH_NODE_DISPLACEMENT:
1266     case SH_NODE_VECTOR_DISPLACEMENT:
1267       ntype->draw_buttons = node_shader_buts_displacement;
1268       break;
1269     case SH_NODE_TANGENT:
1270       ntype->draw_buttons = node_shader_buts_tangent;
1271       break;
1272     case SH_NODE_BSDF_GLOSSY:
1273     case SH_NODE_BSDF_GLASS:
1274     case SH_NODE_BSDF_REFRACTION:
1275       ntype->draw_buttons = node_shader_buts_glossy;
1276       break;
1277     case SH_NODE_BSDF_PRINCIPLED:
1278       ntype->draw_buttons = node_shader_buts_principled;
1279       break;
1280     case SH_NODE_BSDF_ANISOTROPIC:
1281       ntype->draw_buttons = node_shader_buts_anisotropic;
1282       break;
1283     case SH_NODE_SUBSURFACE_SCATTERING:
1284       ntype->draw_buttons = node_shader_buts_subsurface;
1285       break;
1286     case SH_NODE_BSDF_TOON:
1287       ntype->draw_buttons = node_shader_buts_toon;
1288       break;
1289     case SH_NODE_BSDF_HAIR:
1290       ntype->draw_buttons = node_shader_buts_hair;
1291       break;
1292     case SH_NODE_BSDF_HAIR_PRINCIPLED:
1293       ntype->draw_buttons = node_shader_buts_principled_hair;
1294       break;
1295     case SH_NODE_SCRIPT:
1296       ntype->draw_buttons = node_shader_buts_script;
1297       ntype->draw_buttons_ex = node_shader_buts_script_ex;
1298       break;
1299     case SH_NODE_UVMAP:
1300       ntype->draw_buttons = node_shader_buts_uvmap;
1301       break;
1302     case SH_NODE_VERTEX_COLOR:
1303       ntype->draw_buttons = node_shader_buts_vertex_color;
1304       break;
1305     case SH_NODE_UVALONGSTROKE:
1306       ntype->draw_buttons = node_shader_buts_uvalongstroke;
1307       break;
1308     case SH_NODE_OUTPUT_MATERIAL:
1309     case SH_NODE_OUTPUT_LIGHT:
1310     case SH_NODE_OUTPUT_WORLD:
1311       ntype->draw_buttons = node_buts_output_shader;
1312       break;
1313     case SH_NODE_OUTPUT_LINESTYLE:
1314       ntype->draw_buttons = node_buts_output_linestyle;
1315       break;
1316     case SH_NODE_TEX_IES:
1317       ntype->draw_buttons = node_shader_buts_ies;
1318       break;
1319     case SH_NODE_BEVEL:
1320       ntype->draw_buttons = node_shader_buts_bevel;
1321       break;
1322     case SH_NODE_AMBIENT_OCCLUSION:
1323       ntype->draw_buttons = node_shader_buts_ambient_occlusion;
1324       break;
1325     case SH_NODE_TEX_WHITE_NOISE:
1326       ntype->draw_buttons = node_shader_buts_white_noise;
1327       break;
1328     case SH_NODE_OUTPUT_AOV:
1329       ntype->draw_buttons = node_shader_buts_output_aov;
1330       break;
1331   }
1332 }
1333
1334 /* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
1335
1336 static void node_buts_image_views(uiLayout *layout,
1337                                   bContext *UNUSED(C),
1338                                   PointerRNA *ptr,
1339                                   PointerRNA *imaptr)
1340 {
1341   uiLayout *col;
1342
1343   if (!imaptr->data) {
1344     return;
1345   }
1346
1347   col = uiLayoutColumn(layout, false);
1348
1349   if (RNA_boolean_get(ptr, "has_views")) {
1350     if (RNA_enum_get(ptr, "view") == 0) {
1351       uiItemR(col, ptr, "view", DEFAULT_FLAGS, NULL, ICON_CAMERA_STEREO);
1352     }
1353     else {
1354       uiItemR(col, ptr, "view", DEFAULT_FLAGS, NULL, ICON_SCENE);
1355     }
1356   }
1357 }
1358
1359 static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
1360 {
1361   bNode *node = ptr->data;
1362
1363   PointerRNA iuserptr;
1364   RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr);
1365   uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
1366   uiTemplateID(layout,
1367                C,
1368                ptr,
1369                "image",
1370                "IMAGE_OT_new",
1371                "IMAGE_OT_open",
1372                NULL,
1373                UI_TEMPLATE_ID_FILTER_ALL,
1374                false,
1375                NULL);
1376   if (!node->id) {
1377     return;
1378   }
1379
1380   PointerRNA imaptr = RNA_pointer_get(ptr, "image");
1381
1382   node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr, true, true);
1383
1384   node_buts_image_views(layout, C, ptr, &imaptr);
1385 }
1386
1387 static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
1388 {
1389   bNode *node = ptr->data;
1390
1391   PointerRNA iuserptr;
1392   RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr);
1393   uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
1394   uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 1);
1395 }
1396
1397 static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
1398 {
1399   bNode *node = ptr->data;
1400   uiLayout *col, *row;
1401
1402   uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
1403
1404   if (!node->id) {
1405     return;
1406   }
1407
1408   col = uiLayoutColumn(layout, false);
1409   row = uiLayoutRow(col, true);
1410   uiItemR(row, ptr, "layer", DEFAULT_FLAGS, "", ICON_NONE);
1411
1412   PropertyRNA *prop = RNA_struct_find_property(ptr, "layer");
1413   const char *layer_name;
1414   if (!(RNA_property_enum_identifier(
1415           C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name))) {
1416     return;
1417   }
1418
1419   PointerRNA scn_ptr;
1420   char scene_name[MAX_ID_NAME - 2];
1421   scn_ptr = RNA_pointer_get(ptr, "scene");
1422   RNA_string_get(&scn_ptr, "name", scene_name);
1423
1424   PointerRNA op_ptr;
1425   uiItemFullO(
1426       row, "RENDER_OT_render", "", ICON_RENDER_STILL, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
1427   RNA_string_set(&op_ptr, "layer", layer_name);
1428   RNA_string_set(&op_ptr, "scene", scene_name);
1429 }
1430
1431 static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1432 {
1433   uiLayout *col, *row;
1434
1435   col = uiLayoutColumn(layout, false);
1436   const int filter = RNA_enum_get(ptr, "filter_type");
1437   const int reference = RNA_boolean_get(ptr, "use_variable_size");
1438
1439   uiItemR(col, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE);
1440   if (filter != R_FILTER_FAST_GAUSS) {
1441     uiItemR(col, ptr, "use_variable_size", DEFAULT_FLAGS, NULL, ICON_NONE);
1442     if (!reference) {
1443       uiItemR(col, ptr, "use_bokeh", DEFAULT_FLAGS, NULL, ICON_NONE);
1444     }
1445     uiItemR(col, ptr, "use_gamma_correction", DEFAULT_FLAGS, NULL, ICON_NONE);
1446   }
1447
1448   uiItemR(col, ptr, "use_relative", DEFAULT_FLAGS, NULL, ICON_NONE);
1449
1450   if (RNA_boolean_get(ptr, "use_relative")) {
1451     uiItemL(col, IFACE_("Aspect Correction"), ICON_NONE);
1452     row = uiLayoutRow(layout, true);
1453     uiItemR(row, ptr, "aspect_correction", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1454
1455     col = uiLayoutColumn(layout, true);
1456     uiItemR(col, ptr, "factor_x", DEFAULT_FLAGS, IFACE_("X"), ICON_NONE);
1457     uiItemR(col, ptr, "factor_y", DEFAULT_FLAGS, IFACE_("Y"), ICON_NONE);
1458   }
1459   else {
1460     col = uiLayoutColumn(layout, true);
1461     uiItemR(col, ptr, "size_x", DEFAULT_FLAGS, IFACE_("X"), ICON_NONE);
1462     uiItemR(col, ptr, "size_y", DEFAULT_FLAGS, IFACE_("Y"), ICON_NONE);
1463   }
1464   uiItemR(col, ptr, "use_extended_bounds", DEFAULT_FLAGS, NULL, ICON_NONE);
1465 }
1466
1467 static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1468 {
1469   uiLayout *col;
1470
1471   uiItemR(layout, ptr, "iterations", DEFAULT_FLAGS, NULL, ICON_NONE);
1472   uiItemR(layout, ptr, "use_wrap", DEFAULT_FLAGS, NULL, ICON_NONE);
1473
1474   col = uiLayoutColumn(layout, true);
1475   uiItemL(col, IFACE_("Center:"), ICON_NONE);
1476   uiItemR(col, ptr, "center_x", DEFAULT_FLAGS, IFACE_("X"), ICON_NONE);
1477   uiItemR(col, ptr, "center_y", DEFAULT_FLAGS, IFACE_("Y"), ICON_NONE);
1478
1479   uiItemS(layout);
1480
1481   col = uiLayoutColumn(layout, true);
1482   uiItemR(col, ptr, "distance", DEFAULT_FLAGS, NULL, ICON_NONE);
1483   uiItemR(col, ptr, "angle", DEFAULT_FLAGS, NULL, ICON_NONE);
1484
1485   uiItemS(layout);
1486
1487   uiItemR(layout, ptr, "spin", DEFAULT_FLAGS, NULL, ICON_NONE);
1488   uiItemR(layout, ptr, "zoom", DEFAULT_FLAGS, NULL, ICON_NONE);
1489 }
1490
1491 static void node_composit_buts_bilateralblur(uiLayout *layout,
1492                                              bContext *UNUSED(C),
1493                                              PointerRNA *ptr)
1494 {
1495   uiLayout *col;
1496
1497   col = uiLayoutColumn(layout, true);
1498   uiItemR(col, ptr, "iterations", DEFAULT_FLAGS, NULL, ICON_NONE);
1499   uiItemR(col, ptr, "sigma_color", DEFAULT_FLAGS, NULL, ICON_NONE);
1500   uiItemR(col, ptr, "sigma_space", DEFAULT_FLAGS, NULL, ICON_NONE);
1501 }
1502
1503 static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA *ptr)
1504 {
1505   uiLayout *sub, *col;
1506
1507   col = uiLayoutColumn(layout, false);
1508   uiItemL(col, IFACE_("Bokeh Type:"), ICON_NONE);
1509   uiItemR(col, ptr, "bokeh", DEFAULT_FLAGS, "", ICON_NONE);
1510   uiItemR(col, ptr, "angle", DEFAULT_FLAGS, NULL, ICON_NONE);
1511
1512   uiItemR(layout, ptr, "use_gamma_correction", DEFAULT_FLAGS, NULL, ICON_NONE);
1513
1514   col = uiLayoutColumn(layout, false);
1515   uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer") == true);
1516   uiItemR(col, ptr, "f_stop", DEFAULT_FLAGS, NULL, ICON_NONE);
1517
1518   uiItemR(layout, ptr, "blur_max", DEFAULT_FLAGS, NULL, ICON_NONE);
1519   uiItemR(layout, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
1520
1521   col = uiLayoutColumn(layout, false);
1522   uiItemR(col, ptr, "use_preview", DEFAULT_FLAGS, NULL, ICON_NONE);
1523
1524   uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
1525
1526   col = uiLayoutColumn(layout, false);
1527   uiItemR(col, ptr, "use_zbuffer", DEFAULT_FLAGS, NULL, ICON_NONE);
1528   sub = uiLayoutColumn(col, false);
1529   uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer") == false);
1530   uiItemR(sub, ptr, "z_scale", DEFAULT_FLAGS, NULL, ICON_NONE);
1531 }
1532
1533 static void node_composit_buts_antialiasing(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1534 {
1535   uiLayout *col;
1536
1537   col = uiLayoutColumn(layout, false);
1538
1539   uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE);
1540   uiItemR(col, ptr, "contrast_limit", 0, NULL, ICON_NONE);
1541   uiItemR(col, ptr, "corner_rounding", 0, NULL, ICON_NONE);
1542 }
1543
1544 /* qdn: glare node */
1545 static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1546 {
1547   uiItemR(layout, ptr, "glare_type", DEFAULT_FLAGS, "", ICON_NONE);
1548   uiItemR(layout, ptr, "quality", DEFAULT_FLAGS, "", ICON_NONE);
1549
1550   if (RNA_enum_get(ptr, "glare_type") != 1) {
1551     uiItemR(layout, ptr, "iterations", DEFAULT_FLAGS, NULL, ICON_NONE);
1552
1553     if (RNA_enum_get(ptr, "glare_type") != 0) {
1554       uiItemR(layout, ptr, "color_modulation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1555     }
1556   }
1557
1558   uiItemR(layout, ptr, "mix", DEFAULT_FLAGS, NULL, ICON_NONE);
1559   uiItemR(layout, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
1560
1561   if (RNA_enum_get(ptr, "glare_type") == 2) {
1562     uiItemR(layout, ptr, "streaks", DEFAULT_FLAGS, NULL, ICON_NONE);
1563     uiItemR(layout, ptr, "angle_offset", DEFAULT_FLAGS, NULL, ICON_NONE);
1564   }
1565   if (RNA_enum_get(ptr, "glare_type") == 0 || RNA_enum_get(ptr, "glare_type") == 2) {
1566     uiItemR(layout, ptr, "fade", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1567
1568     if (RNA_enum_get(ptr, "glare_type") == 0) {
1569       uiItemR(layout, ptr, "use_rotate_45", DEFAULT_FLAGS, NULL, ICON_NONE);
1570     }
1571   }
1572   if (RNA_enum_get(ptr, "glare_type") == 1) {
1573     uiItemR(layout, ptr, "size", DEFAULT_FLAGS, NULL, ICON_NONE);
1574   }
1575 }
1576
1577 static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1578 {
1579   uiLayout *col;
1580
1581   col = uiLayoutColumn(layout, false);
1582   uiItemR(col, ptr, "tonemap_type", DEFAULT_FLAGS, "", ICON_NONE);
1583   if (RNA_enum_get(ptr, "tonemap_type") == 0) {
1584     uiItemR(col, ptr, "key", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1585     uiItemR(col, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
1586     uiItemR(col, ptr, "gamma", DEFAULT_FLAGS, NULL, ICON_NONE);
1587   }
1588   else {
1589     uiItemR(col, ptr, "intensity", DEFAULT_FLAGS, NULL, ICON_NONE);
1590     uiItemR(col, ptr, "contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1591     uiItemR(col, ptr, "adaptation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1592     uiItemR(col, ptr, "correction", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1593   }
1594 }
1595
1596 static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1597 {
1598   uiLayout *col;
1599
1600   col = uiLayoutColumn(layout, false);
1601   uiItemR(col, ptr, "use_projector", DEFAULT_FLAGS, NULL, ICON_NONE);
1602
1603   col = uiLayoutColumn(col, false);
1604   uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector") == false);
1605   uiItemR(col, ptr, "use_jitter", DEFAULT_FLAGS, NULL, ICON_NONE);
1606   uiItemR(col, ptr, "use_fit", DEFAULT_FLAGS, NULL, ICON_NONE);
1607 }
1608
1609 static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1610 {
1611   uiLayout *col;
1612
1613   col = uiLayoutColumn(layout, false);
1614   uiItemR(col, ptr, "samples", DEFAULT_FLAGS, NULL, ICON_NONE);
1615   uiItemR(col, ptr, "factor", DEFAULT_FLAGS, IFACE_("Blur"), ICON_NONE);
1616
1617   col = uiLayoutColumn(layout, true);
1618   uiItemL(col, IFACE_("Speed:"), ICON_NONE);
1619   uiItemR(col, ptr, "speed_min", DEFAULT_FLAGS, IFACE_("Min"), ICON_NONE);
1620   uiItemR(col, ptr, "speed_max", DEFAULT_FLAGS, IFACE_("Max"), ICON_NONE);
1621
1622   uiItemR(layout, ptr, "use_curved", DEFAULT_FLAGS, NULL, ICON_NONE);
1623 }
1624
1625 static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1626 {
1627   uiItemR(layout, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE);
1628 }
1629
1630 static void node_composit_buts_flip(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1631 {
1632   uiItemR(layout, ptr, "axis", DEFAULT_FLAGS, "", ICON_NONE);
1633 }
1634
1635 static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1636 {
1637   uiLayout *col;
1638
1639   uiItemR(layout, ptr, "use_crop_size", DEFAULT_FLAGS, NULL, ICON_NONE);
1640   uiItemR(layout, ptr, "relative", DEFAULT_FLAGS, NULL, ICON_NONE);
1641
1642   col = uiLayoutColumn(layout, true);
1643   if (RNA_boolean_get(ptr, "relative")) {
1644     uiItemR(col, ptr, "rel_min_x", DEFAULT_FLAGS, IFACE_("Left"), ICON_NONE);
1645     uiItemR(col, ptr, "rel_max_x", DEFAULT_FLAGS, IFACE_("Right"), ICON_NONE);
1646     uiItemR(col, ptr, "rel_min_y", DEFAULT_FLAGS, IFACE_("Up"), ICON_NONE);
1647     uiItemR(col, ptr, "rel_max_y", DEFAULT_FLAGS, IFACE_("Down"), ICON_NONE);
1648   }
1649   else {
1650     uiItemR(col, ptr, "min_x", DEFAULT_FLAGS, IFACE_("Left"), ICON_NONE);
1651     uiItemR(col, ptr, "max_x", DEFAULT_FLAGS, IFACE_("Right"), ICON_NONE);
1652     uiItemR(col, ptr, "min_y", DEFAULT_FLAGS, IFACE_("Up"), ICON_NONE);
1653     uiItemR(col, ptr, "max_y", DEFAULT_FLAGS, IFACE_("Down"), ICON_NONE);
1654   }
1655 }
1656
1657 static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1658 {
1659   uiLayout *row, *col;
1660
1661   col = uiLayoutColumn(layout, false);
1662   row = uiLayoutRow(col, false);
1663   uiItemR(row, ptr, "axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1664   uiItemR(col, ptr, "factor", DEFAULT_FLAGS, NULL, ICON_NONE);
1665 }
1666
1667 static void node_composit_buts_double_edge_mask(uiLayout *layout,
1668                                                 bContext *UNUSED(C),
1669                                                 PointerRNA *ptr)
1670 {
1671   uiLayout *col;
1672
1673   col = uiLayoutColumn(layout, false);
1674
1675   uiItemL(col, IFACE_("Inner Edge:"), ICON_NONE);
1676   uiItemR(col, ptr, "inner_mode", DEFAULT_FLAGS, "", ICON_NONE);
1677   uiItemL(col, IFACE_("Buffer Edge:"), ICON_NONE);
1678   uiItemR(col, ptr, "edge_mode", DEFAULT_FLAGS, "", ICON_NONE);
1679 }
1680
1681 static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1682 {
1683   uiLayout *col;
1684
1685   col = uiLayoutColumn(layout, true);
1686   uiItemR(col, ptr, "use_clamp", DEFAULT_FLAGS, NULL, ICON_NONE);
1687 }
1688
1689 static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1690 {
1691   uiLayout *sub, *col;
1692
1693   col = uiLayoutColumn(layout, true);
1694   uiItemR(col, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
1695   uiItemR(col, ptr, "size", DEFAULT_FLAGS, NULL, ICON_NONE);
1696
1697   col = uiLayoutColumn(layout, true);
1698   uiItemR(col, ptr, "use_min", DEFAULT_FLAGS, NULL, ICON_NONE);
1699   sub = uiLayoutColumn(col, false);
1700   uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
1701   uiItemR(sub, ptr, "min", DEFAULT_FLAGS, "", ICON_NONE);
1702
1703   col = uiLayoutColumn(layout, true);
1704   uiItemR(col, ptr, "use_max", DEFAULT_FLAGS, NULL, ICON_NONE);
1705   sub = uiLayoutColumn(col, false);
1706   uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
1707   uiItemR(sub, ptr, "max", DEFAULT_FLAGS, "", ICON_NONE);
1708 }
1709
1710 static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1711 {
1712   uiLayout *col;
1713
1714   col = uiLayoutColumn(layout, true);
1715   uiItemR(col, ptr, "use_premultiply", DEFAULT_FLAGS, NULL, ICON_NONE);
1716   uiItemR(col, ptr, "premul", DEFAULT_FLAGS, NULL, ICON_NONE);
1717 }
1718
1719 static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1720 {
1721   uiLayout *col;
1722
1723   col = uiLayoutColumn(layout, true);
1724   uiItemR(col, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
1725   uiItemR(col, ptr, "use_antialias_z", DEFAULT_FLAGS, NULL, ICON_NONE);
1726 }
1727
1728 static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1729 {
1730   uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, NULL, ICON_NONE);
1731   uiItemR(layout, ptr, "distance", DEFAULT_FLAGS, NULL, ICON_NONE);
1732   switch (RNA_enum_get(ptr, "mode")) {
1733     case CMP_NODE_DILATEERODE_DISTANCE_THRESH:
1734       uiItemR(layout, ptr, "edge", DEFAULT_FLAGS, NULL, ICON_NONE);
1735       break;
1736     case CMP_NODE_DILATEERODE_DISTANCE_FEATHER:
1737       uiItemR(layout, ptr, "falloff", DEFAULT_FLAGS, NULL, ICON_NONE);
1738       break;
1739   }
1740 }
1741
1742 static void node_composit_buts_inpaint(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1743 {
1744   uiItemR(layout, ptr, "distance", DEFAULT_FLAGS, NULL, ICON_NONE);
1745 }
1746
1747 static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1748 {
1749   uiLayout *col;
1750
1751   col = uiLayoutColumn(layout, false);
1752   uiItemR(col, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
1753   uiItemR(col, ptr, "threshold_neighbor", DEFAULT_FLAGS, NULL, ICON_NONE);
1754 }
1755
1756 static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1757 {
1758   uiLayout *col;
1759
1760   col = uiLayoutColumn(layout, true);
1761   uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1762   uiItemR(col, ptr, "falloff", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1763 }
1764
1765 static void node_composit_buts_distance_matte(uiLayout *layout,
1766                                               bContext *UNUSED(C),
1767                                               PointerRNA *ptr)
1768 {
1769   uiLayout *col, *row;
1770
1771   col = uiLayoutColumn(layout, true);
1772
1773   uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
1774   row = uiLayoutRow(layout, false);
1775   uiItemR(row, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1776
1777   uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1778   uiItemR(col, ptr, "falloff", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1779 }
1780
1781 static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1782 {
1783   uiLayout *row, *col;
1784
1785   uiItemL(layout, IFACE_("Despill Channel:"), ICON_NONE);
1786   row = uiLayoutRow(layout, false);
1787   uiItemR(row, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1788
1789   col = uiLayoutColumn(layout, false);
1790   uiItemR(col, ptr, "limit_method", DEFAULT_FLAGS, NULL, ICON_NONE);
1791
1792   if (RNA_enum_get(ptr, "limit_method") == 0) {
1793     uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
1794     row = uiLayoutRow(col, false);
1795     uiItemR(row, ptr, "limit_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1796   }
1797
1798   uiItemR(col, ptr, "ratio", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1799   uiItemR(col, ptr, "use_unspill", DEFAULT_FLAGS, NULL, ICON_NONE);
1800   if (RNA_boolean_get(ptr, "use_unspill") == true) {
1801     uiItemR(col, ptr, "unspill_red", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1802     uiItemR(col, ptr, "unspill_green", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1803     uiItemR(col, ptr, "unspill_blue", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1804   }
1805 }
1806
1807 static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1808 {
1809   uiLayout *col;
1810
1811   col = uiLayoutColumn(layout, false);
1812   uiItemR(col, ptr, "tolerance", DEFAULT_FLAGS, NULL, ICON_NONE);
1813   uiItemR(col, ptr, "threshold", DEFAULT_FLAGS, NULL, ICON_NONE);
1814
1815   col = uiLayoutColumn(layout, true);
1816   /*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);  Removed for now */
1817   uiItemR(col, ptr, "gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1818   /*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, ICON_NONE);  Removed for now*/
1819 }
1820
1821 static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1822 {
1823   uiLayout *col;
1824
1825   col = uiLayoutColumn(layout, true);
1826   uiItemR(col, ptr, "color_hue", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1827   uiItemR(col, ptr, "color_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1828   uiItemR(col, ptr, "color_value", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1829 }
1830
1831 static void node_composit_buts_channel_matte(uiLayout *layout,
1832                                              bContext *UNUSED(C),
1833                                              PointerRNA *ptr)
1834 {
1835   uiLayout *col, *row;
1836
1837   uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
1838   row = uiLayoutRow(layout, false);
1839   uiItemR(row, ptr, "color_space", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1840
1841   col = uiLayoutColumn(layout, false);
1842   uiItemL(col, IFACE_("Key Channel:"), ICON_NONE);
1843   row = uiLayoutRow(col, false);
1844   uiItemR(row, ptr, "matte_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1845
1846   col = uiLayoutColumn(layout, false);
1847
1848   uiItemR(col, ptr, "limit_method", DEFAULT_FLAGS, NULL, ICON_NONE);
1849   if (RNA_enum_get(ptr, "limit_method") == 0) {
1850     uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
1851     row = uiLayoutRow(col, false);
1852     uiItemR(row, ptr, "limit_channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
1853   }
1854
1855   uiItemR(col, ptr, "limit_max", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1856   uiItemR(col, ptr, "limit_min", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1857 }
1858
1859 static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1860 {
1861   uiLayout *col;
1862
1863   col = uiLayoutColumn(layout, true);
1864   uiItemR(col, ptr, "limit_max", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1865   uiItemR(col, ptr, "limit_min", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1866 }
1867
1868 static void node_composit_buts_map_uv(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1869 {
1870   uiItemR(layout, ptr, "alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
1871 }
1872
1873 static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1874 {
1875   uiItemR(layout, ptr, "index", DEFAULT_FLAGS, NULL, ICON_NONE);
1876   uiItemR(layout, ptr, "use_antialiasing", DEFAULT_FLAGS, NULL, ICON_NONE);
1877 }
1878
1879 static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1880 {
1881   PointerRNA imfptr = RNA_pointer_get(ptr, "format");
1882   const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER;
1883
1884   if (multilayer) {
1885     uiItemL(layout, IFACE_("Path:"), ICON_NONE);
1886   }
1887   else {
1888     uiItemL(layout, IFACE_("Base Path:"), ICON_NONE);
1889   }
1890   uiItemR(layout, ptr, "base_path", DEFAULT_FLAGS, "", ICON_NONE);
1891 }
1892 static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
1893 {
1894   Scene *scene = CTX_data_scene(C);
1895   PointerRNA imfptr = RNA_pointer_get(ptr, "format");
1896   PointerRNA active_input_ptr, op_ptr;
1897   uiLayout *row, *col;
1898   const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER;
1899   const bool is_exr = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_OPENEXR;
1900   const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
1901
1902   node_composit_buts_file_output(layout, C, ptr);
1903   uiTemplateImageSettings(layout, &imfptr, false);
1904
1905   /* disable stereo output for multilayer, too much work for something that no one will use */
1906   /* if someone asks for that we can implement it */
1907   if (is_multiview) {
1908     uiTemplateImageFormatViews(layout, &imfptr, NULL);
1909   }
1910
1911   uiItemS(layout);
1912
1913   uiItemO(layout, IFACE_("Add Input"), ICON_ADD, "NODE_OT_output_file_add_socket");
1914
1915   row = uiLayoutRow(layout, false);
1916   col = uiLayoutColumn(row, true);
1917
1918   const int active_index = RNA_int_get(ptr, "active_input_index");
1919   /* using different collection properties if multilayer format is enabled */
1920   if (multilayer) {
1921     uiTemplateList(col,
1922                    C,
1923                    "UI_UL_list",
1924                    "file_output_node",
1925                    ptr,
1926                    "layer_slots",
1927                    ptr,
1928                    "active_input_index",
1929                    NULL,
1930                    0,
1931                    0,
1932                    0,
1933                    0,
1934                    false,
1935                    false);
1936     RNA_property_collection_lookup_int(
1937         ptr, RNA_struct_find_property(ptr, "layer_slots"), active_index, &active_input_ptr);
1938   }
1939   else {
1940     uiTemplateList(col,
1941                    C,
1942                    "UI_UL_list",
1943                    "file_output_node",
1944                    ptr,
1945                    "file_slots",
1946                    ptr,
1947                    "active_input_index",
1948                    NULL,
1949                    0,
1950                    0,
1951                    0,
1952                    0,
1953                    false,
1954                    false);
1955     RNA_property_collection_lookup_int(
1956         ptr, RNA_struct_find_property(ptr, "file_slots"), active_index, &active_input_ptr);
1957   }
1958   /* XXX collection lookup does not return the ID part of the pointer,
1959    * setting this manually here */
1960   active_input_ptr.owner_id = ptr->owner_id;
1961
1962   col = uiLayoutColumn(row, true);
1963   wmOperatorType *ot = WM_operatortype_find("NODE_OT_output_file_move_active_socket", false);
1964   uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
1965   RNA_enum_set(&op_ptr, "direction", 1);
1966   uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
1967   RNA_enum_set(&op_ptr, "direction", 2);
1968
1969   if (active_input_ptr.data) {
1970     if (multilayer) {
1971       col = uiLayoutColumn(layout, true);
1972
1973       uiItemL(col, IFACE_("Layer:"), ICON_NONE);
1974       row = uiLayoutRow(col, false);
1975       uiItemR(row, &active_input_ptr, "name", DEFAULT_FLAGS, "", ICON_NONE);
1976       uiItemFullO(row,
1977                   "NODE_OT_output_file_remove_active_socket",
1978                   "",
1979                   ICON_X,
1980                   NULL,
1981                   WM_OP_EXEC_DEFAULT,
1982                   UI_ITEM_R_ICON_ONLY,
1983                   NULL);
1984     }
1985     else {
1986       col = uiLayoutColumn(layout, true);
1987
1988       uiItemL(col, IFACE_("File Subpath:"), ICON_NONE);
1989       row = uiLayoutRow(col, false);
1990       uiItemR(row, &active_input_ptr, "path", DEFAULT_FLAGS, "", ICON_NONE);
1991       uiItemFullO(row,
1992                   "NODE_OT_output_file_remove_active_socket",
1993                   "",
1994                   ICON_X,
1995                   NULL,
1996                   WM_OP_EXEC_DEFAULT,
1997                   UI_ITEM_R_ICON_ONLY,
1998                   NULL);
1999
2000       /* format details for individual files */
2001       imfptr = RNA_pointer_get(&active_input_ptr, "format");
2002
2003       col = uiLayoutColumn(layout, true);
2004       uiItemL(col, IFACE_("Format:"), ICON_NONE);
2005       uiItemR(col, &active_input_ptr, "use_node_format", DEFAULT_FLAGS, NULL, ICON_NONE);
2006
2007       const bool is_socket_exr = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_OPENEXR;
2008       const bool use_node_format = RNA_boolean_get(&active_input_ptr, "use_node_format");
2009
2010       if ((!is_exr && use_node_format) || (!is_socket_exr && !use_node_format)) {
2011         uiItemR(col, &active_input_ptr, "save_as_render", DEFAULT_FLAGS, NULL, ICON_NONE);
2012       }
2013
2014       col = uiLayoutColumn(layout, false);
2015       uiLayoutSetActive(col, use_node_format == false);
2016       uiTemplateImageSettings(col, &imfptr, false);
2017
2018       if (is_multiview) {
2019         uiTemplateImageFormatViews(layout, &imfptr, NULL);
2020       }
2021     }
2022   }
2023 }
2024
2025 static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2026 {
2027   uiItemR(layout, ptr, "space", DEFAULT_FLAGS, "", ICON_NONE);
2028
2029   if (RNA_enum_get(ptr, "space") == CMP_SCALE_RENDERPERCENT) {
2030     uiLayout *row;
2031     uiItemR(layout, ptr, "frame_method", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2032     row = uiLayoutRow(layout, true);
2033     uiItemR(row, ptr, "offset_x", DEFAULT_FLAGS, "X", ICON_NONE);
2034     uiItemR(row, ptr, "offset_y", DEFAULT_FLAGS, "Y", ICON_NONE);
2035   }
2036 }
2037
2038 static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2039 {
2040   uiItemR(layout, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE);
2041 }
2042
2043 static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2044 {
2045   uiLayout *col;
2046
2047   col = uiLayoutColumn(layout, false);
2048   uiItemR(col, ptr, "invert_rgb", DEFAULT_FLAGS, NULL, ICON_NONE);
2049   uiItemR(col, ptr, "invert_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
2050 }
2051
2052 static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2053 {
2054   uiItemR(layout, ptr, "mapping", DEFAULT_FLAGS, "", ICON_NONE);
2055 }
2056
2057 static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2058 {
2059   uiItemR(layout, ptr, "channel", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2060 }
2061
2062 static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2063 {
2064   uiLayout *split, *col, *row;
2065
2066   uiItemR(layout, ptr, "correction_method", DEFAULT_FLAGS, NULL, ICON_NONE);
2067
2068   if (RNA_enum_get(ptr, "correction_method") == 0) {
2069
2070     split = uiLayoutSplit(layout, 0.0f, false);
2071     col = uiLayoutColumn(split, false);
2072     uiTemplateColorPicker(col, ptr, "lift", 1, 1, 0, 1);
2073     row = uiLayoutRow(col, false);
2074     uiItemR(row, ptr, "lift", DEFAULT_FLAGS, NULL, ICON_NONE);
2075
2076     col = uiLayoutColumn(split, false);
2077     uiTemplateColorPicker(col, ptr, "gamma", 1, 1, 1, 1);
2078     row = uiLayoutRow(col, false);
2079     uiItemR(row, ptr, "gamma", DEFAULT_FLAGS, NULL, ICON_NONE);
2080
2081     col = uiLayoutColumn(split, false);
2082     uiTemplateColorPicker(col, ptr, "gain", 1, 1, 1, 1);
2083     row = uiLayoutRow(col, false);
2084     uiItemR(row, ptr, "gain", DEFAULT_FLAGS, NULL, ICON_NONE);
2085   }
2086   else {
2087
2088     split = uiLayoutSplit(layout, 0.0f, false);
2089     col = uiLayoutColumn(split, false);
2090     uiTemplateColorPicker(col, ptr, "offset", 1, 1, 0, 1);
2091     row = uiLayoutRow(col, false);
2092     uiItemR(row, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
2093     uiItemR(col, ptr, "offset_basis", DEFAULT_FLAGS, NULL, ICON_NONE);
2094
2095     col = uiLayoutColumn(split, false);
2096     uiTemplateColorPicker(col, ptr, "power", 1, 1, 0, 1);
2097     row = uiLayoutRow(col, false);
2098     uiItemR(row, ptr, "power", DEFAULT_FLAGS, NULL, ICON_NONE);
2099
2100     col = uiLayoutColumn(split, false);
2101     uiTemplateColorPicker(col, ptr, "slope", 1, 1, 0, 1);
2102     row = uiLayoutRow(col, false);
2103     uiItemR(row, ptr, "slope", DEFAULT_FLAGS, NULL, ICON_NONE);
2104   }
2105 }
2106 static void node_composit_buts_colorbalance_ex(uiLayout *layout,
2107                                                bContext *UNUSED(C),
2108                                                PointerRNA *ptr)
2109 {
2110   uiItemR(layout, ptr, "correction_method", DEFAULT_FLAGS, NULL, ICON_NONE);
2111
2112   if (RNA_enum_get(ptr, "correction_method") == 0) {
2113
2114     uiTemplateColorPicker(layout, ptr, "lift", 1, 1, 0, 1);
2115     uiItemR(layout, ptr, "lift", DEFAULT_FLAGS, NULL, ICON_NONE);
2116
2117     uiTemplateColorPicker(layout, ptr, "gamma", 1, 1, 1, 1);
2118     uiItemR(layout, ptr, "gamma", DEFAULT_FLAGS, NULL, ICON_NONE);
2119
2120     uiTemplateColorPicker(layout, ptr, "gain", 1, 1, 1, 1);
2121     uiItemR(layout, ptr, "gain", DEFAULT_FLAGS, NULL, ICON_NONE);
2122   }
2123   else {
2124     uiTemplateColorPicker(layout, ptr, "offset", 1, 1, 0, 1);
2125     uiItemR(layout, ptr, "offset", DEFAULT_FLAGS, NULL, ICON_NONE);
2126
2127     uiTemplateColorPicker(layout, ptr, "power", 1, 1, 0, 1);
2128     uiItemR(layout, ptr, "power", DEFAULT_FLAGS, NULL, ICON_NONE);
2129
2130     uiTemplateColorPicker(layout, ptr, "slope", 1, 1, 0, 1);
2131     uiItemR(layout, ptr, "slope", DEFAULT_FLAGS, NULL, ICON_NONE);
2132   }
2133 }
2134
2135 static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2136 {
2137   bNode *node = ptr->data;
2138   CurveMapping *cumap = node->storage;
2139
2140   if (_sample_col[0] != SAMPLE_FLT_ISNONE) {
2141     cumap->flag |= CUMA_DRAW_SAMPLE;
2142     copy_v3_v3(cumap->sample, _sample_col);
2143   }
2144   else {
2145     cumap->flag &= ~CUMA_DRAW_SAMPLE;
2146   }
2147
2148   uiTemplateCurveMapping(layout, ptr, "mapping", 'h', false, false, false, false);
2149 }
2150
2151 static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2152 {
2153   uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
2154 }
2155
2156 static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr)
2157 {
2158   uiTemplateID(
2159       layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2160 }
2161
2162 static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
2163 {
2164   bNode *node = ptr->data;
2165   PointerRNA clipptr;
2166
2167   uiTemplateID(
2168       layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2169
2170   if (!node->id) {
2171     return;
2172   }
2173
2174   clipptr = RNA_pointer_get(ptr, "clip");
2175
2176   uiTemplateColorspaceSettings(layout, &clipptr, "colorspace_settings");
2177 }
2178
2179 static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, PointerRNA *ptr)
2180 {
2181   bNode *node = ptr->data;
2182
2183   uiTemplateID(
2184       layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2185
2186   if (!node->id) {
2187     return;
2188   }
2189
2190   uiItemR(layout, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE);
2191   uiItemR(layout, ptr, "invert", DEFAULT_FLAGS, NULL, ICON_NONE);
2192 }
2193
2194 static void node_composit_buts_translate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2195 {
2196   uiItemR(layout, ptr, "use_relative", DEFAULT_FLAGS, NULL, ICON_NONE);
2197   uiItemR(layout, ptr, "wrap_axis", DEFAULT_FLAGS, NULL, ICON_NONE);
2198 }
2199
2200 static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2201 {
2202   uiItemR(layout, ptr, "filter_type", DEFAULT_FLAGS, "", ICON_NONE);
2203 }
2204
2205 static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr)
2206 {
2207   bNode *node = ptr->data;
2208
2209   uiTemplateID(
2210       layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2211
2212   if (!node->id) {
2213     return;
2214   }
2215
2216   uiItemR(layout, ptr, "distortion_type", DEFAULT_FLAGS, "", ICON_NONE);
2217 }
2218
2219 static void node_composit_buts_colorcorrection(uiLayout *layout,
2220                                                bContext *UNUSED(C),
2221                                                PointerRNA *ptr)
2222 {
2223   uiLayout *row;
2224
2225   row = uiLayoutRow(layout, false);
2226   uiItemR(row, ptr, "red", DEFAULT_FLAGS, NULL, ICON_NONE);
2227   uiItemR(row, ptr, "green", DEFAULT_FLAGS, NULL, ICON_NONE);
2228   uiItemR(row, ptr, "blue", DEFAULT_FLAGS, NULL, ICON_NONE);
2229
2230   row = uiLayoutRow(layout, false);
2231   uiItemL(row, "", ICON_NONE);
2232   uiItemL(row, IFACE_("Saturation"), ICON_NONE);
2233   uiItemL(row, IFACE_("Contrast"), ICON_NONE);
2234   uiItemL(row, IFACE_("Gamma"), ICON_NONE);
2235   uiItemL(row, IFACE_("Gain"), ICON_NONE);
2236   uiItemL(row, IFACE_("Lift"), ICON_NONE);
2237
2238   row = uiLayoutRow(layout, false);
2239   uiItemL(row, IFACE_("Master"), ICON_NONE);
2240   uiItemR(row, ptr, "master_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2241   uiItemR(row, ptr, "master_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2242   uiItemR(row, ptr, "master_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2243   uiItemR(row, ptr, "master_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2244   uiItemR(row, ptr, "master_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2245
2246   row = uiLayoutRow(layout, false);
2247   uiItemL(row, IFACE_("Highlights"), ICON_NONE);
2248   uiItemR(row, ptr, "highlights_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2249   uiItemR(row, ptr, "highlights_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2250   uiItemR(row, ptr, "highlights_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2251   uiItemR(row, ptr, "highlights_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2252   uiItemR(row, ptr, "highlights_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2253
2254   row = uiLayoutRow(layout, false);
2255   uiItemL(row, IFACE_("Midtones"), ICON_NONE);
2256   uiItemR(row, ptr, "midtones_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2257   uiItemR(row, ptr, "midtones_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2258   uiItemR(row, ptr, "midtones_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2259   uiItemR(row, ptr, "midtones_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2260   uiItemR(row, ptr, "midtones_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2261
2262   row = uiLayoutRow(layout, false);
2263   uiItemL(row, IFACE_("Shadows"), ICON_NONE);
2264   uiItemR(row, ptr, "shadows_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2265   uiItemR(row, ptr, "shadows_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2266   uiItemR(row, ptr, "shadows_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2267   uiItemR(row, ptr, "shadows_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2268   uiItemR(row, ptr, "shadows_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, "", ICON_NONE);
2269
2270   row = uiLayoutRow(layout, false);
2271   uiItemR(row, ptr, "midtones_start", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2272   uiItemR(row, ptr, "midtones_end", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2273 }
2274
2275 static void node_composit_buts_colorcorrection_ex(uiLayout *layout,
2276                                                   bContext *UNUSED(C),
2277                                                   PointerRNA *ptr)
2278 {
2279   uiLayout *row;
2280
2281   row = uiLayoutRow(layout, false);
2282   uiItemR(row, ptr, "red", DEFAULT_FLAGS, NULL, ICON_NONE);
2283   uiItemR(row, ptr, "green", DEFAULT_FLAGS, NULL, ICON_NONE);
2284   uiItemR(row, ptr, "blue", DEFAULT_FLAGS, NULL, ICON_NONE);
2285   row = layout;
2286   uiItemL(row, IFACE_("Saturation"), ICON_NONE);
2287   uiItemR(row, ptr, "master_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2288   uiItemR(row, ptr, "highlights_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2289   uiItemR(row, ptr, "midtones_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2290   uiItemR(row, ptr, "shadows_saturation", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2291
2292   uiItemL(row, IFACE_("Contrast"), ICON_NONE);
2293   uiItemR(row, ptr, "master_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2294   uiItemR(row, ptr, "highlights_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2295   uiItemR(row, ptr, "midtones_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2296   uiItemR(row, ptr, "shadows_contrast", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2297
2298   uiItemL(row, IFACE_("Gamma"), ICON_NONE);
2299   uiItemR(row, ptr, "master_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2300   uiItemR(row, ptr, "highlights_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2301   uiItemR(row, ptr, "midtones_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2302   uiItemR(row, ptr, "shadows_gamma", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2303
2304   uiItemL(row, IFACE_("Gain"), ICON_NONE);
2305   uiItemR(row, ptr, "master_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2306   uiItemR(row, ptr, "highlights_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2307   uiItemR(row, ptr, "midtones_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2308   uiItemR(row, ptr, "shadows_gain", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2309
2310   uiItemL(row, IFACE_("Lift"), ICON_NONE);
2311   uiItemR(row, ptr, "master_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2312   uiItemR(row, ptr, "highlights_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2313   uiItemR(row, ptr, "midtones_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2314   uiItemR(row, ptr, "shadows_lift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2315
2316   row = uiLayoutRow(layout, false);
2317   uiItemR(row, ptr, "midtones_start", DEFAULT_FLAGS, NULL, ICON_NONE);
2318   uiItemR(row, ptr, "midtones_end", DEFAULT_FLAGS, NULL, ICON_NONE);
2319 }
2320
2321 static void node_composit_buts_set_alpha(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2322 {
2323   uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, NULL, ICON_NONE);
2324 }
2325
2326 static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2327 {
2328   uiItemR(layout, ptr, "check", DEFAULT_FLAGS, NULL, ICON_NONE);
2329 }
2330
2331 static void node_composit_buts_switch_view_ex(uiLayout *layout,
2332                                               bContext *UNUSED(C),
2333                                               PointerRNA *UNUSED(ptr))
2334 {
2335   uiItemFullO(layout,
2336               "NODE_OT_switch_view_update",
2337               "Update Views",
2338               ICON_FILE_REFRESH,
2339               NULL,
2340               WM_OP_INVOKE_DEFAULT,
2341               0,
2342               NULL);
2343 }
2344
2345 static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2346 {
2347   uiLayout *row;
2348
2349   row = uiLayoutRow(layout, true);
2350   uiItemR(row, ptr, "x", DEFAULT_FLAGS, NULL, ICON_NONE);
2351   uiItemR(row, ptr, "y", DEFAULT_FLAGS, NULL, ICON_NONE);
2352
2353   row = uiLayoutRow(layout, true);
2354   uiItemR(row, ptr, "width", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2355   uiItemR(row, ptr, "height", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2356
2357   uiItemR(layout, ptr, "rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
2358   uiItemR(layout, ptr, "mask_type", DEFAULT_FLAGS, NULL, ICON_NONE);
2359 }
2360
2361 static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2362 {
2363   uiItemR(layout, ptr, "flaps", DEFAULT_FLAGS, NULL, ICON_NONE);
2364   uiItemR(layout, ptr, "angle", DEFAULT_FLAGS, NULL, ICON_NONE);
2365   uiItemR(layout, ptr, "rounding", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2366   uiItemR(layout, ptr, "catadioptric", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2367   uiItemR(layout, ptr, "shift", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2368 }
2369
2370 static void node_composit_buts_bokehblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2371 {
2372   uiItemR(layout, ptr, "use_variable_size", DEFAULT_FLAGS, NULL, ICON_NONE);
2373   // uiItemR(layout, ptr, "f_stop", DEFAULT_FLAGS, NULL, ICON_NONE); /* UNUSED */
2374   uiItemR(layout, ptr, "blur_max", DEFAULT_FLAGS, NULL, ICON_NONE);
2375   uiItemR(layout, ptr, "use_extended_bounds", DEFAULT_FLAGS, NULL, ICON_NONE);
2376 }
2377
2378 static void node_composit_backdrop_viewer(
2379     SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
2380 {
2381   //  node_composit_backdrop_canvas(snode, backdrop, node, x, y);
2382   if (node->custom1 == 0) {
2383     const float backdropWidth = backdrop->x;
2384     const float backdropHeight = backdrop->y;
2385     const float cx = x + snode->zoom * backdropWidth * node->custom3;
2386     const float cy = y + snode->zoom * backdropHeight * node->custom4;
2387     const float cross_size = 12 * U.pixelsize;
2388
2389     GPUVertFormat *format = immVertexFormat();
2390     uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
2391
2392     immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
2393
2394     immUniformColor3f(1.0f, 1.0f, 1.0f);
2395
2396     immBegin(GPU_PRIM_LINES, 4);
2397     immVertex2f(pos, cx - cross_size, cy - cross_size);
2398     immVertex2f(pos, cx + cross_size, cy + cross_size);
2399     immVertex2f(pos, cx + cross_size, cy - cross_size);
2400     immVertex2f(pos, cx - cross_size, cy + cross_size);
2401     immEnd();
2402
2403     immUnbindProgram();
2404   }
2405 }
2406
2407 static void node_composit_backdrop_boxmask(
2408     SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
2409 {
2410   NodeBoxMask *boxmask = node->storage;
2411   const float backdropWidth = backdrop->x;
2412   const float backdropHeight = backdrop->y;
2413   const float aspect = backdropWidth / backdropHeight;
2414   const float rad = -boxmask->rotation;
2415   const float cosine = cosf(rad);
2416   const float sine = sinf(rad);
2417   const float halveBoxWidth = backdropWidth * (boxmask->width / 2.0f);
2418   const float halveBoxHeight = backdropHeight * (boxmask->height / 2.0f) * aspect;
2419
2420   float cx, cy, x1, x2, x3, x4;
2421   float y1, y2, y3, y4;
2422
2423   cx = x + snode->zoom * backdropWidth * boxmask->x;
2424   cy = y + snode->zoom * backdropHeight * boxmask->y;
2425
2426   x1 = cx - (cosine * halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2427   x2 = cx - (cosine * -halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2428   x3 = cx - (cosine * -halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2429   x4 = cx - (cosine * halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2430   y1 = cy - (-sine * halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2431   y2 = cy - (-sine * -halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2432   y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2433   y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2434
2435   GPUVertFormat *format = immVertexFormat();
2436   uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
2437
2438   immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
2439
2440   immUniformColor3f(1.0f, 1.0f, 1.0f);
2441
2442   immBegin(GPU_PRIM_LINE_LOOP, 4);
2443   immVertex2f(pos, x1, y1);
2444   immVertex2f(pos, x2, y2);
2445   immVertex2f(pos, x3, y3);
2446   immVertex2f(pos, x4, y4);
2447   immEnd();
2448
2449   immUnbindProgram();
2450 }
2451
2452 static void node_composit_backdrop_ellipsemask(
2453     SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
2454 {
2455   NodeEllipseMask *ellipsemask = node->storage;
2456   const float backdropWidth = backdrop->x;
2457   const float backdropHeight = backdrop->y;
2458   const float aspect = backdropWidth / backdropHeight;
2459   const float rad = -ellipsemask->rotation;
2460   const float cosine = cosf(rad);
2461   const float sine = sinf(rad);
2462   const float halveBoxWidth = backdropWidth * (ellipsemask->width / 2.0f);
2463   const float halveBoxHeight = backdropHeight * (ellipsemask->height / 2.0f) * aspect;
2464
2465   float cx, cy, x1, x2, x3, x4;
2466   float y1, y2, y3, y4;
2467
2468   cx = x + snode->zoom * backdropWidth * ellipsemask->x;
2469   cy = y + snode->zoom * backdropHeight * ellipsemask->y;
2470
2471   x1 = cx - (cosine * halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2472   x2 = cx - (cosine * -halveBoxWidth + sine * halveBoxHeight) * snode->zoom;
2473   x3 = cx - (cosine * -halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2474   x4 = cx - (cosine * halveBoxWidth + sine * -halveBoxHeight) * snode->zoom;
2475   y1 = cy - (-sine * halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2476   y2 = cy - (-sine * -halveBoxWidth + cosine * halveBoxHeight) * snode->zoom;
2477   y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2478   y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom;
2479
2480   GPUVertFormat *format = immVertexFormat();
2481   uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
2482
2483   immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
2484
2485   immUniformColor3f(1.0f, 1.0f, 1.0f);
2486
2487   immBegin(GPU_PRIM_LINE_LOOP, 4);
2488   immVertex2f(pos, x1, y1);
2489   immVertex2f(pos, x2, y2);
2490   immVertex2f(pos, x3, y3);
2491   immVertex2f(pos, x4, y4);
2492   immEnd();
2493
2494   immUnbindProgram();
2495 }
2496
2497 static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2498 {
2499   uiLayout *row;
2500   row = uiLayoutRow(layout, true);
2501   uiItemR(row, ptr, "x", DEFAULT_FLAGS, NULL, ICON_NONE);
2502   uiItemR(row, ptr, "y", DEFAULT_FLAGS, NULL, ICON_NONE);
2503   row = uiLayoutRow(layout, true);
2504   uiItemR(row, ptr, "width", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2505   uiItemR(row, ptr, "height", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2506
2507   uiItemR(layout, ptr, "rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
2508   uiItemR(layout, ptr, "mask_type", DEFAULT_FLAGS, NULL, ICON_NONE);
2509 }
2510
2511 static void node_composit_buts_composite(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2512 {
2513   uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
2514 }
2515
2516 static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2517 {
2518   uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
2519 }
2520
2521 static void node_composit_buts_viewer_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2522 {
2523   uiLayout *col;
2524
2525   uiItemR(layout, ptr, "use_alpha", DEFAULT_FLAGS, NULL, ICON_NONE);
2526   uiItemR(layout, ptr, "tile_order", DEFAULT_FLAGS, NULL, ICON_NONE);
2527   if (RNA_enum_get(ptr, "tile_order") == 0) {
2528     col = uiLayoutColumn(layout, true);
2529     uiItemR(col, ptr, "center_x", DEFAULT_FLAGS, NULL, ICON_NONE);
2530     uiItemR(col, ptr, "center_y", DEFAULT_FLAGS, NULL, ICON_NONE);
2531   }
2532 }
2533
2534 static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
2535 {
2536   bNode *node = ptr->data;
2537
2538   uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2539   uiItemR(layout, ptr, "use_feather", DEFAULT_FLAGS, NULL, ICON_NONE);
2540
2541   uiItemR(layout, ptr, "size_source", DEFAULT_FLAGS, "", ICON_NONE);
2542
2543   if (node->custom1 & (CMP_NODEFLAG_MASK_FIXED | CMP_NODEFLAG_MASK_FIXED_SCENE)) {
2544     uiItemR(layout, ptr, "size_x", DEFAULT_FLAGS, NULL, ICON_NONE);
2545     uiItemR(layout, ptr, "size_y", DEFAULT_FLAGS, NULL, ICON_NONE);
2546   }
2547
2548   uiItemR(layout, ptr, "use_motion_blur", DEFAULT_FLAGS, NULL, ICON_NONE);
2549   if (node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) {
2550     uiItemR(layout, ptr, "motion_blur_samples", DEFAULT_FLAGS, NULL, ICON_NONE);
2551     uiItemR(layout, ptr, "motion_blur_shutter", DEFAULT_FLAGS, NULL, ICON_NONE);
2552   }
2553 }
2554
2555 static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, PointerRNA *ptr)
2556 {
2557   bNode *node = ptr->data;
2558
2559   uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2560
2561   if (node->id) {
2562     MovieClip *clip = (MovieClip *)node->id;
2563     uiLayout *col;
2564     PointerRNA tracking_ptr;
2565
2566     RNA_pointer_create(&clip->id, &RNA_MovieTracking, &clip->tracking, &tracking_ptr);
2567
2568     col = uiLayoutColumn(layout, true);
2569     uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
2570   }
2571 }
2572
2573 static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2574 {
2575   /* bNode *node = ptr->data; */ /* UNUSED */
2576
2577   uiItemR(layout, ptr, "blur_pre", DEFAULT_FLAGS, NULL, ICON_NONE);
2578   uiItemR(layout, ptr, "screen_balance", DEFAULT_FLAGS, NULL, ICON_NONE);
2579   uiItemR(layout, ptr, "despill_factor", DEFAULT_FLAGS, NULL, ICON_NONE);
2580   uiItemR(layout, ptr, "despill_balance", DEFAULT_FLAGS, NULL, ICON_NONE);
2581   uiItemR(layout, ptr, "edge_kernel_radius", DEFAULT_FLAGS, NULL, ICON_NONE);
2582   uiItemR(layout, ptr, "edge_kernel_tolerance", DEFAULT_FLAGS, NULL, ICON_NONE);
2583   uiItemR(layout, ptr, "clip_black", DEFAULT_FLAGS, NULL, ICON_NONE);
2584   uiItemR(layout, ptr, "clip_white", DEFAULT_FLAGS, NULL, ICON_NONE);
2585   uiItemR(layout, ptr, "dilate_distance", DEFAULT_FLAGS, NULL, ICON_NONE);
2586   uiItemR(layout, ptr, "feather_falloff", DEFAULT_FLAGS, NULL, ICON_NONE);
2587   uiItemR(layout, ptr, "feather_distance", DEFAULT_FLAGS, NULL, ICON_NONE);
2588   uiItemR(layout, ptr, "blur_post", DEFAULT_FLAGS, NULL, ICON_NONE);
2589 }
2590
2591 static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRNA *ptr)
2592 {
2593   bNode *node = ptr->data;
2594
2595   uiTemplateID(
2596       layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2597
2598   if (node->id) {
2599     MovieClip *clip = (MovieClip *)node->id;
2600     MovieTracking *tracking = &clip->tracking;
2601     MovieTrackingObject *object;
2602     uiLayout *col;
2603     PointerRNA tracking_ptr;
2604     NodeTrackPosData *data = node->storage;
2605
2606     RNA_pointer_create(&clip->id, &RNA_MovieTracking, tracking, &tracking_ptr);
2607
2608     col = uiLayoutColumn(layout, false);
2609     uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
2610
2611     object = BKE_tracking_object_get_named(tracking, data->tracking_object);
2612     if (object) {
2613       PointerRNA object_ptr;
2614
2615       RNA_pointer_create(&clip->id, &RNA_MovieTrackingObject, object, &object_ptr);
2616
2617       uiItemPointerR(col, ptr, "track_name", &object_ptr, "tracks", "", ICON_ANIM_DATA);
2618     }
2619     else {
2620       uiItemR(layout, ptr, "track_name", DEFAULT_FLAGS, "", ICON_ANIM_DATA);
2621     }
2622
2623     uiItemR(layout, ptr, "position", DEFAULT_FLAGS, NULL, ICON_NONE);
2624
2625     if (ELEM(node->custom1, CMP_TRACKPOS_RELATIVE_FRAME, CMP_TRACKPOS_ABSOLUTE_FRAME)) {
2626       uiItemR(layout, ptr, "frame_relative", DEFAULT_FLAGS, NULL, ICON_NONE);
2627     }
2628   }
2629 }
2630
2631 static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, PointerRNA *ptr)
2632 {
2633   bNode *node = ptr->data;
2634   NodePlaneTrackDeformData *data = node->storage;
2635
2636   uiTemplateID(
2637       layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2638
2639   if (node->id) {
2640     MovieClip *clip = (MovieClip *)node->id;
2641     MovieTracking *tracking = &clip->tracking;
2642     MovieTrackingObject *object;
2643     uiLayout *col;
2644     PointerRNA tracking_ptr;
2645
2646     RNA_pointer_create(&clip->id, &RNA_MovieTracking, tracking, &tracking_ptr);
2647
2648     col = uiLayoutColumn(layout, false);
2649     uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
2650
2651     object = BKE_tracking_object_get_named(tracking, data->tracking_object);
2652     if (object) {
2653       PointerRNA object_ptr;
2654
2655       RNA_pointer_create(&clip->id, &RNA_MovieTrackingObject, object, &object_ptr);
2656
2657       uiItemPointerR(
2658           col, ptr, "plane_track_name", &object_ptr, "plane_tracks", "", ICON_ANIM_DATA);
2659     }
2660     else {
2661       uiItemR(layout, ptr, "plane_track_name", 0, "", ICON_ANIM_DATA);
2662     }
2663   }
2664
2665   uiItemR(layout, ptr, "use_motion_blur", DEFAULT_FLAGS, NULL, ICON_NONE);
2666   if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
2667     uiItemR(layout, ptr, "motion_blur_samples", DEFAULT_FLAGS, NULL, ICON_NONE);
2668     uiItemR(layout, ptr, "motion_blur_shutter", DEFAULT_FLAGS, NULL, ICON_NONE);
2669   }
2670 }
2671
2672 static void node_composit_buts_cornerpin(uiLayout *UNUSED(layout),
2673                                          bContext *UNUSED(C),
2674                                          PointerRNA *UNUSED(ptr))
2675 {
2676 }
2677
2678 static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2679 {
2680   uiItemR(layout, ptr, "source", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, "", ICON_NONE);
2681   uiItemR(layout, ptr, "ray_length", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, NULL, ICON_NONE);
2682 }
2683
2684 static void node_composit_buts_cryptomatte_legacy(uiLayout *layout,
2685                                                   bContext *UNUSED(C),
2686                                                   PointerRNA *ptr)
2687 {
2688   uiLayout *col = uiLayoutColumn(layout, true);
2689
2690   uiItemL(col, IFACE_("Matte Objects:"), ICON_NONE);
2691
2692   uiLayout *row = uiLayoutRow(col, true);
2693   uiTemplateCryptoPicker(row, ptr, "add", ICON_ADD);
2694   uiTemplateCryptoPicker(row, ptr, "remove", ICON_REMOVE);
2695
2696   uiItemR(col, ptr, "matte_id", DEFAULT_FLAGS, "", ICON_NONE);
2697 }
2698
2699 static void node_composit_buts_cryptomatte_legacy_ex(uiLayout *layout,
2700                                                      bContext *UNUSED(C),
2701                                                      PointerRNA *UNUSED(ptr))
2702 {
2703   uiItemO(layout, IFACE_("Add Crypto Layer"), ICON_ADD, "NODE_OT_cryptomatte_layer_add");
2704   uiItemO(layout, IFACE_("Remove Crypto Layer"), ICON_REMOVE, "NODE_OT_cryptomatte_layer_remove");
2705 }
2706
2707 static void node_composit_buts_cryptomatte(uiLayout *layout, bContext *C, PointerRNA *ptr)
2708 {
2709   bNode *node = ptr->data;
2710
2711   uiLayout *row = uiLayoutRow(layout, true);
2712   uiItemR(row, ptr, "source", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
2713
2714   uiLayout *col = uiLayoutColumn(layout, false);
2715   if (node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER) {
2716     uiTemplateID(col, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2717   }
2718   else {
2719     uiTemplateID(
2720         col, C, ptr, "image", NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL);
2721
2722     NodeCryptomatte *crypto = (NodeCryptomatte *)node->storage;
2723     PointerRNA imaptr = RNA_pointer_get(ptr, "image");
2724     PointerRNA iuserptr;
2725     RNA_pointer_create((ID *)ptr->owner_id, &RNA_ImageUser, &crypto->iuser, &iuserptr);
2726     uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
2727
2728     node_buts_image_user(col, C, ptr, &imaptr, &iuserptr, false, false);
2729     node_buts_image_views(col, C, ptr, &imaptr);
2730   }
2731
2732   col = uiLayoutColumn(layout, true);
2733   uiItemR(col, ptr, "layer_name", 0, "", ICON_NONE);
2734   uiItemL(col, IFACE_("Matte ID:"), ICON_NONE);
2735
2736   row = uiLayoutRow(col, true);
2737   uiItemR(row, ptr, "matte_id", DEFAULT_FLAGS, "", ICON_NONE);
2738   uiTemplateCryptoPicker(row, ptr, "add", ICON_ADD);
2739   uiTemplateCryptoPicker(row, ptr, "remove", ICON_REMOVE);
2740 }
2741
2742 static void node_composit_buts_brightcontrast(uiLayout *layout,
2743                                               bContext *UNUSED(C),
2744                                               PointerRNA *ptr)
2745 {
2746   uiItemR(layout, ptr, "use_premultiply", DEFAULT_FLAGS, NULL, ICON_NONE);
2747 }
2748
2749 static void node_composit_buts_denoise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
2750 {
2751 #ifndef WITH_OPENIMAGEDENOISE
2752   uiItemL(layout, IFACE_("Disabled, built without OpenImageDenoise"), ICON_ERROR);
2753 #else
2754   /* Always supported through Accelerate framework BNNS on macOS. */
2755 #  ifndef __APPLE__
2756   if (!BLI_cpu_support_sse41()) {
2757     uiItemL(layout, IFACE_("Disabled, CPU with SSE4.1 is required"), ICON_ERROR);
2758   }
2759 #  endif
2760 #endif
2761
2762   uiItemR(layout, ptr, "use_hdr", DEFAULT_FLAGS, NULL, ICON_NONE);
2763 }
2764
2765 /* only once called */
2766 static void node_composit_set_butfunc(bNodeType *ntype)
2767 {
2768   switch (ntype->type) {
2769     case CMP_NODE_IMAGE:
2770       ntype->draw_buttons = node_composit_buts_image;
2771       ntype->draw_buttons_ex = node_composit_buts_image_ex;
2772       break;
2773     case CMP_NODE_R_LAYERS:
2774       ntype->draw_buttons = node_composit_buts_viewlayers;
2775       break;
2776     case CMP_NODE_NORMAL:
2777       ntype->draw_buttons = node_buts_normal;
2778       break;
2779     case CMP_NODE_CURVE_VEC:
2780       ntype->draw_buttons = node_buts_curvevec;
2781       break;
2782     case CMP_NODE_CURVE_RGB:
2783       ntype->draw_buttons = node_buts_curvecol;
2784       break;
2785     case CMP_NODE_VALUE:
2786       ntype->draw_buttons = node_buts_value;
2787       break;
2788     case CMP_NODE_RGB:
2789       ntype->draw_buttons = node_buts_rgb;
2790       break;
2791     case CMP_NODE_FLIP:
2792       ntype->draw_buttons = node_composit_buts_flip;
2793       break;
2794     case CMP_NODE_SPLITVIEWER:
2795       ntype->draw_buttons = node_composit_buts_splitviewer;
2796       break;
2797     case CMP_NODE_MIX_RGB:
2798       ntype->draw_buttons = node_buts_mix_rgb;
2799       break;
2800     case CMP_NODE_VALTORGB:
2801       ntype->draw_buttons = node_buts_colorramp;
2802       break;
2803     case CMP_NODE_CROP:
2804       ntype->draw_buttons = node_composit_buts_crop;
2805       break;
2806     case CMP_NODE_BLUR:
2807       ntype->draw_buttons = node_composit_buts_blur;
2808       break;
2809     case CMP_NODE_DBLUR:
2810       ntype->draw_buttons = node_composit_buts_dblur;
2811       break;
2812     case CMP_NODE_BILATERALBLUR:
2813       ntype->draw_buttons = node_composit_buts_bilateralblur;
2814       break;
2815     case CMP_NODE_DEFOCUS:
2816       ntype->draw_buttons = node_composit_buts_defocus;
2817       break;
2818     case CMP_NODE_ANTIALIASING:
2819       ntype->draw_buttons = node_composit_buts_antialiasing;
2820       break;
2821     case CMP_NODE_GLARE:
2822       ntype->draw_buttons = node_composit_buts_glare;
2823       break;
2824     case CMP_NODE_TONEMAP:
2825       ntype->draw_buttons = node_composit_buts_tonemap;
2826       break;
2827     case CMP_NODE_LENSDIST:
2828       ntype->draw_buttons = node_composit_buts_lensdist;
2829       break;
2830     case CMP_NODE_VECBLUR:
2831       ntype->draw_buttons = node_composit_buts_vecblur;
2832       break;
2833     case CMP_NODE_FILTER:
2834       ntype->draw_buttons = node_composit_buts_filter;
2835       break;
2836     case CMP_NODE_MAP_VALUE:
2837       ntype->draw_buttons = node_composit_buts_map_value;
2838       break;
2839     case CMP_NODE_MAP_RANGE:
2840       ntype->draw_buttons = node_composit_buts_map_range;
2841       break;
2842     case CMP_NODE_TIME:
2843       ntype->draw_buttons = node_buts_time;
2844       break;
2845     case CMP_NODE_ALPHAOVER:
2846       ntype->draw_buttons = node_composit_buts_alphaover;
2847       break;
2848     case CMP_NODE_TEXTURE:
2849       ntype->draw_buttons = node_buts_texture;
2850       break;
2851     case CMP_NODE_DILATEERODE:
2852       ntype->draw_buttons = node_composit_buts_dilateerode;
2853       break;
2854     case CMP_NODE_INPAINT:
2855       ntype->draw_buttons = node_composit_buts_inpaint;
2856       break;
2857     case CMP_NODE_DESPECKLE:
2858       ntype->draw_buttons = node_composit_buts_despeckle;
2859       break;
2860     case CMP_NODE_OUTPUT_FILE:
2861       ntype->draw_buttons = node_composit_buts_file_output;
2862       ntype->draw_buttons_ex = node_composit_buts_file_output_ex;
2863       break;
2864     case CMP_NODE_DIFF_MATTE:
2865       ntype->draw_buttons = node_composit_buts_diff_matte;
2866       break;
2867     case CMP_NODE_DIST_MATTE:
2868       ntype->draw_buttons = node_composit_buts_distance_matte;
2869       break;
2870     case CMP_NODE_COLOR_SPILL:
2871       ntype->draw_buttons = node_composit_buts_color_spill;
2872       break;
2873     case CMP_NODE_CHROMA_MATTE:
2874       ntype->draw_buttons = node_composit_buts_chroma_matte;
2875       break;
2876     case CMP_NODE_COLOR_MATTE:
2877       ntype->draw_buttons = node_composit_buts_color_matte;
2878       break;
2879     case CMP_NODE_SCALE:
2880       ntype->draw_buttons = node_composit_buts_scale;
2881       break;
2882     case CMP_NODE_ROTATE:
2883       ntype->draw_buttons = node_composit_buts_rotate;
2884       break;
2885     case CMP_NODE_CHANNEL_MATTE:
2886       ntype->draw_buttons = node_composit_buts_channel_matte;
2887       break;
2888     case CMP_NODE_LUMA_MATTE:
2889       ntype->draw_buttons = node_composit_buts_luma_matte;
2890       break;
2891     case CMP_NODE_MAP_UV:
2892       ntype->draw_buttons = node_composit_buts_map_uv;
2893       break;
2894     case CMP_NODE_ID_MASK:
2895       ntype->draw_buttons = node_composit_buts_id_mask;
2896       break;
2897     case CMP_NODE_DOUBLEEDGEMASK:
2898       ntype->draw_buttons = node_composit_buts_double_edge_mask;
2899       break;
2900     case CMP_NODE_MATH:
2901       ntype->draw_buttons = node_buts_math;
2902       break;
2903     case CMP_NODE_INVERT:
2904       ntype->draw_buttons = node_composit_buts_invert;
2905       break;
2906     case CMP_NODE_PREMULKEY:
2907       ntype->draw_buttons = node_composit_buts_premulkey;
2908       break;
2909     case CMP_NODE_VIEW_LEVELS:
2910       ntype->draw_buttons = node_composit_buts_view_levels;
2911       break;
2912     case CMP_NODE_COLORBALANCE:
2913       ntype->draw_buttons = node_composit_buts_colorbalance;
2914       ntype->draw_buttons_ex = node_composit_buts_colorbalance_ex;
2915       break;
2916     case CMP_NODE_HUECORRECT:
2917       ntype->draw_buttons = node_composit_buts_huecorrect;
2918       break;
2919     case CMP_NODE_ZCOMBINE:
2920       ntype->draw_buttons = node_composit_buts_zcombine;
2921       break;
2922     case CMP_NODE_COMBYCCA:
2923     case CMP_NODE_SEPYCCA:
2924       ntype->draw_buttons = node_composit_buts_ycc;
2925       break;
2926     case CMP_NODE_MOVIECLIP:
2927       ntype->draw_buttons = node_composit_buts_movieclip;
2928       ntype->draw_buttons_ex = node_composit_buts_movieclip_ex;
2929       break;
2930     case CMP_NODE_STABILIZE2D:
2931       ntype->draw_buttons = node_composit_buts_stabilize2d;
2932       break;
2933     case CMP_NODE_TRANSFORM:
2934       ntype->draw_buttons = node_composit_buts_transform;
2935       break;
2936     case CMP_NODE_TRANSLATE:
2937       ntype->draw_buttons = node_composit_buts_translate;
2938       break;
2939     case CMP_NODE_MOVIEDISTORTION:
2940       ntype->draw_buttons = node_composit_buts_moviedistortion;
2941       break;
2942     case CMP_NODE_COLORCORRECTION:
2943       ntype->draw_buttons = node_composit_buts_colorcorrection;
2944       ntype->draw_buttons_ex = node_composit_buts_colorcorrection_ex;
2945       break;
2946     case CMP_NODE_SETALPHA:
2947       ntype->draw_buttons = node_composit_buts_set_alpha;
2948       break;
2949     case CMP_NODE_SWITCH:
2950       ntype->draw_buttons = node_composit_buts_switch;
2951       break;
2952     case CMP_NODE_SWITCH_VIEW:
2953       ntype->draw_buttons_ex = node_composit_buts_switch_view_ex;
2954       break;
2955     case CMP_NODE_MASK_BOX:
2956       ntype->draw_buttons = node_composit_buts_boxmask;
2957       ntype->draw_backdrop = node_composit_backdrop_boxmask;
2958       break;
2959     case CMP_NODE_MASK_ELLIPSE:
2960       ntype->draw_buttons = node_composit_buts_ellipsemask;
2961       ntype->draw_backdrop = node_composit_backdrop_ellipsemask;
2962       break;
2963     case CMP_NODE_BOKEHIMAGE:
2964       ntype->draw_buttons = node_composit_buts_bokehimage;
2965       break;
2966     case CMP_NODE_BOKEHBLUR:
2967       ntype->draw_buttons = node_composit_buts_bokehblur;
2968       break;
2969     case CMP_NODE_VIEWER:
2970       ntype->draw_buttons = node_composit_buts_viewer;
2971       ntype->draw_buttons_ex = node_composit_buts_viewer_ex;
2972       ntype->draw_backdrop = node_composit_backdrop_viewer;
2973       break;
2974     case CMP_NODE_COMPOSITE:
2975       ntype->draw_buttons = node_composit_buts_composite;
2976       break;
2977     case CMP_NODE_MASK:
2978       ntype->draw_buttons = node_composit_buts_mask;
2979       break;
2980     case CMP_NODE_KEYINGSCREEN:
2981       ntype->draw_buttons = node_composit_buts_keyingscreen;
2982       break;
2983     case CMP_NODE_KEYING:
2984       ntype->draw_buttons = node_composit_buts_keying;
2985       break;
2986     case CMP_NODE_TRACKPOS:
2987       ntype->draw_buttons = node_composit_buts_trackpos;
2988       break;
2989     case CMP_NODE_PLANETRACKDEFORM:
2990       ntype->draw_buttons = node_composit_buts_planetrackdeform;
2991       break;
2992     case CMP_NODE_CORNERPIN:
2993       ntype->draw_buttons = node_composit_buts_cornerpin;
2994       break;
2995     case CMP_NODE_SUNBEAMS:
2996       ntype->draw_buttons = node_composit_buts_sunbeams;
2997       break;
2998     case CMP_NODE_CRYPTOMATTE:
2999       ntype->draw_buttons = node_composit_buts_cryptomatte;
3000       break;
3001     case CMP_NODE_CRYPTOMATTE_LEGACY:
3002       ntype->draw_buttons = node_composit_buts_cryptomatte_legacy;
3003       ntype->draw_buttons_ex = node_composit_buts_cryptomatte_legacy_ex;
3004       break;
3005     case CMP_NODE_BRIGHTCONTRAST:
3006       ntype->draw_buttons = node_composit_buts_brightcontrast;
3007       break;
3008     case CMP_NODE_DENOISE:
3009       ntype->draw_buttons = node_composit_buts_denoise;
3010       break;
3011   }
3012 }
3013
3014 /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
3015
3016 static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
3017 {
3018   uiLayout *col;
3019
3020   col = uiLayoutColumn(layout, true);
3021   uiItemR(col, ptr, "offset", DEFAULT_FLAGS | UI_ITEM_R_SLIDER, IFACE_("Offset"), ICON_NONE);
3022   uiItemR(col, ptr, "offset_frequency", DEFAULT_FLAGS, IFACE_("Frequency"), ICON_NONE);
3023
3024   col = uiLayoutColumn(layout, true);
3025   uiItemR(col, ptr, "squash", DEFAULT_FLAGS, IFACE_("Squash"), ICON_NONE);
3026   uiItemR(col, ptr, "squash_frequency", DEFAULT_FLAGS, IFACE_("Frequency"), ICON_NONE);
3027 }
3028
3029 static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
3030 {
3031   PointerRNA tex_ptr;
3032   bNode *node = ptr->data;
3033   ID *id = ptr->owner_id;
3034   Tex *tex = (Tex *)node->storage;
3035   uiLayout *col, *row;
3036
3037   RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr);
3038
3039   col = uiLayoutColumn(layout, false);
3040
3041   switch (tex->type) {
3042     case TEX_BLEND:
3043       uiItemR(col, &tex_ptr, "progression", DEFAULT_FLAGS, "", ICON_NONE);
3044       row = uiLayoutRow(col, false);
3045       uiItemR(row, &tex_ptr, "use_flip_axis", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3046       break;
3047
3048     case TEX_MARBLE:
3049       row = uiLayoutRow(col, false);
3050       uiItemR(row, &tex_ptr, "marble_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3051       row = uiLayoutRow(col, false);
3052       uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3053       row = uiLayoutRow(col, false);
3054       uiItemR(row, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
3055       row = uiLayoutRow(col, false);
3056       uiItemR(row, &tex_ptr, "noise_basis_2", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3057       break;
3058
3059     case TEX_MAGIC:
3060       uiItemR(col, &tex_ptr, "noise_depth", DEFAULT_FLAGS, NULL, ICON_NONE);
3061       break;
3062
3063     case TEX_STUCCI:
3064       row = uiLayoutRow(col, false);
3065       uiItemR(row, &tex_ptr, "stucci_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3066       row = uiLayoutRow(col, false);
3067       uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3068       uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
3069       break;
3070
3071     case TEX_WOOD:
3072       uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
3073       uiItemR(col, &tex_ptr, "wood_type", DEFAULT_FLAGS, "", ICON_NONE);
3074       row = uiLayoutRow(col, false);
3075       uiItemR(row, &tex_ptr, "noise_basis_2", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3076       row = uiLayoutRow(col, false);
3077       uiLayoutSetActive(row, !(ELEM(tex->stype, TEX_BAND, TEX_RING)));
3078       uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3079       break;
3080
3081     case TEX_CLOUDS:
3082       uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
3083       row = uiLayoutRow(col, false);
3084       uiItemR(row, &tex_ptr, "cloud_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3085       row = uiLayoutRow(col, false);
3086       uiItemR(row, &tex_ptr, "noise_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE);
3087       uiItemR(col,
3088               &tex_ptr,
3089               "noise_depth",
3090               DEFAULT_FLAGS | UI_ITEM_R_EXPAND,
3091               IFACE_("Depth"),
3092               ICON_NONE);
3093       break;
3094
3095     case TEX_DISTNOISE:
3096       uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
3097       uiItemR(col, &tex_ptr, "noise_distortion", DEFAULT_FLAGS, "", ICON_NONE);
3098       break;
3099
3100     case TEX_MUSGRAVE:
3101       uiItemR(col, &tex_ptr, "musgrave_type", DEFAULT_FLAGS, "", ICON_NONE);
3102       uiItemR(col, &tex_ptr, "noise_basis", DEFAULT_FLAGS, "", ICON_NONE);
3103       break;
3104     case TEX_VORONOI:
3105       uiItemR(col, &tex_ptr, "distance_metric", DEFAULT_FLAGS, "", ICON_NONE);
3106       if (tex->vn_distm == TEX_MINKOVSKY) {
3107         uiItemR(col, &tex_ptr, "minkovsky_exponent", DEFAULT_FLAGS, NULL, ICON_NONE);
3108       }
3109       uiItemR(col, &tex_ptr, "color_mode", DEFAULT_FLAGS, "", ICON_NONE);
3110       break;
3111   }
3112 }
3113
3114 static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
3115 {
3116   uiTemplateID(layout,
3117                C,
3118                ptr,
3119                "image",
3120                "IMAGE_OT_new",
3121                "IMAGE_OT_open",
3122                NULL,
3123                UI_TEMPLATE_ID_FILTER_ALL,
3124                false,
3125                NULL);
3126 }
3127
3128 static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
3129 {
3130   bNode *node = ptr->data;
3131   PointerRNA iuserptr;
3132
3133   RNA_pointer_create(ptr->owner_id, &RNA_ImageUser, node->storage, &iuserptr);
3134   uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0);
3135 }
3136
3137 static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
3138 {
3139   uiItemR(layout, ptr, "filepath", DEFAULT_FLAGS, "", ICON_NONE);
3140 }
3141
3142 /* only once called */
3143 static void node_texture_set_butfunc(bNodeType *ntype)
3144 {
3145   if (ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX) {
3146     ntype->draw_buttons = node_texture_buts_proc;
3147   }
3148   else {
3149     switch (ntype->type) {
3150
3151       case TEX_NODE_MATH:
3152         ntype->draw_buttons = node_buts_math;
3153         break;
3154
3155       case TEX_NODE_MIX_RGB:
3156         ntype->draw_buttons = node_buts_mix_rgb;
3157         break;
3158
3159       case TEX_NODE_VALTORGB:
3160         ntype->draw_buttons = node_buts_colorramp;
3161         break;
3162
3163       case TEX_NODE_CURVE_RGB:
3164         ntype->draw_buttons = node_buts_curvecol;
3165         break;
3166
3167       case TEX_NODE_CURVE_TIME:
3168         ntype->draw_buttons = node_buts_time;
3169         break;
3170
3171       case TEX_NODE_TEXTURE:
3172         ntype->draw_buttons = node_buts_texture;
3173         break;
3174
3175       case TEX_NODE_BRICKS:
3176         ntype->draw_buttons = node_texture_buts_bricks;
3177         break;
3178
3179       case TEX_NODE_IMAGE:
3180         ntype->draw_buttons = node_texture_buts_image;
3181         ntype->draw_buttons_ex = node_texture_buts_image_ex;
3182         break;
3183
3184       case TEX_NODE_OUTPUT:
3185         ntype->draw_buttons = node_texture_buts_output;
3186         break;
3187     }
3188   }
3189 }
3190
3191 /* ****** init draw callbacks for all tree types, only called in usiblender.c, once ************ */
3192
3193 static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
3194 {
3195   bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
3196   bNode *node = ptr->data;
3197   ED_node_tag_update_nodetree(bmain, ntree, node);
3198 }
3199
3200 static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocketTemplate *stemp)
3201 {
3202   StructRNA *srna = ntype->rna_ext.srna;
3203   PropertyRNA *prop = RNA_struct_type_find_property(srna, stemp->identifier);
3204
3205   if (prop) {
3206     RNA_def_property_update_runtime(prop, node_property_update_default);
3207   }
3208 }
3209
3210 static void node_template_properties_update(bNodeType *ntype)
3211 {
3212   bNodeSocketTemplate *stemp;
3213
3214   if (ntype->inputs) {
3215     for (stemp = ntype->inputs; stemp->type >= 0; stemp++) {
3216       node_socket_template_properties_update(ntype, stemp);
3217     }
3218   }
3219   if (ntype->outputs) {
3220     for (stemp = ntype->outputs; stemp->type >= 0; stemp++) {
3221       node_socket_template_properties_update(ntype, stemp);
3222     }
3223   }
3224 }
3225
3226 static void node_socket_undefined_draw(bContext *UNUSED(C),
3227                                        uiLayout *layout,
3228                                        PointerRNA *UNUSED(ptr),
3229                                        PointerRNA *UNUSED(node_ptr),
3230                                        const char *UNUSED(text))
3231 {
3232   uiItemL(layout, IFACE_("Undefined Socket Type"), ICON_ERROR);
3233 }
3234
3235 static void node_socket_undefined_draw_color(bContext *UNUSED(C),
3236                                              PointerRNA *UNUSED(ptr),
3237                                              PointerRNA *UNUSED(node_ptr),
3238                                              float *r_color)
3239 {
3240   r_color[0] = 1.0f;
3241   r_color[1] = 0.0f;
3242   r_color[2] = 0.0f;
3243   r_color[3] = 1.0f;
3244 }
3245
3246 static void node_socket_undefined_interface_draw(bContext *UNUSED(C),
3247                                                  uiLayout *layout,
3248                                                  PointerRNA *UNUSED(ptr))
3249 {
3250   uiItemL(layout, IFACE_("Undefined Socket Type"), ICON_ERROR);
3251 }
3252
3253 static void node_socket_undefined_interface_draw_color(bContext *UNUSED(C),
3254                                                        PointerRNA *UNUSED(ptr),
3255                                                        float *r_color)
3256 {
3257   r_color[0] = 1.0f;
3258   r_color[1] = 0.0f;
3259   r_color[2] = 0.0f;
3260   r_color[3] = 1.0f;
3261 }
3262
3263 void ED_node_init_butfuncs(void)
3264 {
3265   /* Fallback types for undefined tree, nodes, sockets
3266    * Defined in blenkernel, but not registered in type hashes.
3267    */
3268
3269   /* default ui functions */
3270   NodeTypeUndefined.draw_nodetype = node_draw_default;
3271   NodeTypeUndefined.draw_nodetype_prepare = node_update_default;
3272   NodeTypeUndefined.select_area_func = node_select_area_default;
3273   NodeTypeUndefined.tweak_area_func = node_tweak_area_default;
3274   NodeTypeUndefined.draw_buttons = NULL;
3275   NodeTypeUndefined.draw_buttons_ex = NULL;
3276   NodeTypeUndefined.resize_area_func = node_resize_area_default;
3277
3278   NodeSocketTypeUndefined.draw = node_socket_undefined_draw;
3279   NodeSocketTypeUndefined.draw_color = node_socket_undefined_draw_color;
3280   NodeSocketTypeUndefined.interface_draw = node_socket_undefined_interface_draw;
3281   NodeSocketTypeUndefined.interface_draw_color = node_socket_undefined_interface_draw_color;
3282
3283   /* node type ui functions */
3284   NODE_TYPES_BEGIN (ntype) {
3285     /* default ui functions */
3286     ntype->draw_nodetype = node_draw_default;
3287     ntype->draw_nodetype_prepare = node_update_default;
3288     ntype->select_area_func = node_select_area_default;
3289     ntype->tweak_area_func = node_tweak_area_default;
3290     ntype->resize_area_func = node_resize_area_default;
3291
3292     node_common_set_butfunc(ntype);
3293
3294     node_composit_set_butfunc(ntype);
3295     node_shader_set_butfunc(ntype);
3296     node_texture_set_butfunc(ntype);
3297
3298     /* define update callbacks for socket properties */
3299     node_template_properties_update(ntype);
3300   }
3301   NODE_TYPES_END;
3302
3303   /* tree type icons */
3304   ntreeType_Composite->ui_icon = ICON_NODE_COMPOSITING;
3305   ntreeType_Shader->ui_icon = ICON_NODE_MATERIAL;
3306   ntreeType_Texture->ui_icon = ICON_NODE_TEXTURE;
3307   ntreeType_Geometry->ui_icon = ICON_NODETREE;
3308 }
3309
3310 void ED_init_custom_node_type(bNodeType *ntype)
3311 {
3312   /* default ui functions */
3313   ntype->draw_nodetype = node_draw_default;
3314   ntype->draw_nodetype_prepare = node_update_default;
3315   ntype->resize_area_func = node_resize_area_default;
3316   ntype->select_area_func = node_select_area_default;
3317   ntype->tweak_area_func = node_tweak_area_default;
3318 }
3319
3320 void ED_init_custom_node_socket_type(bNodeSocketType *stype)
3321 {
3322   /* default ui functions */
3323   stype->draw = node_socket_button_label;
3324 }
3325
3326 static const float virtual_node_socket_color[4] = {0.2, 0.2, 0.2, 1.0};
3327
3328 /* maps standard socket integer type to a color */
3329 static const float std_node_socket_colors[][4] = {
3330     {0.63, 0.63, 0.63, 1.0}, /* SOCK_FLOAT */
3331     {0.39, 0.39, 0.78, 1.0}, /* SOCK_VECTOR */
3332     {0.78, 0.78, 0.16, 1.0}, /* SOCK_RGBA */
3333     {0.39, 0.78, 0.39, 1.0}, /* SOCK_SHADER */
3334     {0.80, 0.65, 0.84, 1.0}, /* SOCK_BOOLEAN */
3335     {0.0, 0.0, 0.0, 1.0},    /*__SOCK_MESH (deprecated) */
3336     {0.35, 0.55, 0.36, 1.0}, /* SOCK_INT */
3337     {0.44, 0.70, 1.00, 1.0}, /* SOCK_STRING */
3338     {0.93, 0.62, 0.36, 1.0}, /* SOCK_OBJECT */
3339     {0.39, 0.22, 0.39, 1.0}, /* SOCK_IMAGE */
3340     {0.00, 0.84, 0.64, 1.0}, /* SOCK_GEOMETRY */
3341     {0.96, 0.96, 0.96, 1.0}, /* SOCK_COLLECTION */
3342     {0.62, 0.31, 0.64, 1.0}, /* SOCK_TEXTURE */
3343     {0.92, 0.46, 0.51, 1.0}, /* SOCK_MATERIAL */
3344 };
3345
3346 /* common color callbacks for standard types */
3347 static void std_node_socket_draw_color(bContext *UNUSED(C),
3348                                        PointerRNA *ptr,
3349                                        PointerRNA *UNUSED(node_ptr),
3350                                        float *r_color)
3351 {
3352   bNodeSocket *sock = ptr->data;
3353   int type = sock->typeinfo->type;
3354   copy_v4_v4(r_color, std_node_socket_colors[type]);
3355 }
3356 static void std_node_socket_interface_draw_color(bContext *UNUSED(C),
3357                                                  PointerRNA *ptr,
3358                                                  float *r_color)
3359 {
3360   bNodeSocket *sock = ptr->data;
3361   int type = sock->typeinfo->type;
3362   copy_v4_v4(r_color, std_node_socket_colors[type]);
3363 }
3364
3365 /* draw function for file output node sockets,
3366  * displays only sub-path and format, no value button */
3367 static void node_file_output_socket_draw(bContext *C,
3368                                          uiLayout *layout,
3369                                          PointerRNA *ptr,
3370                                          PointerRNA *node_ptr)
3371 {
3372   bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
3373   bNodeSocket *sock = ptr->data;
3374   uiLayout *row;
3375   PointerRNA inputptr;
3376
3377   row = uiLayoutRow(layout, false);
3378
3379   PointerRNA imfptr = RNA_pointer_get(node_ptr, "format");
3380   int imtype = RNA_enum_get(&imfptr, "file_format");
3381
3382   if (imtype == R_IMF_IMTYPE_MULTILAYER) {
3383     NodeImageMultiFileSocket *input = sock->storage;
3384     RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr);
3385
3386     uiItemL(row, input->layer, ICON_NONE);
3387   }
3388   else {
3389     NodeImageMultiFileSocket *input = sock->storage;
3390     uiBlock *block;
3391     RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr);
3392
3393     uiItemL(row, input->path, ICON_NONE);
3394
3395     if (!RNA_boolean_get(&inputptr, "use_node_format")) {
3396       imfptr = RNA_pointer_get(&inputptr, "format");
3397     }
3398
3399     const char *imtype_name;
3400     PropertyRNA *imtype_prop = RNA_struct_find_property(&imfptr, "file_format");
3401     RNA_property_enum_name((bContext *)C,
3402                            &imfptr,
3403                            imtype_prop,
3404                            RNA_property_enum_get(&imfptr, imtype_prop),
3405                            &imtype_name);
3406     block = uiLayoutGetBlock(row);
3407     UI_block_emboss_set(block, UI_EMBOSS_PULLDOWN);
3408     uiItemL(row, imtype_name, ICON_NONE);
3409     UI_block_emboss_set(block, UI_EMBOSS_NONE);
3410   }
3411 }
3412
3413 static void std_node_socket_draw(
3414     bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, const char *text)
3415 {
3416   bNode *node = node_ptr->data;
3417   bNodeSocket *sock = ptr->data;
3418   int type = sock->typeinfo->type;
3419   /*int subtype = sock->typeinfo->subtype;*/
3420
3421   /* XXX not nice, eventually give this node its own socket type ... */
3422   if (node->type == CMP_NODE_OUTPUT_FILE) {
3423     node_file_output_socket_draw(C, layout, ptr, node_ptr);
3424     return;
3425   }
3426
3427   if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) {
3428     node_socket_button_label(C, layout, ptr, node_ptr, text);
3429     return;
3430   }
3431
3432   switch (type) {
3433     case SOCK_FLOAT:
3434     case SOCK_INT:
3435     case SOCK_BOOLEAN:
3436       uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0);
3437       break;
3438     case SOCK_VECTOR:
3439       if (sock->flag & SOCK_COMPACT) {
3440         uiTemplateComponentMenu(layout, ptr, "default_value", text);
3441       }
3442       else {
3443         if (sock->typeinfo->subtype == PROP_DIRECTION) {
3444           uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE);
3445         }
3446         else {
3447           uiLayout *column = uiLayoutColumn(layout, true);
3448           uiItemR(column, ptr, "default_value", DEFAULT_FLAGS, text, ICON_NONE);
3449         }
3450       }
3451       break;
3452     case SOCK_RGBA: {
3453       uiLayout *row = uiLayoutSplit(layout, 0.4f, false);
3454       uiItemL(row, text, 0);
3455       uiItemR(row, ptr, "default_value", DEFAULT_FLAGS, "", 0);
3456       break;
3457     }
3458     case SOCK_STRING: {
3459       uiLayout *row = uiLayoutSplit(layout, 0.4f, false);
3460       uiItemL(row, text, 0);
3461
3462       const bNodeTree *node_tree = (const bNodeTree *)node_ptr->owner_id;
3463       if (node_tree->type == NTREE_GEOMETRY) {
3464         node_geometry_add_attribute_search_button(C, node_tree, node, ptr, row);
3465       }
3466       else {
3467         uiItemR(row, ptr, "default_value", DEFAULT_FLAGS, "", 0);
3468       }
3469
3470       break;
3471     }
3472     case SOCK_OBJECT: {
3473       uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0);
3474       break;
3475     }
3476     case SOCK_IMAGE: {
3477       uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0);
3478       break;
3479     }
3480     case SOCK_COLLECTION: {
3481       uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0);
3482       break;
3483     }
3484     case SOCK_TEXTURE: {
3485       uiTemplateID(layout, C, ptr, "default_value", "texture.new", NULL, NULL, 0, ICON_NONE, NULL);
3486       break;
3487     }
3488     case SOCK_MATERIAL: {
3489       uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0);
3490       break;
3491     }
3492     default:
3493       node_socket_button_label(C, layout, ptr, node_ptr, text);
3494       break;
3495   }
3496 }
3497
3498 static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *ptr)
3499 {
3500   bNodeSocket *sock = ptr->data;
3501   int type = sock->typeinfo->type;
3502
3503   uiLayout *col = uiLayoutColumn(layout, false);
3504
3505   switch (type) {
3506     case SOCK_FLOAT: {
3507       uiItemR(col, ptr, "default_value", DEFAULT_FLAGS, IFACE_("Default"), ICON_NONE);
3508       uiLayout *sub = uiLayoutColumn(col, true);
3509       uiItemR(sub, ptr, "min_value", DEFAULT_FLAGS, IFACE_("Min"), ICON_NONE);
3510       uiItemR(sub, ptr, "max_value", DEFAULT_FLAGS, IFACE_("Max"), ICON_NONE);
3511       break;
3512     }
3513     case SOCK_INT: {
3514       uiItemR(col, ptr, "default_value", DEFAULT_FLAGS, IFACE_("Default"), ICON_NONE);
3515       uiLayout *sub = uiLayoutColumn(col, true);
3516       uiItemR(sub, ptr, "min_value", DEFAULT_FLAGS, IFACE_("Min"), ICON_NONE);
3517       uiItemR(sub, ptr, "max_value", DEFAULT_FLAGS, IFACE_("Max"), ICON_NONE);
3518       break;
3519     }
3520     case SOCK_VECTOR: {
3521       uiItemR(col, ptr, "default_value", UI_ITEM_R_EXPAND, IFACE_("Default"), ICON_NONE);
3522       uiLayout *sub = uiLayoutColumn(col, true);
3523       uiItemR(sub, ptr, "min_value", DEFAULT_FLAGS, IFACE_("Min"), ICON_NONE);
3524       uiItemR(sub, ptr, "max_value", DEFAULT_FLAGS, IFACE_("Max"), ICON_NONE);
3525       break;
3526     }
3527     case SOCK_BOOLEAN:
3528     case SOCK_RGBA:
3529     case SOCK_STRING: {
3530       uiItemR(col, ptr, "default_value", DEFAULT_FLAGS, IFACE_("Default"), 0);
3531       break;
3532     }
3533   }
3534
3535   uiItemR(layout, ptr, "hide_value", DEFAULT_FLAGS, NULL, 0);
3536 }
3537
3538 void ED_init_standard_node_socket_type(bNodeSocketType *stype)
3539 {
3540   stype->draw = std_node_socket_draw;
3541   stype->draw_color = std_node_socket_draw_color;
3542   stype->interface_draw = std_node_socket_interface_draw;
3543   stype->interface_draw_color = std_node_socket_interface_draw_color;
3544 }
3545
3546 static void node_socket_virtual_draw_color(bContext *UNUSED(C),
3547                                            PointerRNA *UNUSED(ptr),
3548                                            PointerRNA *UNUSED(node_ptr),
3549                                            float *r_color)
3550 {
3551   copy_v4_v4(r_color, virtual_node_socket_color);
3552 }
3553
3554 void ED_init_node_socket_type_virtual(bNodeSocketType *stype)
3555 {
3556   stype->draw = node_socket_button_label;
3557   stype->draw_color = node_socket_virtual_draw_color;
3558 }
3559
3560 /* ************** Generic drawing ************** */
3561
3562 void draw_nodespace_back_pix(const bContext *C,
3563                              ARegion *region,
3564                              SpaceNode *snode,
3565                              bNodeInstanceKey parent_key)
3566 {
3567   Main *bmain = CTX_data_main(C);
3568   bNodeInstanceKey active_viewer_key = (snode->nodetree ? snode->nodetree->active_viewer_key :
3569                                                           NODE_INSTANCE_KEY_NONE);
3570   GPU_matrix_push_projection();
3571   GPU_matrix_push();
3572   wmOrtho2_region_pixelspace(region);
3573   GPU_matrix_identity_set();
3574   ED_region_draw_cb_draw(C, region, REGION_DRAW_BACKDROP);
3575   GPU_matrix_pop_projection();
3576   GPU_matrix_pop();
3577
3578   if (!(snode->flag & SNODE_BACKDRAW) || !ED_node_is_compositor(snode)) {
3579     return;
3580   }
3581
3582   if (parent_key.value != active_viewer_key.value) {
3583     return;
3584   }
3585
3586   GPU_matrix_push_projection();
3587   GPU_matrix_push();
3588
3589   /* The draw manager is used to draw the backdrop image. */
3590   GPUFrameBuffer *old_fb = GPU_framebuffer_active_get();
3591   GPU_framebuffer_restore();
3592   BLI_thread_lock(LOCK_DRAW_IMAGE);
3593   DRW_draw_view(C);
3594   BLI_thread_unlock(LOCK_DRAW_IMAGE);
3595   GPU_framebuffer_bind_no_srgb(old_fb);
3596   /* Draw manager changes the depth state. Set it back to NONE. Without this the node preview
3597    * images aren't drawn correctly. */
3598   GPU_depth_test(GPU_DEPTH_NONE);
3599
3600   void *lock;
3601   Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
3602   ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
3603   if (ibuf) {
3604     /* somehow the offset has to be calculated inverse */
3605     wmOrtho2_region_pixelspace(region);
3606     const float x = (region->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
3607     const float y = (region->winy - snode->zoom * ibuf->y) / 2 + snode->yof;
3608
3609     /** \note draw selected info on backdrop */
3610     if (snode->edittree) {
3611       bNode *node = snode->edittree->nodes.first;
3612       rctf *viewer_border = &snode->nodetree->viewer_border;
3613       while (node) {
3614         if (node->flag & NODE_SELECT) {
3615           if (node->typeinfo->draw_backdrop) {
3616             node->typeinfo->draw_backdrop(snode, ibuf, node, x, y);
3617           }
3618         }
3619         node = node->next;
3620       }
3621
3622       if ((snode->nodetree->flag & NTREE_VIEWER_BORDER) &&
3623           viewer_border->xmin < viewer_border->xmax && viewer_border->ymin < viewer_border->ymax) {
3624