Merging trunk up to r38932.
[blender.git] / release / scripts / startup / bl_ui / space_view3d.py
index d5930c3..fdd4833 100644 (file)
@@ -54,21 +54,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 +79,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
@@ -177,6 +174,15 @@ class VIEW3D_MT_transform(bpy.types.Menu):
         layout.operator("object.origin_set", text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
         layout.operator("object.origin_set", text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
 
+        layout.separator()
+
+        layout.operator("object.randomize_transform")
+        layout.operator("object.align")
+        
+        layout.separator()
+        
+        layout.operator("object.anim_transforms_to_deltas")
+
 
 class VIEW3D_MT_mirror(bpy.types.Menu):
     bl_label = "Mirror"
@@ -347,6 +353,30 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu):
         layout.operator("view3d.fly")
 
 
+class VIEW3D_MT_ndof_settings(bpy.types.Menu):
+    bl_label = "3D Mouse Settings"
+
+    def draw(self, context):
+        layout = self.layout
+        input_prefs = context.user_preferences.inputs
+
+        layout.separator()
+        layout.prop(input_prefs, "ndof_sensitivity")
+
+        if context.space_data.type == 'VIEW_3D':
+            layout.separator()
+            layout.prop(input_prefs, "ndof_show_guide")
+
+            layout.separator()
+            layout.label(text="orbit options")
+            layout.prop(input_prefs, "ndof_orbit_invert_axes")
+
+            layout.separator()
+            layout.label(text="fly options")
+            layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY')
+            layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM')
+
+
 class VIEW3D_MT_view_align(bpy.types.Menu):
     bl_label = "Align View"
 
@@ -680,6 +710,7 @@ class VIEW3D_MT_object(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -766,10 +797,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,10 +883,15 @@ class VIEW3D_MT_object_apply(bpy.types.Menu):
     def draw(self, context):
         layout = self.layout
 
-        layout.operator("object.location_apply", text="Location")
-        layout.operator("object.rotation_apply", text="Rotation")
-        layout.operator("object.scale_apply", text="Scale")
+        layout.operator("object.transform_apply", text="Location").location = True
+        layout.operator("object.transform_apply", text="Rotation").rotation = True
+        layout.operator("object.transform_apply", text="Scale").scale = True
+        props = layout.operator("object.transform_apply", text="Rotation & Scale")
+        props.scale = True
+        props.rotation = True
+
         layout.separator()
+
         layout.operator("object.visual_transform_apply", text="Visual Transform")
         layout.operator("object.duplicates_make_real")
 
@@ -1039,6 +1081,7 @@ class VIEW3D_MT_paint_weight(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1053,6 +1096,10 @@ class VIEW3D_MT_paint_weight(bpy.types.Menu):
         layout.operator("object.vertex_group_clean", text="Clean")
         layout.operator("object.vertex_group_levels", text="Levels")
 
+        layout.separator()
+
+        layout.operator("paint.weight_set")
+
 # ********** Sculpt menu **********
 
 
@@ -1082,17 +1129,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")
@@ -1115,6 +1163,7 @@ class VIEW3D_MT_particle(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1168,6 +1217,7 @@ class VIEW3D_MT_pose(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1225,7 +1275,7 @@ 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):
@@ -1346,6 +1396,49 @@ 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(bpy.types.Menu, BoneOptions):
+    bl_label = "Toggle Bone Options"
+    type = 'TOGGLE'
+
+
+class VIEW3D_MT_bone_options_enable(bpy.types.Menu, BoneOptions):
+    bl_label = "Enable Bone Options"
+    type = 'ENABLE'
+
+
+class VIEW3D_MT_bone_options_disable(bpy.types.Menu, BoneOptions):
+    bl_label = "Disable Bone Options"
+    type = 'DISABLE'
+
 # ********** Edit Menus, suffix from ob.type **********
 
 
@@ -1359,6 +1452,7 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1830,6 +1924,7 @@ class VIEW3D_MT_edit_meta(bpy.types.Menu):
 
         layout.operator("ed.undo")
         layout.operator("ed.redo")
+        layout.operator("ed.undo_history")
 
         layout.separator()
 
@@ -1937,7 +2032,7 @@ 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):
@@ -2010,6 +2105,9 @@ class VIEW3D_PT_view3d_properties(bpy.types.Panel):
         elif not view.lock_object:
             col.prop(view, "lock_cursor", text="Lock to Cursor")
 
+        col = layout.column()
+        col.prop(view, "lock_camera")
+
         col = layout.column(align=True)
         col.label(text="Clip:")
         col.prop(view, "clip_start", text="Start")
@@ -2301,7 +2399,8 @@ 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):
@@ -2334,7 +2433,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
@@ -2350,3 +2449,6 @@ def unregister():
 
 if __name__ == "__main__":
     register()
+
+if __name__ == "__main__":  # only for live edit.
+    bpy.utils.register_module(__name__)