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