Skip to content
Snippets Groups Projects
node_efficiency_tools.py 155 KiB
Newer Older
  • Learn to ignore specific revisions
  •             layout.menu(NWMergeShadersMenu.bl_idname, text="Use Shaders")
            layout.menu(NWMergeMixMenu.bl_idname, text="Use Mix Nodes")
            layout.menu(NWMergeMathMenu.bl_idname, text="Use Math Nodes")
    
            props = layout.operator(NWMergeNodes.bl_idname, text="Use Z-Combine Nodes")
            props.mode = 'MIX'
            props.merge_type = 'ZCOMBINE'
    
    class NWMergeShadersMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_merge_shaders_menu"
    
        bl_label = "Merge Selected Nodes using Shaders"
    
        def draw(self, context):
            layout = self.layout
    
            for type in ('MIX', 'ADD'):
                props = layout.operator(NWMergeNodes.bl_idname, text=type)
    
                props.mode = type
                props.merge_type = 'SHADER'
    
    
    
    class NWMergeMixMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_merge_mix_menu"
    
        bl_label = "Merge Selected Nodes using Mix"
    
        def draw(self, context):
            layout = self.layout
            for type, name, description in blend_types:
    
                props = layout.operator(NWMergeNodes.bl_idname, text=name)
    
                props.mode = type
                props.merge_type = 'MIX'
    
    
    
    class NWConnectionListOutputs(Menu, NWBase):
        bl_idname = "NODE_MT_nw_connection_list_out"
        bl_label = "From:"
    
        def draw(self, context):
            layout = self.layout
            nodes, links = get_nodes_links(context)
    
            n1 = nodes[context.scene.NWLazySource]
    
            if n1.type == "R_LAYERS":
                index=0
                for o in n1.outputs:
                    if o.enabled:  # Check which passes the render layer has enabled
                        layout.operator(NWCallInputsMenu.bl_idname, text=o.name, icon="RADIOBUT_OFF").from_socket=index
                    index+=1
            else:
                index=0
                for o in n1.outputs:
                    layout.operator(NWCallInputsMenu.bl_idname, text=o.name, icon="RADIOBUT_OFF").from_socket=index
                    index+=1
    
    
    class NWConnectionListInputs(Menu, NWBase):
        bl_idname = "NODE_MT_nw_connection_list_in"
        bl_label = "To:"
    
        def draw(self, context):
            layout = self.layout
            nodes, links = get_nodes_links(context)
    
            n2 = nodes[context.scene.NWLazyTarget]
    
            #print (self.from_socket)
    
            index = 0
            for i in n2.inputs:
                op = layout.operator(NWMakeLink.bl_idname, text=i.name, icon="FORWARD")
                op.from_socket = context.scene.NWSourceSocket
                op.to_socket = index
                index+=1
    
    
    
    class NWMergeMathMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_merge_math_menu"
    
        bl_label = "Merge Selected Nodes using Math"
    
        def draw(self, context):
            layout = self.layout
            for type, name, description in operations:
    
                props = layout.operator(NWMergeNodes.bl_idname, text=name)
    
                props.mode = type
                props.merge_type = 'MATH'
    
    
    
    class NWBatchChangeNodesMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_batch_change_nodes_menu"
    
        bl_label = "Batch Change Selected Nodes"
    
        def draw(self, context):
            layout = self.layout
    
            layout.menu(NWBatchChangeBlendTypeMenu.bl_idname)
            layout.menu(NWBatchChangeOperationMenu.bl_idname)
    
    class NWBatchChangeBlendTypeMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_batch_change_blend_type_menu"
    
        bl_label = "Batch Change Blend Type"
    
        def draw(self, context):
            layout = self.layout
            for type, name, description in blend_types:
    
                props = layout.operator(NWBatchChangeNodes.bl_idname, text=name)
    
                props.blend_type = type
                props.operation = 'CURRENT'
    
    
    
    class NWBatchChangeOperationMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_batch_change_operation_menu"
    
        bl_label = "Batch Change Math Operation"
    
        def draw(self, context):
            layout = self.layout
            for type, name, description in operations:
    
                props = layout.operator(NWBatchChangeNodes.bl_idname, text=name)
    
                props.blend_type = 'CURRENT'
                props.operation = type
    
    
    
    class NWCopyToSelectedMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_copy_node_properties_menu"
    
        bl_label = "Copy to Selected"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator(NWCopySettings.bl_idname, text="Settings from Active")
            layout.menu(NWCopyLabelMenu.bl_idname)
    
    class NWCopyLabelMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_copy_label_menu"
    
        bl_label = "Copy Label"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator(NWCopyLabel.bl_idname, text="from Active Node's Label").option = 'FROM_ACTIVE'
            layout.operator(NWCopyLabel.bl_idname, text="from Linked Node's Label").option = 'FROM_NODE'
            layout.operator(NWCopyLabel.bl_idname, text="from Linked Output's Name").option = 'FROM_SOCKET'
    
    class NWAddReroutesMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_add_reroutes_menu"
    
        bl_label = "Add Reroutes"
        bl_description = "Add Reroute Nodes to Selected Nodes' Outputs"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator(NWAddReroutes.bl_idname, text="to All Outputs").option = 'ALL'
            layout.operator(NWAddReroutes.bl_idname, text="to Loose Outputs").option = 'LOOSE'
            layout.operator(NWAddReroutes.bl_idname, text="to Linked Outputs").option = 'LINKED'
    
    class NWLinkActiveToSelectedMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_link_active_to_selected_menu"
    
        bl_label = "Link Active to Selected"
    
        def draw(self, context):
            layout = self.layout
    
            layout.menu(NWLinkStandardMenu.bl_idname)
            layout.menu(NWLinkUseNodeNameMenu.bl_idname)
            layout.menu(NWLinkUseOutputsNamesMenu.bl_idname)
    
    class NWLinkStandardMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_link_standard_menu"
    
        bl_label = "To All Selected"
    
        def draw(self, context):
            layout = self.layout
    
            props = layout.operator(NWLinkActiveToSelected.bl_idname, text="Don't Replace Links")
    
            props.replace = False
            props.use_node_name = False
            props.use_outputs_names = False
    
            props = layout.operator(NWLinkActiveToSelected.bl_idname, text="Replace Links")
    
            props.replace = True
            props.use_node_name = False
            props.use_outputs_names = False
    
    
    
    class NWLinkUseNodeNameMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_link_use_node_name_menu"
    
        bl_label = "Use Node Name/Label"
    
        def draw(self, context):
            layout = self.layout
    
            props = layout.operator(NWLinkActiveToSelected.bl_idname, text="Don't Replace Links")
    
            props.replace = False
            props.use_node_name = True
            props.use_outputs_names = False
    
            props = layout.operator(NWLinkActiveToSelected.bl_idname, text="Replace Links")
    
            props.replace = True
            props.use_node_name = True
            props.use_outputs_names = False
    
    class NWLinkUseOutputsNamesMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_link_use_outputs_names_menu"
    
        bl_label = "Use Outputs Names"
    
        def draw(self, context):
            layout = self.layout
    
            props = layout.operator(NWLinkActiveToSelected.bl_idname, text="Don't Replace Links")
    
            props.replace = False
            props.use_node_name = False
            props.use_outputs_names = True
    
            props = layout.operator(NWLinkActiveToSelected.bl_idname, text="Replace Links")
    
            props.replace = True
            props.use_node_name = False
            props.use_outputs_names = True
    
    class NWNodeAlignMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_node_align_menu"
    
        bl_label = "Align Nodes"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator(NWAlignNodes.bl_idname, text="Horizontally").option = 'AXIS_X'
            layout.operator(NWAlignNodes.bl_idname, text="Vertically").option = 'AXIS_Y'
    
    class NWVertColMenu(bpy.types.Menu):
        bl_idname = "NODE_MT_nw_node_vertex_color_menu"
        bl_label = "Vertex Colors"
    
        @classmethod
        def poll(cls, context):
            if context.area.spaces[0].node_tree:
                if context.area.spaces[0].node_tree.type == 'SHADER':
                    return True
                else:
                    return False
            else:
                return False
    
        def draw(self, context):
            l = self.layout
            nodes, links = get_nodes_links(context)
            mat = context.object.active_material
    
            objs = []
            for obj in bpy.data.objects:
                for slot in obj.material_slots:
                    if slot.material == mat:
                        objs.append(obj)
            vcols = []
            for obj in objs:
                if obj.data.vertex_colors:
                    for vcol in obj.data.vertex_colors:
                        vcols.append(vcol.name)
            vcols = list(set(vcols))  # get a unique list
    
            if vcols:
                for vcol in vcols:
                    l.operator(NWAddAttrNode.bl_idname, text=vcol).attr_name = vcol
            else:
                l.label("No Vertex Color layers on objects with this material")
    
    
    class NWSwitchNodeTypeMenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_node_type_menu"
        bl_label = "Switch Type to..."
    
        def draw(self, context):
            layout = self.layout
            tree = context.space_data.node_tree
            if tree.type == 'SHADER':
                layout.menu(NWSwitchShadersInputSubmenu.bl_idname)
                layout.menu(NWSwitchShadersOutputSubmenu.bl_idname)
                layout.menu(NWSwitchShadersShaderSubmenu.bl_idname)
                layout.menu(NWSwitchShadersTextureSubmenu.bl_idname)
                layout.menu(NWSwitchShadersColorSubmenu.bl_idname)
                layout.menu(NWSwitchShadersVectorSubmenu.bl_idname)
                layout.menu(NWSwitchShadersConverterSubmenu.bl_idname)
                layout.menu(NWSwitchShadersLayoutSubmenu.bl_idname)
            if tree.type == 'COMPOSITING':
                layout.menu(NWSwitchCompoInputSubmenu.bl_idname)
                layout.menu(NWSwitchCompoOutputSubmenu.bl_idname)
                layout.menu(NWSwitchCompoColorSubmenu.bl_idname)
                layout.menu(NWSwitchCompoConverterSubmenu.bl_idname)
                layout.menu(NWSwitchCompoFilterSubmenu.bl_idname)
                layout.menu(NWSwitchCompoVectorSubmenu.bl_idname)
                layout.menu(NWSwitchCompoMatteSubmenu.bl_idname)
                layout.menu(NWSwitchCompoDistortSubmenu.bl_idname)
                layout.menu(NWSwitchCompoLayoutSubmenu.bl_idname)
    
    
    class NWSwitchShadersInputSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_input_submenu"
        bl_label = "Input"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_input_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchShadersOutputSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_output_submenu"
        bl_label = "Output"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_output_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchShadersShaderSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_shader_submenu"
        bl_label = "Shader"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_shader_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchShadersTextureSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_texture_submenu"
        bl_label = "Texture"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_texture_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchShadersColorSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_color_submenu"
        bl_label = "Color"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_color_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchShadersVectorSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_vector_submenu"
        bl_label = "Vector"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_vector_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchShadersConverterSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_converter_submenu"
        bl_label = "Converter"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_converter_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchShadersLayoutSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_shaders_layout_submenu"
        bl_label = "Layout"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in shaders_layout_nodes_props:
                if type != 'FRAME':
                    props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                    props.to_type = ident
    
    
    class NWSwitchCompoInputSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_input_submenu"
        bl_label = "Input"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_input_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoOutputSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_output_submenu"
        bl_label = "Output"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_output_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoColorSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_color_submenu"
        bl_label = "Color"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_color_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoConverterSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_converter_submenu"
        bl_label = "Converter"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_converter_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoFilterSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_filter_submenu"
        bl_label = "Filter"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_filter_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoVectorSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_vector_submenu"
        bl_label = "Vector"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_vector_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoMatteSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_matte_submenu"
        bl_label = "Matte"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_matte_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoDistortSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_distort_submenu"
        bl_label = "Distort"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_distort_nodes_props:
                props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                props.to_type = ident
    
    
    class NWSwitchCompoLayoutSubmenu(Menu, NWBase):
        bl_idname = "NODE_MT_nw_switch_compo_layout_submenu"
        bl_label = "Layout"
    
        def draw(self, context):
            layout = self.layout
            for ident, type, rna_name in compo_layout_nodes_props:
                if type != 'FRAME':
                    props = layout.operator(NWSwitchNodeType.bl_idname, text=rna_name)
                    props.to_type = ident
    
    
    #
    #  APPENDAGES TO EXISTING UI
    #
    
    
    
    def select_parent_children_buttons(self, context):
        layout = self.layout
    
        layout.operator(NWSelectParentChildren.bl_idname, text="Select frame's members (children)").option = 'CHILD'
        layout.operator(NWSelectParentChildren.bl_idname, text="Select parent frame").option = 'PARENT'
    
    
    def attr_nodes_menu_func(self, context):
        col = self.layout.column(align=True)
        col.menu("NODE_MT_nw_node_vertex_color_menu")
        col.separator()
    
    
    
    def multipleimages_menu_func(self, context):
        col = self.layout.column(align=True)
        col.operator(NWAddMultipleImages.bl_idname, text="Multiple Images")
        col.operator(NWAddSequence.bl_idname, text="Image Sequence")
        col.separator()
        
    
    
    def bgreset_menu_func(self, context):
        self.layout.operator(NWResetBG.bl_idname)
    
    
    #  REGISTER/UNREGISTER CLASSES AND KEYMAP ITEMS
    
    # kmi_defs entry: (identifier, key, CTRL, SHIFT, ALT, props, nice name)
    
    # props entry: (property name, property value)
    kmi_defs = (
        # MERGE NODES
    
        # NWMergeNodes with Ctrl (AUTO).
        (NWMergeNodes.bl_idname, 'NUMPAD_0', True, False, False,
            (('mode', 'MIX'), ('merge_type', 'AUTO'),), "Merge Nodes (Automatic)"),
        (NWMergeNodes.bl_idname, 'ZERO', True, False, False,
            (('mode', 'MIX'), ('merge_type', 'AUTO'),), "Merge Nodes (Automatic)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_PLUS', True, False, False,
            (('mode', 'ADD'), ('merge_type', 'AUTO'),), "Merge Nodes (Add)"),
        (NWMergeNodes.bl_idname, 'EQUAL', True, False, False,
            (('mode', 'ADD'), ('merge_type', 'AUTO'),), "Merge Nodes (Add)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_ASTERIX', True, False, False,
            (('mode', 'MULTIPLY'), ('merge_type', 'AUTO'),), "Merge Nodes (Multiply)"),
        (NWMergeNodes.bl_idname, 'EIGHT', True, False, False,
            (('mode', 'MULTIPLY'), ('merge_type', 'AUTO'),), "Merge Nodes (Multiply)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_MINUS', True, False, False,
            (('mode', 'SUBTRACT'), ('merge_type', 'AUTO'),), "Merge Nodes (Subtract)"),
        (NWMergeNodes.bl_idname, 'MINUS', True, False, False,
            (('mode', 'SUBTRACT'), ('merge_type', 'AUTO'),), "Merge Nodes (Subtract)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_SLASH', True, False, False,
            (('mode', 'DIVIDE'), ('merge_type', 'AUTO'),), "Merge Nodes (Divide)"),
        (NWMergeNodes.bl_idname, 'SLASH', True, False, False,
            (('mode', 'DIVIDE'), ('merge_type', 'AUTO'),), "Merge Nodes (Divide)"),
        (NWMergeNodes.bl_idname, 'COMMA', True, False, False,
            (('mode', 'LESS_THAN'), ('merge_type', 'MATH'),), "Merge Nodes (Less than)"),
        (NWMergeNodes.bl_idname, 'PERIOD', True, False, False,
            (('mode', 'GREATER_THAN'), ('merge_type', 'MATH'),), "Merge Nodes (Greater than)"),
    
        (NWMergeNodes.bl_idname, 'NUMPAD_PERIOD', True, False, False,
            (('mode', 'MIX'), ('merge_type', 'ZCOMBINE'),), "Merge Nodes (Z-Combine)"),
    
        # NWMergeNodes with Ctrl Alt (MIX)
        (NWMergeNodes.bl_idname, 'NUMPAD_0', True, False, True,
            (('mode', 'MIX'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Mix)"),
        (NWMergeNodes.bl_idname, 'ZERO', True, False, True,
            (('mode', 'MIX'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Mix)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_PLUS', True, False, True,
            (('mode', 'ADD'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Add)"),
        (NWMergeNodes.bl_idname, 'EQUAL', True, False, True,
            (('mode', 'ADD'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Add)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_ASTERIX', True, False, True,
            (('mode', 'MULTIPLY'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Multiply)"),
        (NWMergeNodes.bl_idname, 'EIGHT', True, False, True,
            (('mode', 'MULTIPLY'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Multiply)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_MINUS', True, False, True,
            (('mode', 'SUBTRACT'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Subtract)"),
        (NWMergeNodes.bl_idname, 'MINUS', True, False, True,
            (('mode', 'SUBTRACT'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Subtract)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_SLASH', True, False, True,
            (('mode', 'DIVIDE'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Divide)"),
        (NWMergeNodes.bl_idname, 'SLASH', True, False, True,
            (('mode', 'DIVIDE'), ('merge_type', 'MIX'),), "Merge Nodes (Color, Divide)"),
        # NWMergeNodes with Ctrl Shift (MATH)
        (NWMergeNodes.bl_idname, 'NUMPAD_PLUS', True, True, False,
            (('mode', 'ADD'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Add)"),
        (NWMergeNodes.bl_idname, 'EQUAL', True, True, False,
            (('mode', 'ADD'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Add)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_ASTERIX', True, True, False,
            (('mode', 'MULTIPLY'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Multiply)"),
        (NWMergeNodes.bl_idname, 'EIGHT', True, True, False,
            (('mode', 'MULTIPLY'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Multiply)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_MINUS', True, True, False,
            (('mode', 'SUBTRACT'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Subtract)"),
        (NWMergeNodes.bl_idname, 'MINUS', True, True, False,
            (('mode', 'SUBTRACT'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Subtract)"),
        (NWMergeNodes.bl_idname, 'NUMPAD_SLASH', True, True, False,
            (('mode', 'DIVIDE'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Divide)"),
        (NWMergeNodes.bl_idname, 'SLASH', True, True, False,
            (('mode', 'DIVIDE'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Divide)"),
        (NWMergeNodes.bl_idname, 'COMMA', True, True, False,
            (('mode', 'LESS_THAN'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Less than)"),
        (NWMergeNodes.bl_idname, 'PERIOD', True, True, False,
            (('mode', 'GREATER_THAN'), ('merge_type', 'MATH'),), "Merge Nodes (Math, Greater than)"),
    
        # BATCH CHANGE NODES
    
        # NWBatchChangeNodes with Alt
        (NWBatchChangeNodes.bl_idname, 'NUMPAD_0', False, False, True,
            (('blend_type', 'MIX'), ('operation', 'CURRENT'),), "Batch change blend type (Mix)"),
        (NWBatchChangeNodes.bl_idname, 'ZERO', False, False, True,
            (('blend_type', 'MIX'), ('operation', 'CURRENT'),), "Batch change blend type (Mix)"),
        (NWBatchChangeNodes.bl_idname, 'NUMPAD_PLUS', False, False, True,
            (('blend_type', 'ADD'), ('operation', 'ADD'),), "Batch change blend type (Add)"),
        (NWBatchChangeNodes.bl_idname, 'EQUAL', False, False, True,
            (('blend_type', 'ADD'), ('operation', 'ADD'),), "Batch change blend type (Add)"),
        (NWBatchChangeNodes.bl_idname, 'NUMPAD_ASTERIX', False, False, True,
            (('blend_type', 'MULTIPLY'), ('operation', 'MULTIPLY'),), "Batch change blend type (Multiply)"),
        (NWBatchChangeNodes.bl_idname, 'EIGHT', False, False, True,
            (('blend_type', 'MULTIPLY'), ('operation', 'MULTIPLY'),), "Batch change blend type (Multiply)"),
        (NWBatchChangeNodes.bl_idname, 'NUMPAD_MINUS', False, False, True,
            (('blend_type', 'SUBTRACT'), ('operation', 'SUBTRACT'),), "Batch change blend type (Subtract)"),
        (NWBatchChangeNodes.bl_idname, 'MINUS', False, False, True,
            (('blend_type', 'SUBTRACT'), ('operation', 'SUBTRACT'),), "Batch change blend type (Subtract)"),
        (NWBatchChangeNodes.bl_idname, 'NUMPAD_SLASH', False, False, True,
            (('blend_type', 'DIVIDE'), ('operation', 'DIVIDE'),), "Batch change blend type (Divide)"),
        (NWBatchChangeNodes.bl_idname, 'SLASH', False, False, True,
            (('blend_type', 'DIVIDE'), ('operation', 'DIVIDE'),), "Batch change blend type (Divide)"),
        (NWBatchChangeNodes.bl_idname, 'COMMA', False, False, True,
            (('blend_type', 'CURRENT'), ('operation', 'LESS_THAN'),), "Batch change blend type (Current)"),
        (NWBatchChangeNodes.bl_idname, 'PERIOD', False, False, True,
            (('blend_type', 'CURRENT'), ('operation', 'GREATER_THAN'),), "Batch change blend type (Current)"),
        (NWBatchChangeNodes.bl_idname, 'DOWN_ARROW', False, False, True,
            (('blend_type', 'NEXT'), ('operation', 'NEXT'),), "Batch change blend type (Next)"),
        (NWBatchChangeNodes.bl_idname, 'UP_ARROW', False, False, True,
            (('blend_type', 'PREV'), ('operation', 'PREV'),), "Batch change blend type (Previous)"),
    
        # LINK ACTIVE TO SELECTED
    
        # Don't use names, don't replace links (K)
    
        (NWLinkActiveToSelected.bl_idname, 'K', False, False, False,
            (('replace', False), ('use_node_name', False), ('use_outputs_names', False),), "Link active to selected (Don't replace links)"),
    
        # Don't use names, replace links (Shift K)
    
        (NWLinkActiveToSelected.bl_idname, 'K', False, True, False,
            (('replace', True), ('use_node_name', False), ('use_outputs_names', False),), "Link active to selected (Replace links)"),
    
        # Use node name, don't replace links (')
    
        (NWLinkActiveToSelected.bl_idname, 'QUOTE', False, False, False,
            (('replace', False), ('use_node_name', True), ('use_outputs_names', False),), "Link active to selected (Don't replace links, node names)"),
        # Use node name, replace links (Shift ')
        (NWLinkActiveToSelected.bl_idname, 'QUOTE', False, True, False,
            (('replace', True), ('use_node_name', True), ('use_outputs_names', False),), "Link active to selected (Replace links, node names)"),
        # Don't use names, don't replace links (;)
        (NWLinkActiveToSelected.bl_idname, 'SEMI_COLON', False, False, False,
            (('replace', False), ('use_node_name', False), ('use_outputs_names', True),), "Link active to selected (Don't replace links, output names)"),
    
        # Don't use names, replace links (')
    
        (NWLinkActiveToSelected.bl_idname, 'SEMI_COLON', False, True, False,
            (('replace', True), ('use_node_name', False), ('use_outputs_names', True),), "Link active to selected (Replace links, output names)"),
    
        # CHANGE MIX FACTOR
    
        (NWChangeMixFactor.bl_idname, 'LEFT_ARROW', False, False, True, (('option', -0.1),), "Reduce Mix Factor by 0.1"),
        (NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', False, False, True, (('option', 0.1),), "Increase Mix Factor by 0.1"),
        (NWChangeMixFactor.bl_idname, 'LEFT_ARROW', False, True, True, (('option', -0.01),), "Reduce Mix Factor by 0.01"),
        (NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', False, True, True, (('option', 0.01),), "Increase Mix Factor by 0.01"),
        (NWChangeMixFactor.bl_idname, 'LEFT_ARROW', True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
        (NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', True, True, True, (('option', 1.0),), "Set Mix Factor to 1.0"),
        (NWChangeMixFactor.bl_idname, 'NUMPAD_0', True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
        (NWChangeMixFactor.bl_idname, 'ZERO', True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
        (NWChangeMixFactor.bl_idname, 'NUMPAD_1', True, True, True, (('option', 1.0),), "Mix Factor to 1.0"),
        (NWChangeMixFactor.bl_idname, 'ONE', True, True, True, (('option', 1.0),), "Set Mix Factor to 1.0"),
    
        # CLEAR LABEL (Alt L)
    
        (NWClearLabel.bl_idname, 'L', False, False, True, (('option', False),), "Clear node labels"),
        # MODIFY LABEL (Alt Shift L)
        (NWModifyLabels.bl_idname, 'L', False, True, True, None, "Modify node labels"),
        # Copy Label from active to selected
        (NWCopyLabel.bl_idname, 'V', False, True, False, (('option', 'FROM_ACTIVE'),), "Copy label from active to selected"),
    
    Bartek Skorupa's avatar
    Bartek Skorupa committed
        # DETACH OUTPUTS (Alt Shift D)
    
        (NWDetachOutputs.bl_idname, 'D', False, True, True, None, "Detach outputs"),
    
    Bartek Skorupa's avatar
    Bartek Skorupa committed
        # LINK TO OUTPUT NODE (O)
    
        (NWLinkToOutputNode.bl_idname, 'O', False, False, False, None, "Link to output node"),
    
        # SELECT PARENT/CHILDREN
        # Select Children
    
        (NWSelectParentChildren.bl_idname, 'RIGHT_BRACKET', False, False, False, (('option', 'CHILD'),), "Select children"),
    
        (NWSelectParentChildren.bl_idname, 'LEFT_BRACKET', False, False, False, (('option', 'PARENT'),), "Select Parent"),
    
        (NWAddTextureSetup.bl_idname, 'T', True, False, False, None, "Add texture setup"),
        # Reset backdrop
        (NWResetBG.bl_idname, 'Z', False, False, False, None, "Reset backdrop image zoom"),
        # Delete unused
        (NWDeleteUnused.bl_idname, 'X', False, False, True, None, "Delete unused nodes"),
        # Frame Seleted
        (NWFrameSelected.bl_idname, 'P', False, True, False, None, "Frame selected nodes"),
        # Swap Outputs
    
        (NWSwapLinks.bl_idname, 'S', False, False, True, None, "Swap Outputs"),
    
        # Emission Viewer
        (NWEmissionViewer.bl_idname, 'LEFTMOUSE', True, True, False, None, "Connect to Cycles Viewer node"),
        # Reload Images
        (NWReloadImages.bl_idname, 'R', False, False, True, None, "Reload images"),
        # Lazy Mix
        (NWLazyMix.bl_idname, 'RIGHTMOUSE', False, False, True, None, "Lazy Mix"),
        # Lazy Connect
        (NWLazyConnect.bl_idname, 'RIGHTMOUSE', True, False, False, None, "Lazy Connect"),
    
        # Lazy Connect with Menu
        (NWLazyConnect.bl_idname, 'RIGHTMOUSE', True, True, False, (('with_menu', True),), "Lazy Connect with Socket Menu"),
    
        ('wm.call_menu', 'SPACE', True, False, False, (('name', NodeWranglerMenu.bl_idname),), "Node Wranger menu"),
        ('wm.call_menu', 'SLASH', False, False, False, (('name', NWAddReroutesMenu.bl_idname),), "Add Reroutes menu"),
        ('wm.call_menu', 'NUMPAD_SLASH', False, False, False, (('name', NWAddReroutesMenu.bl_idname),), "Add Reroutes menu"),
        ('wm.call_menu', 'EQUAL', False, True, False, (('name', NWNodeAlignMenu.bl_idname),), "Node alignment menu"),
        ('wm.call_menu', 'BACK_SLASH', False, False, False, (('name', NWLinkActiveToSelectedMenu.bl_idname),), "Link active to selected (menu)"),
        ('wm.call_menu', 'C', False, True, False, (('name', NWCopyToSelectedMenu.bl_idname),), "Copy to selected (menu)"),
        ('wm.call_menu', 'S', False, True, False, (('name', NWSwitchNodeTypeMenu.bl_idname),), "Switch node type menu"),
    )
    
        # props
        bpy.types.Scene.NWBusyDrawing = StringProperty(
            name="Busy Drawing!",
            default="",
            description="An internal property used to store only the first mouse position")
    
        bpy.types.Scene.NWLazySource = StringProperty(
            name="Lazy Source!",
            default="x",
            description="An internal property used to store the first node in a Lazy Connect operation")
        bpy.types.Scene.NWLazyTarget = StringProperty(
            name="Lazy Target!",
    
            description="An internal property used to store the last node in a Lazy Connect operation")
        bpy.types.Scene.NWSourceSocket = IntProperty(
            name="Source Socket!",
            default=0,
            description="An internal property used to store the source socket in a Lazy Connect operation")
    
        bpy.utils.register_module(__name__)
    
        km = bpy.context.window_manager.keyconfigs.addon.keymaps.new(name='Node Editor', space_type="NODE_EDITOR")
    
        for (identifier, key, CTRL, SHIFT, ALT, props, nicename) in kmi_defs:
    
            kmi = km.keymap_items.new(identifier, key, 'PRESS', ctrl=CTRL, shift=SHIFT, alt=ALT)
            if props:
                for prop, value in props:
                    setattr(kmi.properties, prop, value)
            addon_keymaps.append((km, kmi))
    
        # menu items
        bpy.types.NODE_MT_select.append(select_parent_children_buttons)
    
        bpy.types.NODE_MT_category_SH_NEW_INPUT.prepend(attr_nodes_menu_func)
        bpy.types.NODE_PT_category_SH_NEW_INPUT.prepend(attr_nodes_menu_func)
        bpy.types.NODE_PT_backdrop.append(bgreset_menu_func)
    
        bpy.types.NODE_MT_category_SH_NEW_TEXTURE.prepend(multipleimages_menu_func)
        bpy.types.NODE_PT_category_SH_NEW_TEXTURE.prepend(multipleimages_menu_func)
        bpy.types.NODE_MT_category_CMP_INPUT.prepend(multipleimages_menu_func)
        bpy.types.NODE_PT_category_CMP_INPUT.prepend(multipleimages_menu_func)
    
        # props
        del bpy.types.Scene.NWBusyDrawing
    
        del bpy.types.Scene.NWLazySource
        del bpy.types.Scene.NWLazyTarget
        del bpy.types.Scene.NWSourceSocket
    
        bpy.utils.unregister_module(__name__)
    
        for km, kmi in addon_keymaps:
            km.keymap_items.remove(kmi)
        addon_keymaps.clear()
    
    
        # menuitems
        bpy.types.NODE_MT_select.remove(select_parent_children_buttons)
        bpy.types.NODE_MT_category_SH_NEW_INPUT.remove(attr_nodes_menu_func)
        bpy.types.NODE_PT_category_SH_NEW_INPUT.remove(attr_nodes_menu_func)
        bpy.types.NODE_PT_backdrop.remove(bgreset_menu_func)
    
        bpy.types.NODE_MT_category_SH_NEW_TEXTURE.remove(multipleimages_menu_func)
        bpy.types.NODE_PT_category_SH_NEW_TEXTURE.remove(multipleimages_menu_func)
        bpy.types.NODE_MT_category_CMP_INPUT.remove(multipleimages_menu_func)
        bpy.types.NODE_PT_category_CMP_INPUT.remove(multipleimages_menu_func)
    
    if __name__ == "__main__":