f04cefc6d2b95feb672aaae8e88cfe9465b9ab6e
[blender-staging.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, "nodetree", NULL, NULL, "");
78 }
79
80 static void node_buts_value(uiLayout *layout, bContext *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 *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 *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, "alpha", 0, "", ICON_IMAGE_RGB_ALPHA);
117 }
118
119 static void node_buts_time(uiLayout *layout, bContext *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, "start", 0, "Sta", 0);
138         uiItemR(row, ptr, "end", 0, "End", 0);
139 }
140
141 static void node_buts_colorramp(uiLayout *layout, bContext *C, PointerRNA *ptr)
142 {
143         uiTemplateColorRamp(layout, ptr, "color_ramp", 0);
144 }
145
146 static void node_buts_curvevec(uiLayout *layout, bContext *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 *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 *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 *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 *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 *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, "diffuse", 0, NULL, 0);
311         uiItemR(col, ptr, "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 *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, "clamp_minimum", 0, "Min", 0);
333         uiItemR(row, ptr, "minimum", 0, "", 0);
334         
335         row= uiLayoutRow(layout, 1);
336         uiItemR(row, ptr, "clamp_maximum", 0, "Max", 0);
337         uiItemR(row, ptr, "maximum", 0, "", 0);
338         
339 }
340
341 static void node_shader_buts_vect_math(uiLayout *layout, bContext *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, "frames", 0, NULL, 0);
482                 uiItemR(col, ptr, "start", 0, NULL, 0);
483                 uiItemR(col, ptr, "offset", 0, NULL, 0);
484                 uiItemR(col, ptr, "cyclic", 0, NULL, 0);
485                 uiItemR(col, ptr, "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 *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, "bokeh", 0, NULL, 0);
536                 uiItemR(col, ptr, "gamma", 0, NULL, 0);
537         }
538         
539         uiItemR(col, ptr, "relative", 0, NULL, 0);
540         col= uiLayoutColumn(layout, 1);
541         if (RNA_boolean_get(ptr, "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, "sizex", 0, "X", 0);
547                 uiItemR(col, ptr, "sizey", 0, "Y", 0);
548         }
549 }
550
551 static void node_composit_buts_dblur(uiLayout *layout, bContext *C, PointerRNA *ptr)
552 {
553         uiLayout *col;
554         
555         uiItemR(layout, ptr, "iterations", 0, NULL, 0);
556         uiItemR(layout, ptr, "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 *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 *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, "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, "max_blur", 0, NULL, 0);
601         uiItemR(layout, ptr, "threshold", 0, NULL, 0);
602
603         col = uiLayoutColumn(layout, 0);
604         uiItemR(col, ptr, "preview", 0, NULL, 0);
605         sub = uiLayoutColumn(col, 0);
606         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "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 *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, "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 *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 *C, PointerRNA *ptr)
667 {
668         uiLayout *col;
669
670         col= uiLayoutColumn(layout, 0);
671         uiItemR(col, ptr, "projector", 0, NULL, 0);
672
673         col = uiLayoutColumn(col, 0);
674         uiLayoutSetActive(col, RNA_boolean_get(ptr, "projector")==0);
675         uiItemR(col, ptr, "jitter", 0, NULL, 0);
676         uiItemR(col, ptr, "fit", 0, NULL, 0);
677 }
678
679 static void node_composit_buts_vecblur(uiLayout *layout, bContext *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, "min_speed", 0, "Min", 0);
690         uiItemR(col, ptr, "max_speed", 0, "Max", 0);
691
692         uiItemR(layout, ptr, "curved", 0, NULL, 0);
693 }
694
695 static void node_composit_buts_filter(uiLayout *layout, bContext *C, PointerRNA *ptr)
696 {
697         uiItemR(layout, ptr, "filter_type", 0, "", 0);
698 }
699
700 static void node_composit_buts_flip(uiLayout *layout, bContext *C, PointerRNA *ptr)
701 {
702         uiItemR(layout, ptr, "axis", 0, "", 0);
703 }
704
705 static void node_composit_buts_crop(uiLayout *layout, bContext *C, PointerRNA *ptr)
706 {
707         uiLayout *col;
708         
709         uiItemR(layout, ptr, "crop_size", 0, NULL, 0);
710         
711         col= uiLayoutColumn(layout, 1);
712         uiItemR(col, ptr, "x1", 0, "Left", 0);
713         uiItemR(col, ptr, "x2", 0, "Right", 0);
714         uiItemR(col, ptr, "y1", 0, "Up", 0);
715         uiItemR(col, ptr, "y2", 0, "Down", 0);
716 }
717
718 static void node_composit_buts_splitviewer(uiLayout *layout, bContext *C, PointerRNA *ptr)
719 {
720         uiLayout *row, *col;
721         
722         col= uiLayoutColumn(layout, 0);
723         row= uiLayoutRow(col, 0);
724         uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, 0);
725         uiItemR(col, ptr, "factor", 0, NULL, 0);
726 }
727
728 static void node_composit_buts_map_value(uiLayout *layout, bContext *C, PointerRNA *ptr)
729 {
730         uiLayout *sub, *col;
731         
732         col =uiLayoutColumn(layout, 1);
733         uiItemR(col, ptr, "offset", 0, NULL, 0);
734         uiItemR(col, ptr, "size", 0, NULL, 0);
735         
736         col =uiLayoutColumn(layout, 1);
737         uiItemR(col, ptr, "use_min", 0, NULL, 0);
738         sub =uiLayoutColumn(col, 0);
739         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
740         uiItemR(sub, ptr, "min", 0, "", 0);
741         
742         col =uiLayoutColumn(layout, 1);
743         uiItemR(col, ptr, "use_max", 0, NULL, 0);
744         sub =uiLayoutColumn(col, 0);
745         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max"));
746         uiItemR(sub, ptr, "max", 0, "", 0);
747 }
748
749 static void node_composit_buts_alphaover(uiLayout *layout, bContext *C, PointerRNA *ptr)
750 {       
751         uiLayout *col;
752         
753         col =uiLayoutColumn(layout, 1);
754         uiItemR(col, ptr, "convert_premul", 0, NULL, 0);
755         uiItemR(col, ptr, "premul", 0, NULL, 0);
756 }
757
758 static void node_composit_buts_hue_sat(uiLayout *layout, bContext *C, PointerRNA *ptr)
759 {
760         uiLayout *col;
761         
762         col =uiLayoutColumn(layout, 0);
763         uiItemR(col, ptr, "hue", UI_ITEM_R_SLIDER, NULL, 0);
764         uiItemR(col, ptr, "sat", UI_ITEM_R_SLIDER, NULL, 0);
765         uiItemR(col, ptr, "val", UI_ITEM_R_SLIDER, NULL, 0);
766 }
767
768 static void node_composit_buts_dilateerode(uiLayout *layout, bContext *C, PointerRNA *ptr)
769 {
770         uiItemR(layout, ptr, "distance", 0, NULL, 0);
771 }
772
773 static void node_composit_buts_diff_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
774 {
775         uiLayout *col;
776         
777         col =uiLayoutColumn(layout, 1);
778         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, 0);
779         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, 0);
780 }
781
782 static void node_composit_buts_distance_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
783 {
784         uiLayout *col;
785         
786         col =uiLayoutColumn(layout, 1);
787         uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, 0);
788         uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, 0);
789 }
790
791 static void node_composit_buts_color_spill(uiLayout *layout, bContext *C, PointerRNA *ptr)
792 {
793         uiLayout *row, *col;
794         
795    uiItemL(layout, "Despill Channel:", 0);
796    row =uiLayoutRow(layout,0);
797         uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, 0);
798
799    col= uiLayoutColumn(layout, 0);
800    uiItemR(col, ptr, "algorithm", 0, NULL, 0);
801
802    if(RNA_enum_get(ptr, "algorithm")==0) {
803           uiItemL(col, "Limiting Channel:", 0);
804           row=uiLayoutRow(col,0);
805           uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, 0);
806    }
807
808    uiItemR(col, ptr, "ratio", UI_ITEM_R_SLIDER, NULL, 0);
809    uiItemR(col, ptr, "unspill", 0, NULL, 0);   
810    if (RNA_enum_get(ptr, "unspill")== 1) {
811           uiItemR(col, ptr, "unspill_red", UI_ITEM_R_SLIDER, NULL, 0);
812           uiItemR(col, ptr, "unspill_green", UI_ITEM_R_SLIDER, NULL, 0);
813           uiItemR(col, ptr, "unspill_blue", UI_ITEM_R_SLIDER, NULL, 0);
814    }
815 }
816
817 static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
818 {
819         uiLayout *col;
820         
821         col= uiLayoutColumn(layout, 0);
822         uiItemR(col, ptr, "acceptance", 0, NULL, 0);
823         uiItemR(col, ptr, "cutoff", 0, NULL, 0);
824         
825         col= uiLayoutColumn(layout, 1);
826    /*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, 0);  Removed for now */
827         uiItemR(col, ptr, "gain", UI_ITEM_R_SLIDER, NULL, 0);
828    /*uiItemR(col, ptr, "shadow_adjust", UI_ITEM_R_SLIDER, NULL, 0);  Removed for now*/
829 }
830
831 static void node_composit_buts_color_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
832 {
833         uiLayout *col;
834         
835         col= uiLayoutColumn(layout, 1);
836         uiItemR(col, ptr, "h", UI_ITEM_R_SLIDER, NULL, 0);
837         uiItemR(col, ptr, "s", UI_ITEM_R_SLIDER, NULL, 0);
838         uiItemR(col, ptr, "v", UI_ITEM_R_SLIDER, NULL, 0);
839 }
840
841 static void node_composit_buts_channel_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
842 {       
843         uiLayout *col, *row;
844
845    uiItemL(layout, "Color Space:", 0);
846         row= uiLayoutRow(layout, 0);
847         uiItemR(row, ptr, "color_space", UI_ITEM_R_EXPAND, NULL, 0);
848
849    col=uiLayoutColumn(layout, 0);  
850    uiItemL(col, "Key Channel:", 0);
851         row= uiLayoutRow(col, 0);
852         uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, 0);
853
854         col =uiLayoutColumn(layout, 0);
855
856    uiItemR(col, ptr, "algorithm", 0, NULL, 0);
857    if(RNA_enum_get(ptr, "algorithm")==0) {
858           uiItemL(col, "Limiting Channel:", 0);
859           row=uiLayoutRow(col,0);
860           uiItemR(row, ptr, "limit_channel", UI_ITEM_R_EXPAND, NULL, 0);
861    }
862    
863         uiItemR(col, ptr, "high", UI_ITEM_R_SLIDER, NULL, 0);
864         uiItemR(col, ptr, "low", UI_ITEM_R_SLIDER, NULL, 0);
865 }
866
867 static void node_composit_buts_luma_matte(uiLayout *layout, bContext *C, PointerRNA *ptr)
868 {
869         uiLayout *col;
870         
871         col= uiLayoutColumn(layout, 1);
872         uiItemR(col, ptr, "high", UI_ITEM_R_SLIDER, NULL, 0);
873         uiItemR(col, ptr, "low", UI_ITEM_R_SLIDER, NULL, 0);
874 }
875
876 static void node_composit_buts_map_uv(uiLayout *layout, bContext *C, PointerRNA *ptr)
877 {
878         uiItemR(layout, ptr, "alpha", 0, NULL, 0);
879 }
880
881 static void node_composit_buts_id_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
882 {
883         uiItemR(layout, ptr, "index", 0, NULL, 0);
884 }
885
886 static void node_composit_buts_file_output(uiLayout *layout, bContext *C, PointerRNA *ptr)
887 {
888         uiLayout *col, *row;
889
890         col= uiLayoutColumn(layout, 0);
891         uiItemR(col, ptr, "filepath", 0, "", 0);
892         uiItemR(col, ptr, "image_type", 0, "", 0);
893         
894         row= uiLayoutRow(layout, 0);
895         if (RNA_enum_get(ptr, "image_type")== R_OPENEXR) {
896                 uiItemR(row, ptr, "exr_half", 0, NULL, 0);
897                 uiItemR(row, ptr, "exr_codec", 0, "", 0);
898         }
899         else if (RNA_enum_get(ptr, "image_type")== R_JPEG90) {
900                 uiItemR(row, ptr, "quality", UI_ITEM_R_SLIDER, "Quality", 0);
901         }
902         else if (RNA_enum_get(ptr, "image_type")== R_PNG) {
903                 uiItemR(row, ptr, "quality", UI_ITEM_R_SLIDER, "Compression", 0);
904         }
905         
906         row= uiLayoutRow(layout, 1);
907         uiItemR(row, ptr, "frame_start", 0, "Start", 0);
908         uiItemR(row, ptr, "frame_end", 0, "End", 0);
909 }
910
911 static void node_composit_buts_scale(uiLayout *layout, bContext *C, PointerRNA *ptr)
912 {
913         uiItemR(layout, ptr, "space", 0, "", 0);
914 }
915
916 static void node_composit_buts_rotate(uiLayout *layout, bContext *C, PointerRNA *ptr)
917 {
918    uiItemR(layout, ptr, "filter", 0, "", 0);
919 }
920
921 static void node_composit_buts_invert(uiLayout *layout, bContext *C, PointerRNA *ptr)
922 {
923         uiLayout *col;
924         
925         col= uiLayoutColumn(layout, 0);
926         uiItemR(col, ptr, "rgb", 0, NULL, 0);
927         uiItemR(col, ptr, "alpha", 0, NULL, 0);
928 }
929
930 static void node_composit_buts_premulkey(uiLayout *layout, bContext *C, PointerRNA *ptr)
931 {
932         uiItemR(layout, ptr, "mapping", 0, "", 0);
933 }
934
935 static void node_composit_buts_view_levels(uiLayout *layout, bContext *C, PointerRNA *ptr)
936 {
937         uiItemR(layout, ptr, "channel", UI_ITEM_R_EXPAND, NULL, 0);
938 }
939
940 static void node_composit_buts_colorbalance(uiLayout *layout, bContext *C, PointerRNA *ptr)
941 {
942         uiLayout *split, *col, *row;
943         
944         uiItemR(layout, ptr, "correction_formula", 0, NULL, 0);
945         
946         if (RNA_enum_get(ptr, "correction_formula")== 0) {
947         
948                 split = uiLayoutSplit(layout, 0, 0);
949                 col = uiLayoutColumn(split, 0);
950                 uiTemplateColorWheel(col, ptr, "lift", 1, 1, 0, 1);
951                 row = uiLayoutRow(col, 0);
952                 uiItemR(row, ptr, "lift", 0, NULL, 0);
953                 
954                 col = uiLayoutColumn(split, 0);
955                 uiTemplateColorWheel(col, ptr, "gamma", 1, 1, 1, 1);
956                 row = uiLayoutRow(col, 0);
957                 uiItemR(row, ptr, "gamma", 0, NULL, 0);
958                 
959                 col = uiLayoutColumn(split, 0);
960                 uiTemplateColorWheel(col, ptr, "gain", 1, 1, 1, 1);
961                 row = uiLayoutRow(col, 0);
962                 uiItemR(row, ptr, "gain", 0, NULL, 0);
963
964         } else {
965                 
966                 split = uiLayoutSplit(layout, 0, 0);
967                 col = uiLayoutColumn(split, 0);
968                 uiTemplateColorWheel(col, ptr, "offset", 1, 1, 0, 1);
969                 row = uiLayoutRow(col, 0);
970                 uiItemR(row, ptr, "offset", 0, NULL, 0);
971                 
972                 col = uiLayoutColumn(split, 0);
973                 uiTemplateColorWheel(col, ptr, "power", 1, 1, 0, 1);
974                 row = uiLayoutRow(col, 0);
975                 uiItemR(row, ptr, "power", 0, NULL, 0);
976                 
977                 col = uiLayoutColumn(split, 0);
978                 uiTemplateColorWheel(col, ptr, "slope", 1, 1, 0, 1);
979                 row = uiLayoutRow(col, 0);
980                 uiItemR(row, ptr, "slope", 0, NULL, 0);
981         }
982
983 }
984
985 static void node_composit_buts_huecorrect(uiLayout *layout, bContext *C, PointerRNA *ptr)
986 {
987         uiTemplateCurveMapping(layout, ptr, "mapping", 'h', 0, 0);
988 }
989
990 /* only once called */
991 static void node_composit_set_butfunc(bNodeType *ntype)
992 {
993         switch(ntype->type) {
994                 /* case NODE_GROUP:      note, typeinfo for group is generated... see "XXX ugly hack" */
995
996                 case CMP_NODE_IMAGE:
997                         ntype->uifunc= node_composit_buts_image;
998                         break;
999                 case CMP_NODE_R_LAYERS:
1000                         ntype->uifunc= node_composit_buts_renderlayers;
1001                         break;
1002                 case CMP_NODE_NORMAL:
1003                         ntype->uifunc= node_buts_normal;
1004                         break;
1005                 case CMP_NODE_CURVE_VEC:
1006                         ntype->uifunc= node_buts_curvevec;
1007                         break;
1008                 case CMP_NODE_CURVE_RGB:
1009                         ntype->uifunc= node_buts_curvecol;
1010                         break;
1011                 case CMP_NODE_VALUE:
1012                         ntype->uifunc= node_buts_value;
1013                         break;
1014                 case CMP_NODE_RGB:
1015                         ntype->uifunc= node_buts_rgb;
1016                         break;
1017                 case CMP_NODE_FLIP:
1018                         ntype->uifunc= node_composit_buts_flip;
1019                         break;
1020                 case CMP_NODE_SPLITVIEWER:
1021                         ntype->uifunc= node_composit_buts_splitviewer;
1022                         break;
1023                 case CMP_NODE_MIX_RGB:
1024                         ntype->uifunc= node_buts_mix_rgb;
1025                         break;
1026                 case CMP_NODE_VALTORGB:
1027                         ntype->uifunc= node_buts_colorramp;
1028                         break;
1029                 case CMP_NODE_CROP:
1030                         ntype->uifunc= node_composit_buts_crop;
1031                         break;
1032                 case CMP_NODE_BLUR:
1033                         ntype->uifunc= node_composit_buts_blur;
1034                         break;
1035                 case CMP_NODE_DBLUR:
1036                         ntype->uifunc= node_composit_buts_dblur;
1037                         break;
1038                 case CMP_NODE_BILATERALBLUR:
1039                         ntype->uifunc= node_composit_buts_bilateralblur;
1040                         break;
1041                 case CMP_NODE_DEFOCUS:
1042                         ntype->uifunc = node_composit_buts_defocus;
1043                         break;
1044                 case CMP_NODE_GLARE:
1045                         ntype->uifunc = node_composit_buts_glare;
1046                         break;
1047                 case CMP_NODE_TONEMAP:
1048                         ntype->uifunc = node_composit_buts_tonemap;
1049                         break;
1050                 case CMP_NODE_LENSDIST:
1051                         ntype->uifunc = node_composit_buts_lensdist;
1052                         break;
1053                 case CMP_NODE_VECBLUR:
1054                         ntype->uifunc= node_composit_buts_vecblur;
1055                         break;
1056                 case CMP_NODE_FILTER:
1057                         ntype->uifunc= node_composit_buts_filter;
1058                         break;
1059                 case CMP_NODE_MAP_VALUE:
1060                         ntype->uifunc= node_composit_buts_map_value;
1061                         break;
1062                 case CMP_NODE_TIME:
1063                         ntype->uifunc= node_buts_time;
1064                         break;
1065                 case CMP_NODE_ALPHAOVER:
1066                         ntype->uifunc= node_composit_buts_alphaover;
1067                         break;
1068                 case CMP_NODE_HUE_SAT:
1069                         ntype->uifunc= node_composit_buts_hue_sat;
1070                         break;
1071                 case CMP_NODE_TEXTURE:
1072                         ntype->uifunc= node_buts_texture;
1073                         break;
1074                 case CMP_NODE_DILATEERODE:
1075                         ntype->uifunc= node_composit_buts_dilateerode;
1076                         break;
1077                 case CMP_NODE_OUTPUT_FILE:
1078                         ntype->uifunc= node_composit_buts_file_output;
1079                         break;  
1080                 case CMP_NODE_DIFF_MATTE:
1081                         ntype->uifunc=node_composit_buts_diff_matte;
1082                         break;
1083                 case CMP_NODE_DIST_MATTE:
1084                         ntype->uifunc=node_composit_buts_distance_matte;
1085                         break;
1086                 case CMP_NODE_COLOR_SPILL:
1087                         ntype->uifunc=node_composit_buts_color_spill;
1088                         break;
1089                 case CMP_NODE_CHROMA_MATTE:
1090                         ntype->uifunc=node_composit_buts_chroma_matte;
1091                         break;
1092                 case CMP_NODE_COLOR_MATTE:
1093                         ntype->uifunc=node_composit_buts_color_matte;
1094                         break;
1095                 case CMP_NODE_SCALE:
1096                         ntype->uifunc= node_composit_buts_scale;
1097                         break;
1098           case CMP_NODE_ROTATE:
1099                  ntype->uifunc=node_composit_buts_rotate;
1100                  break;
1101                 case CMP_NODE_CHANNEL_MATTE:
1102                         ntype->uifunc= node_composit_buts_channel_matte;
1103                         break;
1104                 case CMP_NODE_LUMA_MATTE:
1105                         ntype->uifunc= node_composit_buts_luma_matte;
1106                         break;
1107                 case CMP_NODE_MAP_UV:
1108                         ntype->uifunc= node_composit_buts_map_uv;
1109                         break;
1110                 case CMP_NODE_ID_MASK:
1111                         ntype->uifunc= node_composit_buts_id_mask;
1112                         break;
1113                 case CMP_NODE_MATH:
1114                         ntype->uifunc= node_buts_math;
1115                         break;
1116                 case CMP_NODE_INVERT:
1117                         ntype->uifunc= node_composit_buts_invert;
1118                         break;
1119                 case CMP_NODE_PREMULKEY:
1120                         ntype->uifunc= node_composit_buts_premulkey;
1121                         break;
1122                 case CMP_NODE_VIEW_LEVELS:
1123                         ntype->uifunc=node_composit_buts_view_levels;
1124                          break;
1125                 case CMP_NODE_COLORBALANCE:
1126                         ntype->uifunc=node_composit_buts_colorbalance;
1127                          break;
1128                 case CMP_NODE_HUECORRECT:
1129                         ntype->uifunc=node_composit_buts_huecorrect;
1130                          break;
1131                 default:
1132                         ntype->uifunc= NULL;
1133         }
1134 }
1135
1136 /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */
1137
1138 static void node_texture_buts_bricks(uiLayout *layout, bContext *C, PointerRNA *ptr)
1139 {
1140         uiLayout *col;
1141         
1142         col= uiLayoutColumn(layout, 1);
1143         uiItemR(col, ptr, "offset", 0, "Offset", 0);
1144         uiItemR(col, ptr, "offset_frequency", 0, "Frequency", 0);
1145         
1146         col= uiLayoutColumn(layout, 1);
1147         uiItemR(col, ptr, "squash", 0, "Squash", 0);
1148         uiItemR(col, ptr, "squash_frequency", 0, "Frequency", 0);
1149 }
1150
1151 static void node_texture_buts_proc(uiLayout *layout, bContext *C, PointerRNA *ptr)
1152 {
1153         PointerRNA tex_ptr;
1154         bNode *node= ptr->data;
1155         ID *id= ptr->id.data;
1156         Tex *tex = (Tex *)node->storage;
1157         uiLayout *col, *row;
1158         
1159         RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr);
1160
1161         col= uiLayoutColumn(layout, 0);
1162
1163         switch( tex->type ) {
1164                 case TEX_BLEND:
1165                         uiItemR(col, &tex_ptr, "progression", 0, "", 0);
1166                         row= uiLayoutRow(col, 0);
1167                         uiItemR(row, &tex_ptr, "flip_axis", UI_ITEM_R_EXPAND, NULL, 0);
1168                         break;
1169
1170                 case TEX_MARBLE:
1171                         row= uiLayoutRow(col, 0);
1172                         uiItemR(row, &tex_ptr, "stype", UI_ITEM_R_EXPAND, NULL, 0);
1173                         row= uiLayoutRow(col, 0);
1174                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, 0);
1175                         row= uiLayoutRow(col, 0);
1176                         uiItemR(row, &tex_ptr, "noisebasis2", UI_ITEM_R_EXPAND, NULL, 0);
1177                         break;
1178
1179                 case TEX_WOOD:
1180                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", 0);
1181                         uiItemR(col, &tex_ptr, "stype", 0, "", 0);
1182                         row= uiLayoutRow(col, 0);
1183                         uiItemR(row, &tex_ptr, "noisebasis2", UI_ITEM_R_EXPAND, NULL, 0);
1184                         row= uiLayoutRow(col, 0);
1185                         uiLayoutSetActive(row, !(RNA_enum_get(&tex_ptr, "stype")==TEX_BAND || RNA_enum_get(&tex_ptr, "stype")==TEX_RING)); 
1186                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, 0);
1187                         break;
1188                         
1189                 case TEX_CLOUDS:
1190                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", 0);
1191                         row= uiLayoutRow(col, 0);
1192                         uiItemR(row, &tex_ptr, "stype", UI_ITEM_R_EXPAND, NULL, 0);
1193                         row= uiLayoutRow(col, 0);
1194                         uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, 0);
1195                         uiItemR(col, &tex_ptr, "noise_depth", UI_ITEM_R_EXPAND, "Depth", 0);
1196                         break;
1197                         
1198                 case TEX_DISTNOISE:
1199                         uiItemR(col, &tex_ptr, "noise_basis", 0, "", 0);
1200                         uiItemR(col, &tex_ptr, "noise_distortion", 0, "", 0);
1201                         break;
1202         }
1203 }
1204
1205 static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
1206 {
1207         uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
1208 }
1209
1210 static void node_texture_buts_output(uiLayout *layout, bContext *C, PointerRNA *ptr)
1211 {
1212         uiItemR(layout, ptr, "output_name", 0, "", 0);
1213 }
1214
1215 /* only once called */
1216 static void node_texture_set_butfunc(bNodeType *ntype)
1217 {
1218         if( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) {
1219                 ntype->uifunc = node_texture_buts_proc;
1220         }
1221         else switch(ntype->type) {
1222                 
1223                 case TEX_NODE_MATH:
1224                         ntype->uifunc = node_buts_math;
1225                         break;
1226                 
1227                 case TEX_NODE_MIX_RGB:
1228                         ntype->uifunc = node_buts_mix_rgb;
1229                         break;
1230                         
1231                 case TEX_NODE_VALTORGB:
1232                         ntype->uifunc = node_buts_colorramp;
1233                         break;
1234                         
1235                 case TEX_NODE_CURVE_RGB:
1236                         ntype->uifunc= node_buts_curvecol;
1237                         break;
1238                         
1239                 case TEX_NODE_CURVE_TIME:
1240                         ntype->uifunc = node_buts_time;
1241                         break;
1242                         
1243                 case TEX_NODE_TEXTURE:
1244                         ntype->uifunc = node_buts_texture;
1245                         break;
1246                         
1247                 case TEX_NODE_BRICKS:
1248                         ntype->uifunc = node_texture_buts_bricks;
1249                         break;
1250                         
1251                 case TEX_NODE_IMAGE:
1252                         ntype->uifunc = node_texture_buts_image;
1253                         break;
1254                         
1255                 case TEX_NODE_OUTPUT:
1256                         ntype->uifunc = node_texture_buts_output;
1257                         break;
1258                         
1259                 default:
1260                         ntype->uifunc= NULL;
1261         }
1262 }
1263
1264 /* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */
1265
1266 void ED_init_node_butfuncs(void)
1267 {
1268         bNodeType *ntype;
1269         
1270         /* shader nodes */
1271         ntype= node_all_shaders.first;
1272         while(ntype) {
1273                 node_shader_set_butfunc(ntype);
1274                 ntype= ntype->next;
1275         }
1276         /* composit nodes */
1277         ntype= node_all_composit.first;
1278         while(ntype) {
1279                 node_composit_set_butfunc(ntype);
1280                 ntype= ntype->next;
1281         }
1282         ntype = node_all_textures.first;
1283         while(ntype) {
1284                 node_texture_set_butfunc(ntype);
1285                 ntype= ntype->next;
1286         }
1287 }
1288
1289 /* ************** Generic drawing ************** */
1290
1291 void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage)
1292 {
1293         
1294         if((snode->flag & SNODE_BACKDRAW) && snode->treetype==NTREE_COMPOSIT) {
1295                 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1296                 void *lock;
1297                 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
1298                 if(ibuf) {
1299                         float x, y; 
1300                         
1301                         glMatrixMode(GL_PROJECTION);
1302                         glPushMatrix();
1303                         glMatrixMode(GL_MODELVIEW);
1304                         glPushMatrix();
1305
1306                         /* keep this, saves us from a version patch */
1307                         if(snode->zoom==0.0f) snode->zoom= 1.0f;
1308                         
1309                         /* somehow the offset has to be calculated inverse */
1310                         
1311                         glaDefine2DArea(&ar->winrct);
1312                         /* ortho at pixel level curarea */
1313                         wmOrtho2(-0.375, ar->winx-0.375, -0.375, ar->winy-0.375);
1314                         
1315                         x = (ar->winx-snode->zoom*ibuf->x)/2 + snode->xof;
1316                         y = (ar->winy-snode->zoom*ibuf->y)/2 + snode->yof;
1317                         
1318                         if(!ibuf->rect) {
1319                                 if(color_manage)
1320                                         ibuf->profile = IB_PROFILE_LINEAR_RGB;
1321                                 else
1322                                         ibuf->profile = IB_PROFILE_NONE;
1323                                 IMB_rect_from_float(ibuf);
1324                         }
1325
1326                         if(ibuf->rect) {
1327                                 glPixelZoom(snode->zoom, snode->zoom);
1328                                 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
1329                                 glPixelZoom(1.0f, 1.0f);
1330                         }
1331                         
1332                         glMatrixMode(GL_PROJECTION);
1333                         glPopMatrix();
1334                         glMatrixMode(GL_MODELVIEW);
1335                         glPopMatrix();
1336                 }
1337
1338                 BKE_image_release_ibuf(ima, lock);
1339         }
1340 }
1341
1342 #if 0
1343 /* note: needs to be userpref or opengl profile option */
1344 static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
1345 {
1346
1347         draw_nodespace_grid(snode);
1348         
1349         if(snode->flag & SNODE_BACKDRAW) {
1350                 Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
1351                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1352                 if(ibuf) {
1353                         int x, y;
1354                         float zoom = 1.0;
1355
1356                         glMatrixMode(GL_PROJECTION);
1357                         glPushMatrix();
1358                         glMatrixMode(GL_MODELVIEW);
1359                         glPushMatrix();
1360                         
1361                         glaDefine2DArea(&sa->winrct);
1362
1363                         if(ibuf->x > sa->winx || ibuf->y > sa->winy) {
1364                                 float zoomx, zoomy;
1365                                 zoomx= (float)sa->winx/ibuf->x;
1366                                 zoomy= (float)sa->winy/ibuf->y;
1367                                 zoom = MIN2(zoomx, zoomy);
1368                         }
1369                         
1370                         x = (sa->winx-zoom*ibuf->x)/2 + snode->xof;
1371                         y = (sa->winy-zoom*ibuf->y)/2 + snode->yof;
1372
1373                         glPixelZoom(zoom, zoom);
1374
1375                         glColor4f(1.0, 1.0, 1.0, 1.0);
1376                         if(ibuf->rect)
1377                                 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
1378                         else if(ibuf->channels==4)
1379                                 glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float);
1380
1381                         glPixelZoom(1.0, 1.0);
1382
1383                         glMatrixMode(GL_PROJECTION);
1384                         glPopMatrix();
1385                         glMatrixMode(GL_MODELVIEW);
1386                         glPopMatrix();
1387                 }
1388         }
1389 }
1390 #endif
1391
1392 /* if v2d not NULL, it clips and returns 0 if not visible */
1393 int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
1394 {
1395         float dist, vec[4][2];
1396         
1397         /* in v0 and v3 we put begin/end points */
1398         if(link->fromsock) {
1399                 vec[0][0]= link->fromsock->locx;
1400                 vec[0][1]= link->fromsock->locy;
1401         }
1402         else {
1403                 if(snode==NULL) return 0;
1404                 vec[0][0]= snode->mx;
1405                 vec[0][1]= snode->my;
1406         }
1407         if(link->tosock) {
1408                 vec[3][0]= link->tosock->locx;
1409                 vec[3][1]= link->tosock->locy;
1410         }
1411         else {
1412                 if(snode==NULL) return 0;
1413                 vec[3][0]= snode->mx;
1414                 vec[3][1]= snode->my;
1415         }
1416         
1417         dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
1418         
1419         /* check direction later, for top sockets */
1420         vec[1][0]= vec[0][0]+dist;
1421         vec[1][1]= vec[0][1];
1422         
1423         vec[2][0]= vec[3][0]-dist;
1424         vec[2][1]= vec[3][1];
1425         
1426         if(v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax); /* clipped */      
1427         else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin); /* clipped */
1428         else {
1429                 
1430                 /* always do all three, to prevent data hanging around */
1431                 forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2);
1432                 forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2);
1433                 
1434                 return 1;
1435         }
1436         return 0;
1437 }
1438
1439 #define LINK_RESOL      24
1440 void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int do_shaded)
1441 {
1442         float coord_array[LINK_RESOL+1][2];
1443         
1444         if(node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
1445                 float dist, spline_step = 0.0f;
1446                 int i;
1447                 
1448                 /* we can reuse the dist variable here to increment the GL curve eval amount*/
1449                 dist = 1.0f/(float)LINK_RESOL;
1450                 
1451                 glBegin(GL_LINE_STRIP);
1452                 for(i=0; i<=LINK_RESOL; i++) {
1453                         if(do_shaded) {
1454                                 UI_ThemeColorBlend(th_col1, th_col2, spline_step);
1455                                 spline_step += dist;
1456                         }                               
1457                         glVertex2fv(coord_array[i]);
1458                 }
1459                 glEnd();
1460         }
1461 }
1462
1463 /* note; this is used for fake links in groups too */
1464 void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
1465 {
1466         int do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE;
1467         
1468         if(link->fromnode==NULL && link->tonode==NULL)
1469                 return;
1470         
1471         if(link->fromnode==NULL || link->tonode==NULL) {
1472                 UI_ThemeColor(TH_WIRE);
1473                 do_shaded= 0;
1474         }
1475         else {
1476                 /* going to give issues once... */
1477                 if(link->tosock->flag & SOCK_UNAVAIL)
1478                         return;
1479                 if(link->fromsock->flag & SOCK_UNAVAIL)
1480                         return;
1481                 
1482                 /* a bit ugly... but thats how we detect the internal group links */
1483                 if(link->fromnode==link->tonode) {
1484                         UI_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f);
1485                         do_shaded= 0;
1486                 }
1487                 else {
1488                         /* check cyclic */
1489                         if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
1490                                 if(link->fromnode->flag & SELECT)
1491                                         th_col1= TH_EDGE_SELECT;
1492                                 if(link->tonode->flag & SELECT)
1493                                         th_col2= TH_EDGE_SELECT;
1494                         }                               
1495                         else {
1496                                 UI_ThemeColor(TH_REDALERT);
1497                                 do_shaded= 0;
1498                         }
1499                 }
1500         }
1501         
1502         node_draw_link_bezier(v2d, snode, link, th_col1, th_col2, do_shaded);
1503 }
1504
1505