Cycles: svn merge -r39457:39669 https://svn.blender.org/svnroot/bf-blender/trunk...
[blender-staging.git] / release / scripts / startup / bl_ui / space_view3d.py
index 2cba1ac1ece367191fe37da3b2fb883ae168b55c..90a49501375937cc69f34a1ed68faaadeacfd7fa 100644 (file)
 
 # <pep8 compliant>
 import bpy
+from bpy.types import Header, Menu, Operator, Panel
 
 
-class VIEW3D_HT_header(bpy.types.Header):
+class VIEW3D_HT_header(Header):
     bl_space_type = 'VIEW_3D'
 
     def draw(self, context):
@@ -54,21 +55,13 @@ class VIEW3D_HT_header(bpy.types.Header):
                 sub.menu("VIEW3D_MT_object")
 
         row = layout.row()
+        # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode...
         row.template_header_3D()
 
-        # do in C for now since these buttons cant be both toggle AND exclusive.
-        '''
-        if obj and obj.mode == 'EDIT' and obj.type == 'MESH':
-            row_sub = row.row(align=True)
-            row_sub.prop(toolsettings, "mesh_select_mode", text="", index=0, icon='VERTEXSEL')
-            row_sub.prop(toolsettings, "mesh_select_mode", text="", index=1, icon='EDGESEL')
-            row_sub.prop(toolsettings, "mesh_select_mode", text="", index=2, icon='FACESEL')
-        '''
-
         if obj:
             # Particle edit
             if obj.mode == 'PARTICLE_EDIT':
-                row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True, toggle=True)
+                row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
 
             # Occlude geometry
             if view.viewport_shade in {'SOLID', 'SHADED', 'TEXTURED'} and (obj.mode == 'PARTICLE_EDIT' or (obj.mode == 'EDIT' and obj.type == 'MESH')):
@@ -87,16 +80,21 @@ class VIEW3D_HT_header(bpy.types.Header):
                     row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True)
 
         # Snap
+        snap_element = toolsettings.snap_element
         row = layout.row(align=True)
         row.prop(toolsettings, "use_snap", text="")
         row.prop(toolsettings, "snap_element", text="", icon_only=True)
-        if toolsettings.snap_element != 'INCREMENT':
+        if snap_element != 'INCREMENT':
             row.prop(toolsettings, "snap_target", text="")
-            if obj and obj.mode == 'OBJECT':
-                row.prop(toolsettings, "use_snap_align_rotation", text="")
-        if toolsettings.snap_element == 'VOLUME':
+            if obj:
+                if obj.mode == 'OBJECT':
+                    row.prop(toolsettings, "use_snap_align_rotation", text="")
+                elif obj.mode == 'EDIT':
+                    row.prop(toolsettings, "use_snap_self", text="")
+
+        if snap_element == 'VOLUME':
             row.prop(toolsettings, "use_snap_peel_object", text="")
-        elif toolsettings.snap_element == 'FACE':
+        elif snap_element == 'FACE':
             row.prop(toolsettings, "use_snap_project", text="")
 
         # OpenGL render
@@ -131,7 +129,7 @@ class ShowHideMenu():
         layout.operator("%s.hide" % self._operator_name, text="Hide Unselected").unselected = True
 
 
-class VIEW3D_MT_transform(bpy.types.Menu):
+class VIEW3D_MT_transform(Menu):
     bl_label = "Transform"
 
     # TODO: get rid of the custom text strings?
@@ -183,7 +181,7 @@ class VIEW3D_MT_transform(bpy.types.Menu):
         layout.operator("object.align")
 
 
-class VIEW3D_MT_mirror(bpy.types.Menu):
+class VIEW3D_MT_mirror(Menu):
     bl_label = "Mirror"
 
     def draw(self, context):
@@ -221,7 +219,7 @@ class VIEW3D_MT_mirror(bpy.types.Menu):
             layout.operator("object.vertex_group_mirror")
 
 
-class VIEW3D_MT_snap(bpy.types.Menu):
+class VIEW3D_MT_snap(Menu):
     bl_label = "Snap"
 
     def draw(self, context):
@@ -238,7 +236,7 @@ class VIEW3D_MT_snap(bpy.types.Menu):
         layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
 
 
-class VIEW3D_MT_uv_map(bpy.types.Menu):
+class VIEW3D_MT_uv_map(Menu):
     bl_label = "UV Mapping"
 
     def draw(self, context):
@@ -271,7 +269,7 @@ class VIEW3D_MT_uv_map(bpy.types.Menu):
 # ********** View menus **********
 
 
