diff --git a/scripts/startup/bl_operators/node.py b/scripts/startup/bl_operators/node.py index 5d67b09943d..88dfe30bd30 100644 --- a/scripts/startup/bl_operators/node.py +++ b/scripts/startup/bl_operators/node.py @@ -918,32 +918,15 @@ class NODE_OT_interface_item_new(NodeInterfaceOperator, Operator): bl_label = "New Item" bl_options = {'REGISTER', 'UNDO'} - def get_items(_self, context): - items = [ - ('INPUT', "Input", ""), - ('OUTPUT', "Output", ""), - ('PANEL', "Panel", ""), - ] - - if context is None: - return items - - snode = context.space_data - tree = snode.edit_tree - interface = tree.interface - - active_item = interface.active - # Panels have the extra option to add a toggle. - if active_item and active_item.item_type == 'PANEL': - items.append(('PANEL_TOGGLE', "Panel Toggle", "")) - - return items - item_type: EnumProperty( name="Item Type", description="Type of the item to create", - items=get_items, - default=0, + items=( + ('INPUT', "Input", ""), + ('OUTPUT', "Output", ""), + ('PANEL', "Panel", ""), + ), + default='INPUT', ) # Returns a valid socket type for the given tree or None. @@ -979,18 +962,6 @@ class NODE_OT_interface_item_new(NodeInterfaceOperator, Operator): item = interface.new_socket("Socket", socket_type=self.find_valid_socket_type(tree), in_out='OUTPUT') elif self.item_type == 'PANEL': item = interface.new_panel("Panel") - elif self.item_type == 'PANEL_TOGGLE': - active_panel = active_item - if len(active_panel.interface_items) > 0: - first_item = active_panel.interface_items[0] - if type(first_item) is bpy.types.NodeTreeInterfaceSocketBool and first_item.is_panel_toggle: - self.report({'INFO'}, "Panel already has a toggle") - return {'CANCELLED'} - item = interface.new_socket(active_panel.name, socket_type='NodeSocketBool', in_out='INPUT') - item.is_panel_toggle = True - interface.move_to_parent(item, active_panel, 0) - # Return in this case because we don't want to move the item. - return {'FINISHED'} else: return {'CANCELLED'} @@ -1005,6 +976,55 @@ class NODE_OT_interface_item_new(NodeInterfaceOperator, Operator): return {'FINISHED'} +class NODE_OT_interface_item_new_panel_toggle(Operator): + '''Add a checkbox to the currently selected panel''' + bl_idname = "node.interface_item_new_panel_toggle" + bl_label = "New Panel Toggle" + bl_options = {'REGISTER', 'UNDO'} + + @staticmethod + def get_panel_toggle(panel): + if len(panel.interface_items) > 0: + first_item = panel.interface_items[0] + if type(first_item) is bpy.types.NodeTreeInterfaceSocketBool and first_item.is_panel_toggle: + return first_item + + return None + + @classmethod + def poll(cls, context): + try: + snode = context.space_data + tree = snode.edit_tree + interface = tree.interface + + active_item = interface.active + + if active_item.item_type != 'PANEL': + cls.poll_message_set("Active item is not a panel") + return False + + if cls.get_panel_toggle(active_item) is not None: + cls.poll_message_set("Panel already has a toggle") + return False + + return True + except AttributeError: + return False + + def execute(self, context): + snode = context.space_data + tree = snode.edit_tree + + interface = tree.interface + active_panel = interface.active + + item = interface.new_socket(active_panel.name, socket_type='NodeSocketBool', in_out='INPUT') + item.is_panel_toggle = True + interface.move_to_parent(item, active_panel, 0) + return {'FINISHED'} + + class NODE_OT_interface_item_duplicate(NodeInterfaceOperator, Operator): """Add a copy of the active item to the interface""" bl_idname = "node.interface_item_duplicate" @@ -1311,6 +1331,7 @@ classes = ( NODE_OT_add_closure_zone, NODE_OT_collapse_hide_unused_toggle, NODE_OT_interface_item_new, + NODE_OT_interface_item_new_panel_toggle, NODE_OT_interface_item_duplicate, NODE_OT_interface_item_remove, NODE_OT_interface_item_make_panel_toggle, diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index 3eab941b10e..af8089a34f3 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -1022,6 +1022,19 @@ class NODE_MT_node_tree_interface_context_menu(Menu): layout.operator("node.interface_item_unlink_panel_toggle") +class NODE_MT_node_tree_interface_new_item(Menu): + bl_label = "New Item" + + def draw(self, context): + layout = self.layout + layout.operator_enum("node.interface_item_new", "item_type") + + active_item = context.space_data.edit_tree.interface.active + + if active_item.item_type == 'PANEL': + layout.operator("node.interface_item_new_panel_toggle", text="Panel Toggle") + + class NODE_PT_node_tree_properties(Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' @@ -1176,6 +1189,7 @@ classes = ( NODE_PT_geometry_node_tool_options, NODE_PT_node_color_presets, NODE_PT_node_tree_properties, + NODE_MT_node_tree_interface_new_item, NODE_MT_node_tree_interface_context_menu, NODE_PT_node_tree_animation, NODE_PT_active_node_generic, diff --git a/source/blender/editors/space_node/node_tree_interface_ui.cc b/source/blender/editors/space_node/node_tree_interface_ui.cc index 187d30ba4ff..bd40ea80979 100644 --- a/source/blender/editors/space_node/node_tree_interface_ui.cc +++ b/source/blender/editors/space_node/node_tree_interface_ui.cc @@ -57,7 +57,7 @@ void node_tree_interface_draw(bContext &C, uiLayout &layout, bNodeTree &tree) uiLayout &col = row.column(true); col.enabled_set(ID_IS_EDITABLE(&tree.id)); - col.op_menu_enum(&C, "node.interface_item_new", "item_type", "", ICON_ADD); + col.menu("NODE_MT_node_tree_interface_new_item", "", ICON_ADD); col.op("node.interface_item_remove", "", ICON_REMOVE); col.separator(); col.menu("NODE_MT_node_tree_interface_context_menu", "", ICON_DOWNARROW_HLT);