# ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### # import bpy from bpy.types import Operator from bpy.props import (EnumProperty, FloatVectorProperty, StringProperty, CollectionProperty ) # XXX These node item lists should actually be generated by a callback at operator execution time (see node_type_items below), # using the active node tree from the context. Due to a difficult bug in bpy this is not possible (item list memory gets freed too early), # so for now just copy the static item lists to these global variables. # # In the custom_nodes branch, the static per-tree-type node items are replaced by a single independent type list anyway (with a poll function # to limit node types to the respective trees). So this workaround is only temporary. node_type_items_dict = {} node_type_items_dict['SHADER'] = [(item.identifier, item.name, item.description, item.value) for item in bpy.types.ShaderNode.bl_rna.properties['type'].enum_items] node_type_items_dict['COMPOSITING'] = [(item.identifier, item.name, item.description, item.value) for item in bpy.types.CompositorNode.bl_rna.properties['type'].enum_items] node_type_items_dict['TEXTURE'] = [(item.identifier, item.name, item.description, item.value) for item in bpy.types.TextureNode.bl_rna.properties['type'].enum_items] # Returns the enum item list for the edited tree in the context def node_type_items(self, context): snode = context.space_data if not snode: return [] tree = snode.edit_tree if not tree: return [] # XXX Does not work correctly, see comment above #return [(item.identifier, item.name, item.description, item.value) for item in tree.nodes.bl_rna.functions['new'].parameters['type'].enum_items] if tree.type in node_type_items_dict: return node_type_items_dict[tree.type] else: return [] class NODE_OT_add_search(bpy.types.Operator): '''Add a node to the active tree''' bl_idname = "node.add_search" bl_label = "Search and Add Node" bl_options = {'REGISTER', 'UNDO'} # XXX this should be called 'node_type' but the operator search property is hardcoded to 'type' by a hack in bpy_operator_wrap.c ... type = EnumProperty(items=node_type_items, name="Node Type", description="Node type") def create_node(self, context): space = context.space_data tree = space.edit_tree node = tree.nodes.new(type=self.type) for n in tree.nodes: if n==node: node.select = True tree.nodes.active = node else: node.select = False node.location = space.cursor_location return node @classmethod def poll(cls, context): space = context.space_data # needs active node editor and a tree to add nodes to return space.type == 'NODE_EDITOR' and space.edit_tree def execute(self, context): self.create_node(context) return {'FINISHED'} def invoke(self, context, event): space = context.space_data v2d = context.region.view2d # convert mouse position to the View2D for later node placement space.cursor_location = v2d.region_to_view(event.mouse_region_x, event.mouse_region_y) context.window_manager.invoke_search_popup(self) return {'CANCELLED'}