-class VIEW3D_MT_view(bpy.types.Menu):
+class VIEW3D_MT_view(Menu):
     bl_label = "View"
 
     def draw(self, context):
@@ -330,7 +328,7 @@ class VIEW3D_MT_view(bpy.types.Menu):
         layout.operator("screen.screen_full_area")
 
 
-class VIEW3D_MT_view_navigation(bpy.types.Menu):
+class VIEW3D_MT_view_navigation(Menu):
     bl_label = "Navigation"
 
     def draw(self, context):
@@ -353,7 +351,7 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu):
         layout.operator("view3d.fly")
 
 
-class VIEW3D_MT_view_align(bpy.types.Menu):
+class VIEW3D_MT_view_align(Menu):
     bl_label = "Align View"
 
     def draw(self, context):
@@ -369,7 +367,7 @@ class VIEW3D_MT_view_align(bpy.types.Menu):
         layout.operator("view3d.view_center_cursor")
 
 
-class VIEW3D_MT_view_align_selected(bpy.types.Menu):
+class VIEW3D_MT_view_align_selected(Menu):
     bl_label = "Align View to Selected"
 
     def draw(self, context):
@@ -395,7 +393,7 @@ class VIEW3D_MT_view_align_selected(bpy.types.Menu):
         props.type = 'LEFT'
 
 
-class VIEW3D_MT_view_cameras(bpy.types.Menu):
+class VIEW3D_MT_view_cameras(Menu):
     bl_label = "Cameras"
 
     def draw(self, context):
@@ -407,7 +405,7 @@ class VIEW3D_MT_view_cameras(bpy.types.Menu):
 # ********** Select menus, suffix from context.mode **********
 
 
