Moved a couple of common properties into the NodeAddOperator base class to avoid repetitive code. A new operator node_add_and_link is another variant that first creates a node and them connects a specific socket to an existing one (defined by context pointer).
This commit is contained in:
@@ -20,52 +20,7 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.types import Operator, PropertyGroup
|
from bpy.types import Operator, PropertyGroup
|
||||||
from bpy.props import BoolProperty, CollectionProperty, EnumProperty, StringProperty
|
from bpy.props import BoolProperty, CollectionProperty, EnumProperty, IntProperty, StringProperty
|
||||||
|
|
||||||
|
|
||||||
# Base class for node 'Add' operators
|
|
||||||
class NodeAddOperator():
|
|
||||||
@staticmethod
|
|
||||||
def store_mouse_cursor(context, event):
|
|
||||||
space = context.space_data
|
|
||||||
v2d = context.region.view2d
|
|
||||||
tree = space.edit_tree
|
|
||||||
|
|
||||||
# convert mouse position to the View2D for later node placement
|
|
||||||
if context.region.type == 'WINDOW':
|
|
||||||
space.cursor_location = v2d.region_to_view(event.mouse_region_x,
|
|
||||||
event.mouse_region_y)
|
|
||||||
else:
|
|
||||||
space.cursor_location = tree.view_center
|
|
||||||
|
|
||||||
def create_node(self, context, node_type):
|
|
||||||
space = context.space_data
|
|
||||||
tree = space.edit_tree
|
|
||||||
|
|
||||||
# select only the new node
|
|
||||||
for n in tree.nodes:
|
|
||||||
n.select = False
|
|
||||||
|
|
||||||
node = tree.nodes.new(type=node_type)
|
|
||||||
|
|
||||||
if space.use_hidden_preview:
|
|
||||||
node.show_preview = False
|
|
||||||
|
|
||||||
node.select = True
|
|
||||||
tree.nodes.active = node
|
|
||||||
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)
|
|
||||||
|
|
||||||
# Default invoke stores the mouse position to place the node correctly
|
|
||||||
def invoke(self, context, event):
|
|
||||||
self.store_mouse_cursor(context, event)
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
|
|
||||||
class NodeSetting(PropertyGroup):
|
class NodeSetting(PropertyGroup):
|
||||||
@@ -75,11 +30,8 @@ class NodeSetting(PropertyGroup):
|
|||||||
default="",
|
default="",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Simple basic operator for adding a node
|
# Base class for node 'Add' operators
|
||||||
class NODE_OT_add_node(NodeAddOperator, Operator):
|
class NodeAddOperator():
|
||||||
'''Add a node to the active tree'''
|
|
||||||
bl_idname = "node.add_node"
|
|
||||||
bl_label = "Add Node"
|
|
||||||
|
|
||||||
type = StringProperty(
|
type = StringProperty(
|
||||||
name="Node Type",
|
name="Node Type",
|
||||||
@@ -96,8 +48,28 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
|
|||||||
type=NodeSetting,
|
type=NodeSetting,
|
||||||
)
|
)
|
||||||
|
|
||||||
def execute(self, context):
|
@staticmethod
|
||||||
node = self.create_node(context, self.type)
|
def store_mouse_cursor(context, event):
|
||||||
|
space = context.space_data
|
||||||
|
v2d = context.region.view2d
|
||||||
|
tree = space.edit_tree
|
||||||
|
|
||||||
|
# convert mouse position to the View2D for later node placement
|
||||||
|
if context.region.type == 'WINDOW':
|
||||||
|
space.cursor_location = v2d.region_to_view(event.mouse_region_x,
|
||||||
|
event.mouse_region_y)
|
||||||
|
else:
|
||||||
|
space.cursor_location = tree.view_center
|
||||||
|
|
||||||
|
def create_node(self, context):
|
||||||
|
space = context.space_data
|
||||||
|
tree = space.edit_tree
|
||||||
|
|
||||||
|
# select only the new node
|
||||||
|
for n in tree.nodes:
|
||||||
|
n.select = False
|
||||||
|
|
||||||
|
node = tree.nodes.new(type=self.type)
|
||||||
|
|
||||||
for setting in self.settings:
|
for setting in self.settings:
|
||||||
# XXX catch exceptions here?
|
# XXX catch exceptions here?
|
||||||
@@ -110,8 +82,27 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
|
|||||||
print (str(e))
|
print (str(e))
|
||||||
# Continue despite invalid attribute
|
# Continue despite invalid attribute
|
||||||
|
|
||||||
|
if space.use_hidden_preview:
|
||||||
|
node.show_preview = False
|
||||||
|
|
||||||
|
node.select = True
|
||||||
|
tree.nodes.active = node
|
||||||
|
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)
|
||||||
|
|
||||||
|
# Default execute simply adds a node
|
||||||
|
def execute(self, context):
|
||||||
|
self.create_node(context)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
# Default invoke stores the mouse position to place the node correctly
|
||||||
|
# and optionally invokes the transform operator
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
self.store_mouse_cursor(context, event)
|
self.store_mouse_cursor(context, event)
|
||||||
result = self.execute(context)
|
result = self.execute(context)
|
||||||
@@ -122,6 +113,43 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# Simple basic operator for adding a node
|
||||||
|
class NODE_OT_add_node(NodeAddOperator, Operator):
|
||||||
|
'''Add a node to the active tree'''
|
||||||
|
bl_idname = "node.add_node"
|
||||||
|
bl_label = "Add Node"
|
||||||
|
|
||||||
|
|
||||||
|
# Add a node and link it to an existing socket
|
||||||
|
class NODE_OT_add_and_link_node(NodeAddOperator, Operator):
|
||||||
|
'''Add a node to the active tree and link to an existing socket'''
|
||||||
|
bl_idname = "node.add_and_link_node"
|
||||||
|
bl_label = "Add and Link Node"
|
||||||
|
|
||||||
|
link_socket_index = IntProperty(
|
||||||
|
name="Link Socket Index",
|
||||||
|
description="Index of the socket to link",
|
||||||
|
)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
space = context.space_data
|
||||||
|
ntree = space.edit_tree
|
||||||
|
|
||||||
|
node = self.create_node(context)
|
||||||
|
if not node:
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
to_socket = getattr(context, "link_to_socket", None)
|
||||||
|
if to_socket:
|
||||||
|
ntree.links.new(node.outputs[self.link_socket_index], to_socket)
|
||||||
|
|
||||||
|
from_socket = getattr(context, "link_from_socket", None)
|
||||||
|
if from_socket:
|
||||||
|
ntree.links.new(from_socket, node.inputs[self.link_socket_index])
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
def node_classes_iter(base=bpy.types.Node):
|
def node_classes_iter(base=bpy.types.Node):
|
||||||
"""
|
"""
|
||||||
Yields all true node classes by checking for the is_registered_node_type classmethod.
|
Yields all true node classes by checking for the is_registered_node_type classmethod.
|
||||||
|
|||||||
Reference in New Issue
Block a user