diff options
-rw-r--r-- | release/scripts/modules/nodeitems_utils.py | 13 | ||||
-rw-r--r-- | release/scripts/startup/bl_operators/node.py | 107 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_node.py | 1 |
3 files changed, 55 insertions, 66 deletions
diff --git a/release/scripts/modules/nodeitems_utils.py b/release/scripts/modules/nodeitems_utils.py index 3fbafc3ae9b..b58207d7c65 100644 --- a/release/scripts/modules/nodeitems_utils.py +++ b/release/scripts/modules/nodeitems_utils.py @@ -114,6 +114,19 @@ def register_node_categories(identifier, cat_list): _node_categories[identifier] = (cat_list, draw_add_menu, menu_types, panel_types) +def node_categories_iter(context): + for cat_type in _node_categories.values(): + for cat in cat_type[0]: + if cat.poll and cat.poll(context): + yield cat + + +def node_items_iter(context): + for cat in node_categories_iter(context): + for item in cat.items(context): + yield item + + def unregister_node_cat_types(cats): bpy.types.NODE_MT_add.remove(cats[1]) for mt in cats[2]: diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index 39d701a8f25..c7081b6b5c1 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -18,7 +18,7 @@ # <pep8-80 compliant> -import bpy +import bpy, nodeitems_utils from bpy.types import Operator, PropertyGroup from bpy.props import BoolProperty, CollectionProperty, EnumProperty, IntProperty, StringProperty @@ -62,15 +62,20 @@ class NodeAddOperator(): else: space.cursor_location = tree.view_center - def create_node(self, context): + # XXX explicit node_type argument is usually not necessary, but required to make search operator work: + # add_search has to override the 'type' property since it's hardcoded in bpy_operator_wrap.c ... + def create_node(self, context, node_type=None): space = context.space_data tree = space.edit_tree + if node_type is None: + node_type = self.type + # select only the new node for n in tree.nodes: n.select = False - node = tree.nodes.new(type=self.type) + node = tree.nodes.new(type=node_type) for setting in self.settings: # XXX catch exceptions here? @@ -151,83 +156,53 @@ class NODE_OT_add_and_link_node(NodeAddOperator, Operator): return {'FINISHED'} -def node_classes_iter(base=bpy.types.Node): - """ - Yields all true node classes by checking for the is_registered_node_type classmethod. - Node types can use specialized subtypes of bpy.types.Node, which are not usable - nodes themselves (e.g. CompositorNode). - """ - if base.is_registered_node_type(): - yield base - for subclass in base.__subclasses__(): - for node_class in node_classes_iter(subclass): - yield node_class - - -def node_class_items_iter(node_class, context): - identifier = node_class.bl_rna.identifier - # XXX Checking for explicit group node types is stupid. - # This should be replaced by a generic system of generating - # node items via callback. - # Group node_tree pointer should also use a poll function to filter the library list, - # but cannot do that without a node instance here. A node callback could just use the internal poll function. - if identifier in {'ShaderNodeGroup', 'CompositorNodeGroup', 'TextureNodeGroup'}: - tree_idname = context.space_data.edit_tree.bl_idname - for group in bpy.data.node_groups: - if group.bl_idname == tree_idname: - # XXX empty string should be replaced by description from tree - yield (group.name, "", {"node_tree": group}) - else: - yield (node_class.bl_rna.name, node_class.bl_rna.description, {}) - - -def node_items_iter(context): - snode = context.space_data - if not snode: - return - tree = snode.edit_tree - if not tree: - return - - for node_class in node_classes_iter(): - if node_class.poll(tree): - for item in node_class_items_iter(node_class, context): - yield (node_class,) + item - - -# Create an enum list from node class items -def node_type_items_cb(self, context): - # XXX Python has to keep a ref to those strings, else they may be freed :( - NODE_OT_add_search._enum_str_store = [(str(index), item[1], item[2]) - for index, item in enumerate(node_items_iter(context))] - return NODE_OT_add_search._enum_str_store - - class NODE_OT_add_search(NodeAddOperator, Operator): '''Add a node to the active tree''' bl_idname = "node.add_search" bl_label = "Search and Add Node" bl_options = {'REGISTER', 'UNDO'} - # XXX Python has to keep a ref to the data (strings) generated by enum's callback, else they may be freed :( - _enum_str_store = [] + # Create an enum list from node items + def node_enum_items(self, context): + enum_items = [] + for index, item in enumerate(nodeitems_utils.node_items_iter(context)): + nodetype = getattr(bpy.types, item.nodetype, None) + if nodetype: + enum_items.append((str(index), item.label, nodetype.bl_rna.description, index)) + return enum_items + + # Look up the item based on index + def find_node_item(self, context): + for index, item in enumerate(nodeitems_utils.node_items_iter(context)): + if str(index) == self.type: + return item + return None - # XXX this should be called 'node_type' but the operator search + # XXX this should be called 'node_item' but the operator search # property is hardcoded to 'type' by a hack in bpy_operator_wrap.c ... type = EnumProperty( name="Node Type", description="Node type", - items=node_type_items_cb, + items=node_enum_items, ) def execute(self, context): - for index, item in enumerate(node_items_iter(context)): - if str(index) == self.type: - node = self.create_node(context, item[0].bl_rna.identifier) - for prop, value in item[3].items(): - setattr(node, prop, value) - break - return {'FINISHED'} + item = self.find_node_item(context) + if item: + # apply settings from the node item + for setting in item.settings.items(): + ops = self.settings.add() + ops.name = setting[0] + ops.value = setting[1] + + self.create_node(context, item.nodetype) + + if self.use_transform: + bpy.ops.transform.translate('INVOKE_DEFAULT') + + return {'FINISHED'} + else: + return {'CANCELLED'} def invoke(self, context, event): self.store_mouse_cursor(context, event) diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index f58679e836d..86d53648cc1 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -117,6 +117,7 @@ class NODE_MT_add(bpy.types.Menu): layout.operator_context = 'INVOKE_DEFAULT' op = layout.operator("node.add_search", text="Search ...") + op.use_transform = True # actual node submenus are added by draw functions from node categories |