-class VIEW3D_MT_select_object(bpy.types.Menu):
+class VIEW3D_MT_select_object(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -433,7 +431,7 @@ class VIEW3D_MT_select_object(bpy.types.Menu):
         layout.operator("object.select_pattern", text="Select Pattern...")
 
 
-class VIEW3D_MT_select_pose(bpy.types.Menu):
+class VIEW3D_MT_select_pose(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -470,7 +468,7 @@ class VIEW3D_MT_select_pose(bpy.types.Menu):
         layout.operator("object.select_pattern", text="Select Pattern...")
 
 
-class VIEW3D_MT_select_particle(bpy.types.Menu):
+class VIEW3D_MT_select_particle(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -495,7 +493,7 @@ class VIEW3D_MT_select_particle(bpy.types.Menu):
         layout.operator("particle.select_tips", text="Tips")
 
 
-class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
+class VIEW3D_MT_select_edit_mesh(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -547,7 +545,7 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
         layout.operator("mesh.region_to_loop")
 
 
-class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
+class VIEW3D_MT_select_edit_curve(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -576,7 +574,7 @@ class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
         layout.operator("curve.select_less")
 
 
-class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
+class VIEW3D_MT_select_edit_surface(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -602,7 +600,7 @@ class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
         layout.operator("curve.select_less")
 
 
-class VIEW3D_MT_select_edit_metaball(bpy.types.Menu):
+class VIEW3D_MT_select_edit_metaball(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -620,7 +618,7 @@ class VIEW3D_MT_select_edit_metaball(bpy.types.Menu):
         layout.operator("mball.select_random_metaelems")
 
 
-class VIEW3D_MT_select_edit_lattice(bpy.types.Menu):
+class VIEW3D_MT_select_edit_lattice(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -633,7 +631,7 @@ class VIEW3D_MT_select_edit_lattice(bpy.types.Menu):
         layout.operator("lattice.select_all", text="Select/Deselect All")
 
 
-class VIEW3D_MT_select_edit_armature(bpy.types.Menu):
+class VIEW3D_MT_select_edit_armature(Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -664,7 +662,7 @@ class VIEW3D_MT_select_edit_armature(bpy.types.Menu):
         layout.operator("object.select_pattern", text="Select Pattern...")
 
 
-class VIEW3D_MT_select_face(bpy.types.Menu):  # XXX no matching enum
+class VIEW3D_MT_select_face(Menu):  # XXX no matching enum
     bl_label = "Select"
 
     def draw(self, context):
@@ -677,7 +675,7 @@ class VIEW3D_MT_select_face(bpy.types.Menu):  # XXX no matching enum
 # ********** Object menu **********
 
 
-class VIEW3D_MT_object(bpy.types.Menu):
+class VIEW3D_MT_object(Menu):
     bl_context = "objectmode"
     bl_label = "Object"
 
@@ -686,6 +684,7 @@ class VIEW3D_MT_object(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -734,7 +733,7 @@ class VIEW3D_MT_object(bpy.types.Menu):
         layout.operator_menu_enum("object.convert", "target")
 
 
-class VIEW3D_MT_object_animation(bpy.types.Menu):
+class VIEW3D_MT_object_animation(Menu):
     bl_label = "Animation"
 
     def draw(self, context):
@@ -745,7 +744,7 @@ class VIEW3D_MT_object_animation(bpy.types.Menu):
         layout.operator("anim.keying_set_active_set", text="Change Keying Set...")
 
 
-class VIEW3D_MT_object_clear(bpy.types.Menu):
+class VIEW3D_MT_object_clear(Menu):
     bl_label = "Clear"
 
     def draw(self, context):
@@ -757,7 +756,7 @@ class VIEW3D_MT_object_clear(bpy.types.Menu):
         layout.operator("object.origin_clear", text="Origin")
 
 
-class VIEW3D_MT_object_specials(bpy.types.Menu):
+class VIEW3D_MT_object_specials(Menu):
     bl_label = "Specials"
 
     @classmethod
@@ -772,10 +771,16 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
         if obj.type == 'CAMERA':
             layout.operator_context = 'INVOKE_REGION_WIN'
 
-            props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
-            props.data_path_iter = "selected_editable_objects"
-            props.data_path_item = "data.lens"
-            props.input_scale = 0.1
+            if obj.data.type == 'PERSP':
+                props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
+                props.data_path_iter = "selected_editable_objects"
+                props.data_path_item = "data.lens"
+                props.input_scale = 0.1
+            else:
+                props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
+                props.data_path_iter = "selected_editable_objects"
+                props.data_path_item = "data.ortho_scale"
+                props.input_scale = 0.01
 
             if not obj.data.dof_object:
                 #layout.label(text="Test Has DOF obj");
@@ -846,7 +851,7 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
         props = layout.operator("object.hide_render_clear_all")
 
 
-class VIEW3D_MT_object_apply(bpy.types.Menu):
+class VIEW3D_MT_object_apply(Menu):
     bl_label = "Apply"
 
     def draw(self, context):
@@ -865,7 +870,7 @@ class VIEW3D_MT_object_apply(bpy.types.Menu):
         layout.operator("object.duplicates_make_real")
 
 
-class VIEW3D_MT_object_parent(bpy.types.Menu):
+class VIEW3D_MT_object_parent(Menu):
     bl_label = "Parent"
 
     def draw(self, context):
@@ -875,7 +880,7 @@ class VIEW3D_MT_object_parent(bpy.types.Menu):
         layout.operator("object.parent_clear", text="Clear")
 
 
-class VIEW3D_MT_object_track(bpy.types.Menu):
+class VIEW3D_MT_object_track(Menu):
     bl_label = "Track"
 
     def draw(self, context):
@@ -885,7 +890,7 @@ class VIEW3D_MT_object_track(bpy.types.Menu):
         layout.operator("object.track_clear", text="Clear")
 
 
-class VIEW3D_MT_object_group(bpy.types.Menu):
+class VIEW3D_MT_object_group(Menu):
     bl_label = "Group"
 
     def draw(self, context):
@@ -900,7 +905,7 @@ class VIEW3D_MT_object_group(bpy.types.Menu):
         layout.operator("group.objects_remove_active")
 
 
-class VIEW3D_MT_object_constraints(bpy.types.Menu):
+class VIEW3D_MT_object_constraints(Menu):
     bl_label = "Constraints"
 
     def draw(self, context):
@@ -911,7 +916,7 @@ class VIEW3D_MT_object_constraints(bpy.types.Menu):
         layout.operator("object.constraints_clear")
 
 
-class VIEW3D_MT_object_showhide(bpy.types.Menu):
+class VIEW3D_MT_object_showhide(Menu):
     bl_label = "Show/Hide"
 
     def draw(self, context):
@@ -922,7 +927,7 @@ class VIEW3D_MT_object_showhide(bpy.types.Menu):
         layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
 
 
-class VIEW3D_MT_make_single_user(bpy.types.Menu):
+class VIEW3D_MT_make_single_user(Menu):
     bl_label = "Make Single User"
 
     def draw(self, context):
@@ -944,7 +949,7 @@ class VIEW3D_MT_make_single_user(bpy.types.Menu):
         props.animation = True
 
 
-class VIEW3D_MT_make_links(bpy.types.Menu):
+class VIEW3D_MT_make_links(Menu):
     bl_label = "Make Links"
 
     def draw(self, context):
@@ -961,7 +966,7 @@ class VIEW3D_MT_make_links(bpy.types.Menu):
         layout.operator_enum("object.make_links_data", "type")  # inline
 
 
-class VIEW3D_MT_object_game(bpy.types.Menu):
+class VIEW3D_MT_object_game(Menu):
     bl_label = "Game"
 
     def draw(self, context):
@@ -983,7 +988,7 @@ class VIEW3D_MT_object_game(bpy.types.Menu):
 # ********** Vertex paint menu **********
 
 
-class VIEW3D_MT_paint_vertex(bpy.types.Menu):
+class VIEW3D_MT_paint_vertex(Menu):
     bl_label = "Paint"
 
     def draw(self, context):
@@ -998,7 +1003,7 @@ class VIEW3D_MT_paint_vertex(bpy.types.Menu):
         layout.operator("paint.vertex_color_dirt")
 
 
-class VIEW3D_MT_hook(bpy.types.Menu):
+class VIEW3D_MT_hook(Menu):
     bl_label = "Hooks"
 
     def draw(self, context):
@@ -1017,7 +1022,7 @@ class VIEW3D_MT_hook(bpy.types.Menu):
             layout.operator_menu_enum("object.hook_recenter", "modifier")
 
 
-class VIEW3D_MT_vertex_group(bpy.types.Menu):
+class VIEW3D_MT_vertex_group(Menu):
     bl_label = "Vertex Groups"
 
     def draw(self, context):
@@ -1042,7 +1047,7 @@ class VIEW3D_MT_vertex_group(bpy.types.Menu):
 # ********** Weight paint menu **********
 
 
-class VIEW3D_MT_paint_weight(bpy.types.Menu):
+class VIEW3D_MT_paint_weight(Menu):
     bl_label = "Weights"
 
     def draw(self, context):
@@ -1050,6 +1055,7 @@ class VIEW3D_MT_paint_weight(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1071,7 +1077,7 @@ class VIEW3D_MT_paint_weight(bpy.types.Menu):
 # ********** Sculpt menu **********
 
 
-class VIEW3D_MT_sculpt(bpy.types.Menu):
+class VIEW3D_MT_sculpt(Menu):
     bl_label = "Sculpt"
 
     def draw(self, context):
@@ -1097,17 +1103,18 @@ class VIEW3D_MT_sculpt(bpy.types.Menu):
         layout.operator_menu_enum("brush.curve_preset", "shape")
         layout.separator()
 
-        sculpt_tool = brush.sculpt_tool
+        if brush is not None:  # unlikely but can happen
+            sculpt_tool = brush.sculpt_tool
 
-        if sculpt_tool != 'GRAB':
-            layout.prop_menu_enum(brush, "stroke_method")
+            if sculpt_tool != 'GRAB':
+                layout.prop_menu_enum(brush, "stroke_method")
 
-            if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
-                layout.prop_menu_enum(brush, "direction")
+                if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
+                    layout.prop_menu_enum(brush, "direction")
 
-            if sculpt_tool == 'LAYER':
-                layout.prop(brush, "use_persistent")
-                layout.operator("sculpt.set_persistent_base")
+                if sculpt_tool == 'LAYER':
+                    layout.prop(brush, "use_persistent")
+                    layout.operator("sculpt.set_persistent_base")
 
         layout.separator()
         layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
@@ -1120,7 +1127,7 @@ class VIEW3D_MT_sculpt(bpy.types.Menu):
 # ********** Particle menu **********
 
 
-class VIEW3D_MT_particle(bpy.types.Menu):
+class VIEW3D_MT_particle(Menu):
     bl_label = "Particle"
 
     def draw(self, context):
@@ -1130,6 +1137,7 @@ class VIEW3D_MT_particle(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1151,7 +1159,7 @@ class VIEW3D_MT_particle(bpy.types.Menu):
         layout.menu("VIEW3D_MT_particle_showhide")
 
 
-class VIEW3D_MT_particle_specials(bpy.types.Menu):
+class VIEW3D_MT_particle_specials(Menu):
     bl_label = "Specials"
 
     def draw(self, context):
@@ -1169,13 +1177,13 @@ class VIEW3D_MT_particle_specials(bpy.types.Menu):
         layout.operator("particle.remove_doubles")
 
 
-class VIEW3D_MT_particle_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
     _operator_name = "particle"
 
 # ********** Pose Menu **********
 
 
-class VIEW3D_MT_pose(bpy.types.Menu):
+class VIEW3D_MT_pose(Menu):
     bl_label = "Pose"
 
     def draw(self, context):
@@ -1183,6 +1191,7 @@ class VIEW3D_MT_pose(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1240,10 +1249,10 @@ class VIEW3D_MT_pose(bpy.types.Menu):
         layout.separator()
 
         layout.menu("VIEW3D_MT_pose_showhide")
-        layout.operator_menu_enum("pose.flags_set", 'mode', text="Bone Settings")
+        layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
 
 
-class VIEW3D_MT_pose_transform(bpy.types.Menu):
+class VIEW3D_MT_pose_transform(Menu):
     bl_label = "Clear Transform"
 
     def draw(self, context):
@@ -1258,7 +1267,7 @@ class VIEW3D_MT_pose_transform(bpy.types.Menu):
         layout.label(text="Origin")
 
 
-class VIEW3D_MT_pose_slide(bpy.types.Menu):
+class VIEW3D_MT_pose_slide(Menu):
     bl_label = "In-Betweens"
 
     def draw(self, context):
@@ -1269,7 +1278,7 @@ class VIEW3D_MT_pose_slide(bpy.types.Menu):
         layout.operator("pose.breakdown")
 
 
-class VIEW3D_MT_pose_propagate(bpy.types.Menu):
+class VIEW3D_MT_pose_propagate(Menu):
     bl_label = "Propagate"
 
     def draw(self, context):
@@ -1287,7 +1296,7 @@ class VIEW3D_MT_pose_propagate(bpy.types.Menu):
         layout.operator("pose.propagate", text="On Selected Markers").mode = 'SELECTED_MARKERS'
 
 
-class VIEW3D_MT_pose_library(bpy.types.Menu):
+class VIEW3D_MT_pose_library(Menu):
     bl_label = "Pose Library"
 
     def draw(self, context):
@@ -1302,7 +1311,7 @@ class VIEW3D_MT_pose_library(bpy.types.Menu):
         layout.operator("poselib.pose_remove", text="Remove Pose...")
 
 
-class VIEW3D_MT_pose_motion(bpy.types.Menu):
+class VIEW3D_MT_pose_motion(Menu):
     bl_label = "Motion Paths"
 
     def draw(self, context):
@@ -1312,7 +1321,7 @@ class VIEW3D_MT_pose_motion(bpy.types.Menu):
         layout.operator("pose.paths_clear", text="Clear")
 
 
-class VIEW3D_MT_pose_group(bpy.types.Menu):
+class VIEW3D_MT_pose_group(Menu):
     bl_label = "Bone Groups"
 
     def draw(self, context):
@@ -1326,7 +1335,7 @@ class VIEW3D_MT_pose_group(bpy.types.Menu):
         layout.operator("pose.group_unassign")
 
 
-class VIEW3D_MT_pose_ik(bpy.types.Menu):
+class VIEW3D_MT_pose_ik(Menu):
     bl_label = "Inverse Kinematics"
 
     def draw(self, context):
@@ -1336,7 +1345,7 @@ class VIEW3D_MT_pose_ik(bpy.types.Menu):
         layout.operator("pose.ik_clear")
 
 
-class VIEW3D_MT_pose_constraints(bpy.types.Menu):
+class VIEW3D_MT_pose_constraints(Menu):
     bl_label = "Constraints"
 
     def draw(self, context):
@@ -1347,11 +1356,11 @@ class VIEW3D_MT_pose_constraints(bpy.types.Menu):
         layout.operator("pose.constraints_clear")
 
 
-class VIEW3D_MT_pose_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_pose_showhide(ShowHideMenu, Menu):
     _operator_name = "pose"
 
 
-class VIEW3D_MT_pose_apply(bpy.types.Menu):
+class VIEW3D_MT_pose_apply(Menu):
     bl_label = "Apply"
 
     def draw(self, context):
@@ -1361,10 +1370,53 @@ class VIEW3D_MT_pose_apply(bpy.types.Menu):
         layout.operator("pose.visual_transform_apply")
 
 
+class BoneOptions:
+    def draw(self, context):
+        layout = self.layout
+
+        options = [
+            "show_wire",
+            "use_deform",
+            "use_envelope_multiply",
+            "use_inherit_rotation",
+            "use_inherit_scale",
+        ]
+
+        if context.mode == 'EDIT_ARMATURE':
+            bone_props = bpy.types.EditBone.bl_rna.properties
+            data_path_iter = "selected_bones"
+            opt_suffix = ""
+            options.append("lock")
+        else:  # posemode
+            bone_props = bpy.types.Bone.bl_rna.properties
+            data_path_iter = "selected_pose_bones"
+            opt_suffix = "bone."
+
+        for opt in options:
+            props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name)
+            props.data_path_iter = data_path_iter
+            props.data_path_item = opt_suffix + opt
+            props.type = self.type
+
+
+class VIEW3D_MT_bone_options_toggle(Menu, BoneOptions):
+    bl_label = "Toggle Bone Options"
+    type = 'TOGGLE'
+
+
+class VIEW3D_MT_bone_options_enable(Menu, BoneOptions):
+    bl_label = "Enable Bone Options"
+    type = 'ENABLE'
+
+
+class VIEW3D_MT_bone_options_disable(Menu, BoneOptions):
+    bl_label = "Disable Bone Options"
+    type = 'DISABLE'
+
 # ********** Edit Menus, suffix from ob.type **********
 
 
-class VIEW3D_MT_edit_mesh(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh(Menu):
     bl_label = "Mesh"
 
     def draw(self, context):
@@ -1374,6 +1426,7 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1410,7 +1463,7 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu):
         layout.menu("VIEW3D_MT_edit_mesh_showhide")
 
 
-class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_specials(Menu):
     bl_label = "Specials"
 
     def draw(self, context):
@@ -1435,7 +1488,7 @@ class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu):
         layout.operator("mesh.select_vertex_path")
 
 
-class VIEW3D_MT_edit_mesh_select_mode(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_select_mode(Menu):
     bl_label = "Mesh Select Mode"
 
     def draw(self, context):
@@ -1456,7 +1509,7 @@ class VIEW3D_MT_edit_mesh_select_mode(bpy.types.Menu):
         prop.data_path = "tool_settings.mesh_select_mode"
 
 
-class VIEW3D_MT_edit_mesh_extrude(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_extrude(Menu):
     bl_label = "Extrude"
 
     _extrude_funcs = { \
@@ -1490,7 +1543,7 @@ class VIEW3D_MT_edit_mesh_extrude(bpy.types.Menu):
             self._extrude_funcs[menu_id](layout)
 
 
-class VIEW3D_OT_edit_mesh_extrude_individual_move(bpy.types.Operator):
+class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
     "Extrude individual elements and move"
     bl_label = "Extrude Individual and Move"
     bl_idname = "view3d.edit_mesh_extrude_individual_move"
@@ -1519,7 +1572,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(bpy.types.Operator):
         return self.execute(context)
 
 
-class VIEW3D_OT_edit_mesh_extrude_move(bpy.types.Operator):
+class VIEW3D_OT_edit_mesh_extrude_move(Operator):
     "Extrude and move along normals"
     bl_label = "Extrude and Move on Normals"
     bl_idname = "view3d.edit_mesh_extrude_move_normal"
@@ -1545,7 +1598,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(bpy.types.Operator):
         return self.execute(context)
 
 
-class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_vertices(Menu):
     bl_label = "Vertices"
 
     def draw(self, context):
@@ -1577,7 +1630,7 @@ class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
         layout.menu("VIEW3D_MT_hook")
 
 
-class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_edges(Menu):
     bl_label = "Edges"
 
     def draw(self, context):
@@ -1617,7 +1670,7 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
         layout.operator("mesh.region_to_loop")
 
 
-class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_faces(Menu):
     bl_label = "Faces"
     bl_idname = "VIEW3D_MT_edit_mesh_faces"
 
@@ -1665,7 +1718,7 @@ class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
         layout.operator_menu_enum("mesh.colors_mirror", "axis")
 
 
-class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_normals(Menu):
     bl_label = "Normals"
 
     def draw(self, context):
@@ -1679,7 +1732,7 @@ class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu):
         layout.operator("mesh.flip_normals")
 
 
-class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu):
     _operator_name = "mesh"
 
 # Edit Curve
@@ -1719,13 +1772,13 @@ def draw_curve(self, context):
     layout.menu("VIEW3D_MT_edit_curve_showhide")
 
 
-class VIEW3D_MT_edit_curve(bpy.types.Menu):
+class VIEW3D_MT_edit_curve(Menu):
     bl_label = "Curve"
 
     draw = draw_curve
 
 
-class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_ctrlpoints(Menu):
     bl_label = "Control Points"
 
     def draw(self, context):
@@ -1747,7 +1800,7 @@ class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu):
             layout.menu("VIEW3D_MT_hook")
 
 
-class VIEW3D_MT_edit_curve_segments(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_segments(Menu):
     bl_label = "Segments"
 
     def draw(self, context):
@@ -1757,7 +1810,7 @@ class VIEW3D_MT_edit_curve_segments(bpy.types.Menu):
         layout.operator("curve.switch_direction")
 
 
-class VIEW3D_MT_edit_curve_specials(bpy.types.Menu):
+class VIEW3D_MT_edit_curve_specials(Menu):
     bl_label = "Specials"
 
     def draw(self, context):
@@ -1771,17 +1824,17 @@ class VIEW3D_MT_edit_curve_specials(bpy.types.Menu):
         layout.operator("curve.smooth_radius")
 
 
-class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, bpy.types.Menu):
+class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, Menu):
     _operator_name = "curve"
 
 
-class VIEW3D_MT_edit_surface(bpy.types.Menu):
+class VIEW3D_MT_edit_surface(Menu):
     bl_label = "Surface"
 
     draw = draw_curve
 
 
-class VIEW3D_MT_edit_font(bpy.types.Menu):
+class VIEW3D_MT_edit_font(Menu):
     bl_label = "Text"
 
     def draw(self, context):
@@ -1801,7 +1854,7 @@ class VIEW3D_MT_edit_font(bpy.types.Menu):
         layout.operator("font.style_toggle", text="Toggle Small Caps").style = 'SMALL_CAPS'
 
 
-class VIEW3D_MT_edit_text_chars(bpy.types.Menu):
+class VIEW3D_MT_edit_text_chars(Menu):
     bl_label = "Special Characters"
 
     def draw(self, context):
@@ -1835,7 +1888,7 @@ class VIEW3D_MT_edit_text_chars(bpy.types.Menu):
         layout.operator("font.text_insert", text="Spanish Exclamation Mark|Alt !").text = b'\xC2\xA1'.decode()
 
 
-class VIEW3D_MT_edit_meta(bpy.types.Menu):
+class VIEW3D_MT_edit_meta(Menu):
     bl_label = "Metaball"
 
     def draw(self, context):
@@ -1845,6 +1898,7 @@ class VIEW3D_MT_edit_meta(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1867,7 +1921,7 @@ class VIEW3D_MT_edit_meta(bpy.types.Menu):
         layout.menu("VIEW3D_MT_edit_meta_showhide")
 
 
-class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu):
+class VIEW3D_MT_edit_meta_showhide(Menu):
     bl_label = "Show/Hide"
 
     def draw(self, context):
@@ -1878,7 +1932,7 @@ class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu):
         layout.operator("mball.hide_metaelems", text="Hide Unselected").unselected = True
 
 
-class VIEW3D_MT_edit_lattice(bpy.types.Menu):
+class VIEW3D_MT_edit_lattice(Menu):
     bl_label = "Lattice"
 
     def draw(self, context):
@@ -1900,7 +1954,7 @@ class VIEW3D_MT_edit_lattice(bpy.types.Menu):
         layout.prop_menu_enum(settings, "proportional_edit_falloff")
 
 
-class VIEW3D_MT_edit_armature(bpy.types.Menu):
+class VIEW3D_MT_edit_armature(Menu):
     bl_label = "Armature"
 
     def draw(self, context):
@@ -1952,10 +2006,10 @@ class VIEW3D_MT_edit_armature(bpy.types.Menu):
 
         layout.separator()
 
-        layout.operator_menu_enum("armature.flags_set", "mode", text="Bone Settings")
+        layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
 
 
-class VIEW3D_MT_armature_specials(bpy.types.Menu):
+class VIEW3D_MT_armature_specials(Menu):
     bl_label = "Specials"
 
     def draw(self, context):
@@ -1975,7 +2029,7 @@ class VIEW3D_MT_armature_specials(bpy.types.Menu):
         layout.operator("armature.flip_names", text="Flip Names")
 
 
-class VIEW3D_MT_edit_armature_parent(bpy.types.Menu):
+class VIEW3D_MT_edit_armature_parent(Menu):
     bl_label = "Parent"
 
     def draw(self, context):
@@ -1985,7 +2039,7 @@ class VIEW3D_MT_edit_armature_parent(bpy.types.Menu):
         layout.operator("armature.parent_clear", text="Clear")
 
 
-class VIEW3D_MT_edit_armature_roll(bpy.types.Menu):
+class VIEW3D_MT_edit_armature_roll(Menu):
     bl_label = "Bone Roll"
 
     def draw(self, context):
@@ -2000,7 +2054,7 @@ class VIEW3D_MT_edit_armature_roll(bpy.types.Menu):
 # ********** Panel **********
 
 
-class VIEW3D_PT_view3d_properties(bpy.types.Panel):
+class VIEW3D_PT_view3d_properties(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "View"
@@ -2020,9 +2074,11 @@ class VIEW3D_PT_view3d_properties(bpy.types.Panel):
         col.prop(view, "lens")
         col.label(text="Lock to Object:")
         col.prop(view, "lock_object", text="")
-        if view.lock_object and view.lock_object.type == 'ARMATURE':
-            col.prop_search(view, "lock_bone", view.lock_object.data, "bones", text="")
-        elif not view.lock_object:
+        lock_object = view.lock_object
+        if lock_object:
+            if lock_object.type == 'ARMATURE':
+                col.prop_search(view, "lock_bone", lock_object.data, "edit_bones" if lock_object.mode == 'EDIT' else "bones", text="")
+        else:
             col.prop(view, "lock_cursor", text="Lock to Cursor")
 
         col = layout.column()
@@ -2041,7 +2097,7 @@ class VIEW3D_PT_view3d_properties(bpy.types.Panel):
         layout.column().prop(view, "cursor_location")
 
 
-class VIEW3D_PT_view3d_name(bpy.types.Panel):
+class VIEW3D_PT_view3d_name(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Item"
@@ -2066,7 +2122,7 @@ class VIEW3D_PT_view3d_name(bpy.types.Panel):
                 row.prop(bone, "name", text="")
 
 
-class VIEW3D_PT_view3d_display(bpy.types.Panel):
+class VIEW3D_PT_view3d_display(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Display"
@@ -2119,7 +2175,6 @@ class VIEW3D_PT_view3d_display(bpy.types.Panel):
         col = layout.column()
         col.label(text="Shading:")
         col.prop(gs, "material_mode", text="")
-        col.prop(view, "show_textured_solid")
 
         layout.separator()
 
@@ -2138,7 +2193,7 @@ class VIEW3D_PT_view3d_display(bpy.types.Panel):
             row.prop(region, "use_box_clip")
 
 
-class VIEW3D_PT_view3d_meshdisplay(bpy.types.Panel):
+class VIEW3D_PT_view3d_meshdisplay(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Mesh Display"
@@ -2175,7 +2230,7 @@ class VIEW3D_PT_view3d_meshdisplay(bpy.types.Panel):
         col.prop(mesh, "show_extra_face_area")
 
 
-class VIEW3D_PT_view3d_curvedisplay(bpy.types.Panel):
+class VIEW3D_PT_view3d_curvedisplay(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Curve Display"
@@ -2197,7 +2252,7 @@ class VIEW3D_PT_view3d_curvedisplay(bpy.types.Panel):
         col.prop(context.scene.tool_settings, "normal_size", text="Normal Size")
 
 
-class VIEW3D_PT_background_image(bpy.types.Panel):
+class VIEW3D_PT_background_image(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Background Images"
@@ -2250,7 +2305,7 @@ class VIEW3D_PT_background_image(bpy.types.Panel):
                         row.prop(bg, "offset_y", text="Y")
 
 
-class VIEW3D_PT_transform_orientations(bpy.types.Panel):
+class VIEW3D_PT_transform_orientations(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Transform Orientations"
@@ -2278,7 +2333,7 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel):
             col.operator("transform.delete_orientation", text="Delete")
 
 
-class VIEW3D_PT_etch_a_ton(bpy.types.Panel):
+class VIEW3D_PT_etch_a_ton(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Skeleton Sketching"
@@ -2319,10 +2374,11 @@ class VIEW3D_PT_etch_a_ton(bpy.types.Panel):
             col.prop(toolsettings, "use_etch_autoname")
             col.prop(toolsettings, "etch_number")
             col.prop(toolsettings, "etch_side")
-            col.operator("sketch.convert", text="Convert")
+
+        col.operator("sketch.convert", text="Convert")
 
 
-class VIEW3D_PT_context_properties(bpy.types.Panel):
+class VIEW3D_PT_context_properties(Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
     bl_label = "Properties"
@@ -2352,7 +2408,7 @@ class VIEW3D_PT_context_properties(bpy.types.Panel):
 
     def draw(self, context):
         import rna_prop_ui
-        member = __class__._active_context_member(context)
+        member = VIEW3D_PT_context_properties._active_context_member(context)
 
         if member:
             # Draw with no edit button