Skip to content
Snippets Groups Projects
space_view3d_toolshelf_menu.py 126 KiB
Newer Older
  • Learn to ignore specific revisions
  •     bl_label = "Transform"
    
        def draw(self, context):
            layout = self.layout
    
            layout.menu("VIEW3D_MT_ManipulatorMenu12")
    
            layout.operator("transform.translate", text="Move")
    
            layout.operator("transform.rotate", text="Rotate")
            layout.operator("transform.resize", text="Scale")
            UseSeparator(self, context)
            layout.operator("pose.transforms_clear", text="Clear All")
            layout.operator("pose.loc_clear", text="Location")
            layout.operator("pose.rot_clear", text="Rotation")
            layout.operator("pose.scale_clear", text="Scale")
    
            UseSeparator(self, context)
    
            layout.operator("pose.user_transforms_clear", text="Reset unkeyed")
            obj = context.object
            if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}:
    
                if obj.data.display_type == 'BBONE':
    
                    layout.operator("transform.transform", text="Scale BBone").mode = 'BONE_SIZE'
    
                elif obj.data.display_type == 'ENVELOPE':
    
                    layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONE_SIZE'
                    layout.operator("transform.transform", text="Scale Radius").mode = 'BONE_ENVELOPE'
    
    
    # View Menu's #
    
    class VIEW3D_MT_View_Directions2(Menu):
        bl_label = "Directions"
    
        def draw(self, context):
            layout = self.layout
            layout.operator("view3d.viewnumpad", text="Camera").type = 'CAMERA'
            UseSeparator(self, context)
            layout.operator("view3d.viewnumpad", text="Top").type = 'TOP'
            layout.operator("view3d.viewnumpad", text="Bottom").type = 'BOTTOM'
            UseSeparator(self, context)
            layout.operator("view3d.viewnumpad", text="Front").type = 'FRONT'
            layout.operator("view3d.viewnumpad", text="Back").type = 'BACK'
            UseSeparator(self, context)
            layout.operator("view3d.viewnumpad", text="Right").type = 'RIGHT'
            layout.operator("view3d.viewnumpad", text="Left").type = 'LEFT'
    
    
    class VIEW3D_MT_View_Border2(Menu):
        bl_label = "Set Border"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator_context = 'INVOKE_REGION_WIN'
    
            layout.operator("view3d.clip_border", text="Clipping Border...")
            layout.operator("view3d.zoom_border", text="Zoom Border...")
            layout.operator("view3d.render_border", text="Render Border...").camera_only = False
    
    class VIEW3D_MT_View_Toggle2(Menu):
        bl_label = "View Toggle"
    
        def draw(self, context):
            layout = self.layout
            layout.operator_context = 'INVOKE_REGION_WIN'
            layout.operator("screen.area_dupli")
            UseSeparator(self, context)
            layout.operator("screen.region_quadview")
            layout.operator("screen.screen_full_area", text="Toggle Maximize Area")
            layout.operator("screen.screen_full_area").use_hide_panels = True
    
    class VIEW3D_MT_View_Menu2(Menu):
        bl_label = "View"
    
        def draw(self, context):
            layout = self.layout
    
            layout.menu("VIEW3D_MT_Shade2")
    
            UseSeparator(self, context)
            layout.menu("VIEW3D_MT_view_cameras", text="Cameras")
    
            layout.menu("VIEW3D_MT_View_Directions2")
            layout.menu("VIEW3D_MT_View_Navigation2")
    
            layout.menu("VIEW3D_MT_View_Align2")
            layout.menu("VIEW3D_MT_View_Toggle2")
    
            layout.operator("view3d.view_persportho")
            layout.operator("view3d.localview", text="View Global/Local")
            layout.operator("view3d.view_selected").use_all_regions = False
            layout.operator("view3d.view_all").center = False
            UseSeparator(self, context)
    
            layout.menu("VIEW3D_MT_View_Border2")
    
            layout.operator("view3d.layers", text="Show All Layers").nr = 0
            UseSeparator(self, context)
            # New menu entry for Animation player
    
            layout.menu("VIEW3D_MT_Animation_Player2",
    
                        text="Playback Animation", icon='PLAY')
    
    
    class VIEW3D_MT_View_Navigation2(Menu):
        bl_label = "Navigation"
    
        def draw(self, context):
            from math import pi
            layout = self.layout
            layout.operator_enum("view3d.view_orbit", "type")
            props = layout.operator("view3d.view_orbit", "Orbit Opposite")
            props.type = 'ORBITRIGHT'
            props.angle = pi
    
            UseSeparator(self, context)
            layout.operator("view3d.view_roll", text="Roll Left").type = 'LEFT'
            layout.operator("view3d.view_roll", text="Roll Right").type = 'RIGHT'
            UseSeparator(self, context)
            layout.operator_enum("view3d.view_pan", "type")
            UseSeparator(self, context)
            layout.operator("view3d.zoom", text="Zoom In").delta = 1
            layout.operator("view3d.zoom", text="Zoom Out").delta = -1
            UseSeparator(self, context)
            layout.operator("view3d.zoom_camera_1_to_1", text="Zoom Camera 1:1")
            UseSeparator(self, context)
            layout.operator("view3d.fly")
            layout.operator("view3d.walk")
    
    
    class VIEW3D_MT_View_Align2(Menu):
        bl_label = "Align View"
    
        def draw(self, context):
            layout = self.layout
            layout.operator("view3d.view_all", text="Center Cursor and View All").center = True
            layout.operator("view3d.view_center_cursor")
            UseSeparator(self, context)
            layout.operator("view3d.camera_to_view", text="Align Active Camera to View")
            layout.operator("view3d.camera_to_view_selected", text="Align Active Camera to Selected")
            UseSeparator(self, context)
            layout.operator("view3d.view_selected")
            layout.operator("view3d.view_lock_to_active")
            layout.operator("view3d.view_lock_clear")
    
    class VIEW3D_MT_View_Align_Selected2(Menu):
        bl_label = "Align View to Active"
    
            props = layout.operator("view3d.viewnumpad", text="Top")
            props.align_active = True
            props.type = 'TOP'
            props = layout.operator("view3d.viewnumpad", text="Bottom")
            props.align_active = True
            props.type = 'BOTTOM'
            props = layout.operator("view3d.viewnumpad", text="Front")
            props.align_active = True
            props.type = 'FRONT'
            props = layout.operator("view3d.viewnumpad", text="Back")
            props.align_active = True
            props.type = 'BACK'
            props = layout.operator("view3d.viewnumpad", text="Right")
            props.align_active = True
            props.type = 'RIGHT'
            props = layout.operator("view3d.viewnumpad", text="Left")
            props.align_active = True
            props.type = 'LEFT'
    
    
    class VIEW3D_MT_View_Cameras2(Menu):
        bl_label = "Cameras"
    
        def draw(self, context):
            layout = self.layout
            layout.operator("view3d.object_as_camera")
            layout.operator("view3d.viewnumpad", text="Active Camera").type = 'CAMERA'
    
    # Matcap and AO, Wire all and X-Ray entries thanks to marvin.k.breuer
    class VIEW3D_MT_Shade2(Menu):
        bl_label = "Shade"
    
            layout.prop(context.space_data, "viewport_shade", expand=True)
            UseSeparator(self, context)
    
            if context.active_object:
                if(context.mode == 'EDIT_MESH'):
                    layout.operator("MESH_OT_faces_shade_smooth")
                    layout.operator("MESH_OT_faces_shade_flat")
                else:
                    layout.operator("OBJECT_OT_shade_smooth")
                    layout.operator("OBJECT_OT_shade_flat")
    
            UseSeparator(self, context)
    
            layout.operator("view3d.display_wire_all2", text="Wire all", icon='SHADING_WIRE')
    
            layout.prop(context.object, "show_in_front", text="X-Ray", icon="META_CUBE")
    
    
            UseSeparator(self, context)
            layout.prop(context.space_data.fx_settings, "use_ssao",
                        text="Ambient Occlusion", icon="GROUP")
            layout.prop(context.space_data, "use_matcap", icon="MATCAP_01")
    
            if context.space_data.use_matcap:
                row = layout.column(1)
                row.scale_y = 0.3
                row.scale_x = 0.5
                row.template_icon_view(context.space_data, "matcap_icon")
    
    # Animation Player (Thanks to marvin.k.breuer) #
    class VIEW3D_MT_Animation_Player2(Menu):
        bl_label = "Animation Player"
    
            layout.operator("screen.frame_jump", text="Jump REW", icon='REW').end = False
            layout.operator("screen.keyframe_jump", text="Previous FR", icon='PREV_KEYFRAME').next = False
    
            UseSeparator(self, context)
            layout.operator("screen.animation_play", text="Reverse", icon='PLAY_REVERSE').reverse = True
            layout.operator("screen.animation_play", text="PLAY", icon='PLAY')
            layout.operator("screen.animation_play", text="Stop", icon='PAUSE')
            UseSeparator(self, context)
    
            layout.operator("screen.keyframe_jump", text="Next FR", icon='NEXT_KEYFRAME').next = True
            layout.operator("screen.frame_jump", text="Jump FF", icon='FF').end = True
    
    # Select Menu's #
    
    # Object Select #
    class VIEW3D_MT_Select_Object2(Menu):
        bl_label = "Select"
    
    
        def draw(self, context):
            layout = self.layout
            layout.operator_context = 'INVOKE_REGION_WIN'
    
            layout.operator("view3d.select_box")
    
            layout.operator("object.select_all").action = 'TOGGLE'
            layout.operator("object.select_all", text="Inverse").action = 'INVERT'
            layout.operator("object.select_random", text="Random")
            layout.operator("object.select_mirror", text="Mirror")
    
            layout.operator("object.select_by_layer", text="Select All by Layer")
            layout.operator_menu_enum("object.select_by_type", "type",
                                      text="Select All by Type...")
            layout.operator_menu_enum("object.select_grouped", "type",
                                      text="Grouped")
            layout.operator_menu_enum("object.select_linked", "type",
                                      text="Linked")
    
            layout.operator("object.select_camera", text="Select Camera")
            UseSeparator(self, context)
    
            layout.menu("VIEW3D_MT_Select_Object_More_Less2", text="More/Less")
    
            layout.operator("object.select_pattern", text="Select Pattern...")
    
    
    class VIEW3D_MT_Select_Object_More_Less2(Menu):
        bl_label = "Select More/Less"
    
            layout.operator("object.select_more", text="More")
            layout.operator("object.select_less", text="Less")
            UseSeparator(self, context)
            props = layout.operator("object.select_hierarchy", text="Parent")
            props.extend = False
            props.direction = 'PARENT'
            props = layout.operator("object.select_hierarchy", text="Child")
            props.extend = False
            props.direction = 'CHILD'
            UseSeparator(self, context)
            props = layout.operator("object.select_hierarchy", text="Extend Parent")
            props.extend = True
            props.direction = 'PARENT'
            props = layout.operator("object.select_hierarchy", text="Extend Child")
            props.extend = True
            props.direction = 'CHILD'
    
    
    # Edit Select #
    class VIEW3D_MT_Select_Edit_Mesh2(Menu):
        bl_label = "Select"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_box")
    
            layout.operator("mesh.select_all").action = 'TOGGLE'
            layout.operator("mesh.select_all", text="Inverse").action = 'INVERT'
    
            layout.operator("mesh.select_linked", text="Linked")
            layout.operator("mesh.faces_select_linked_flat",
                            text="Linked Flat Faces")
    
            layout.operator("mesh.select_random", text="Random")
            layout.operator("mesh.select_nth", text="Every N Number of Verts")
    
            layout.menu("VIEW3D_MT_Edit_Mesh_Select_Trait2")
            layout.menu("VIEW3D_MT_Edit_Mesh_Select_Similar2")
            layout.menu("VIEW3D_MT_Edit_Mesh_Select_More_Less2")
    
            UseSeparator(self, context)
            layout.operator("mesh.select_mirror", text="Mirror")
    
            layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
            layout.operator("mesh.select_axis", text="Side of Active")
    
            layout.operator("mesh.shortest_path_select", text="Shortest Path")
            UseSeparator(self, context)
            layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False
            layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True
            layout.operator("mesh.loop_to_region")
            layout.operator("mesh.region_to_loop")
    
    class VIEW3D_MT_Edit_Mesh_Select_Similar2(Menu):
        bl_label = "Select Similar"
    
        def draw(self, context):
            layout = self.layout
            layout.operator_enum("mesh.select_similar", "type")
            layout.operator("mesh.select_similar_region", text="Face Regions")
    
    class VIEW3D_MT_Edit_Mesh_Select_Trait2(Menu):
        bl_label = "Select All by Trait"
    
        def draw(self, context):
            layout = self.layout
            if context.scene.tool_settings.mesh_select_mode[2] is False:
                layout.operator("mesh.select_non_manifold", text="Non Manifold")
            layout.operator("mesh.select_loose", text="Loose Geometry")
            layout.operator("mesh.select_interior_faces", text="Interior Faces")
            layout.operator("mesh.select_face_by_sides", text="By Number of Verts")
            layout.operator("mesh.select_ungrouped", text="Ungrouped Verts")
    
    class VIEW3D_MT_Edit_Mesh_Select_More_Less2(Menu):
        bl_label = "Select More/Less"
    
            layout.operator("mesh.select_more", text="More")
            layout.operator("mesh.select_less", text="Less")
            UseSeparator(self, context)
            layout.operator("mesh.select_next_item", text="Next Active")
            layout.operator("mesh.select_prev_item", text="Previous Active")
    
    
    # Edit Curve Select #
    class VIEW3D_MT_Select_Edit_Curve2(Menu):
        bl_label = "Select"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_box")
    
            layout.operator("curve.select_all").action = 'TOGGLE'
    
            layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
    
            UseSeparator(self, context)
            layout.operator("curve.select_random")
            layout.operator("curve.select_linked", text="Select Linked")
            layout.operator("curve.select_similar", text="Select Similar")
    
            layout.operator("curve.de_select_first")
            layout.operator("curve.de_select_last")
            layout.operator("curve.select_next")
            layout.operator("curve.select_previous")
    
            layout.operator("curve.select_more")
            layout.operator("curve.select_less")
    
    
    # Armature Select #
    class VIEW3D_MT_SelectArmatureMenu2(Menu):
        bl_label = "Select"
    
            layout.operator("view3d.select_box")
    
            layout.operator("armature.select_all")
            layout.operator("armature.select_inverse", text="Inverse")
            layout.operator("armature.select_hierarchy",
                            text="Parent").direction = 'PARENT'
            layout.operator("armature.select_hierarchy",
                            text="Child").direction = 'CHILD'
            props = layout.operator("armature.select_hierarchy",
                                    text="Extend Parent")
            props.extend = True
            props.direction = 'PARENT'
            props = layout.operator("armature.select_hierarchy",
                                    text="Extend Child")
            props.extend = True
            props.direction = 'CHILD'
            layout.operator("object.select_pattern", text="Select Pattern...")
    
    
    
    class VIEW3D_MT_Select_Edit_Armature2(Menu):
        bl_label = "Select"
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
    
            UseSeparator(self, context)
    
            layout.operator("armature.select_all").action = 'TOGGLE'
            layout.operator("armature.select_all", text="Inverse").action = 'INVERT'
            layout.operator("armature.select_mirror", text="Mirror").extend = False
    
            UseSeparator(self, context)
    
            layout.operator("armature.select_more", text="More")
            layout.operator("armature.select_less", text="Less")
    
            UseSeparator(self, context)
    
            props = layout.operator("armature.select_hierarchy", text="Parent")
            props.extend = False
            props.direction = 'PARENT'
    
            props = layout.operator("armature.select_hierarchy", text="Child")
            props.extend = False
            props.direction = 'CHILD'
    
            UseSeparator(self, context)
    
            props = layout.operator("armature.select_hierarchy", text="Extend Parent")
            props.extend = True
            props.direction = 'PARENT'
    
            props = layout.operator("armature.select_hierarchy", text="Extend Child")
            props.extend = True
            props.direction = 'CHILD'
    
            layout.operator_menu_enum("armature.select_similar", "type", text="Similar")
            layout.operator("object.select_pattern", text="Select Pattern...")
    
    
    class VIEW3D_MT_Select_Pose2(Menu):
        bl_label = "Select"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            UseSeparator(self, context)
    
            layout.operator("pose.select_all").action = 'TOGGLE'
            layout.operator("pose.select_all", text="Inverse").action = 'INVERT'
    
            layout.operator("pose.select_mirror", text="Flip Active")
    
            layout.operator("pose.select_constraint_target",
                            text="Constraint Target")
    
            layout.operator("pose.select_linked", text="Linked")
            layout.operator("pose.select_hierarchy",
                            text="Parent").direction = 'PARENT'
            layout.operator("pose.select_hierarchy",
                            text="Child").direction = 'CHILD'
            props = layout.operator("pose.select_hierarchy", text="Extend Parent")
            props.extend = True
            props.direction = 'PARENT'
            props = layout.operator("pose.select_hierarchy", text="Extend Child")
            props.extend = True
            props.direction = 'CHILD'
            layout.operator_menu_enum("pose.select_grouped", "type",
                                      text="Grouped")
    
            layout.operator("object.select_pattern", text="Select Pattern...")
    
            layout.menu("VIEW3D_MT_Select_Pose_More_Less2")
    
    class VIEW3D_MT_Select_Pose_More_Less2(Menu):
        bl_label = "Select More/Less"
    
            props = layout.operator("pose.select_hierarchy", text="Parent")
            props.extend = False
            props.direction = 'PARENT'
    
            props = layout.operator("pose.select_hierarchy", text="Child")
            props.extend = False
            props.direction = 'CHILD'
    
            props = layout.operator("pose.select_hierarchy", text="Extend Parent")
            props.extend = True
            props.direction = 'PARENT'
    
            props = layout.operator("pose.select_hierarchy", text="Extend Child")
            props.extend = True
            props.direction = 'CHILD'
    
    
    class VIEW3D_MT_PoseCopy2(Menu):
        bl_label = "Pose Copy"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("pose.copy")
            layout.operator("pose.paste")
            layout.operator("pose.paste",
                            text="Paste X-Flipped Pose").flipped = True
    
    
    class VIEW3D_MT_PoseNames2(Menu):
        bl_label = "Pose Names"
    
    
        def draw(self, context):
            layout = self.layout
            layout.operator_context = 'EXEC_AREA'
            layout.operator("pose.autoside_names",
                            text="AutoName Left/Right").axis = 'XAXIS'
            layout.operator("pose.autoside_names",
                            text="AutoName Front/Back").axis = 'YAXIS'
            layout.operator("pose.autoside_names",
                            text="AutoName Top/Bottom").axis = 'ZAXIS'
            layout.operator("pose.flip_names")
    
    
    
    # Surface Select #
    class VIEW3D_MT_Select_Edit_Surface2(Menu):
        bl_label = "Select"
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            UseSeparator(self, context)
    
            layout.operator("curve.select_all").action = 'TOGGLE'
    
            layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
    
            layout.operator("curve.select_random")
            layout.operator("curve.select_nth")
    
            layout.operator("curve.select_linked", text="Select Linked")
            layout.operator("curve.select_similar", text="Select Similar")
    
            layout.operator("curve.select_more")
            layout.operator("curve.select_less")
    
    
    # Metaball Select #
    class VIEW3D_MT_SelectMetaball2(Menu):
        bl_label = "Select"
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            UseSeparator(self, context)
    
            layout.operator("mball.select_all").action = 'TOGGLE'
            layout.operator("mball.select_all").action = 'INVERT'
            layout.operator("mball.select_random_metaelems")
    
    
    class VIEW3D_MT_Select_Edit_Metaball2(Menu):
        bl_label = "Select"
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            layout.operator("mball.select_all").action = 'TOGGLE'
            layout.operator("mball.select_all", text="Inverse").action = 'INVERT'
            layout.operator("mball.select_random_metaelems")
            layout.operator_menu_enum("mball.select_similar", "type", text="Similar")
    
    # Particle Select #
    class VIEW3D_MT_Selection_Mode_Particle2(Menu):
        bl_label = "Particle Select and Display Mode"
    
            toolsettings = context.tool_settings
    
            layout.prop(toolsettings.particle_edit, "select_mode", expand=True)
    
    class VIEW3D_MT_Select_Particle2(Menu):
        bl_label = "Select"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            UseSeparator(self, context)
    
            layout.operator("particle.select_all").action = 'TOGGLE'
            layout.operator("particle.select_linked")
            layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
    
            UseSeparator(self, context)
            layout.operator("particle.select_more")
            layout.operator("particle.select_less")
    
            UseSeparator(self, context)
            layout.operator("particle.select_random")
    
            UseSeparator(self, context)
            layout.operator("particle.select_roots", text="Roots")
            layout.operator("particle.select_tips", text="Tips")
    
    # Lattice Edit Select #
    class VIEW3D_MT_Select_Edit_Lattice2(Menu):
        bl_label = "Select"
    
        def draw(self, context):
            layout = self.layout
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            UseSeparator(self, context)
            layout.operator("lattice.select_mirror")
            layout.operator("lattice.select_random")
            layout.operator("lattice.select_all").action = 'TOGGLE'
            layout.operator("lattice.select_all", text="Inverse").action = 'INVERT'
            UseSeparator(self, context)
            layout.operator("lattice.select_ungrouped", text="Ungrouped Verts")
    
    # Grease Pencil Select #
    class VIEW3D_MT_Select_Gpencil2(Menu):
        # To Do: used in 3dview header might work if mapped to mouse
        # Not in Class List yet
        bl_label = "Select"
    
            layout.operator("gpencil.select_box")
    
            layout.operator("gpencil.select_circle")
    
            layout.operator("gpencil.select_all", text="(De)select All").action = 'TOGGLE'
            layout.operator("gpencil.select_all", text="Inverse").action = 'INVERT'
            layout.operator("gpencil.select_linked", text="Linked")
            # layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped")
            layout.operator("gpencil.select_grouped", text="Grouped")
    
            layout.operator("gpencil.select_more")
            layout.operator("gpencil.select_less")
    
    # Text Select #
    class VIEW3D_MT_Select_Edit_Text2(Menu):
        # To Do: used in 3dview header might work if mapped to mouse
        # Not in Class List yet
        bl_label = "Edit"
    
            layout.operator("font.text_copy", text="Copy")
            layout.operator("font.text_cut", text="Cut")
            layout.operator("font.text_paste", text="Paste")
            layout.operator("font.text_paste_from_file")
            layout.operator("font.select_all")
    
    # Paint Mode Menus #
    class VIEW3D_MT_Select_Paint_Mask2(Menu):
        bl_label = "Select"
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            layout.operator("paint.face_select_all").action = 'TOGGLE'
            layout.operator("paint.face_select_all", text="Inverse").action = 'INVERT'
            layout.operator("paint.face_select_linked", text="Linked")
    
    class VIEW3D_MT_Select_Paint_Mask_Vertex2(Menu):
        bl_label = "Select"
    
            layout.operator("view3d.select_box")
    
            layout.operator("view3d.select_circle")
            layout.operator("paint.vert_select_all").action = 'TOGGLE'
            layout.operator("paint.vert_select_all", text="Inverse").action = 'INVERT'
            layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts")
    
    class VIEW3D_MT_Angle_Control2(Menu):
        bl_label = "Angle Control"
    
        @classmethod
        def poll(cls, context):
            settings = UnifiedPaintPanel.paint_settings(context)
            if not settings:
                return False
    
            brush = settings.brush
            tex_slot = brush.texture_slot
    
            return tex_slot.has_texture_angle and tex_slot.has_texture_angle_source
    
            settings = UnifiedPaintPanel.paint_settings(context)
            brush = settings.brush
    
            sculpt = (context.sculpt_object is not None)
    
            tex_slot = brush.texture_slot
    
            layout.prop(tex_slot, "use_rake", text="Rake")
    
            if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle:
                if sculpt:
                    if brush.sculpt_capabilities.has_random_texture_angle:
                        layout.prop(tex_slot, "use_random", text="Random")
                else:
                    layout.prop(tex_slot, "use_random", text="Random")
    
    # Cursor Menu Operators #
    class VIEW3D_OT_Pivot_Cursor2(Operator):
    
        bl_idname = "view3d.pivot_cursor2"
    
        bl_description = "Set Pivot Point back to Cursor"
    
            space = context.space_data
            return (hasattr(space, "pivot_point") and space.pivot_point != 'CURSOR')
    
    
        def execute(self, context):
            bpy.context.space_data.pivot_point = 'CURSOR'
            return {'FINISHED'}
    
    
    class VIEW3D_OT_Revert_Pivot2(Operator):
    
        bl_idname = "view3d.revert_pivot2"
    
        bl_label = "Revert Pivot Point to Median"
        bl_description = "Set Pivot Point back to Median"
    
            space = context.space_data
            return (hasattr(space, "pivot_point") and space.pivot_point != 'MEDIAN_POINT')
    
    
        def execute(self, context):
            bpy.context.space_data.pivot_point = 'MEDIAN_POINT'
            return{'FINISHED'}
    
    
    # Cursor Edge Intersection Defs #
    
    def edgeIntersect(context, operator):
        from mathutils.geometry import intersect_line_line
    
        obj = context.active_object
    
        if (obj.type != "MESH"):
            operator.report({'ERROR'}, "Object must be a mesh")
            return None
    
        edges = []
        mesh = obj.data
        verts = mesh.vertices
    
        is_editmode = (obj.mode == 'EDIT')
        if is_editmode:
            bpy.ops.object.mode_set(mode='OBJECT')
    
        for e in mesh.edges:
            if e.select:
                edges.append(e)
    
                if len(edges) > 2:
                    break
    
        if is_editmode:
            bpy.ops.object.mode_set(mode='EDIT')
    
        if len(edges) != 2:
            operator.report({'ERROR'},
                            "Operator requires exactly 2 edges to be selected")
            return
    
        line = intersect_line_line(verts[edges[0].vertices[0]].co,
                                   verts[edges[0].vertices[1]].co,
                                   verts[edges[1].vertices[0]].co,
                                   verts[edges[1].vertices[1]].co)
    
        if line is None:
            operator.report({'ERROR'}, "Selected edges do not intersect")
            return
    
        point = line[0].lerp(line[1], 0.5)
        context.scene.cursor_location = obj.matrix_world * point
    
    
    # Cursor Edge Intersection Operator #
    class VIEW3D_OT_CursorToEdgeIntersection2(Operator):
    
        bl_idname = "view3d.snap_cursor_to_edge_intersection2"
    
        bl_label = "Cursor to Edge Intersection"
    
        bl_description = "Finds the mid-point of the shortest distance between two edges"
    
    
        @classmethod
        def poll(cls, context):
            obj = context.active_object
    
            return (obj is not None and obj.type == 'MESH')
    
            # Prevent unsupported Execution in Local View modes
            space_data = bpy.context.space_data
            if True in space_data.layers_local_view:
                self.report({'INFO'}, 'Global Perspective modes only unable to continue.')
                return {'FINISHED'}
    
    # Set Mode Operator #
    class SetObjectMode2(Operator):
    
        bl_idname = "object.set_object_mode2"
    
        bl_label = "Set the object interactive mode"
        bl_description = "I set the interactive mode of object"
        bl_options = {'REGISTER'}
    
    
        mode: bpy.props.StringProperty(name="Interactive mode", default="OBJECT")
    
    
        def execute(self, context):
            if (context.active_object):
                try:
                    bpy.ops.object.mode_set(mode=self.mode)
                except TypeError:
                    msg = context.active_object.name + " It is not possible to enter into the interactive mode"
                    self.report(type={"WARNING"}, message=msg)
            else:
                self.report(type={"WARNING"}, message="There is no active object")
            return {'FINISHED'}
    
    
    # Origin To Selected Edit Mode #
    def vfeOrigin(context):
        try:
            cursorPositionX = context.scene.cursor_location[0]
            cursorPositionY = context.scene.cursor_location[1]
            cursorPositionZ = context.scene.cursor_location[2]
            bpy.ops.view3d.snap_cursor_to_selected()
            bpy.ops.object.mode_set()
            bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
            bpy.ops.object.mode_set(mode='EDIT')
            context.scene.cursor_location[0] = cursorPositionX
            context.scene.cursor_location[1] = cursorPositionY
            context.scene.cursor_location[2] = cursorPositionZ
            return True
        except:
            return False
    
    
    class SetOriginToSelected2(Operator):
    
        bl_idname = "object.setorigintoselected2"
    
        bl_label = "Set Origin to Selected"
        bl_description = "Set Origin to Selected"
    
        @classmethod
        def poll(cls, context):
            return (context.area.type == "VIEW_3D" and context.active_object is not None)
    
        def execute(self, context):
            check = vfeOrigin(context)
            if not check:
                self.report({"ERROR"}, "Set Origin to Selected could not be performed")
                return {'CANCELLED'}
    
            return {'FINISHED'}
    
    
    # Code thanks to Isaac Weaver (wisaac) D1963
    class SnapCursSelToCenter2(Operator):
    
        bl_idname = "view3d.snap_cursor_selected_to_center2"
    
        bl_label = "Snap Cursor & Selection to Center"
        bl_description = ("Snap 3D cursor and selected objects to the center \n"
                          "Works only in Object Mode")
    
        @classmethod
        def poll(cls, context):
            return (context.area.type == "VIEW_3D" and context.mode == "OBJECT")
    
        def execute(self, context):
            context.space_data.cursor_location = (0, 0, 0)
            for obj in context.selected_objects:
                obj.location = (0, 0, 0)
            return {'FINISHED'}
    
    
    # Preferences utility functions
    
    # Draw Separator #
    def UseSeparator(operator, context):
    
        useSep = bpy.context.preferences.addons[__name__].preferences.use_separators
    
        if useSep:
            operator.layout.separator()
    
    
    # Use compact brushes menus #
    def UseBrushesLists():
        # separate function just for more convience
    
        useLists = bpy.context.preferences.addons[__name__].preferences.use_brushes_lists
    
    
        return bool(useLists)
    
    
    # Addon Preferences #
    class VIEW3D_MT_Space_Dynamic_Menu_Pref2(bpy.types.AddonPreferences):
        bl_idname = __name__
    
    
        use_separators: bpy.props.BoolProperty(
    
            name="Use Separators in the menus",
            default=True,
            description=("Use separators in the menus, a trade-off between \n"
                         "readability vs. using more space for displaying items")
        )
    
    
        use_brushes_lists: bpy.props.BoolProperty(
    
            name="Use compact menus for brushes",
            default=False,
            description=("Use more compact menus instead  \n"
                         "of thumbnails for displaying brushes")
        )
    
            row = layout.row()
            row.prop(self, "use_separators")
            row.prop(self, "use_brushes_lists")
    
    
    # Addons Preferences Update Panel
    
    meta-androcto's avatar
    meta-androcto committed
    def update_panel(self, context):
        try:
            bpy.utils.unregister_class(VIEW3D_PT_Toolshelf_menu)
        except:
            pass
    
        VIEW3D_PT_Toolshelf_menu.bl_category = context.preferences.addons[__name__].preferences.category
    
        bpy.utils.register_class(VIEW3D_PT_Toolshelf_menu)
    
    # Draw Separator #
    def UseSeparator(operator, context):
    
        useSep = bpy.context.preferences.addons[__name__].preferences.use_separators
    
        if useSep:
            operator.layout.separator()
    
    
    # Use compact brushes menus #
    def UseBrushesLists():
        # separate function just for more convience
    
        useLists = bpy.context.preferences.addons[__name__].preferences.use_brushes_lists
    
    class ToolshelfMenuAddonPreferences(AddonPreferences):
    
    meta-androcto's avatar
    meta-androcto committed
        bl_idname = __name__
    
    
        category: bpy.props.StringProperty(
    
    meta-androcto's avatar
    meta-androcto committed
                name="Category",
                description="Choose a name for the category of the panel",
                default="Dynamic",
                update=update_panel)
    
    
        use_separators: bpy.props.BoolProperty(
    
            name="Use Separators in the menus",
            default=False,
            description=("Use separators in the menus, a trade-off between \n"
                         "readability vs. using more space for displaying items")
        )
    
        use_brushes_lists: bpy.props.BoolProperty(
    
            name="Use compact menus for brushes",
            default=True,
            description=("Use more compact menus instead  \n"
                         "of thumbnails for displaying brushes")
        )
    
        def draw(self, context):
    
    meta-androcto's avatar
    meta-androcto committed
            layout = self.layout
            row = layout.row()
    
            row.prop(self, "use_separators")
            row.prop(self, "use_brushes_lists")
            row = layout.row()
    
    meta-androcto's avatar
    meta-androcto committed
            col = row.column()
            col.label(text="Category:")
            col.prop(self, "category", text="")