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