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