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