for monad clone / monad make unique
this comes directly from blender's source. unedited. (storing here for later)
python
# Base class for node 'Add' operators
class NodeAddOperator:
type = StringProperty(
name="Node Type",
description="Node type",
)
use_transform = BoolProperty(
name="Use Transform",
description="Start transform operator after inserting the node",
default=False,
)
settings = CollectionProperty(
name="Settings",
description="Settings to be applied on the newly created node",
type=NodeSetting,
options={'SKIP_SAVE'},
)
def store_mouse_cursor(context, event):
space = context.space_data
tree = space.edit_tree
# convert mouse position to the View2D for later node placement
if context.region.type == 'WINDOW':
# convert mouse position to the View2D for later node placement
space.cursor_location_from_region(
event.mouse_region_x, event.mouse_region_y)
else:
space.cursor_location = tree.view_center
# 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=node_type)
for setting in self.settings:
# XXX catch exceptions here?
value = eval(setting.value)
try:
setattr(node, setting.name, value)
except AttributeError as e:
self.report(
{'ERROR_INVALID_INPUT'},
"Node has no attribute " + setting.name)
print(str(e))
# Continue despite invalid attribute
node.select = True
tree.nodes.active = node
node.location = space.cursor_location
return node
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 and not space.edit_tree.library)
# Default execute simply adds a node
def execute(self, context):
if self.properties.is_property_set("type"):
self.create_node(context)
return {'FINISHED'}
else:
return {'CANCELLED'}
# Default invoke stores the mouse position to place the node correctly
# and optionally invokes the transform operator
def invoke(self, context, event):
self.store_mouse_cursor(context, event)
result = self.execute(context)
if self.use_transform and ('FINISHED' in result):
# removes the node again if transform is canceled
bpy.ops.node.translate_attach_remove_on_cancel('INVOKE_DEFAULT')
return result