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