Merge with 2.5 -r 22173:22620.
[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 #include "BKE_utildefines.h"
49
50 #include "ED_screen.h"
51 #include "ED_types.h"
52 #include "ED_util.h"
53
54 #include "WM_api.h"
55 #include "WM_types.h"
56
57 #include "BIF_gl.h"
58 #include "BIF_glutil.h"
59
60 #include "UI_interface.h"
61 #include "UI_resources.h"
62 #include "UI_view2d.h"
63
64 #include "node_intern.h"
65
66 /* ************************ add menu *********************** */
67
68 static void do_node_add(bContext *C, void *arg, int event)
69 {
70         SpaceNode *snode= CTX_wm_space_node(C);
71         bNode *node;
72         
73         /* store selection in temp test flag */
74         for(node= snode->edittree->nodes.first; node; node= node->next) {
75                 if(node->flag & NODE_SELECT) node->flag |= NODE_TEST;
76                 else node->flag &= ~NODE_TEST;
77         }
78         
79         node= node_add_node(snode, CTX_data_scene(C), event, snode->mx, snode->my);
80         
81         /* uses test flag */
82         snode_autoconnect(snode, node, NODE_TEST);
83                 
84         snode_handle_recalc(C, snode);
85 }
86
87 static void node_auto_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass)
88 {
89         Main *bmain= CTX_data_main(C);
90         SpaceNode *snode= CTX_wm_space_node(C);
91         bNodeTree *ntree;
92         int nodeclass= GET_INT_FROM_POINTER(arg_nodeclass);
93         int tot= 0, a;
94         
95         ntree = snode->nodetree;
96
97         if(!ntree) {
98                 uiItemS(layout);
99                 return;
100         }
101
102         /* mostly taken from toolbox.c, node_add_sublevel() */
103         if(nodeclass==NODE_CLASS_GROUP) {
104                 bNodeTree *ngroup= bmain->nodetree.first;
105                 for(; ngroup; ngroup= ngroup->id.next)
106                         if(ngroup->type==ntree->type)
107                                 tot++;
108         }
109         else {
110                 bNodeType *type = ntree->alltypes.first;
111                 while(type) {
112                         if(type->nclass == nodeclass)
113                                 tot++;
114                         type= type->next;
115                 }
116         }       
117         
118         if(tot==0) {
119                 uiItemS(layout);
120                 return;
121         }
122
123         uiLayoutSetFunc(layout, do_node_add, NULL);
124         
125         if(nodeclass==NODE_CLASS_GROUP) {
126                 bNodeTree *ngroup= bmain->nodetree.first;
127
128                 for(tot=0, a=0; ngroup; ngroup= ngroup->id.next, tot++) {
129                         if(ngroup->type==ntree->type) {
130                                 uiItemV(layout, ngroup->id.name+2, 0, NODE_GROUP_MENU+tot);
131                                 a++;
132                         }
133                 }
134         }
135         else {
136                 bNodeType *type;
137                 int script=0;
138
139                 for(a=0, type= ntree->alltypes.first; type; type=type->next) {
140                         if(type->nclass == nodeclass && type->name) {
141                                 if(type->type == NODE_DYNAMIC) {
142                                         uiItemV(layout, type->name, 0, NODE_DYNAMIC_MENU+script);
143                                         script++;
144                                 }
145                                 else
146                                         uiItemV(layout, type->name, 0, type->type);
147
148                                 a++;
149                         }
150                 }
151         }
152 }
153
154 static void node_menu_add(const bContext *C, Menu *menu)
155 {
156         uiLayout *layout= menu->layout;
157         SpaceNode *snode= CTX_wm_space_node(C);
158
159         if(!snode->nodetree)
160                 uiLayoutSetActive(layout, 0);
161
162         if(snode->treetype==NTREE_SHADER) {
163                 uiItemMenuF(layout, "Input", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
164                 uiItemMenuF(layout, "Output", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT));
165                 uiItemMenuF(layout, "Color", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR));
166                 uiItemMenuF(layout, "Vector", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR));
167                 uiItemMenuF(layout, "Convertor", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
168                 uiItemMenuF(layout, "Group", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
169                 uiItemMenuF(layout, "Dynamic", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC));
170         }
171         else if(snode->treetype==NTREE_COMPOSIT) {
172                 uiItemMenuF(layout, "Input", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
173                 uiItemMenuF(layout, "Output", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT));
174                 uiItemMenuF(layout, "Color", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR));
175                 uiItemMenuF(layout, "Vector", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR));
176                 uiItemMenuF(layout, "Filter", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_FILTER));
177                 uiItemMenuF(layout, "Convertor", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
178                 uiItemMenuF(layout, "Matte", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_MATTE));
179                 uiItemMenuF(layout, "Distort", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT));
180                 uiItemMenuF(layout, "Group", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
181         }
182         else if(snode->treetype==NTREE_TEXTURE) {
183                 uiItemMenuF(layout, "Input", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
184                 uiItemMenuF(layout, "Output", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT));
185                 uiItemMenuF(layout, "Color", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR));
186                 uiItemMenuF(layout, "Patterns", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_PATTERN));
187                 uiItemMenuF(layout, "Textures", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE));
188                 uiItemMenuF(layout, "Convertor", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
189                 uiItemMenuF(layout, "Distort", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT));
190                 uiItemMenuF(layout, "Group", 0, node_auto_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
191         }
192 }
193
194 void node_menus_register(ARegionType *art)
195 {
196         MenuType *mt;
197
198         mt= MEM_callocN(sizeof(MenuType), "spacetype node menu add");
199         strcpy(mt->idname, "NODE_MT_add");
200         strcpy(mt->label, "Add");
201         mt->draw= node_menu_add;
202         BLI_addtail(&art->menutypes, mt);
203 }
204
205 #if 0
206 static void do_node_nodemenu(bContext *C, void *arg, int event)
207 {
208         ScrArea *curarea= CTX_wm_area(C);
209         SpaceNode *snode= CTX_wm_space_node(C); 
210         int fromlib=0;
211         
212         /* functions in editnode.c assume there's a tree */
213         if(snode->nodetree==NULL)
214                 return;
215         fromlib= (snode->id && snode->id->lib);
216         
217         switch(event) {
218                 case 1: /* grab/move */
219                         // XXX node_transform_ext(0,0);
220                         break;
221                 case 2: /* duplicate */
222                         if(fromlib) fromlib= -1;
223                         else ; // XXX node_adduplicate(snode);
224                         break;
225                 case 3: /* delete */
226                         if(fromlib) fromlib= -1;
227                         else ; // XXX node_delete(snode);
228                         break;
229                 case 4: /* make group */
230                         // XXX node_make_group(snode);
231                         break;
232                 case 5: /* ungroup */
233                         // XXX node_ungroup(snode);
234                         break;
235                 case 6: /* edit group */
236                         if(fromlib) fromlib= -1;
237                         else ; // XXX snode_make_group_editable(snode, NULL);
238                         break;
239                 case 7: /* hide/unhide */
240                         // XXX node_hide(snode);
241                         break;
242                 case 8: /* read saved render layers */
243                         // XXX node_read_renderlayers(snode);
244                         break;
245                 case 9: /* show cyclic */
246                         // XXX ntreeSolveOrder(snode->edittree);
247                         break;
248                 case 10: /* execute */
249                         // XXXX addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
250                         break;
251                 case 11: /* make link */
252                         // XXX node_make_link(snode);
253                         break;
254                 case 12: /* rename */
255                         // XXX node_rename(snode);
256                         break;
257                 case 13: /* read saved full sample layers */
258                         // XXX node_read_fullsamplelayers(snode);
259                         break;
260                 case 14: /* connect viewer */
261                         // XXX node_active_link_viewer(snode);
262                         break;
263                         
264         }
265         
266         // XXX if(fromlib==-1) error_libdata();
267         
268         ED_area_tag_redraw(curarea);
269 }
270
271 static uiBlock *node_nodemenu(bContext *C, ARegion *ar, void *arg_unused)
272 {
273         ScrArea *curarea= CTX_wm_area(C);
274         SpaceNode *snode= CTX_wm_space_node(C);
275         uiBlock *block;
276         short yco= 0, menuwidth=120;
277         
278         block= uiBeginBlock(C, ar, "node_nodemenu", UI_EMBOSSP);
279         uiBlockSetButmFunc(block, do_node_nodemenu, NULL);
280         
281         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
282         
283         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
284         
285         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
286         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
287         
288         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
289
290         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Link|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
291
292         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
293         
294         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
295         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ungroup|Alt G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
296         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Edit Group|Tab", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
297         
298         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
299         
300         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide/Unhide|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
301         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
302         
303         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
304         
305         if(snode->treetype==NTREE_COMPOSIT) {
306                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Execute Composite|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
307                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Read Saved Render Results|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
308                 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, "");
309                 
310                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
311                 
312                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Connect Node to Viewer|Ctrl RMB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
313                 
314                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
315         }
316         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Cyclic Dependencies|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
317         
318         if(curarea->headertype==HEADERTOP) {
319                 uiBlockSetDirection(block, UI_DOWN);
320         }
321         else {
322                 uiBlockSetDirection(block, UI_TOP);
323                 uiBlockFlipOrder(block);
324         }
325         
326         uiTextBoundsBlock(block, 50);
327         uiEndBlock(C, block);
328         
329         return block;
330 }
331 #endif
332