Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * 00022 * Contributor(s): Blender Foundation 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <string.h> 00033 #include <stdio.h> 00034 00035 #include "DNA_space_types.h" 00036 #include "DNA_node_types.h" 00037 #include "DNA_scene_types.h" 00038 #include "DNA_screen_types.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_utildefines.h" 00044 00045 #include "BLF_translation.h" 00046 00047 #include "BKE_context.h" 00048 #include "BKE_global.h" 00049 #include "BKE_main.h" 00050 #include "BKE_node.h" 00051 #include "BKE_scene.h" 00052 #include "BKE_screen.h" 00053 00054 #include "RNA_access.h" 00055 00056 #include "WM_api.h" 00057 #include "WM_types.h" 00058 00059 #include "UI_interface.h" 00060 #include "UI_interface_icons.h" 00061 #include "UI_resources.h" 00062 #include "UI_view2d.h" 00063 00064 #include "node_intern.h" 00065 00066 /* ************************ add menu *********************** */ 00067 00068 static void do_node_add(bContext *C, bNodeTemplate *ntemp) 00069 { 00070 Main *bmain= CTX_data_main(C); 00071 Scene *scene= CTX_data_scene(C); 00072 SpaceNode *snode= CTX_wm_space_node(C); 00073 ScrArea *sa= CTX_wm_area(C); 00074 ARegion *ar; 00075 bNode *node; 00076 00077 /* get location to add node at mouse */ 00078 for(ar=sa->regionbase.first; ar; ar=ar->next) { 00079 if(ar->regiontype == RGN_TYPE_WINDOW) { 00080 wmWindow *win= CTX_wm_window(C); 00081 int x= win->eventstate->x - ar->winrct.xmin; 00082 int y= win->eventstate->y - ar->winrct.ymin; 00083 00084 if(y < 60) y+= 60; 00085 UI_view2d_region_to_view(&ar->v2d, x, y, &snode->mx, &snode->my); 00086 } 00087 } 00088 00089 /* store selection in temp test flag */ 00090 for(node= snode->edittree->nodes.first; node; node= node->next) { 00091 if(node->flag & NODE_SELECT) node->flag |= NODE_TEST; 00092 else node->flag &= ~NODE_TEST; 00093 } 00094 00095 /* node= */ node_add_node(snode, bmain, scene, ntemp, snode->mx, snode->my); 00096 00097 /* select previous selection before autoconnect */ 00098 for(node= snode->edittree->nodes.first; node; node= node->next) { 00099 if(node->flag & NODE_TEST) node->flag |= NODE_SELECT; 00100 } 00101 00102 /* deselect after autoconnection */ 00103 for(node= snode->edittree->nodes.first; node; node= node->next) { 00104 if(node->flag & NODE_TEST) node->flag &= ~NODE_SELECT; 00105 } 00106 00107 snode_notify(C, snode); 00108 snode_dag_update(C, snode); 00109 } 00110 00111 static void do_node_add_static(bContext *C, void *UNUSED(arg), int event) 00112 { 00113 bNodeTemplate ntemp; 00114 ntemp.type = event; 00115 do_node_add(C, &ntemp); 00116 } 00117 00118 static void do_node_add_group(bContext *C, void *UNUSED(arg), int event) 00119 { 00120 SpaceNode *snode= CTX_wm_space_node(C); 00121 bNodeTemplate ntemp; 00122 00123 if (event>=0) { 00124 ntemp.ngroup= BLI_findlink(&G.main->nodetree, event); 00125 ntemp.type = ntemp.ngroup->nodetype; 00126 } 00127 else { 00128 ntemp.type = -event; 00129 switch (ntemp.type) { 00130 case NODE_GROUP: 00131 ntemp.ngroup = ntreeAddTree("Group", snode->treetype, ntemp.type); 00132 break; 00133 case NODE_FORLOOP: 00134 ntemp.ngroup = ntreeAddTree("For Loop", snode->treetype, ntemp.type); 00135 break; 00136 case NODE_WHILELOOP: 00137 ntemp.ngroup = ntreeAddTree("While Loop", snode->treetype, ntemp.type); 00138 break; 00139 default: 00140 ntemp.ngroup = NULL; 00141 } 00142 } 00143 if (!ntemp.ngroup) 00144 return; 00145 00146 do_node_add(C, &ntemp); 00147 } 00148 00149 #if 0 /* disabled */ 00150 static void do_node_add_dynamic(bContext *C, void *UNUSED(arg), int event) 00151 { 00152 bNodeTemplate ntemp; 00153 ntemp.type = NODE_DYNAMIC; 00154 do_node_add(C, &ntemp); 00155 } 00156 #endif 00157 00158 static int node_tree_has_type(int treetype, int nodetype) 00159 { 00160 bNodeTreeType *ttype= ntreeGetType(treetype); 00161 bNodeType *ntype; 00162 for (ntype=ttype->node_types.first; ntype; ntype=ntype->next) { 00163 if (ntype->type==nodetype) 00164 return 1; 00165 } 00166 return 0; 00167 } 00168 00169 static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) 00170 { 00171 Main *bmain= CTX_data_main(C); 00172 Scene *scene= CTX_data_scene(C); 00173 SpaceNode *snode= CTX_wm_space_node(C); 00174 bNodeTree *ntree; 00175 int nodeclass= GET_INT_FROM_POINTER(arg_nodeclass); 00176 int event, compatibility= 0; 00177 00178 ntree = snode->nodetree; 00179 00180 if(!ntree) { 00181 uiItemS(layout); 00182 return; 00183 } 00184 00185 if(ntree->type == NTREE_SHADER) { 00186 if(scene_use_new_shading_nodes(scene)) 00187 compatibility= NODE_NEW_SHADING; 00188 else 00189 compatibility= NODE_OLD_SHADING; 00190 } 00191 00192 if (nodeclass==NODE_CLASS_GROUP) { 00193 bNodeTree *ngroup; 00194 00195 uiLayoutSetFunc(layout, do_node_add_group, NULL); 00196 00197 /* XXX hack: negative numbers used for empty group types */ 00198 if (node_tree_has_type(ntree->type, NODE_GROUP)) 00199 uiItemV(layout, "New Group", 0, -NODE_GROUP); 00200 if (node_tree_has_type(ntree->type, NODE_FORLOOP)) 00201 uiItemV(layout, "New For Loop", 0, -NODE_FORLOOP); 00202 if (node_tree_has_type(ntree->type, NODE_WHILELOOP)) 00203 uiItemV(layout, "New While Loop", 0, -NODE_WHILELOOP); 00204 uiItemS(layout); 00205 00206 for(ngroup=bmain->nodetree.first, event=0; ngroup; ngroup= ngroup->id.next, ++event) { 00207 /* only use group trees */ 00208 if (ngroup->type==ntree->type && ELEM3(ngroup->nodetype, NODE_GROUP, NODE_FORLOOP, NODE_WHILELOOP)) { 00209 uiItemV(layout, ngroup->id.name+2, 0, event); 00210 } 00211 } 00212 } 00213 else if (nodeclass==NODE_DYNAMIC) { 00214 /* disabled */ 00215 } 00216 else { 00217 bNodeType *ntype; 00218 00219 uiLayoutSetFunc(layout, do_node_add_static, NULL); 00220 00221 for (ntype=ntreeGetType(ntree->type)->node_types.first; ntype; ntype=ntype->next) { 00222 if (ntype->nclass==nodeclass && ntype->name) 00223 if (!compatibility || (ntype->compatibility & compatibility)) 00224 uiItemV(layout, ntype->name, 0, ntype->type); 00225 } 00226 } 00227 } 00228 00229 static void node_menu_add_foreach_cb(void *calldata, int nclass, const char *name) 00230 { 00231 uiLayout *layout= calldata; 00232 uiItemMenuF(layout, name, 0, node_add_menu, SET_INT_IN_POINTER(nclass)); 00233 } 00234 00235 static void node_menu_add(const bContext *C, Menu *menu) 00236 { 00237 Scene *scene= CTX_data_scene(C); 00238 SpaceNode *snode= CTX_wm_space_node(C); 00239 uiLayout *layout= menu->layout; 00240 bNodeTreeType *ntreetype= ntreeGetType(snode->treetype); 00241 00242 if(!snode->nodetree) 00243 uiLayoutSetActive(layout, 0); 00244 00245 if(ntreetype && ntreetype->foreach_nodeclass) 00246 ntreetype->foreach_nodeclass(scene, layout, node_menu_add_foreach_cb); 00247 } 00248 00249 void node_menus_register(void) 00250 { 00251 MenuType *mt; 00252 00253 mt= MEM_callocN(sizeof(MenuType), "spacetype node menu add"); 00254 strcpy(mt->idname, "NODE_MT_add"); 00255 strcpy(mt->label, "Add"); 00256 mt->draw= node_menu_add; 00257 WM_menutype_add(mt); 00258 } 00259