Reverted incorrect merge (missing files)
[blender.git] / source / blender / editors / space_node / node_header.c
1 /**
2  * $Id: node_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
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) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_space_types.h"
33 #include "DNA_node_types.h"
34 #include "DNA_material_types.h"
35 #include "DNA_texture_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_screen_types.h"
38 #include "DNA_windowmanager_types.h"
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43
44 #include "BKE_context.h"
45 #include "BKE_screen.h"
46 #include "BKE_node.h"
47 #include "BKE_main.h"
48
49 #include "ED_screen.h"
50 #include "ED_types.h"
51 #include "ED_util.h"
52
53 #include "WM_api.h"
54 #include "WM_types.h"
55
56 #include "BIF_gl.h"
57 #include "BIF_glutil.h"
58
59 #include "UI_interface.h"
60 #include "UI_resources.h"
61 #include "UI_view2d.h"
62
63 #include "node_intern.h"
64
65 /* ************************ header area region *********************** */
66
67 static void do_node_selectmenu(bContext *C, void *arg, int event)
68 {
69         ScrArea *curarea= CTX_wm_area(C);
70         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C); 
71         
72         /* functions in editnode.c assume there's a tree */
73         if(snode->nodetree==NULL)
74                 return;
75         
76         switch(event) {
77                 case 1: /* border select */
78                         WM_operator_name_call(C, "NODE_OT_select_border", WM_OP_INVOKE_REGION_WIN, NULL);
79                         break;
80                 case 2: /* select/deselect all */
81                         // XXX node_deselectall(snode, 1);
82                         break;
83                 case 3: /* select linked in */
84                         // XXX node_select_linked(snode, 0);
85                         break;
86                 case 4: /* select linked out */
87                         // XXX node_select_linked(snode, 1);
88                         break;
89         }
90         
91         ED_area_tag_redraw(curarea);
92 }
93
94 static uiBlock *node_selectmenu(bContext *C, ARegion *ar, void *arg_unused)
95 {
96         ScrArea *curarea= CTX_wm_area(C);
97         uiBlock *block;
98         short yco= 0, menuwidth=120;
99         
100         block= uiBeginBlock(C, ar, "node_selectmenu", UI_EMBOSSP);
101         uiBlockSetButmFunc(block, do_node_selectmenu, NULL);
102         
103         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
104         
105         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
106         
107         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
108         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Linked From|L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
109         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Linked To|Shift L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
110         
111         if(curarea->headertype==HEADERTOP) {
112                 uiBlockSetDirection(block, UI_DOWN);
113         }
114         else {
115                 uiBlockSetDirection(block, UI_TOP);
116                 uiBlockFlipOrder(block);
117         }
118         
119         uiTextBoundsBlock(block, 50);
120         uiEndBlock(C, block);
121         
122         return block;
123 }
124
125 void do_node_addmenu(bContext *C, void *arg, int event)
126 {
127         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
128         bNode *node;
129         
130         /* store selection in temp test flag */
131         for(node= snode->edittree->nodes.first; node; node= node->next) {
132                 if(node->flag & NODE_SELECT) node->flag |= NODE_TEST;
133                 else node->flag &= ~NODE_TEST;
134         }
135         
136         node= node_add_node(snode, CTX_data_scene(C), event, snode->mx, snode->my);
137         
138         /* uses test flag */
139         snode_autoconnect(snode, node, NODE_TEST);
140                 
141         snode_handle_recalc(C, snode);
142 }
143
144 static void node_make_addmenu(bContext *C, int nodeclass, uiBlock *block)
145 {
146         Main *bmain= CTX_data_main(C);
147         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
148         bNodeTree *ntree;
149         int tot= 0, a;
150         short yco= 0, menuwidth=120;
151         
152         ntree = snode->nodetree;
153         if(ntree) {
154                 /* mostly taken from toolbox.c, node_add_sublevel() */
155                 if(ntree) {
156                         if(nodeclass==NODE_CLASS_GROUP) {
157                                 bNodeTree *ngroup= bmain->nodetree.first;
158                                 for(; ngroup; ngroup= ngroup->id.next)
159                                         if(ngroup->type==ntree->type)
160                                                 tot++;
161                         }
162                         else {
163                                 bNodeType *type = ntree->alltypes.first;
164                                 while(type) {
165                                         if(type->nclass == nodeclass)
166                                                 tot++;
167                                         type= type->next;
168                                 }
169                         }
170                 }       
171                 
172                 if(tot==0) {
173                         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
174                         return;
175                 }
176                 
177                 if(nodeclass==NODE_CLASS_GROUP) {
178                         bNodeTree *ngroup= bmain->nodetree.first;
179                         for(tot=0, a=0; ngroup; ngroup= ngroup->id.next, tot++) {
180                                 if(ngroup->type==ntree->type) {
181                                         
182                                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, (ngroup->id.name+2), 0, 
183                                                 yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1.0f, (float)(NODE_GROUP_MENU+tot), "");
184                                         a++;
185                                 }
186                         }
187                 }
188                 else {
189                         bNodeType *type;
190                         int script=0;
191                         for(a=0, type= ntree->alltypes.first; type; type=type->next) {
192                                 if( type->nclass == nodeclass && type->name) {
193                                         if(type->type == NODE_DYNAMIC) {
194                                                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, type->name, 0, 
195                                                         yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1.0f, (float)(NODE_DYNAMIC_MENU+script), "");
196                                                 script++;
197                                         } else {
198                                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, type->name, 0, 
199                                                 yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1.0f, (float)(type->type), "");
200                                         }
201                                         a++;
202                                 }
203                         }
204                 }
205         } else {
206                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
207                 return;
208         }
209 }
210
211 static uiBlock *node_add_inputmenu(bContext *C, ARegion *ar, void *arg_unused)
212 {
213         uiBlock *block;
214
215         block= uiBeginBlock(C, ar, "node_add_inputmenu", UI_EMBOSSP);
216         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
217         
218         node_make_addmenu(C, NODE_CLASS_INPUT, block);
219         
220         uiBlockSetDirection(block, UI_RIGHT);
221         uiTextBoundsBlock(block, 60);
222         uiEndBlock(C, block);
223         
224         return block;
225 }
226 static uiBlock *node_add_outputmenu(bContext *C, ARegion *ar, void *arg_unused)
227 {
228         uiBlock *block;
229         
230         block= uiBeginBlock(C, ar, "node_add_outputmenu", UI_EMBOSSP);
231         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
232         
233         node_make_addmenu(C, NODE_CLASS_OUTPUT, block);
234         
235         uiBlockSetDirection(block, UI_RIGHT);
236         uiTextBoundsBlock(block, 60);
237         uiEndBlock(C, block);
238         
239         return block;
240 }
241 static uiBlock *node_add_colormenu(bContext *C, ARegion *ar, void *arg_unused)
242 {
243         uiBlock *block;
244         
245         block= uiBeginBlock(C, ar, "node_add_colormenu", UI_EMBOSSP);
246         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
247         
248         node_make_addmenu(C, NODE_CLASS_OP_COLOR, block);
249         
250         uiBlockSetDirection(block, UI_RIGHT);
251         uiTextBoundsBlock(block, 60);
252         uiEndBlock(C, block);
253         
254         return block;
255 }
256 static uiBlock *node_add_vectormenu(bContext *C, ARegion *ar, void *arg_unused)
257 {
258         uiBlock *block;
259         
260         block= uiBeginBlock(C, ar, "node_add_vectormenu", UI_EMBOSSP);
261         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
262         
263         node_make_addmenu(C, NODE_CLASS_OP_VECTOR, block);
264         
265         uiBlockSetDirection(block, UI_RIGHT);
266         uiTextBoundsBlock(block, 60);
267         uiEndBlock(C, block);
268         
269         return block;
270 }
271 static uiBlock *node_add_filtermenu(bContext *C, ARegion *ar, void *arg_unused)
272 {
273         uiBlock *block;
274         
275         block= uiBeginBlock(C, ar, "node_add_filtermenu", UI_EMBOSSP);
276         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
277         
278         node_make_addmenu(C, NODE_CLASS_OP_FILTER, block);
279         
280         uiBlockSetDirection(block, UI_RIGHT);
281         uiTextBoundsBlock(block, 60);
282         uiEndBlock(C, block);
283         
284         return block;
285 }
286 static uiBlock *node_add_convertermenu(bContext *C, ARegion *ar, void *arg_unused)
287 {
288         uiBlock *block;
289         
290         block= uiBeginBlock(C, ar, "node_add_convertermenu", UI_EMBOSSP);
291         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
292         
293         node_make_addmenu(C, NODE_CLASS_CONVERTOR, block);
294         
295         uiBlockSetDirection(block, UI_RIGHT);
296         uiTextBoundsBlock(block, 60);
297         uiEndBlock(C, block);
298         
299         return block;
300 }
301 static uiBlock *node_add_mattemenu(bContext *C, ARegion *ar, void *arg_unused)
302 {
303         uiBlock *block;
304         
305         block= uiBeginBlock(C, ar, "node_add_mattemenu", UI_EMBOSSP);
306         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
307         
308         node_make_addmenu(C, NODE_CLASS_MATTE, block);
309         
310         uiBlockSetDirection(block, UI_RIGHT);
311         uiTextBoundsBlock(block, 60);
312         uiEndBlock(C, block);
313         
314         return block;
315 }
316 static uiBlock *node_add_distortmenu(bContext *C, ARegion *ar, void *arg_unused)
317 {
318         uiBlock *block;
319         
320         block= uiBeginBlock(C, ar, "node_add_distortmenu", UI_EMBOSSP);
321         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
322         
323         node_make_addmenu(C, NODE_CLASS_DISTORT, block);
324         
325         uiBlockSetDirection(block, UI_RIGHT);
326         uiTextBoundsBlock(block, 60);
327         uiEndBlock(C, block);
328         
329         return block;
330 }
331 static uiBlock *node_add_patternmenu(bContext *C, ARegion *ar,  void *arg_unused)
332 {
333         uiBlock *block;
334         
335         block= uiBeginBlock(C, ar, "node_add_patternmenu", UI_EMBOSSP);
336         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
337         
338         node_make_addmenu(C, NODE_CLASS_PATTERN, block);
339         
340         uiBlockSetDirection(block, UI_RIGHT);
341         uiTextBoundsBlock(block, 60);
342         uiEndBlock(C, block);
343         
344         return block;
345 }
346 static uiBlock *node_add_texturemenu(bContext *C, ARegion *ar, void *arg_unused)
347 {
348         uiBlock *block;
349         
350         block= uiBeginBlock(C, ar, "node_add_texturemenu", UI_EMBOSSP);
351         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
352         
353         node_make_addmenu(C, NODE_CLASS_TEXTURE, block);
354         
355         uiBlockSetDirection(block, UI_RIGHT);
356         uiTextBoundsBlock(block, 60);
357         uiEndBlock(C, block);
358         
359         return block;
360 }
361 static uiBlock *node_add_groupmenu(bContext *C, ARegion *ar, void *arg_unused)
362 {
363         uiBlock *block;
364         
365         block= uiBeginBlock(C, ar, "node_add_groupmenu", UI_EMBOSSP);
366         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
367         
368         node_make_addmenu(C, NODE_CLASS_GROUP, block);
369         
370         uiBlockSetDirection(block, UI_RIGHT);
371         uiTextBoundsBlock(block, 60);
372         uiEndBlock(C, block);
373         
374         return block;
375 }
376
377 static uiBlock *node_add_dynamicmenu(bContext *C, ARegion *ar, void *arg_unused)
378 {
379         uiBlock *block;
380         
381         block= uiBeginBlock(C, ar, "node_add_dynamicmenu", UI_EMBOSSP);
382         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
383         
384         node_make_addmenu(C, NODE_CLASS_OP_DYNAMIC, block);
385         
386         uiBlockSetDirection(block, UI_RIGHT);
387         uiTextBoundsBlock(block, 60);
388         uiEndBlock(C, block);
389         
390         return block;
391 }
392
393 static uiBlock *node_addmenu(bContext *C, ARegion *ar, void *arg_unused)
394 {
395         ScrArea *curarea= CTX_wm_area(C);
396         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
397         uiBlock *block;
398         short yco= 0, menuwidth=120;
399         
400         block= uiBeginBlock(C, ar, "node_addmenu", UI_EMBOSSP);
401         uiBlockSetButmFunc(block, do_node_addmenu, NULL);
402         
403         if(snode->treetype==NTREE_SHADER) {
404                 uiDefIconTextBlockBut(block, node_add_inputmenu, NULL, ICON_RIGHTARROW_THIN, "Input", 0, yco-=20, 120, 19, "");
405                 uiDefIconTextBlockBut(block, node_add_outputmenu, NULL, ICON_RIGHTARROW_THIN, "Output", 0, yco-=20, 120, 19, "");
406                 uiDefIconTextBlockBut(block, node_add_colormenu, NULL, ICON_RIGHTARROW_THIN, "Color", 0, yco-=20, 120, 19, "");
407                 uiDefIconTextBlockBut(block, node_add_vectormenu, NULL, ICON_RIGHTARROW_THIN, "Vector", 0, yco-=20, 120, 19, "");
408                 uiDefIconTextBlockBut(block, node_add_convertermenu, NULL, ICON_RIGHTARROW_THIN, "Convertor", 0, yco-=20, 120, 19, "");
409                 uiDefIconTextBlockBut(block, node_add_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Group", 0, yco-=20, 120, 19, "");
410                 uiDefIconTextBlockBut(block, node_add_dynamicmenu, NULL, ICON_RIGHTARROW_THIN, "Dynamic", 0, yco-=20, 120, 19, "");
411         }
412         else if(snode->treetype==NTREE_COMPOSIT) {
413                 uiDefIconTextBlockBut(block, node_add_inputmenu, NULL, ICON_RIGHTARROW_THIN, "Input", 0, yco-=20, 120, 19, "");
414                 uiDefIconTextBlockBut(block, node_add_outputmenu, NULL, ICON_RIGHTARROW_THIN, "Output", 0, yco-=20, 120, 19, "");
415                 uiDefIconTextBlockBut(block, node_add_colormenu, NULL, ICON_RIGHTARROW_THIN, "Color", 0, yco-=20, 120, 19, "");
416                 uiDefIconTextBlockBut(block, node_add_vectormenu, NULL, ICON_RIGHTARROW_THIN, "Vector", 0, yco-=20, 120, 19, "");
417                 uiDefIconTextBlockBut(block, node_add_filtermenu, NULL, ICON_RIGHTARROW_THIN, "Filter", 0, yco-=20, 120, 19, "");
418                 uiDefIconTextBlockBut(block, node_add_convertermenu, NULL, ICON_RIGHTARROW_THIN, "Convertor", 0, yco-=20, 120, 19, "");
419                 uiDefIconTextBlockBut(block, node_add_mattemenu, NULL, ICON_RIGHTARROW_THIN, "Matte", 0, yco-=20, 120, 19, "");
420                 uiDefIconTextBlockBut(block, node_add_distortmenu, NULL, ICON_RIGHTARROW_THIN, "Distort", 0, yco-=20, 120, 19, "");
421                 uiDefIconTextBlockBut(block, node_add_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Group", 0, yco-=20, 120, 19, "");
422
423         } else if(snode->treetype==NTREE_TEXTURE) {
424                 uiDefIconTextBlockBut(block, node_add_inputmenu, NULL, ICON_RIGHTARROW_THIN, "Input", 0, yco-=20, 120, 19, "");
425                 uiDefIconTextBlockBut(block, node_add_outputmenu, NULL, ICON_RIGHTARROW_THIN, "Output", 0, yco-=20, 120, 19, "");
426                 uiDefIconTextBlockBut(block, node_add_colormenu, NULL, ICON_RIGHTARROW_THIN, "Color", 0, yco-=20, 120, 19, "");
427                 uiDefIconTextBlockBut(block, node_add_patternmenu, NULL, ICON_RIGHTARROW_THIN, "Patterns", 0, yco-=20, 120, 19, "");
428                 uiDefIconTextBlockBut(block, node_add_texturemenu, NULL, ICON_RIGHTARROW_THIN, "Textures", 0, yco-=20, 120, 19, "");
429                 uiDefIconTextBlockBut(block, node_add_convertermenu, NULL, ICON_RIGHTARROW_THIN, "Convertor", 0, yco-=20, 120, 19, "");
430                 uiDefIconTextBlockBut(block, node_add_distortmenu, NULL, ICON_RIGHTARROW_THIN, "Distort", 0, yco-=20, 120, 19, "");
431                 uiDefIconTextBlockBut(block, node_add_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Group", 0, yco-=20, 120, 19, "");
432         }
433         else
434                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); 
435         
436         if(curarea->headertype==HEADERTOP) {
437                 uiBlockSetDirection(block, UI_DOWN);
438         }
439         else {
440                 uiBlockSetDirection(block, UI_TOP);
441                 uiBlockFlipOrder(block);
442         }
443         
444         uiTextBoundsBlock(block, 50);
445         
446         return block;
447 }
448
449 static void do_node_nodemenu(bContext *C, void *arg, int event)
450 {
451         ScrArea *curarea= CTX_wm_area(C);
452         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C); 
453         int fromlib=0;
454         
455         /* functions in editnode.c assume there's a tree */
456         if(snode->nodetree==NULL)
457                 return;
458         fromlib= (snode->id && snode->id->lib);
459         
460         switch(event) {
461                 case 1: /* grab/move */
462                         // XXX node_transform_ext(0,0);
463                         break;
464                 case 2: /* duplicate */
465                         if(fromlib) fromlib= -1;
466                         else ; // XXX node_adduplicate(snode);
467                         break;
468                 case 3: /* delete */
469                         if(fromlib) fromlib= -1;
470                         else ; // XXX node_delete(snode);
471                         break;
472                 case 4: /* make group */
473                         // XXX node_make_group(snode);
474                         break;
475                 case 5: /* ungroup */
476                         // XXX node_ungroup(snode);
477                         break;
478                 case 6: /* edit group */
479                         if(fromlib) fromlib= -1;
480                         else ; // XXX snode_make_group_editable(snode, NULL);
481                         break;
482                 case 7: /* hide/unhide */
483                         // XXX node_hide(snode);
484                         break;
485                 case 8: /* read saved render layers */
486                         // XXX node_read_renderlayers(snode);
487                         break;
488                 case 9: /* show cyclic */
489                         // XXX ntreeSolveOrder(snode->edittree);
490                         break;
491                 case 10: /* execute */
492                         // XXXX addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
493                         break;
494                 case 11: /* make link */
495                         // XXX node_make_link(snode);
496                         break;
497                 case 12: /* rename */
498                         // XXX node_rename(snode);
499                         break;
500                 case 13: /* read saved full sample layers */
501                         // XXX node_read_fullsamplelayers(snode);
502                         break;
503                 case 14: /* connect viewer */
504                         // XXX node_active_link_viewer(snode);
505                         break;
506                         
507         }
508         
509         // XXX if(fromlib==-1) error_libdata();
510         
511         ED_area_tag_redraw(curarea);
512 }
513
514 static uiBlock *node_nodemenu(bContext *C, ARegion *ar, void *arg_unused)
515 {
516         ScrArea *curarea= CTX_wm_area(C);
517         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
518         uiBlock *block;
519         short yco= 0, menuwidth=120;
520         
521         block= uiBeginBlock(C, ar, "node_nodemenu", UI_EMBOSSP);
522         uiBlockSetButmFunc(block, do_node_nodemenu, NULL);
523         
524         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
525         
526         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
527         
528         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
529         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
530         
531         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
532
533         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Link|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
534
535         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
536         
537         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
538         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ungroup|Alt G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
539         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Edit Group|Tab", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
540         
541         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
542         
543         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide/Unhide|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
544         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
545         
546         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
547         
548         if(snode->treetype==NTREE_COMPOSIT) {
549                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Execute Composite|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
550                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Read Saved Render Results|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
551                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Read Saved Full Sample Results|Shift R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
552                 
553                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
554                 
555                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Connect Node to Viewer|Ctrl RMB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
556                 
557                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
558         }
559         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Cyclic Dependencies|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
560         
561         if(curarea->headertype==HEADERTOP) {
562                 uiBlockSetDirection(block, UI_DOWN);
563         }
564         else {
565                 uiBlockSetDirection(block, UI_TOP);
566                 uiBlockFlipOrder(block);
567         }
568         
569         uiTextBoundsBlock(block, 50);
570         uiEndBlock(C, block);
571         
572         return block;
573 }
574
575 static void do_node_viewmenu(bContext *C, void *arg, int event)
576 {
577 //      SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
578 //      ARegion *ar= CTX_wm_region(C);
579         ScrArea *sa= CTX_wm_area(C);
580         
581         switch(event) {
582                 case 1: /* Zoom in */
583                         WM_operator_name_call(C, "VIEW2D_OT_zoom_in", WM_OP_EXEC_REGION_WIN, NULL);
584                         break;
585                 case 2: /* View all */
586                         WM_operator_name_call(C, "VIEW2D_OT_zoom_out", WM_OP_EXEC_REGION_WIN, NULL);
587                         break;
588                 case 3: /* View all */
589                         WM_operator_name_call(C, "NODE_OT_view_all", WM_OP_EXEC_REGION_WIN, NULL);
590                         break;
591                 case 4: /* Grease Pencil */
592                         // XXX add_blockhandler(sa, NODES_HANDLER_GREASEPENCIL, UI_PNL_UNSTOW);
593                         break;
594         }
595         ED_area_tag_redraw(sa);
596 }
597
598 static uiBlock *node_viewmenu(bContext *C, ARegion *ar, void *arg_unused)
599 {
600         ScrArea *curarea= CTX_wm_area(C);
601         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
602         uiBlock *block;
603         short yco= 0, menuwidth=120;
604         
605         block= uiBeginBlock(C, ar, "node_viewmenu", UI_EMBOSSP);
606         uiBlockSetButmFunc(block, do_node_viewmenu, NULL);
607
608         if (snode->nodetree) {
609                 uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Grease Pencil...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
610                 
611                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
612         }
613         
614         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom In|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
615         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom Out|NumPad -", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
616         
617         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
618         
619         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
620         
621         /* XXX if (!curarea->full) 
622                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
623         else 
624                 uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
625         */
626         if(curarea->headertype==HEADERTOP) {
627                 uiBlockSetDirection(block, UI_DOWN);
628         }
629         else {
630                 uiBlockSetDirection(block, UI_TOP);
631                 uiBlockFlipOrder(block);
632         }
633         
634         uiTextBoundsBlock(block, 50);
635         uiEndBlock(C, block);
636         
637         return block;
638 }
639
640 static void do_node_buttons(bContext *C, void *arg, int event)
641 {
642         // NODE_FIX_ME : instead of using "current material/texture/scene", node editor can also pin context?
643         // note: scene context better not gets overridden, that'll clash too much (ton)
644         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
645         Scene *scene= CTX_data_scene(C);
646         Material *ma;
647         Tex *tx;
648         
649         switch(event) {
650                 case B_REDR:
651                         ED_area_tag_redraw(CTX_wm_area(C));                     
652                         break;
653                 case B_NODE_USEMAT:
654                         ma= (Material *)snode->id;
655                         if(ma) {
656                                 if(ma->use_nodes && ma->nodetree==NULL) {
657                                         node_shader_default(ma);
658                                         snode_set_context(snode, scene);
659                                 }
660                         }               
661                         ED_area_tag_redraw(CTX_wm_area(C));                     
662                         break;
663                         
664                 case B_NODE_USESCENE:
665                         if(scene->use_nodes) {
666                                 if(scene->nodetree==NULL)
667                                         node_composit_default(scene);
668                         }
669                         snode_set_context(snode, scene);
670                         ED_area_tag_redraw(CTX_wm_area(C));                     
671                         break;
672                         
673                 case B_NODE_USETEX:
674                         tx = (Tex *)snode->id;
675                         if(tx) {
676                                 tx->type = 0;
677                                 if(tx->use_nodes && tx->nodetree==NULL) {
678                                         node_texture_default(tx);
679                                         snode_set_context(snode, scene);
680                                 }
681                         }
682                         ED_area_tag_redraw(CTX_wm_area(C));                     
683                         break;
684         }
685 }
686
687 void node_header_buttons(const bContext *C, ARegion *ar)
688 {
689         ScrArea *sa= CTX_wm_area(C);
690         SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
691         Scene *scene= CTX_data_scene(C);
692         uiBlock *block;
693         short xco, yco= 3;
694         
695         block= uiBeginBlock(C, ar, "header node", UI_EMBOSS);
696         uiBlockSetHandleFunc(block, do_node_buttons, NULL);
697         
698         xco= ED_area_header_standardbuttons(C, block, yco);
699         
700         if((sa->flag & HEADER_NO_PULLDOWN)==0) {
701                 int xmax;
702         
703                 xmax= GetButStringLength("View");
704                 uiDefPulldownBut(block, node_viewmenu, NULL, 
705                                           "View", xco, yco, xmax-3, 20, "");
706                 xco+= xmax;
707                 
708                 xmax= GetButStringLength("Select");
709                 uiDefPulldownBut(block, node_selectmenu, NULL, 
710                                                  "Select", xco, yco, xmax-3, 20, "");
711                 xco+= xmax;
712                 
713                 xmax= GetButStringLength("Add");
714                 uiDefPulldownBut(block, node_addmenu, NULL, 
715                                                  "Add", xco, yco, xmax-3, 20, "");
716                 xco+= xmax;
717                 
718                 xmax= GetButStringLength("Node");
719                 uiDefPulldownBut(block, node_nodemenu, NULL, 
720                                                  "Node", xco, yco, xmax-3, 20, "");
721                 xco+= xmax;
722         }
723         
724         uiBlockSetEmboss(block, UI_EMBOSS);
725
726         uiBlockSetEmboss(block, UI_EMBOSS);
727         
728         /* main type choosing */
729         uiBlockBeginAlign(block);
730         uiDefIconButI(block, ROW, B_REDR, ICON_MATERIAL_DATA, xco,yco,XIC,YIC-2,
731                                   &(snode->treetype), 2.0f, 0.0f, 0.0f, 0.0f, "Material Nodes");
732         xco+= XIC;
733         uiDefIconButI(block, ROW, B_REDR, ICON_IMAGE_DATA, xco,yco,XIC,YIC-2,
734                                   &(snode->treetype), 2.0f, 1.0f, 0.0f, 0.0f, "Composite Nodes");
735         xco+= XIC;
736         uiDefIconButI(block, ROW, B_REDR, ICON_TEXTURE_DATA, xco,yco,XIC,YIC-2,
737                                   &(snode->treetype), 2.0f, 2.0f, 0.0f, 0.0f, "Texture Nodes");
738         xco+= 2*XIC;
739         uiBlockEndAlign(block);
740
741         /* find and set the context */
742         snode_set_context(snode, scene);
743         
744         if(snode->treetype==NTREE_SHADER) {
745                 if(snode->from) {
746                                                                                 /* 0, NULL -> pin */
747                         // XXX xco= std_libbuttons(block, xco, 0, 0, NULL, B_MATBROWSE, ID_MA, 1, snode->id, snode->from, &(snode->menunr), 
748                         //   B_MATALONE, B_MATLOCAL, B_MATDELETE, B_AUTOMATNAME, B_KEEPDATA);
749                         
750                         if(snode->id) {
751                                 Material *ma= (Material *)snode->id;
752                                 uiDefButC(block, TOG, B_NODE_USEMAT, "Use Nodes", xco+5,yco,90,19, &ma->use_nodes, 0.0f, 0.0f, 0, 0, "");
753                                 xco+=80;
754                         }
755                 }
756         }
757         else if(snode->treetype==NTREE_COMPOSIT) {
758                 int icon;
759                 
760                 if(WM_jobs_test(CTX_wm_manager(C), sa)) icon= ICON_REC; else icon= ICON_BLANK1;
761                 uiDefIconTextButS(block, TOG, B_NODE_USESCENE, icon, "Use Nodes", xco+5,yco,100,19, &scene->use_nodes, 0.0f, 0.0f, 0, 0, "Indicate this Scene will use Nodes and execute them while editing");
762                 xco+= 100;
763                 uiDefButBitI(block, TOG, R_COMP_FREE, B_NOP, "Free Unused", xco+5,yco,100,19, &scene->r.scemode, 0.0f, 0.0f, 0, 0, "Free Nodes that are not used while composite");
764                 xco+= 100;
765                 uiDefButBitS(block, TOG, SNODE_BACKDRAW, B_REDR, "Backdrop", xco+5,yco,90,19, &snode->flag, 0.0f, 0.0f, 0, 0, "Use active Viewer Node output as backdrop");
766                 xco+= 90;
767         }
768         else if(snode->treetype==NTREE_TEXTURE) {
769                 if(snode->from) {
770                         
771                         // XXX xco= std_libbuttons(block, xco, 0, 0, NULL, B_TEXBROWSE, ID_TE, 1, snode->id, snode->from, &(snode->menunr), 
772                         //                 B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA);
773                         
774                         if(snode->id) {
775                                 Tex *tx= (Tex *)snode->id;
776                                 uiDefButC(block, TOG, B_NODE_USETEX, "Use Nodes", xco+5,yco,90,19, &tx->use_nodes, 0.0f, 0.0f, 0, 0, "");
777                                 xco+=80;
778                         }
779                 }
780         }
781         
782         UI_view2d_totRect_set(&ar->v2d, xco+XIC+100, (int)(ar->v2d.tot.ymax-ar->v2d.tot.ymin));
783         
784         uiEndBlock(C, block);
785         uiDrawBlock(C, block);
786 }
787
788