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