use ICON_NULL define rather then 0, makes UI calls less confusing. (no functional...
[blender.git] / source / blender / editors / space_node / drawnode.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb, Thomas Dinges
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <math.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 #include "BLI_blenlib.h"
35 #include "BLI_math.h"
36
37 #include "DNA_node_types.h"
38 #include "DNA_material_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_space_types.h"
42 #include "DNA_screen_types.h"
43
44 #include "BKE_context.h"
45 #include "BKE_curve.h"
46 #include "BKE_image.h"
47 #include "BKE_library.h"
48 #include "BKE_main.h"
49
50 #include "CMP_node.h"
51 #include "SHD_node.h"
52
53 #include "BIF_gl.h"
54 #include "BIF_glutil.h"
55
56 #include "MEM_guardedalloc.h"
57
58
59 #include "RNA_access.h"
60
61 #include "ED_node.h"
62
63 #include "WM_api.h"
64 #include "WM_types.h"
65
66 #include "UI_interface.h"
67 #include "UI_resources.h"
68
69 #include "IMB_imbuf.h"
70 #include "IMB_imbuf_types.h"
71
72 #include "node_intern.h"
73
74
75 /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
76
77 void node_buts_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
78 {
79         uiTemplateIDBrowse(layout, C, ptr, "node_tree", NULL, NULL, "");
80 }
81
82 static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
83 {
84         PointerRNA sockptr;
85         PropertyRNA *prop;
86         
87         /* first socket stores value */
88         prop = RNA_struct_find_property(ptr, "outputs");
89         RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
90         
91         uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NULL);
92 }
93
94 static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
95 {
96         uiLayout *col;
97         PointerRNA sockptr;
98         PropertyRNA *prop;
99         
100         /* first socket stores value */
101         prop = RNA_struct_find_property(ptr, "outputs");
102         RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr);
103         
104         col = uiLayoutColumn(layout, 0);
105         uiTemplateColorWheel(col, &sockptr, "default_value", 1, 0, 0, 0);
106         uiItemR(col, &sockptr, "default_value", 0, "", ICON_NULL);
107 }
108
109 static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
110 {       
111         uiLayout *row;
112
113         bNodeTree *ntree= (bNodeTree*)ptr->id.data;
114
115         row= uiLayoutRow(layout, 1);
116         uiItemR(row, ptr, "blend_type", 0, "", ICON_NULL);
117         if(ntree->type == NTREE_COMPOSIT)
118                 uiItemR(row, ptr, "use_alpha", 0, "", ICON_IMAGE_RGB_ALPHA);
119 }
120
121 static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
122 {
123         uiLayout *row;
124 #if 0
125         /* XXX no context access here .. */
126         bNode *node= ptr->data;
127         CurveMapping *cumap= node->storage;
128         
129         if(cumap) {
130                 cumap->flag |= CUMA_DRAW_CFRA;
131                 if(node->custom1<node->custom2)
132                         cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
133         }
134 #endif
135
136         uiTemplateCurveMapping(layout, ptr, "curve", 's', 0, 0);
137
138         row= uiLayoutRow(layout, 1);
139         uiItemR(row, ptr, "frame_start", 0, "Sta", ICON_NULL);
140         uiItemR(row, ptr, "frame_end", 0, "End", ICON_NULL);
141 }
142
143 static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
144 {
145         uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
146 }
147
148 static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
149 {
150         uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0, 0);
151 }
152
153 static float *_sample_col= NULL;        // bad bad, 2.5 will do better?
154 void node_curvemap_sample(float *col)
155 {
156         _sample_col= col;
157 }
158
159 static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
160 {
161         bNode *node= ptr->data;
162         CurveMapping *cumap= node->storage;
163
164         if(_sample_col) {
165                 cumap->flag |= CUMA_DRAW_SAMPLE;
166                 VECCOPY(cumap->sample, _sample_col);
167         }
168         else 
169                 cumap->flag &= ~CUMA_DRAW_SAMPLE;
170
171         uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0, 0);
172 }
173
174 static void node_normal_cb(bContext *C, void *ntree_v, void *node_v)
175 {
176         Main *bmain = CTX_data_main(C);
177
178         ED_node_generic_update(bmain, ntree_v, node_v);
179         WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree_v);
180 }
181
182 static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
183 {
184         uiBlock *block= uiLayoutAbsoluteBlock(layout);
185         bNodeTree *ntree= ptr->id.data;
186         bNode *node= ptr->data;
187         rctf *butr= &node->butr;
188         bNodeSocket *sock= node->outputs.first;         /* first socket stores normal */
189         uiBut *bt;
190         
191         bt= uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", 
192                           (short)butr->xmin, (short)butr->xmin, butr->xmax-butr->xmin, butr->xmax-butr->xmin, 
193                           sock->ns.vec, 0.0f, 1.0f, 0, 0, "");
194         uiButSetFunc(bt, node_normal_cb, ntree, node);
195 }
196 #if 0 // not used in 2.5x yet
197 static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
198 {
199         Main *bmain= CTX_data_main(C);
200         bNodeTree *ntree= ntree_v;
201         bNode *node= node_v;
202         Tex *tex;
203         
204         if(node->menunr<1) return;
205         
206         if(node->id) {
207                 node->id->us--;
208                 node->id= NULL;
209         }
210         tex= BLI_findlink(&bmain->tex, node->menunr-1);
211
212         node->id= &tex->id;
213         id_us_plus(node->id);
214         BLI_strncpy(node->name, node->id->name+2, sizeof(node->name));
215         
216         nodeSetActive(ntree, node);
217         
218         if( ntree->type == NTREE_TEXTURE )
219                 ntreeTexCheckCyclics( ntree );
220         
221         // allqueue(REDRAWBUTSSHADING, 0);
222         // allqueue(REDRAWNODE, 0);
223         NodeTagChanged(ntree, node); 
224         
225         node->menunr= 0;
226 }
227 #endif
228 static void node_dynamic_update_cb(bContext *C, void *UNUSED(ntree_v), void *node_v)
229 {
230         Main *bmain= CTX_data_main(C);
231         Material *ma;
232         bNode *node= (bNode *)node_v;
233         ID *id= node->id;
234         int error= 0;
235
236         if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) error= 1;
237
238         /* Users only have to press the "update" button in one pynode
239          * and we also update all others sharing the same script */
240         for (ma= bmain->mat.first; ma; ma= ma->id.next) {
241                 if (ma->nodetree) {
242                         bNode *nd;
243                         for (nd= ma->nodetree->nodes.first; nd; nd= nd->next) {
244                                 if ((nd->type == NODE_DYNAMIC) && (nd->id == id)) {
245                                         nd->custom1= 0;
246                                         nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_REPARSE);
247                                         nd->menunr= 0;
248                                         if (error)
249                                                 nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_ERROR);
250                                 }
251                         }
252                 }
253         }
254
255         // allqueue(REDRAWBUTSSHADING, 0);
256         // allqueue(REDRAWNODE, 0);
257         // XXX BIF_preview_changed(ID_MA);
258 }
259
260 static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
261 {
262         bNode *node= ptr->data;
263
264         short multi = (
265                 node->id &&
266                 ((Tex*)node->id)->use_nodes &&
267                 (node->type != CMP_NODE_TEXTURE) &&
268                 (node->type != TEX_NODE_TEXTURE)
269         );
270         
271         uiItemR(layout, ptr, "texture", 0, "", ICON_NULL);
272         
273         if(multi) {
274                 /* Number Drawing not optimal here, better have a list*/
275                 uiItemR(layout, ptr, "node_output", 0, "", ICON_NULL);
276         }
277 }
278
279 static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
280
281         uiItemR(layout, ptr, "operation", 0, "", ICON_NULL);
282 }
283
284 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
285
286 static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v)
287 {
288         Main *bmain= CTX_data_main(C);
289         bNodeTree *ntree= ntree_v;
290         bNode *node= node_v;
291         ID *oldid;
292         
293         if(node->menunr<1) return;
294         
295         if(node->id) {
296                 node->id->us--;
297         }
298         oldid= node->id;
299         node->id= BLI_findlink(&bmain->text, node->menunr-1);
300         id_us_plus(node->id);
301         BLI_strncpy(node->name, node->id->name+2, sizeof(node->name));
302
303         node->custom1= BSET(node->custom1, NODE_DYNAMIC_NEW);
304         
305         nodeSetActive(ntree, node);
306
307         // allqueue(REDRAWBUTSSHADING, 0);
308         // allqueue(REDRAWNODE, 0);
309
310         node->menunr= 0;
311 }
312
313 static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr)
314 {
315         bNode *node= ptr->data;
316         uiLayout *col;
317         
318         uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL);
319         
320         if(!node->id) return;
321         
322         col= uiLayoutColumn(layout, 0);
323         uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NULL);
324         uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NULL);
325         uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NULL);
326 }
327
328 static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
329 {
330         uiLayout *row;
331         
332         uiItemL(layout, "Location:", ICON_NULL);
333         row= uiLayoutRow(layout, 1);
334         uiItemR(row, ptr, "location", 0, "", ICON_NULL);
335         
336         uiItemL(layout, "Rotation:", ICON_NULL);
337         row= uiLayoutRow(layout, 1);
338         uiItemR(row, ptr, "rotation", 0, "", ICON_NULL);
339         
340         uiItemL(layout, "Scale:", ICON_NULL);
341         row= uiLayoutRow(layout, 1);
342         uiItemR(row, ptr, "scale", 0, "", ICON_NULL);
343         
344         row= uiLayoutRow(layout, 1);
345         uiItemR(row, ptr, "use_min", 0, "Min", ICON_NULL);
346         uiItemR(row, ptr, "min", 0, "", ICON_NULL);
347         
348         row= uiLayoutRow(layout, 1);
349         uiItemR(row, ptr, "use_max", 0, "Max", ICON_NULL);
350         uiItemR(row, ptr, "max", 0, "", ICON_NULL);
351         
352 }
353
354 static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
355
356         uiItemR(layout, ptr, "operation", 0, "", ICON_NULL);
357 }
358
359 static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr)
360 {
361         PointerRNA obptr= CTX_data_pointer_get(C, "active_object");
362         uiLayout *col;
363
364         col= uiLayoutColumn(layout, 0);
365
366         if(obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
367                 PointerRNA dataptr= RNA_pointer_get(&obptr, "data");
368
369                 uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_textures", "", ICON_NULL);
370                 uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NULL);
371         }
372         else {
373                 uiItemR(col, ptr, "uv_layer", 0, "UV", ICON_NULL);
374                 uiItemR(col, ptr, "color_layer", 0, "VCol", ICON_NULL);
375         }
376 }
377
378 static void node_shader_buts_dynamic(uiLayout *layout, bContext *C, PointerRNA *ptr)
379
380         Main *bmain= CTX_data_main(C);
381         uiBlock *block= uiLayoutAbsoluteBlock(layout);
382         bNode *node= ptr->data;
383         bNodeTree *ntree= ptr->id.data;
384         rctf *butr= &node->butr;
385         uiBut *bt;
386         // XXX SpaceNode *snode= curarea->spacedata.first;
387         short dy= (short)butr->ymin;
388         int xoff=0;
389
390         /* B_NODE_EXEC is handled in butspace.c do_node_buts */
391         if(!node->id) {
392                         const char *strp;
393                         IDnames_to_pupstring(&strp, NULL, "", &(bmain->text), NULL, NULL);
394                         node->menunr= 0;
395                         bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp, 
396                                                         butr->xmin, dy, 19, 19, 
397                                                         &node->menunr, 0, 0, 0, 0, "Browses existing choices");
398                         uiButSetFunc(bt, node_browse_text_cb, ntree, node);
399                         xoff=19;
400                         if(strp) MEM_freeN((void *)strp);
401         }
402         else {
403                 bt = uiDefBut(block, BUT, B_NOP, "Update",
404                                 butr->xmin+xoff, butr->ymin+20, 50, 19,
405                                 &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)");
406                 uiButSetFunc(bt, node_dynamic_update_cb, ntree, node);
407
408                 if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
409                         // UI_ThemeColor(TH_REDALERT);
410                         // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect);
411                         // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin);
412                         ;
413                 }
414         }
415 }
416
417 /* only once called */
418 static void node_shader_set_butfunc(bNodeType *ntype)
419 {
420         switch(ntype->type) {
421                 /* case NODE_GROUP:      note, typeinfo for group is generated... see "XXX ugly hack" */
422
423                 case SH_NODE_MATERIAL:
424                 case SH_NODE_MATERIAL_EXT:
425                         ntype->uifunc= node_shader_buts_material;
426                         break;
427                 case SH_NODE_TEXTURE:
428                         ntype->uifunc= node_buts_texture;
429                         break;
430                 case SH_NODE_NORMAL:
431                         ntype->uifunc= node_buts_normal;
432                         break;
433                 case SH_NODE_CURVE_VEC:
434                         ntype->uifunc= node_buts_curvevec;
435                         break;
436                 case SH_NODE_CURVE_RGB:
437                         ntype->uifunc= node_buts_curvecol;
438                         break;
439                 case SH_NODE_MAPPING:
440                         ntype->uifunc= node_shader_buts_mapping;
441                         break;
442                 case SH_NODE_VALUE:
443                         ntype->uifunc= node_buts_value;
444                         break;
445                 case SH_NODE_RGB:
446                         ntype->uifunc= node_buts_rgb;
447                         break;
448                 case SH_NODE_MIX_RGB:
449                         ntype->uifunc= node_buts_mix_rgb;
450                         break;
451                 case SH_NODE_VALTORGB:
452                         ntype->uifunc= node_buts_colorramp;
453                         break;
454                 case SH_NODE_MATH: 
455                         ntype->uifunc= node_buts_math;
456                         break; 
457                 case SH_NODE_VECT_MATH: 
458                         ntype->uifunc= node_shader_buts_vect_math;
459                         break; 
460                 case SH_NODE_GEOMETRY:
461                         ntype->uifunc= node_shader_buts_geometry;
462                         break;
463                 case NODE_DYNAMIC:
464                         ntype->uifunc= node_shader_buts_dynamic;
465                         break;
466                 default:
467                         ntype->uifunc= NULL;
468         }
469 }
470
471 /* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
472
473 static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
474 {
475         uiLayout *col;
476         bNode *node= ptr->data;
477         PointerRNA imaptr;
478         PropertyRNA *prop;
479         
480         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
481         
482         if(!node->id) return;
483         
484         prop = RNA_struct_find_property(ptr, "image");
485         if (!prop || RNA_property_type(prop) != PROP_POINTER) return;
486         imaptr= RNA_property_pointer_get(ptr, prop);
487         
488         col= uiLayoutColumn(layout, 0);
489         
490         uiItemR(col, &imaptr, "source", 0, NULL, ICON_NULL);
491         
492         if (ELEM(RNA_enum_get(&imaptr, "source"), IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
493                 col= uiLayoutColumn(layout, 1);
494                 uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NULL);
495                 uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NULL);
496                 uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NULL);
497                 uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NULL);
498                 uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NULL);
499         }
500
501         col= uiLayoutColumn(layout, 0);
502         
503         if (RNA_enum_get(&imaptr, "type")== IMA_TYPE_MULTILAYER)
504                 uiItemR(col, ptr, "layer", 0, NULL, ICON_NULL);
505 }
506
507 static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr)
508 {
509         bNode *node= ptr->data;
510         uiLayout *col, *row;
511         PointerRNA op_ptr;
512         PointerRNA scn_ptr;
513         PropertyRNA *prop;
514         const char *layer_name;
515         char scene_name[19];
516         
517         uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
518         
519         if(!node->id) return;
520
521         col= uiLayoutColumn(layout, 0);
522         row = uiLayoutRow(col, 0);
523         uiItemR(row, ptr, "layer", 0, "", ICON_NULL);
524         
525         prop = RNA_struct_find_property(ptr, "layer");
526         if (!(RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name)))
527                 return;
528         
529         scn_ptr = RNA_pointer_get(ptr, "scene");
530         RNA_string_get(&scn_ptr, "name", scene_name);
531         
532         WM_operator_properties_create(&op_ptr, "RENDER_OT_render");
533         RNA_string_set(&op_ptr, "layer", layer_name);
534         RNA_string_set(&op_ptr, "scene", scene_name);
535         uiItemFullO(row, "RENDER_OT_render", "", ICON_RENDER_STILL, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
536
537 }
538
539
540 static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
541 {
542         uiLayout *col;
543         
544         col= uiLayoutColumn(layout, 0);
545         
546         uiItemR(col, ptr, "filter_type", 0, "", ICON_NULL);
547         if (RNA_enum_get(ptr, "filter_type")!= R_FILTER_FAST_GAUSS) {
548                 uiItemR(col, ptr, "use_bokeh", 0, NULL, ICON_NULL);
549                 uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NULL);
550         }
551         
552         uiItemR(col, ptr, "use_relative", 0, NULL, ICON_NULL);
553         col= uiLayoutColumn(layout, 1);
554         if (RNA_boolean_get(ptr, "use_relative")) {
555                 uiItemR(col, ptr, "factor_x", 0, "X", ICON_NULL);
556                 uiItemR(col, ptr, "factor_y", 0, "Y", ICON_NULL);
557         }
558         else {
559                 uiItemR(col, ptr, "size_x", 0, "X", ICON_NULL);
560                 uiItemR(col, ptr, "size_y", 0, "Y", ICON_NULL);
561         }
562 }
563
564 static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
565 {
566         uiLayout *col;
567         
568         uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NULL);
569         uiItemR(layout, ptr, "use_wrap", 0, NULL, ICON_NULL);
570         
571         col= uiLayoutColumn(layout, 1);
572         uiItemL(col, "Center:", ICON_NULL);
573         uiItemR(col, ptr, "center_x", 0, "X", ICON_NULL);
574         uiItemR(col, ptr, "center_y", 0, "Y", ICON_NULL);
575         
576         uiItemS(layout);
577         
578         col= uiLayoutColumn(layout, 1);
579         uiItemR(col, ptr, "distance", 0, NULL, ICON_NULL);
580         uiItemR(col, ptr, "angle", 0, NULL, ICON_NULL);
581         
582         uiItemS(layout);
583         
584         uiItemR(layout, ptr, "spin", 0, NULL, ICON_NULL);
585         uiItemR(layout, ptr, "zoom", 0, NULL, ICON_NULL);
586 }
587
588 static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
589 {       
590         uiLayout *col;
591         
592         col= uiLayoutColumn(layout, 1);
593         uiItemR(col, ptr, "iterations", 0, NULL, ICON_NULL);
594         uiItemR(col, ptr, "sigma_color", 0, NULL, ICON_NULL);
595         uiItemR(col, ptr, "sigma_space", 0, NULL, ICON_NULL);
596 }
597
598 static void node_composit_buts_defocus(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
599 {
600         uiLayout *sub, *col;
601         
602         col= uiLayoutColumn(layout, 0);
603         uiItemL(col, "Bokeh Type:", ICON_NULL);
604         uiItemR(col, ptr, "bokeh", 0, "", ICON_NULL);
605         uiItemR(col, ptr, "angle", 0, NULL, ICON_NULL);
606
607         uiItemR(layout, ptr, "use_gamma_correction", 0, NULL, ICON_NULL);
608
609         col = uiLayoutColumn(layout, 0);
610         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer")==1);
611         uiItemR(col, ptr, "f_stop", 0, NULL, ICON_NULL);
612
613         uiItemR(layout, ptr, "blur_max", 0, NULL, ICON_NULL);
614         uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NULL);
615
616         col = uiLayoutColumn(layout, 0);
617         uiItemR(col, ptr, "use_preview", 0, NULL, ICON_NULL);
618         sub = uiLayoutColumn(col, 0);
619         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_preview"));
620         uiItemR(sub, ptr, "samples", 0, NULL, ICON_NULL);
621         
622         col = uiLayoutColumn(layout, 0);
623         uiItemR(col, ptr, "use_zbuffer", 0, NULL, ICON_NULL);
624         sub = uiLayoutColumn(col, 0);
625         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer")==0);
626         uiItemR(sub, ptr, "z_scale", 0, NULL, ICON_NULL);
627 }
628
629 /* qdn: glare node */
630 static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
631 {       
632         uiItemR(layout, ptr, "glare_type", 0, "", ICON_NULL);
633         uiItemR(layout, ptr, "quality", 0, "", ICON_NULL);
634
635         if (RNA_enum_get(ptr, "glare_type")!= 1) {
636                 uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NULL);
637         
638                 if (RNA_enum_get(ptr, "glare_type")!= 0) 
639                         uiItemR(layout, ptr, "color_modulation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
640         }
641         
642         uiItemR(layout, ptr, "mix", 0, NULL, ICON_NULL);
643         uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NULL);
644
645         if (RNA_enum_get(ptr, "glare_type")== 2) {
646                 uiItemR(layout, ptr, "streaks", 0, NULL, ICON_NULL);
647                 uiItemR(layout, ptr, "angle_offset", 0, NULL, ICON_NULL);
648         }
649         if (RNA_enum_get(ptr, "glare_type")== 0 || RNA_enum_get(ptr, "glare_type")== 2) {
650                 uiItemR(layout, ptr, "fade", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
651                 
652                 if (RNA_enum_get(ptr, "glare_type")== 0) 
653                         uiItemR(layout, ptr, "use_rotate_45", 0, NULL, ICON_NULL);
654         }
655         if (RNA_enum_get(ptr, "glare_type")== 1) {
656                 uiItemR(layout, ptr, "size", 0, NULL, ICON_NULL);
657         }
658 }
659
660 static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
661 {       
662         uiLayout *col;
663
664         col = uiLayoutColumn(layout, 0);
665         uiItemR(col, ptr, "tonemap_type", 0, "", ICON_NULL);
666         if (RNA_enum_get(ptr, "tonemap_type")== 0) {
667                 uiItemR(col, ptr, "key", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
668                 uiItemR(col, ptr, "offset", 0, NULL, ICON_NULL);
669                 uiItemR(col, ptr, "gamma", 0, NULL, ICON_NULL);
670         }
671         else {
672                 uiItemR(col, ptr, "intensity", 0, NULL, ICON_NULL);
673                 uiItemR(col, ptr, "contrast", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
674                 uiItemR(col, ptr, "adaptation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
675                 uiItemR(col, ptr, "correction", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
676         }
677 }
678
679 static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
680 {
681         uiLayout *col;
682
683         col= uiLayoutColumn(layout, 0);
684         uiItemR(col, ptr, "use_projector", 0, NULL, ICON_NULL);
685
686         col = uiLayoutColumn(col, 0);
687         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_projector")==0);
688         uiItemR(col, ptr, "use_jitter", 0, NULL, ICON_NULL);
689         uiItemR(col, ptr, "use_fit", 0, NULL, ICON_NULL);
690 }
691
692 static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
693 {
694         uiLayout *col;
695         
696         col= uiLayoutColumn(layout, 0);
697         uiItemR(col, ptr, "samples", 0, NULL, ICON_NULL);
698         uiItemR(col, ptr, "factor", 0, "Blur", ICON_NULL);
699         
700         col= uiLayoutColumn(layout, 1);
701         uiItemL(col, "Speed:", ICON_NULL);
702         uiItemR(col, ptr, "speed_min", 0, "Min", ICON_NULL);
703         uiItemR(col, ptr, "speed_max", 0, "Max", ICON_NULL);
704
705         uiItemR(layout, ptr, "use_curved", 0, NULL, ICON_NULL);
706 }
707
708 static void node_composit_buts_filter(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
709 {
710         uiItemR(layout, ptr, "filter_type", 0, "", ICON_NULL);
711 }
712
713 static void node_composit_buts_flip(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
714 {
715         uiItemR(layout, ptr, "axis", 0, "", ICON_NULL);
716 }
717
718 static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
719 {
720         uiLayout *col;
721         
722         uiItemR(layout, ptr, "use_crop_size", 0, NULL, ICON_NULL);
723    uiItemR(layout, ptr, "relative", 0, NULL, ICON_NULL);
724
725         col= uiLayoutColumn(layout, 1);
726    if (RNA_boolean_get(ptr, "relative")){
727       uiItemR(col, ptr, "rel_min_x", 0, "Left", ICON_NULL);
728       uiItemR(col, ptr, "rel_max_x", 0, "Right", ICON_NULL);
729       uiItemR(col, ptr, "rel_min_y", 0, "Up", ICON_NULL);
730       uiItemR(col, ptr, "rel_max_y", 0, "Down", ICON_NULL);
731    } else {
732       uiItemR(col, ptr, "min_x", 0, "Left", ICON_NULL);
733       uiItemR(col, ptr, "max_x", 0, "Right", ICON_NULL);
734       uiItemR(col, ptr, "min_y", 0, "Up", ICON_NULL);
735       uiItemR(col, ptr, "max_y", 0, "Down", ICON_NULL);
736    }
737 }
738
739 static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
740 {
741         uiLayout *row, *col;
742         
743         col= uiLayoutColumn(layout, 0);
744         row= uiLayoutRow(col, 0);
745         uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
746         uiItemR(col, ptr, "factor", 0, NULL, ICON_NULL);
747 }
748
749 static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
750 {
751         uiLayout *sub, *col;
752         
753         col =uiLayoutColumn(layout, 1);
754         uiItemR(col, ptr, "offset", 0, NULL, ICON_NULL);
755         uiItemR(col, ptr, "size", 0, NULL, ICON_NULL);
756         
757         col =uiLayoutColumn(layout, 1);
758         uiItemR(col, ptr, "use_min", 0, NULL, ICON_NULL);
759         sub =uiLayoutColumn(col, 0);
760         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
761         uiItemR(sub, ptr, "min", 0, "", ICON_NULL);
762         
763         col =uiLayoutColumn(layout, 1);
764         uiItemR(col, ptr, "use_max", 0, NULL, ICON_NULL);
765         sub =uiLayoutColumn(col, 0);
766         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
767         uiItemR(sub, ptr, "max", 0, "", ICON_NULL);
768 }
769
770 static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
771 {       
772         uiLayout *col;
773         
774         col =uiLayoutColumn(layout, 1);
775         uiItemR(col, ptr, "use_premultiply", 0, NULL, ICON_NULL);
776         uiItemR(col, ptr, "premul", 0, NULL, ICON_NULL);
777 }
778
779 static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
780 {       
781         uiLayout *col;
782         
783         col =uiLayoutColumn(layout, 1);
784         uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NULL);
785 }
786
787
788 static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
789 {
790         uiLayout *col;
791         
792         col =uiLayoutColumn(layout, 0);
793         uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
794         uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
795         uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
796 }
797
798 static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
799 {
800         uiItemR(layout, ptr, "distance", 0, NULL, ICON_NULL);
801 }
802
803 static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
804 {
805         uiLayout *col;
806         
807         col =uiLayoutColumn(layout, 1);
808         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
809         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
810 }
811
812 static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
813 {
814         uiLayout *col;
815         
816         col =uiLayoutColumn(layout, 1);
817         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
818         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
819 }
820
821 static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
822 {
823         uiLayout *row, *col;
824         
825    uiItemL(layout, "Despill Channel:", ICON_NULL);
826    row =uiLayoutRow(layout,0);
827         uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
828
829    col= uiLayoutColumn(layout, 0);
830    uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NULL);
831
832    if(RNA_enum_get(ptr, "limit_method")==0) {
833           uiItemL(col, "Limiting Channel:", ICON_NULL);
834           row=uiLayoutRow(col,0);
835           uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
836    }
837
838    uiItemR(col, ptr, "ratio", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
839    uiItemR(col, ptr, "use_unspill", 0, NULL, ICON_NULL);
840    if (RNA_enum_get(ptr, "use_unspill")== 1) {
841           uiItemR(col, ptr, "unspill_red", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
842           uiItemR(col, ptr, "unspill_green", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
843           uiItemR(col, ptr, "unspill_blue", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
844    }
845 }
846
847 static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
848 {
849         uiLayout *col;
850         
851         col= uiLayoutColumn(layout, 0);
852         uiItemR(col, ptr, "tolerance", 0, NULL, ICON_NULL);
853         uiItemR(col, ptr, "threshold", 0, NULL, ICON_NULL);
854         
855         col= uiLayoutColumn(layout, 1);
856    /*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NULL);  Removed for now */
857         uiItemR(col, ptr, "gain", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
858    /*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, ICON_NULL);  Removed for now*/
859 }
860
861 static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
862 {
863         uiLayout *col;
864         
865         col= uiLayoutColumn(layout, 1);
866         uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
867         uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
868         uiItemR(col, ptr, "color_value", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
869 }
870
871 static void node_composit_buts_channel_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
872 {       
873         uiLayout *col, *row;
874
875    uiItemL(layout, "Color Space:", ICON_NULL);
876         row= uiLayoutRow(layout, 0);
877         uiItemR(row, ptr, "color_space", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
878
879    col=uiLayoutColumn(layout, 0);  
880    uiItemL(col, "Key Channel:", ICON_NULL);
881         row= uiLayoutRow(col, 0);
882         uiItemR(row, ptr, "matte_channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
883
884         col =uiLayoutColumn(layout, 0);
885
886    uiItemR(col, ptr, "limit_method", 0, NULL, ICON_NULL);
887    if(RNA_enum_get(ptr, "limit_method")==0) {
888           uiItemL(col, "Limiting Channel:", ICON_NULL);
889           row=uiLayoutRow(col,0);
890           uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
891    }
892    
893         uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
894         uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
895 }
896
897 static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
898 {
899         uiLayout *col;
900         
901         col= uiLayoutColumn(layout, 1);
902         uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
903         uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NULL);
904 }
905
906 static void node_composit_buts_map_uv(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
907 {
908         uiItemR(layout, ptr, "alpha", 0, NULL, ICON_NULL);
909 }
910
911 static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
912 {
913         uiItemR(layout, ptr, "index", 0, NULL, ICON_NULL);
914 }
915
916 static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
917 {
918         uiLayout *col, *row;
919
920         col= uiLayoutColumn(layout, 0);
921         uiItemR(col, ptr, "filepath", 0, "", ICON_NULL);
922         uiItemR(col, ptr, "image_type", 0, "", ICON_NULL);
923         
924         row= uiLayoutRow(layout, 0);
925         if (RNA_enum_get(ptr, "image_type")== R_OPENEXR) {
926                 uiItemR(row, ptr, "use_exr_half", 0, NULL, ICON_NULL);
927                 uiItemR(row, ptr, "exr_codec", 0, "", ICON_NULL);
928         }
929         else if (RNA_enum_get(ptr, "image_type")== R_JPEG90) {
930                 uiItemR(row, ptr, "quality", UI_ITEM_R_SLIDER, "Quality", ICON_NULL);
931         }
932         else if (RNA_enum_get(ptr, "image_type")== R_PNG) {
933                 uiItemR(row, ptr, "quality", UI_ITEM_R_SLIDER, "Compression", ICON_NULL);
934         }
935         
936         row= uiLayoutRow(layout, 1);
937         uiItemR(row, ptr, "frame_start", 0, "Start", ICON_NULL);
938         uiItemR(row, ptr, "frame_end", 0, "End", ICON_NULL);
939 }
940
941 static void node_composit_buts_scale(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
942 {
943         uiItemR(layout, ptr, "space", 0, "", ICON_NULL);
944 }
945
946 static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
947 {
948    uiItemR(layout, ptr, "filter_type", 0, "", ICON_NULL);
949 }
950
951 static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
952 {
953         uiLayout *col;
954         
955         col= uiLayoutColumn(layout, 0);
956         uiItemR(col, ptr, "invert_rgb", 0, NULL, ICON_NULL);
957         uiItemR(col, ptr, "invert_alpha", 0, NULL, ICON_NULL);
958 }
959
960 static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
961 {
962         uiItemR(layout, ptr, "mapping", 0, "", ICON_NULL);
963 }
964
965 static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
966 {
967         uiItemR(layout, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
968 }
969
970 static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
971 {
972         uiLayout *split, *col, *row;
973         
974         uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NULL);
975         
976         if (RNA_enum_get(ptr, "correction_method")== 0) {
977         
978                 split = uiLayoutSplit(layout, 0, 0);
979                 col = uiLayoutColumn(split, 0);
980                 uiTemplateColorWheel(col, ptr, "lift", 1, 1, 0, 1);
981                 row = uiLayoutRow(col, 0);
982                 uiItemR(row, ptr, "lift", 0, NULL, ICON_NULL);
983                 
984                 col = uiLayoutColumn(split, 0);
985                 uiTemplateColorWheel(col, ptr, "gamma", 1, 1, 1, 1);
986                 row = uiLayoutRow(col, 0);
987                 uiItemR(row, ptr, "gamma", 0, NULL, ICON_NULL);
988                 
989                 col = uiLayoutColumn(split, 0);
990                 uiTemplateColorWheel(col, ptr, "gain", 1, 1, 1, 1);
991                 row = uiLayoutRow(col, 0);
992                 uiItemR(row, ptr, "gain", 0, NULL, ICON_NULL);
993
994         } else {
995                 
996                 split = uiLayoutSplit(layout, 0, 0);
997                 col = uiLayoutColumn(split, 0);
998                 uiTemplateColorWheel(col, ptr, "offset", 1, 1, 0, 1);
999                 row = uiLayoutRow(col, 0);
1000                 uiItemR(row, ptr, "offset", 0, NULL, ICON_NULL);
1001                 
1002                 col = uiLayoutColumn(split, 0);
1003                 uiTemplateColorWheel(col, ptr, "power", 1, 1, 0, 1);
1004                 row = uiLayoutRow(col, 0);
1005                 uiItemR(row, ptr, "power", 0, NULL, ICON_NULL);
1006                 
1007                 col = uiLayoutColumn(split, 0);
1008                 uiTemplateColorWheel(col, ptr, "slope", 1, 1, 0, 1);
1009                 row = uiLayoutRow(col, 0);
1010                 uiItemR(row, ptr, "slope", 0, NULL, ICON_NULL);
1011         }
1012
1013 }
1014
1015 static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1016 {
1017         uiTemplateCurveMapping(layout, ptr, "mapping", 'h', 0, 0);
1018 }
1019
1020 static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1021
1022         uiItemR(layout, ptr, "mode", 0, "", ICON_NULL);
1023 }
1024
1025 /* only once called */
1026 static void node_composit_set_butfunc(bNodeType *ntype)
1027 {
1028         switch(ntype->type) {
1029                 /* case NODE_GROUP:      note, typeinfo for group is generated... see "XXX ugly hack" */
1030
1031                 case CMP_NODE_IMAGE:
1032                         ntype->uifunc= node_composit_buts_image;
1033                         break;
1034                 case CMP_NODE_R_LAYERS:
1035                         ntype->uifunc= node_composit_buts_renderlayers;
1036                         break;
1037                 case CMP_NODE_NORMAL:
1038                         ntype->uifunc= node_buts_normal;
1039                         break;
1040                 case CMP_NODE_CURVE_VEC:
1041                         ntype->uifunc= node_buts_curvevec;
1042                         break;
1043                 case CMP_NODE_CURVE_RGB:
1044                         ntype->uifunc= node_buts_curvecol;
1045                         break;
1046                 case CMP_NODE_VALUE:
1047                         ntype->uifunc= node_buts_value;
1048                         break;
1049                 case CMP_NODE_RGB:
1050                         ntype->uifunc= node_buts_rgb;
1051                         break;
1052                 case CMP_NODE_FLIP:
1053                         ntype->uifunc= node_composit_buts_flip;
1054                         break;
1055                 case CMP_NODE_SPLITVIEWER:
1056                         ntype->uifunc= node_composit_buts_splitviewer;
1057                         break;
1058                 case CMP_NODE_MIX_RGB:
1059                         ntype->uifunc= node_buts_mix_rgb;
1060                         break;
1061                 case CMP_NODE_VALTORGB:
1062                         ntype->uifunc= node_buts_colorramp;
1063                         break;
1064                 case CMP_NODE_CROP:
1065                         ntype->uifunc= node_composit_buts_crop;
1066                         break;
1067                 case CMP_NODE_BLUR:
1068                         ntype->uifunc= node_composit_buts_blur;
1069                         break;
1070                 case CMP_NODE_DBLUR:
1071                         ntype->uifunc= node_composit_buts_dblur;
1072                         break;
1073                 case CMP_NODE_BILATERALBLUR:
1074                         ntype->uifunc= node_composit_buts_bilateralblur;
1075                         break;
1076                 case CMP_NODE_DEFOCUS:
1077                         ntype->uifunc = node_composit_buts_defocus;
1078                         break;
1079                 case CMP_NODE_GLARE:
1080                         ntype->uifunc = node_composit_buts_glare;
1081                         break;
1082                 case CMP_NODE_TONEMAP:
1083                         ntype->uifunc = node_composit_buts_tonemap;
1084                         break;
1085                 case CMP_NODE_LENSDIST:
1086                         ntype->uifunc = node_composit_buts_lensdist;
1087                         break;
1088                 case CMP_NODE_VECBLUR:
1089                         ntype->uifunc= node_composit_buts_vecblur;
1090                         break;
1091                 case CMP_NODE_FILTER:
1092                         ntype->uifunc= node_composit_buts_filter;
1093                         break;
1094                 case CMP_NODE_MAP_VALUE:
1095                         ntype->uifunc= node_composit_buts_map_value;
1096                         break;
1097                 case CMP_NODE_TIME:
1098                         ntype->uifunc= node_buts_time;
1099                         break;
1100                 case CMP_NODE_ALPHAOVER:
1101                         ntype->uifunc= node_composit_buts_alphaover;
1102                         break;
1103                 case CMP_NODE_HUE_SAT:
1104                         ntype->uifunc= node_composit_buts_hue_sat;
1105                         break;
1106                 case CMP_NODE_TEXTURE:
1107                         ntype->uifunc= node_buts_texture;
1108                         break;
1109                 case CMP_NODE_DILATEERODE:
1110                         ntype->uifunc= node_composit_buts_dilateerode;
1111                         break;
1112                 case CMP_NODE_OUTPUT_FILE:
1113                         ntype->uifunc= node_composit_buts_file_output;
1114                         break;  
1115                 case CMP_NODE_DIFF_MATTE:
1116                         ntype->uifunc=node_composit_buts_diff_matte;
1117                         break;
1118                 case CMP_NODE_DIST_MATTE:
1119                         ntype->uifunc=node_composit_buts_distance_matte;
1120                         break;
1121                 case CMP_NODE_COLOR_SPILL:
1122                         ntype->uifunc=node_composit_buts_color_spill;
1123                         break;
1124                 case CMP_NODE_CHROMA_MATTE:
1125                         ntype->uifunc=node_composit_buts_chroma_matte;
1126                         break;
1127                 case CMP_NODE_COLOR_MATTE:
1128                         ntype->uifunc=node_composit_buts_color_matte;
1129                         break;
1130                 case CMP_NODE_SCALE:
1131                         ntype->uifunc= node_composit_buts_scale;
1132                         break;
1133           case CMP_NODE_ROTATE:
1134                  ntype->uifunc=node_composit_buts_rotate;
1135                  break;
1136                 case CMP_NODE_CHANNEL_MATTE:
1137                         ntype->uifunc= node_composit_buts_channel_matte;
1138                         break;
1139                 case CMP_NODE_LUMA_MATTE:
1140                         ntype->uifunc= node_composit_buts_luma_matte;
1141                         break;
1142                 case CMP_NODE_MAP_UV:
1143                         ntype->uifunc= node_composit_buts_map_uv;
1144                         break;
1145                 case CMP_NODE_ID_MASK:
1146                         ntype->uifunc= node_composit_buts_id_mask;
1147                         break;
1148                 case CMP_NODE_MATH:
1149                         ntype->uifunc= node_buts_math;
1150                         break;
1151                 case CMP_NODE_INVERT:
1152                         ntype->uifunc= node_composit_buts_invert;
1153                         break;
1154                 case CMP_NODE_PREMULKEY:
1155                         ntype->uifunc= node_composit_buts_premulkey;
1156                         break;
1157                 case CMP_NODE_VIEW_LEVELS:
1158                         ntype->uifunc=node_composit_buts_view_levels;
1159                          break;
1160                 case CMP_NODE_COLORBALANCE:
1161                         ntype->uifunc=node_composit_buts_colorbalance;
1162                          break;
1163                 case CMP_NODE_HUECORRECT:
1164                         ntype->uifunc=node_composit_buts_huecorrect;
1165                          break;
1166                 case CMP_NODE_ZCOMBINE:
1167                         ntype->uifunc=node_composit_buts_zcombine;
1168                          break;
1169                 case CMP_NODE_COMBYCCA:
1170                 case CMP_NODE_SEPYCCA:
1171                         ntype->uifunc=node_composit_buts_ycc;
1172                         break;
1173                 default:
1174                         ntype->uifunc= NULL;
1175         }
1176 }
1177
1178 /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
1179
1180 static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1181 {
1182         uiLayout *col;
1183         
1184         col= uiLayoutColumn(layout, 1);
1185         uiItemR(col, ptr, "offset", 0, "Offset", ICON_NULL);
1186         uiItemR(col, ptr, "offset_frequency", 0, "Frequency", ICON_NULL);
1187         
1188         col= uiLayoutColumn(layout, 1);
1189         uiItemR(col, ptr, "squash", 0, "Squash", ICON_NULL);
1190         uiItemR(col, ptr, "squash_frequency", 0, "Frequency", ICON_NULL);
1191 }
1192
1193 static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1194 {
1195         PointerRNA tex_ptr;
1196         bNode *node= ptr->data;
1197         ID *id= ptr->id.data;
1198         Tex *tex = (Tex *)node->storage;
1199         uiLayout *col, *row;
1200         
1201         RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr);
1202
1203         col= uiLayoutColumn(layout, 0);
1204
1205         switch( tex->type ) {
1206                 case TEX_BLEND:
1207                         uiItemR(col, &tex_ptr, "progression", 0, "", ICON_NULL);
1208                         row= uiLayoutRow(col, 0);
1209                         uiItemR(row, &tex_ptr, "use_flip_axis", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1210                         break;
1211
1212                 case TEX_MARBLE:
1213                         row= uiLayoutRow(col, 0);
1214                         uiItemR(row, &tex_ptr, "marble_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1215                         row= uiLayoutRow(col, 0);
1216                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1217                         row= uiLayoutRow(col, 0);
1218                         uiItemR(row, &tex_ptr, "noisebasis_2", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1219                         break;
1220
1221                 case TEX_WOOD:
1222                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NULL);
1223                         uiItemR(col, &tex_ptr, "wood_type", 0, "", ICON_NULL);
1224                         row= uiLayoutRow(col, 0);
1225                         uiItemR(row, &tex_ptr, "noisebasis_2", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1226                         row= uiLayoutRow(col, 0);
1227                         uiLayoutSetActive(row, !(RNA_enum_get(&tex_ptr, "wood_type")==TEX_BAND || RNA_enum_get(&tex_ptr, "wood_type")==TEX_RING)); 
1228                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1229                         break;
1230                         
1231                 case TEX_CLOUDS:
1232                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NULL);
1233                         row= uiLayoutRow(col, 0);
1234                         uiItemR(row, &tex_ptr, "cloud_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1235                         row= uiLayoutRow(col, 0);
1236                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NULL);
1237                         uiItemR(col, &tex_ptr, "noise_depth", UI_ITEM_R_EXPAND, "Depth", ICON_NULL);
1238                         break;
1239                         
1240                 case TEX_DISTNOISE:
1241                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NULL);
1242                         uiItemR(col, &tex_ptr, "noise_distortion", 0, "", ICON_NULL);
1243                         break;
1244         }
1245 }
1246
1247 static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
1248 {
1249         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
1250 }
1251
1252 static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
1253 {
1254         uiItemR(layout, ptr, "filepath", 0, "", ICON_NULL);
1255 }
1256
1257 /* only once called */
1258 static void node_texture_set_butfunc(bNodeType *ntype)
1259 {
1260         if( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) {
1261                 ntype->uifunc = node_texture_buts_proc;
1262         }
1263         else switch(ntype->type) {
1264                 
1265                 case TEX_NODE_MATH:
1266                         ntype->uifunc = node_buts_math;
1267                         break;
1268                 
1269                 case TEX_NODE_MIX_RGB:
1270                         ntype->uifunc = node_buts_mix_rgb;
1271                         break;
1272                         
1273                 case TEX_NODE_VALTORGB:
1274                         ntype->uifunc = node_buts_colorramp;
1275                         break;
1276                         
1277                 case TEX_NODE_CURVE_RGB:
1278                         ntype->uifunc= node_buts_curvecol;
1279                         break;
1280                         
1281                 case TEX_NODE_CURVE_TIME:
1282                         ntype->uifunc = node_buts_time;
1283                         break;
1284                         
1285                 case TEX_NODE_TEXTURE:
1286                         ntype->uifunc = node_buts_texture;
1287                         break;
1288                         
1289                 case TEX_NODE_BRICKS:
1290                         ntype->uifunc = node_texture_buts_bricks;
1291                         break;
1292                         
1293                 case TEX_NODE_IMAGE:
1294                         ntype->uifunc = node_texture_buts_image;
1295                         break;
1296                         
1297                 case TEX_NODE_OUTPUT:
1298                         ntype->uifunc = node_texture_buts_output;
1299                         break;
1300                         
1301                 default:
1302                         ntype->uifunc= NULL;
1303         }
1304 }
1305
1306 /* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */
1307
1308 void ED_init_node_butfuncs(void)
1309 {
1310         bNodeType *ntype;
1311         
1312         /* shader nodes */
1313         ntype= node_all_shaders.first;
1314         while(ntype) {
1315                 node_shader_set_butfunc(ntype);
1316                 ntype= ntype->next;
1317         }
1318         /* composit nodes */
1319         ntype= node_all_composit.first;
1320         while(ntype) {
1321                 node_composit_set_butfunc(ntype);
1322                 ntype= ntype->next;
1323         }
1324         ntype = node_all_textures.first;
1325         while(ntype) {
1326                 node_texture_set_butfunc(ntype);
1327                 ntype= ntype->next;
1328         }
1329 }
1330
1331 /* ************** Generic drawing ************** */
1332
1333 void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage)
1334 {
1335         
1336         if((snode->flag & SNODE_BACKDRAW) && snode->treetype==NTREE_COMPOSIT) {
1337                 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1338                 void *lock;
1339                 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
1340                 if(ibuf) {
1341                         float x, y; 
1342                         
1343                         glMatrixMode(GL_PROJECTION);
1344                         glPushMatrix();
1345                         glMatrixMode(GL_MODELVIEW);
1346                         glPushMatrix();
1347
1348                         /* keep this, saves us from a version patch */
1349                         if(snode->zoom==0.0f) snode->zoom= 1.0f;
1350                         
1351                         /* somehow the offset has to be calculated inverse */
1352                         
1353                         glaDefine2DArea(&ar->winrct);
1354                         /* ortho at pixel level curarea */
1355                         wmOrtho2(-0.375, ar->winx-0.375, -0.375, ar->winy-0.375);
1356                         
1357                         x = (ar->winx-snode->zoom*ibuf->x)/2 + snode->xof;
1358                         y = (ar->winy-snode->zoom*ibuf->y)/2 + snode->yof;
1359                         
1360                         if(!ibuf->rect) {
1361                                 if(color_manage)
1362                                         ibuf->profile = IB_PROFILE_LINEAR_RGB;
1363                                 else
1364                                         ibuf->profile = IB_PROFILE_NONE;
1365                                 IMB_rect_from_float(ibuf);
1366                         }
1367
1368                         if(ibuf->rect) {
1369                                 glPixelZoom(snode->zoom, snode->zoom);
1370                                 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
1371                                 glPixelZoom(1.0f, 1.0f);
1372                         }
1373                         
1374                         glMatrixMode(GL_PROJECTION);
1375                         glPopMatrix();
1376                         glMatrixMode(GL_MODELVIEW);
1377                         glPopMatrix();
1378                 }
1379
1380                 BKE_image_release_ibuf(ima, lock);
1381         }
1382 }
1383
1384 #if 0
1385 /* note: needs to be userpref or opengl profile option */
1386 static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
1387 {
1388
1389         draw_nodespace_grid(snode);
1390         
1391         if(snode->flag & SNODE_BACKDRAW) {
1392                 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1393                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1394                 if(ibuf) {
1395                         int x, y;
1396                         float zoom = 1.0;
1397
1398                         glMatrixMode(GL_PROJECTION);
1399                         glPushMatrix();
1400                         glMatrixMode(GL_MODELVIEW);
1401                         glPushMatrix();
1402                         
1403                         glaDefine2DArea(&sa->winrct);
1404
1405                         if(ibuf->x > sa->winx || ibuf->y > sa->winy) {
1406                                 float zoomx, zoomy;
1407                                 zoomx= (float)sa->winx/ibuf->x;
1408                                 zoomy= (float)sa->winy/ibuf->y;
1409                                 zoom = MIN2(zoomx, zoomy);
1410                         }
1411                         
1412                         x = (sa->winx-zoom*ibuf->x)/2 + snode->xof;
1413                         y = (sa->winy-zoom*ibuf->y)/2 + snode->yof;
1414
1415                         glPixelZoom(zoom, zoom);
1416
1417                         glColor4f(1.0, 1.0, 1.0, 1.0);
1418                         if(ibuf->rect)
1419                                 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
1420                         else if(ibuf->channels==4)
1421                                 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float);
1422
1423                         glPixelZoom(1.0, 1.0);
1424
1425                         glMatrixMode(GL_PROJECTION);
1426                         glPopMatrix();
1427                         glMatrixMode(GL_MODELVIEW);
1428                         glPopMatrix();
1429                 }
1430         }
1431 }
1432 #endif
1433
1434 /* if v2d not NULL, it clips and returns 0 if not visible */
1435 int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
1436 {
1437         float dist, vec[4][2];
1438         
1439         /* in v0 and v3 we put begin/end points */
1440         if(link->fromsock) {
1441                 vec[0][0]= link->fromsock->locx;
1442                 vec[0][1]= link->fromsock->locy;
1443         }
1444         else {
1445                 if(snode==NULL) return 0;
1446                 vec[0][0]= snode->mx;
1447                 vec[0][1]= snode->my;
1448         }
1449         if(link->tosock) {
1450                 vec[3][0]= link->tosock->locx;
1451                 vec[3][1]= link->tosock->locy;
1452         }
1453         else {
1454                 if(snode==NULL) return 0;
1455                 vec[3][0]= snode->mx;
1456                 vec[3][1]= snode->my;
1457         }
1458         
1459         dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
1460         
1461         /* check direction later, for top sockets */
1462         vec[1][0]= vec[0][0]+dist;
1463         vec[1][1]= vec[0][1];
1464         
1465         vec[2][0]= vec[3][0]-dist;
1466         vec[2][1]= vec[3][1];
1467         
1468         if(v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax); /* clipped */      
1469         else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin); /* clipped */
1470         else {
1471                 
1472                 /* always do all three, to prevent data hanging around */
1473                 forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2);
1474                 forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2);
1475                 
1476                 return 1;
1477         }
1478         return 0;
1479 }
1480
1481 #define LINK_RESOL      24
1482 void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int do_shaded)
1483 {
1484         float coord_array[LINK_RESOL+1][2];
1485         
1486         if(node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
1487                 float dist, spline_step = 0.0f;
1488                 int i;
1489                 
1490                 /* we can reuse the dist variable here to increment the GL curve eval amount*/
1491                 dist = 1.0f/(float)LINK_RESOL;
1492                 
1493                 glBegin(GL_LINE_STRIP);
1494                 for(i=0; i<=LINK_RESOL; i++) {
1495                         if(do_shaded) {
1496                                 UI_ThemeColorBlend(th_col1, th_col2, spline_step);
1497                                 spline_step += dist;
1498                         }                               
1499                         glVertex2fv(coord_array[i]);
1500                 }
1501                 glEnd();
1502         }
1503 }
1504
1505 /* note; this is used for fake links in groups too */
1506 void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
1507 {
1508         int do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE;
1509         
1510         if(link->fromnode==NULL && link->tonode==NULL)
1511                 return;
1512         
1513         if(link->fromnode==NULL || link->tonode==NULL) {
1514                 UI_ThemeColor(TH_WIRE);
1515                 do_shaded= 0;
1516         }
1517         else {
1518                 /* going to give issues once... */
1519                 if(link->tosock->flag & SOCK_UNAVAIL)
1520                         return;
1521                 if(link->fromsock->flag & SOCK_UNAVAIL)
1522                         return;
1523                 
1524                 /* a bit ugly... but thats how we detect the internal group links */
1525                 if(link->fromnode==link->tonode) {
1526                         UI_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f);
1527                         do_shaded= 0;
1528                 }
1529                 else {
1530                         /* check cyclic */
1531                         if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
1532                                 if(link->fromnode->flag & SELECT)
1533                                         th_col1= TH_EDGE_SELECT;
1534                                 if(link->tonode->flag & SELECT)
1535                                         th_col2= TH_EDGE_SELECT;
1536                         }                               
1537                         else {
1538                                 UI_ThemeColor(TH_REDALERT);
1539                                 do_shaded= 0;
1540                         }
1541                 }
1542         }
1543         
1544         node_draw_link_bezier(v2d, snode, link, th_col1, th_col2, do_shaded);
1545 }
1546
1547