b4525d4f4986dc0d2534fb81df4bc3459aecdf95
[blender-staging.git] / release / scripts / startup / bl_ui / space_view3d.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from bpy.types import Header, Menu, Panel
22 from bl_ui.properties_grease_pencil_common import GreasePencilDataPanel
23 from bl_ui.properties_paint_common import UnifiedPaintPanel
24 from bpy.app.translations import contexts as i18n_contexts
25
26
27 class VIEW3D_HT_header(Header):
28     bl_space_type = 'VIEW_3D'
29
30     def draw(self, context):
31         layout = self.layout
32
33         view = context.space_data
34         # mode_string = context.mode
35         obj = context.active_object
36         toolsettings = context.tool_settings
37
38         row = layout.row(align=True)
39         row.template_header()
40         sub = row.row(align=True)
41
42         VIEW3D_MT_editor_menus.draw_collapsible(context, layout)
43
44         # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode...
45         row = layout
46         layout.template_header_3D()
47
48         if obj:
49             mode = obj.mode
50             # Particle edit
51             if mode == 'PARTICLE_EDIT':
52                 row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
53
54             # Occlude geometry
55             if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
56                     (mode == 'WEIGHT_PAINT')):
57                 row.prop(view, "use_occlude_geometry", text="")
58
59             # Proportional editing
60             if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
61                 row = layout.row(align=True)
62                 row.prop(toolsettings, "proportional_edit", icon_only=True)
63                 if toolsettings.proportional_edit != 'DISABLED':
64                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
65             elif mode in {'EDIT', 'PARTICLE_EDIT'}:
66                 row = layout.row(align=True)
67                 row.prop(toolsettings, "proportional_edit", icon_only=True)
68                 if toolsettings.proportional_edit != 'DISABLED':
69                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
70             elif mode == 'OBJECT':
71                 row = layout.row(align=True)
72                 row.prop(toolsettings, "use_proportional_edit_objects", icon_only=True)
73                 if toolsettings.use_proportional_edit_objects:
74                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
75         else:
76             # Proportional editing
77             if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
78                 row = layout.row(align=True)
79                 row.prop(toolsettings, "proportional_edit", icon_only=True)
80                 if toolsettings.proportional_edit != 'DISABLED':
81                     row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
82
83         # Snap
84         if not obj or mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}:
85             snap_element = toolsettings.snap_element
86             row = layout.row(align=True)
87             row.prop(toolsettings, "use_snap", text="")
88             row.prop(toolsettings, "snap_element", icon_only=True)
89             if snap_element == 'INCREMENT':
90                 row.prop(toolsettings, "use_snap_grid_absolute", text="")
91             else:
92                 row.prop(toolsettings, "snap_target", text="")
93                 if obj:
94                     if mode in {'OBJECT', 'POSE'} and snap_element != 'VOLUME':
95                         row.prop(toolsettings, "use_snap_align_rotation", text="")
96                     elif mode == 'EDIT':
97                         row.prop(toolsettings, "use_snap_self", text="")
98
99             if snap_element == 'VOLUME':
100                 row.prop(toolsettings, "use_snap_peel_object", text="")
101             elif snap_element == 'FACE':
102                 row.prop(toolsettings, "use_snap_project", text="")
103
104         # AutoMerge editing
105         if obj:
106             if (mode == 'EDIT' and obj.type == 'MESH'):
107                 layout.prop(toolsettings, "use_mesh_automerge", text="", icon='AUTOMERGE_ON')
108
109         # OpenGL render
110         row = layout.row(align=True)
111         row.operator("render.opengl", text="", icon='RENDER_STILL')
112         row.operator("render.opengl", text="", icon='RENDER_ANIMATION').animation = True
113
114         # Pose
115         if obj and mode == 'POSE':
116             row = layout.row(align=True)
117             row.operator("pose.copy", text="", icon='COPYDOWN')
118             row.operator("pose.paste", text="", icon='PASTEDOWN').flipped = False
119             row.operator("pose.paste", text="", icon='PASTEFLIPDOWN').flipped = True
120
121         # GPencil
122         if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
123             row = layout.row(align=True)
124             row.operator("gpencil.copy", text="", icon='COPYDOWN')
125             row.operator("gpencil.paste", text="", icon='PASTEDOWN')
126
127             layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH') # XXX: icon
128
129             layout.prop(context.tool_settings.gpencil_sculpt, "use_select_mask")
130
131
132
133
134 class VIEW3D_MT_editor_menus(Menu):
135     bl_space_type = 'VIEW3D_MT_editor_menus'
136     bl_label = ""
137
138     def draw(self, context):
139         self.draw_menus(self.layout, context)
140
141     @staticmethod
142     def draw_menus(layout, context):
143         obj = context.active_object
144         mode_string = context.mode
145         edit_object = context.edit_object
146         gp_edit = context.gpencil_data and context.gpencil_data.use_stroke_edit_mode
147
148         layout.menu("VIEW3D_MT_view")
149
150         # Select Menu
151         if gp_edit:
152             layout.menu("VIEW3D_MT_select_gpencil")
153         elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
154             mesh = obj.data
155             if mesh.use_paint_mask:
156                 layout.menu("VIEW3D_MT_select_paint_mask")
157             elif mesh.use_paint_mask_vertex and mode_string == 'PAINT_WEIGHT':
158                 layout.menu("VIEW3D_MT_select_paint_mask_vertex")
159         elif mode_string != 'SCULPT':
160             layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
161
162         if gp_edit:
163             pass
164         elif mode_string == 'OBJECT':
165             layout.menu("INFO_MT_add", text="Add")
166         elif mode_string == 'EDIT_MESH':
167             layout.menu("INFO_MT_mesh_add", text="Add")
168         elif mode_string == 'EDIT_CURVE':
169             layout.menu("INFO_MT_curve_add", text="Add")
170         elif mode_string == 'EDIT_SURFACE':
171             layout.menu("INFO_MT_surface_add", text="Add")
172         elif mode_string == 'EDIT_METABALL':
173             layout.menu("INFO_MT_metaball_add", text="Add")
174         elif mode_string == 'EDIT_ARMATURE':
175             layout.menu("INFO_MT_edit_armature_add", text="Add")
176
177         if gp_edit:
178             layout.menu("VIEW3D_MT_edit_gpencil")
179         elif edit_object:
180             layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower())
181         elif obj:
182             if mode_string != 'PAINT_TEXTURE':
183                 layout.menu("VIEW3D_MT_%s" % mode_string.lower())
184             if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}:
185                 layout.menu("VIEW3D_MT_brush")
186             if mode_string == 'SCULPT':
187                 layout.menu("VIEW3D_MT_hide_mask")
188         else:
189             layout.menu("VIEW3D_MT_object")
190
191
192 # ********** Menu **********
193
194
195 # ********** Utilities **********
196
197
198 class ShowHideMenu:
199     bl_label = "Show/Hide"
200     _operator_name = ""
201
202     def draw(self, context):
203         layout = self.layout
204
205         layout.operator("%s.reveal" % self._operator_name, text="Show Hidden")
206         layout.operator("%s.hide" % self._operator_name, text="Hide Selected").unselected = False
207         layout.operator("%s.hide" % self._operator_name, text="Hide Unselected").unselected = True
208
209
210 # Standard transforms which apply to all cases
211 # NOTE: this doesn't seem to be able to be used directly
212 class VIEW3D_MT_transform_base(Menu):
213     bl_label = "Transform"
214
215     # TODO: get rid of the custom text strings?
216     def draw(self, context):
217         layout = self.layout
218
219         layout.operator("transform.translate", text="Grab/Move")
220         # TODO: sub-menu for grab per axis
221         layout.operator("transform.rotate", text="Rotate")
222         # TODO: sub-menu for rot per axis
223         layout.operator("transform.resize", text="Scale")
224         # TODO: sub-menu for scale per axis
225
226         layout.separator()
227
228         layout.operator("transform.tosphere", text="To Sphere")
229         layout.operator("transform.shear", text="Shear")
230         layout.operator("transform.bend", text="Bend")
231         layout.operator("transform.push_pull", text="Push/Pull")
232
233         if context.mode != 'OBJECT':
234             layout.operator("transform.vertex_warp", text="Warp")
235             layout.operator("transform.vertex_random", text="Randomize")
236
237
238 # Generic transform menu - geometry types
239 class VIEW3D_MT_transform(VIEW3D_MT_transform_base):
240     def draw(self, context):
241         # base menu
242         VIEW3D_MT_transform_base.draw(self, context)
243
244         # generic...
245         layout = self.layout
246         layout.operator("transform.shrink_fatten", text="Shrink Fatten")
247
248         layout.separator()
249
250         layout.operator("transform.translate", text="Move Texture Space").texture_space = True
251         layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
252
253
254 # Object-specific extensions to Transform menu
255 class VIEW3D_MT_transform_object(VIEW3D_MT_transform_base):
256     def draw(self, context):
257         layout = self.layout
258
259         # base menu
260         VIEW3D_MT_transform_base.draw(self, context)
261
262         # object-specific option follow...
263         layout.separator()
264
265         layout.operator("transform.translate", text="Move Texture Space").texture_space = True
266         layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
267
268         layout.separator()
269
270         layout.operator_context = 'EXEC_REGION_WIN'
271         layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN'  # XXX see alignmenu() in edit.c of b2.4x to get this working
272
273         layout.separator()
274
275         layout.operator_context = 'EXEC_AREA'
276
277         layout.operator("object.origin_set", text="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
278         layout.operator("object.origin_set", text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
279         layout.operator("object.origin_set", text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
280         layout.operator("object.origin_set", text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS'
281         layout.separator()
282
283         layout.operator("object.randomize_transform")
284         layout.operator("object.align")
285
286         layout.separator()
287
288         layout.operator("object.anim_transforms_to_deltas")
289
290
291 # Armature EditMode extensions to Transform menu
292 class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base):
293     def draw(self, context):
294         layout = self.layout
295
296         # base menu
297         VIEW3D_MT_transform_base.draw(self, context)
298
299         # armature specific extensions follow...
300         layout.separator()
301
302         obj = context.object
303         if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}:
304             if obj.data.draw_type == 'BBONE':
305                 layout.operator("transform.transform", text="Scale BBone").mode = 'BONE_SIZE'
306             elif obj.data.draw_type == 'ENVELOPE':
307                 layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONE_SIZE'
308                 layout.operator("transform.transform", text="Scale Radius").mode = 'BONE_ENVELOPE'
309
310         if context.edit_object and context.edit_object.type == 'ARMATURE':
311             layout.operator("armature.align")
312
313
314 class VIEW3D_MT_mirror(Menu):
315     bl_label = "Mirror"
316
317     def draw(self, context):
318         layout = self.layout
319
320         layout.operator("transform.mirror", text="Interactive Mirror")
321
322         layout.separator()
323
324         layout.operator_context = 'INVOKE_REGION_WIN'
325
326         props = layout.operator("transform.mirror", text="X Global")
327         props.constraint_axis = (True, False, False)
328         props.constraint_orientation = 'GLOBAL'
329         props = layout.operator("transform.mirror", text="Y Global")
330         props.constraint_axis = (False, True, False)
331         props.constraint_orientation = 'GLOBAL'
332         props = layout.operator("transform.mirror", text="Z Global")
333         props.constraint_axis = (False, False, True)
334         props.constraint_orientation = 'GLOBAL'
335
336         if context.edit_object:
337             layout.separator()
338
339             props = layout.operator("transform.mirror", text="X Local")
340             props.constraint_axis = (True, False, False)
341             props.constraint_orientation = 'LOCAL'
342             props = layout.operator("transform.mirror", text="Y Local")
343             props.constraint_axis = (False, True, False)
344             props.constraint_orientation = 'LOCAL'
345             props = layout.operator("transform.mirror", text="Z Local")
346             props.constraint_axis = (False, False, True)
347             props.constraint_orientation = 'LOCAL'
348
349             layout.operator("object.vertex_group_mirror")
350
351
352 class VIEW3D_MT_snap(Menu):
353     bl_label = "Snap"
354
355     def draw(self, context):
356         layout = self.layout
357
358         layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid")
359         layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False
360         layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
361
362         layout.separator()
363
364         layout.operator("view3d.snap_cursor_to_selected", text="Cursor to Selected")
365         layout.operator("view3d.snap_cursor_to_center", text="Cursor to Center")
366         layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
367         layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
368
369
370 class VIEW3D_MT_uv_map(Menu):
371     bl_label = "UV Mapping"
372
373     def draw(self, context):
374         layout = self.layout
375
376         layout.operator("uv.unwrap")
377
378         layout.operator_context = 'INVOKE_DEFAULT'
379         layout.operator("uv.smart_project")
380         layout.operator("uv.lightmap_pack")
381         layout.operator("uv.follow_active_quads")
382
383         layout.separator()
384
385         layout.operator_context = 'EXEC_REGION_WIN'
386         layout.operator("uv.cube_project")
387         layout.operator("uv.cylinder_project")
388         layout.operator("uv.sphere_project")
389
390         layout.separator()
391
392         layout.operator_context = 'INVOKE_REGION_WIN'
393         layout.operator("uv.project_from_view").scale_to_bounds = False
394         layout.operator("uv.project_from_view", text="Project from View (Bounds)").scale_to_bounds = True
395
396         layout.separator()
397
398         layout.operator("uv.reset")
399
400
401 # ********** View menus **********
402
403
404 class VIEW3D_MT_view(Menu):
405     bl_label = "View"
406
407     def draw(self, context):
408         layout = self.layout
409
410         layout.operator("view3d.properties", icon='MENU_PANEL')
411         layout.operator("view3d.toolshelf", icon='MENU_PANEL')
412
413         layout.separator()
414
415         layout.operator("view3d.viewnumpad", text="Camera").type = 'CAMERA'
416         layout.operator("view3d.viewnumpad", text="Top").type = 'TOP'
417         layout.operator("view3d.viewnumpad", text="Bottom").type = 'BOTTOM'
418         layout.operator("view3d.viewnumpad", text="Front").type = 'FRONT'
419         layout.operator("view3d.viewnumpad", text="Back").type = 'BACK'
420         layout.operator("view3d.viewnumpad", text="Right").type = 'RIGHT'
421         layout.operator("view3d.viewnumpad", text="Left").type = 'LEFT'
422
423         layout.menu("VIEW3D_MT_view_cameras", text="Cameras")
424
425         layout.separator()
426
427         layout.operator("view3d.view_persportho")
428
429         layout.separator()
430
431         layout.menu("VIEW3D_MT_view_navigation")
432         layout.menu("VIEW3D_MT_view_align")
433
434         layout.separator()
435
436         layout.operator_context = 'INVOKE_REGION_WIN'
437
438         layout.operator("view3d.clip_border", text="Clipping Border...")
439         layout.operator("view3d.zoom_border", text="Zoom Border...")
440         layout.operator("view3d.render_border", text="Render Border...").camera_only = False
441         layout.operator("view3d.clear_render_border")
442
443         layout.separator()
444
445         layout.operator("view3d.layers", text="Show All Layers").nr = 0
446
447         layout.separator()
448
449         layout.operator("view3d.localview", text="View Global/Local")
450         layout.operator("view3d.view_selected").use_all_regions = False
451         layout.operator("view3d.view_all").center = False
452
453         layout.separator()
454
455         layout.operator("screen.animation_play", text="Playback Animation")
456
457         layout.separator()
458
459         layout.operator("screen.area_dupli")
460         layout.operator("screen.region_quadview")
461         layout.operator("screen.screen_full_area", text="Toggle Maximize Area")
462         layout.operator("screen.screen_full_area").use_hide_panels = True
463
464
465 class VIEW3D_MT_view_navigation(Menu):
466     bl_label = "Navigation"
467
468     def draw(self, context):
469         from math import pi
470         layout = self.layout
471
472         layout.operator_enum("view3d.view_orbit", "type")
473         props = layout.operator("view3d.view_orbit", "Orbit Opposite")
474         props.type = 'ORBITRIGHT'
475         props.angle = pi
476
477         layout.separator()
478
479         layout.operator("view3d.view_roll", text="Roll Left").type = 'LEFT'
480         layout.operator("view3d.view_roll", text="Roll Right").type = 'RIGHT'
481
482         layout.separator()
483
484         layout.operator_enum("view3d.view_pan", "type")
485
486         layout.separator()
487
488         layout.operator("view3d.zoom", text="Zoom In").delta = 1
489         layout.operator("view3d.zoom", text="Zoom Out").delta = -1
490         layout.operator("view3d.zoom_camera_1_to_1", text="Zoom Camera 1:1")
491
492         layout.separator()
493
494         layout.operator("view3d.fly")
495         layout.operator("view3d.walk")
496
497
498 class VIEW3D_MT_view_align(Menu):
499     bl_label = "Align View"
500
501     def draw(self, context):
502         layout = self.layout
503
504         layout.menu("VIEW3D_MT_view_align_selected")
505
506         layout.separator()
507
508         layout.operator("view3d.view_all", text="Center Cursor and View All").center = True
509         layout.operator("view3d.camera_to_view", text="Align Active Camera to View")
510         layout.operator("view3d.camera_to_view_selected", text="Align Active Camera to Selected")
511         layout.operator("view3d.view_selected")
512         layout.operator("view3d.view_center_cursor")
513
514         layout.separator()
515
516         layout.operator("view3d.view_lock_to_active")
517         layout.operator("view3d.view_lock_clear")
518
519
520 class VIEW3D_MT_view_align_selected(Menu):
521     bl_label = "Align View to Active"
522
523     def draw(self, context):
524         layout = self.layout
525
526         props = layout.operator("view3d.viewnumpad", text="Top")
527         props.align_active = True
528         props.type = 'TOP'
529
530         props = layout.operator("view3d.viewnumpad", text="Bottom")
531         props.align_active = True
532         props.type = 'BOTTOM'
533
534         props = layout.operator("view3d.viewnumpad", text="Front")
535         props.align_active = True
536         props.type = 'FRONT'
537
538         props = layout.operator("view3d.viewnumpad", text="Back")
539         props.align_active = True
540         props.type = 'BACK'
541
542         props = layout.operator("view3d.viewnumpad", text="Right")
543         props.align_active = True
544         props.type = 'RIGHT'
545
546         props = layout.operator("view3d.viewnumpad", text="Left")
547         props.align_active = True
548         props.type = 'LEFT'
549
550
551 class VIEW3D_MT_view_cameras(Menu):
552     bl_label = "Cameras"
553
554     def draw(self, context):
555         layout = self.layout
556
557         layout.operator("view3d.object_as_camera")
558         layout.operator("view3d.viewnumpad", text="Active Camera").type = 'CAMERA'
559
560
561 # ********** Select menus, suffix from context.mode **********
562
563 class VIEW3D_MT_select_object_more_less(Menu):
564     bl_label = "Select More/Less"
565
566     def draw(self, context):
567         layout = self.layout
568
569         layout = self.layout
570
571         layout.operator("object.select_more", text="More")
572         layout.operator("object.select_less", text="Less")
573
574         layout.separator()
575
576         props = layout.operator("object.select_hierarchy", text="Parent")
577         props.extend = False
578         props.direction = 'PARENT'
579
580         props = layout.operator("object.select_hierarchy", text="Child")
581         props.extend = False
582         props.direction = 'CHILD'
583
584         layout.separator()
585
586         props = layout.operator("object.select_hierarchy", text="Extend Parent")
587         props.extend = True
588         props.direction = 'PARENT'
589
590         props = layout.operator("object.select_hierarchy", text="Extend Child")
591         props.extend = True
592         props.direction = 'CHILD'
593
594
595 class VIEW3D_MT_select_object(Menu):
596     bl_label = "Select"
597
598     def draw(self, context):
599         layout = self.layout
600
601         layout.operator("view3d.select_border")
602         layout.operator("view3d.select_circle")
603
604         layout.separator()
605
606         layout.operator("object.select_all").action = 'TOGGLE'
607         layout.operator("object.select_all", text="Inverse").action = 'INVERT'
608         layout.operator("object.select_random", text="Random")
609         layout.operator("object.select_mirror", text="Mirror")
610         layout.operator("object.select_by_layer", text="Select All by Layer")
611         layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
612         layout.operator("object.select_camera", text="Select Camera")
613
614         layout.separator()
615
616         layout.menu("VIEW3D_MT_select_object_more_less")
617
618         layout.separator()
619
620         layout.operator_menu_enum("object.select_grouped", "type", text="Grouped")
621         layout.operator_menu_enum("object.select_linked", "type", text="Linked")
622         layout.operator("object.select_pattern", text="Select Pattern...")
623
624
625 class VIEW3D_MT_select_pose_more_less(Menu):
626     bl_label = "Select More/Less"
627
628     def draw(self, context):
629         layout = self.layout
630
631         layout = self.layout
632
633         props = layout.operator("pose.select_hierarchy", text="Parent")
634         props.extend = False
635         props.direction = 'PARENT'
636
637         props = layout.operator("pose.select_hierarchy", text="Child")
638         props.extend = False
639         props.direction = 'CHILD'
640
641         layout.separator()
642
643         props = layout.operator("pose.select_hierarchy", text="Extend Parent")
644         props.extend = True
645         props.direction = 'PARENT'
646
647         props = layout.operator("pose.select_hierarchy", text="Extend Child")
648         props.extend = True
649         props.direction = 'CHILD'
650
651
652 class VIEW3D_MT_select_pose(Menu):
653     bl_label = "Select"
654
655     def draw(self, context):
656         layout = self.layout
657
658         layout.operator("view3d.select_border")
659         layout.operator("view3d.select_circle")
660
661         layout.separator()
662
663         layout.operator("pose.select_all").action = 'TOGGLE'
664         layout.operator("pose.select_all", text="Inverse").action = 'INVERT'
665         layout.operator("pose.select_mirror", text="Flip Active")
666         layout.operator("pose.select_constraint_target", text="Constraint Target")
667         layout.operator("pose.select_linked", text="Linked")
668
669         layout.separator()
670
671         layout.menu("VIEW3D_MT_select_pose_more_less")
672
673         layout.separator()
674
675         layout.operator_menu_enum("pose.select_grouped", "type", text="Grouped")
676         layout.operator("object.select_pattern", text="Select Pattern...")
677
678
679 class VIEW3D_MT_select_particle(Menu):
680     bl_label = "Select"
681
682     def draw(self, context):
683         layout = self.layout
684
685         layout.operator("view3d.select_border")
686
687         layout.separator()
688
689         layout.operator("particle.select_all").action = 'TOGGLE'
690         layout.operator("particle.select_linked")
691         layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
692
693         layout.separator()
694
695         layout.operator("particle.select_more")
696         layout.operator("particle.select_less")
697
698         layout.separator()
699
700         layout.operator("particle.select_random")
701
702         layout.separator()
703
704         layout.operator("particle.select_roots", text="Roots")
705         layout.operator("particle.select_tips", text="Tips")
706
707
708 class VIEW3D_MT_edit_mesh_select_similar(Menu):
709     bl_label = "Select Similar"
710
711     def draw(self, context):
712         layout = self.layout
713
714         layout.operator_enum("mesh.select_similar", "type")
715
716         layout.separator()
717
718         layout.operator("mesh.select_similar_region", text="Face Regions")
719
720
721 class VIEW3D_MT_edit_mesh_select_by_trait(Menu):
722     bl_label = "Select All by Trait"
723
724     def draw(self, context):
725         layout = self.layout
726         if context.scene.tool_settings.mesh_select_mode[2] is False:
727             layout.operator("mesh.select_non_manifold", text="Non Manifold")
728         layout.operator("mesh.select_loose", text="Loose Geometry")
729         layout.operator("mesh.select_interior_faces", text="Interior Faces")
730         layout.operator("mesh.select_face_by_sides")
731
732         layout.separator()
733
734         layout.operator("mesh.select_ungrouped", text="Ungrouped Verts")
735
736
737 class VIEW3D_MT_edit_mesh_select_more_less(Menu):
738     bl_label = "Select More/Less"
739
740     def draw(self, context):
741         layout = self.layout
742
743         layout.operator("mesh.select_more", text="More")
744         layout.operator("mesh.select_less", text="Less")
745
746         layout.separator()
747
748         layout.operator("mesh.select_next_item", text="Next Active")
749         layout.operator("mesh.select_prev_item", text="Previous Active")
750
751
752 class VIEW3D_MT_select_edit_mesh(Menu):
753     bl_label = "Select"
754
755     def draw(self, context):
756         layout = self.layout
757
758         layout.operator("view3d.select_border")
759         layout.operator("view3d.select_circle")
760
761         layout.separator()
762
763         # primitive
764         layout.operator("mesh.select_all").action = 'TOGGLE'
765         layout.operator("mesh.select_all", text="Inverse").action = 'INVERT'
766
767         layout.separator()
768
769         # numeric
770         layout.operator("mesh.select_random", text="Random")
771         layout.operator("mesh.select_nth")
772
773         layout.separator()
774
775         # geometric
776         layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
777         layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
778
779         layout.separator()
780
781         # other ...
782         layout.menu("VIEW3D_MT_edit_mesh_select_similar")
783
784         layout.separator()
785
786         layout.menu("VIEW3D_MT_edit_mesh_select_by_trait")
787
788         layout.separator()
789
790         layout.menu("VIEW3D_MT_edit_mesh_select_more_less")
791
792         layout.separator()
793
794         layout.operator("mesh.select_mirror", text="Mirror")
795         layout.operator("mesh.select_axis", text="Side of Active")
796
797         layout.operator("mesh.select_linked", text="Linked")
798         layout.operator("mesh.shortest_path_select", text="Shortest Path")
799         layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False
800         layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True
801
802         layout.separator()
803
804         layout.operator("mesh.loop_to_region")
805         layout.operator("mesh.region_to_loop")
806
807
808 class VIEW3D_MT_select_edit_curve(Menu):
809     bl_label = "Select"
810
811     def draw(self, context):
812         layout = self.layout
813
814         layout.operator("view3d.select_border")
815         layout.operator("view3d.select_circle")
816
817         layout.separator()
818
819         layout.operator("curve.select_all").action = 'TOGGLE'
820         layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
821         layout.operator("curve.select_random")
822         layout.operator("curve.select_nth")
823         layout.operator("curve.select_linked", text="Select Linked")
824         layout.operator("curve.select_similar", text="Select Similar")
825
826         layout.separator()
827
828         layout.operator("curve.de_select_first")
829         layout.operator("curve.de_select_last")
830         layout.operator("curve.select_next")
831         layout.operator("curve.select_previous")
832
833         layout.separator()
834
835         layout.operator("curve.select_more")
836         layout.operator("curve.select_less")
837
838
839 class VIEW3D_MT_select_edit_surface(Menu):
840     bl_label = "Select"
841
842     def draw(self, context):
843         layout = self.layout
844
845         layout.operator("view3d.select_border")
846         layout.operator("view3d.select_circle")
847
848         layout.separator()
849
850         layout.operator("curve.select_all").action = 'TOGGLE'
851         layout.operator("curve.select_all", text="Inverse").action = 'INVERT'
852         layout.operator("curve.select_random")
853         layout.operator("curve.select_nth")
854         layout.operator("curve.select_linked", text="Select Linked")
855         layout.operator("curve.select_similar", text="Select Similar")
856
857         layout.separator()
858
859         layout.operator("curve.select_row")
860
861         layout.separator()
862
863         layout.operator("curve.select_more")
864         layout.operator("curve.select_less")
865
866
867 class VIEW3D_MT_select_edit_text(Menu):
868     # intentional name mis-match
869     # select menu for 3d-text doesn't make sense
870     bl_label = "Edit"
871
872     def draw(self, context):
873         layout = self.layout
874
875         layout.operator("font.text_copy", text="Copy")
876         layout.operator("font.text_cut", text="Cut")
877         layout.operator("font.text_paste", text="Paste")
878
879         layout.separator()
880
881         layout.operator("font.text_paste_from_file")
882
883         layout.separator()
884
885         layout.operator("font.select_all")
886
887
888 class VIEW3D_MT_select_edit_metaball(Menu):
889     bl_label = "Select"
890
891     def draw(self, context):
892         layout = self.layout
893
894         layout.operator("view3d.select_border")
895         layout.operator("view3d.select_circle")
896
897         layout.separator()
898
899         layout.operator("mball.select_all").action = 'TOGGLE'
900         layout.operator("mball.select_all", text="Inverse").action = 'INVERT'
901
902         layout.separator()
903
904         layout.operator("mball.select_random_metaelems")
905
906         layout.separator()
907
908         layout.operator_menu_enum("mball.select_similar", "type", text="Similar")
909
910
911 class VIEW3D_MT_select_edit_lattice(Menu):
912     bl_label = "Select"
913
914     def draw(self, context):
915         layout = self.layout
916
917         layout.operator("view3d.select_border")
918         layout.operator("view3d.select_circle")
919
920         layout.separator()
921
922         layout.operator("lattice.select_mirror")
923         layout.operator("lattice.select_random")
924         layout.operator("lattice.select_all").action = 'TOGGLE'
925         layout.operator("lattice.select_all", text="Inverse").action = 'INVERT'
926
927         layout.separator()
928
929         layout.operator("lattice.select_ungrouped", text="Ungrouped Verts")
930
931
932 class VIEW3D_MT_select_edit_armature(Menu):
933     bl_label = "Select"
934
935     def draw(self, context):
936         layout = self.layout
937
938         layout.operator("view3d.select_border")
939         layout.operator("view3d.select_circle")
940
941         layout.separator()
942
943         layout.operator("armature.select_all").action = 'TOGGLE'
944         layout.operator("armature.select_all", text="Inverse").action = 'INVERT'
945         layout.operator("armature.select_mirror", text="Mirror").extend = False
946
947         layout.separator()
948
949         layout.operator("armature.select_more", text="More")
950         layout.operator("armature.select_less", text="Less")
951
952         layout.separator()
953
954         props = layout.operator("armature.select_hierarchy", text="Parent")
955         props.extend = False
956         props.direction = 'PARENT'
957
958         props = layout.operator("armature.select_hierarchy", text="Child")
959         props.extend = False
960         props.direction = 'CHILD'
961
962         layout.separator()
963
964         props = layout.operator("armature.select_hierarchy", text="Extend Parent")
965         props.extend = True
966         props.direction = 'PARENT'
967
968         props = layout.operator("armature.select_hierarchy", text="Extend Child")
969         props.extend = True
970         props.direction = 'CHILD'
971
972         layout.operator_menu_enum("armature.select_similar", "type", text="Similar")
973         layout.operator("object.select_pattern", text="Select Pattern...")
974
975
976 class VIEW3D_MT_select_gpencil(Menu):
977     bl_label = "Select"
978
979     def draw(self, context):
980         layout = self.layout
981
982         layout.operator("gpencil.select_border")
983         layout.operator("gpencil.select_circle")
984
985         layout.separator()
986
987         layout.operator("gpencil.select_all", text="(De)select All").action = 'TOGGLE'
988         layout.operator("gpencil.select_all", text="Inverse").action = 'INVERT'
989         layout.operator("gpencil.select_linked", text="Linked")
990         #layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped")
991         layout.operator("gpencil.select_grouped", text="Grouped")
992
993         layout.separator()
994
995         layout.operator("gpencil.select_more")
996         layout.operator("gpencil.select_less")
997
998
999 class VIEW3D_MT_select_paint_mask(Menu):
1000     bl_label = "Select"
1001
1002     def draw(self, context):
1003         layout = self.layout
1004
1005         layout.operator("view3d.select_border")
1006         layout.operator("view3d.select_circle")
1007
1008         layout.separator()
1009
1010         layout.operator("paint.face_select_all").action = 'TOGGLE'
1011         layout.operator("paint.face_select_all", text="Inverse").action = 'INVERT'
1012
1013         layout.separator()
1014
1015         layout.operator("paint.face_select_linked", text="Linked")
1016
1017
1018 class VIEW3D_MT_select_paint_mask_vertex(Menu):
1019     bl_label = "Select"
1020
1021     def draw(self, context):
1022         layout = self.layout
1023
1024         layout.operator("view3d.select_border")
1025         layout.operator("view3d.select_circle")
1026
1027         layout.separator()
1028
1029         layout.operator("paint.vert_select_all").action = 'TOGGLE'
1030         layout.operator("paint.vert_select_all", text="Inverse").action = 'INVERT'
1031
1032         layout.separator()
1033
1034         layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts")
1035
1036
1037 class VIEW3D_MT_angle_control(Menu):
1038     bl_label = "Angle Control"
1039
1040     @classmethod
1041     def poll(cls, context):
1042         settings = UnifiedPaintPanel.paint_settings(context)
1043         if not settings:
1044             return False
1045
1046         brush = settings.brush
1047         tex_slot = brush.texture_slot
1048
1049         return tex_slot.has_texture_angle and tex_slot.has_texture_angle_source
1050
1051     def draw(self, context):
1052         layout = self.layout
1053
1054         settings = UnifiedPaintPanel.paint_settings(context)
1055         brush = settings.brush
1056
1057         sculpt = (context.sculpt_object is not None)
1058
1059         tex_slot = brush.texture_slot
1060
1061         layout.prop(tex_slot, "use_rake", text="Rake")
1062
1063         if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle:
1064             if sculpt:
1065                 if brush.sculpt_capabilities.has_random_texture_angle:
1066                     layout.prop(tex_slot, "use_random", text="Random")
1067             else:
1068                 layout.prop(tex_slot, "use_random", text="Random")
1069
1070
1071 # ********** Add menu **********
1072
1073 # XXX: INFO_MT_ names used to keep backwards compatibility (Addons etc that hook into the menu)
1074
1075
1076 class INFO_MT_mesh_add(Menu):
1077     bl_idname = "INFO_MT_mesh_add"
1078     bl_label = "Mesh"
1079
1080     def draw(self, context):
1081         from .space_view3d_toolbar import VIEW3D_PT_tools_add_object
1082
1083         layout = self.layout
1084
1085         layout.operator_context = 'INVOKE_REGION_WIN'
1086
1087         VIEW3D_PT_tools_add_object.draw_add_mesh(layout)
1088
1089
1090 class INFO_MT_curve_add(Menu):
1091     bl_idname = "INFO_MT_curve_add"
1092     bl_label = "Curve"
1093
1094     def draw(self, context):
1095         from .space_view3d_toolbar import VIEW3D_PT_tools_add_object
1096         layout = self.layout
1097
1098         layout.operator_context = 'INVOKE_REGION_WIN'
1099
1100         VIEW3D_PT_tools_add_object.draw_add_curve(layout)
1101
1102
1103 class INFO_MT_surface_add(Menu):
1104     bl_idname = "INFO_MT_surface_add"
1105     bl_label = "Surface"
1106
1107     def draw(self, context):
1108         from .space_view3d_toolbar import VIEW3D_PT_tools_add_object
1109         layout = self.layout
1110
1111         layout.operator_context = 'INVOKE_REGION_WIN'
1112
1113         VIEW3D_PT_tools_add_object.draw_add_surface(layout)
1114
1115
1116 class INFO_MT_metaball_add(Menu):
1117     bl_idname = "INFO_MT_metaball_add"
1118     bl_label = "Metaball"
1119
1120     def draw(self, context):
1121         layout = self.layout
1122
1123         layout.operator_context = 'INVOKE_REGION_WIN'
1124         layout.operator_enum("object.metaball_add", "type")
1125
1126
1127 class INFO_MT_edit_curve_add(Menu):
1128     bl_idname = "INFO_MT_edit_curve_add"
1129     bl_label = "Add"
1130
1131     def draw(self, context):
1132         is_surf = context.active_object.type == 'SURFACE'
1133
1134         layout = self.layout
1135         layout.operator_context = 'EXEC_REGION_WIN'
1136
1137         if is_surf:
1138             INFO_MT_surface_add.draw(self, context)
1139         else:
1140             INFO_MT_curve_add.draw(self, context)
1141
1142
1143 class INFO_MT_edit_armature_add(Menu):
1144     bl_idname = "INFO_MT_edit_armature_add"
1145     bl_label = "Armature"
1146
1147     def draw(self, context):
1148         layout = self.layout
1149
1150         layout.operator_context = 'EXEC_REGION_WIN'
1151         layout.operator("armature.bone_primitive_add", text="Single Bone", icon='BONE_DATA')
1152
1153
1154 class INFO_MT_armature_add(Menu):
1155     bl_idname = "INFO_MT_armature_add"
1156     bl_label = "Armature"
1157
1158     def draw(self, context):
1159         layout = self.layout
1160
1161         layout.operator_context = 'EXEC_REGION_WIN'
1162         layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA')
1163
1164
1165 class INFO_MT_lamp_add(Menu):
1166     bl_idname = "INFO_MT_lamp_add"
1167     bl_label = "Lamp"
1168
1169     def draw(self, context):
1170         layout = self.layout
1171
1172         layout.operator_context = 'INVOKE_REGION_WIN'
1173         layout.operator_enum("object.lamp_add", "type")
1174
1175
1176 class INFO_MT_add(Menu):
1177     bl_label = "Add"
1178
1179     def draw(self, context):
1180         layout = self.layout
1181
1182         # note, don't use 'EXEC_SCREEN' or operators wont get the 'v3d' context.
1183
1184         # Note: was EXEC_AREA, but this context does not have the 'rv3d', which prevents
1185         #       "align_view" to work on first call (see [#32719]).
1186         layout.operator_context = 'EXEC_REGION_WIN'
1187
1188         #layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
1189         layout.menu("INFO_MT_mesh_add", icon='OUTLINER_OB_MESH')
1190
1191         #layout.operator_menu_enum("object.curve_add", "type", text="Curve", icon='OUTLINER_OB_CURVE')
1192         layout.menu("INFO_MT_curve_add", icon='OUTLINER_OB_CURVE')
1193         #layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE')
1194         layout.menu("INFO_MT_surface_add", icon='OUTLINER_OB_SURFACE')
1195         layout.menu("INFO_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META')
1196         layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
1197         layout.separator()
1198
1199         layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
1200         layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
1201         layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY')
1202         layout.separator()
1203
1204         layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
1205         layout.separator()
1206
1207         layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
1208         layout.menu("INFO_MT_lamp_add", icon='OUTLINER_OB_LAMP')
1209         layout.separator()
1210
1211         layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_EMPTY')
1212         layout.separator()
1213
1214         if len(bpy.data.groups) > 10:
1215             layout.operator_context = 'INVOKE_REGION_WIN'
1216             layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_EMPTY')
1217         else:
1218             layout.operator_menu_enum("object.group_instance_add", "group", text="Group Instance", icon='OUTLINER_OB_EMPTY')
1219
1220
1221 # ********** Object menu **********
1222
1223
1224 class VIEW3D_MT_object(Menu):
1225     bl_context = "objectmode"
1226     bl_label = "Object"
1227
1228     def draw(self, context):
1229         layout = self.layout
1230         view = context.space_data
1231         is_local_view = (view.local_view is not None)
1232
1233         layout.operator("ed.undo")
1234         layout.operator("ed.redo")
1235         layout.operator("ed.undo_history")
1236
1237         layout.separator()
1238
1239         layout.menu("VIEW3D_MT_transform_object")
1240         layout.menu("VIEW3D_MT_mirror")
1241         layout.menu("VIEW3D_MT_object_clear")
1242         layout.menu("VIEW3D_MT_object_apply")
1243         layout.menu("VIEW3D_MT_snap")
1244
1245         layout.separator()
1246
1247         layout.menu("VIEW3D_MT_object_animation")
1248
1249         layout.separator()
1250
1251         layout.operator("object.duplicate_move")
1252         layout.operator("object.duplicate_move_linked")
1253         layout.operator("object.delete", text="Delete...").use_global = False
1254         layout.operator("object.proxy_make", text="Make Proxy...")
1255         layout.menu("VIEW3D_MT_make_links", text="Make Links...")
1256         layout.operator("object.make_dupli_face")
1257         layout.operator_menu_enum("object.make_local", "type", text="Make Local...")
1258         layout.menu("VIEW3D_MT_make_single_user")
1259
1260         layout.separator()
1261
1262         layout.menu("VIEW3D_MT_object_parent")
1263         layout.menu("VIEW3D_MT_object_track")
1264         layout.menu("VIEW3D_MT_object_group")
1265         layout.menu("VIEW3D_MT_object_constraints")
1266
1267         layout.separator()
1268
1269         layout.menu("VIEW3D_MT_object_quick_effects")
1270
1271         layout.separator()
1272
1273         layout.menu("VIEW3D_MT_object_game")
1274
1275         layout.separator()
1276
1277         layout.operator("object.join")
1278         layout.operator("object.data_transfer")
1279         layout.operator("object.datalayout_transfer")
1280
1281         layout.separator()
1282
1283         if is_local_view:
1284             layout.operator_context = 'EXEC_REGION_WIN'
1285             layout.operator("object.move_to_layer", text="Move out of Local View")
1286             layout.operator_context = 'INVOKE_REGION_WIN'
1287         else:
1288             layout.operator("object.move_to_layer", text="Move to Layer...")
1289
1290         layout.menu("VIEW3D_MT_object_showhide")
1291
1292         layout.operator_menu_enum("object.convert", "target")
1293
1294
1295 class VIEW3D_MT_object_animation(Menu):
1296     bl_label = "Animation"
1297
1298     def draw(self, context):
1299         layout = self.layout
1300
1301         layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...")
1302         layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframes...")
1303         layout.operator("anim.keyframe_clear_v3d", text="Clear Keyframes...")
1304         layout.operator("anim.keying_set_active_set", text="Change Keying Set...")
1305
1306         layout.separator()
1307
1308         layout.operator("nla.bake", text="Bake Action...")
1309
1310
1311 class VIEW3D_MT_object_clear(Menu):
1312     bl_label = "Clear"
1313
1314     def draw(self, context):
1315         layout = self.layout
1316
1317         layout.operator("object.location_clear", text="Location")
1318         layout.operator("object.rotation_clear", text="Rotation")
1319         layout.operator("object.scale_clear", text="Scale")
1320         layout.operator("object.origin_clear", text="Origin")
1321
1322
1323 class VIEW3D_MT_object_specials(Menu):
1324     bl_label = "Specials"
1325
1326     @classmethod
1327     def poll(cls, context):
1328         # add more special types
1329         return context.object
1330
1331     def draw(self, context):
1332         layout = self.layout
1333
1334         scene = context.scene
1335         obj = context.object
1336
1337         if obj.type == 'CAMERA':
1338             layout.operator_context = 'INVOKE_REGION_WIN'
1339
1340             if obj.data.type == 'PERSP':
1341                 props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
1342                 props.data_path_iter = "selected_editable_objects"
1343                 props.data_path_item = "data.lens"
1344                 props.input_scale = 0.1
1345                 if obj.data.lens_unit == 'MILLIMETERS':
1346                     props.header_text = "Camera Lens Angle: %.1fmm"
1347                 else:
1348                     props.header_text = "Camera Lens Angle: %.1f\u00B0"
1349
1350             else:
1351                 props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
1352                 props.data_path_iter = "selected_editable_objects"
1353                 props.data_path_item = "data.ortho_scale"
1354                 props.input_scale = 0.01
1355                 props.header_text = "Camera Lens Scale: %.3f"
1356
1357             if not obj.data.dof_object:
1358                 view = context.space_data
1359                 if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
1360                     props = layout.operator("ui.eyedropper_depth", text="DOF Distance (Pick)")
1361                 else:
1362                     props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
1363                     props.data_path_iter = "selected_editable_objects"
1364                     props.data_path_item = "data.dof_distance"
1365                     props.input_scale = 0.02
1366                     props.header_text = "DOF Distance: %.3f"
1367                 del view
1368
1369         if obj.type in {'CURVE', 'FONT'}:
1370             layout.operator_context = 'INVOKE_REGION_WIN'
1371
1372             props = layout.operator("wm.context_modal_mouse", text="Extrude Size")
1373             props.data_path_iter = "selected_editable_objects"
1374             props.data_path_item = "data.extrude"
1375             props.input_scale = 0.01
1376             props.header_text = "Extrude Size: %.3f"
1377
1378             props = layout.operator("wm.context_modal_mouse", text="Width Size")
1379             props.data_path_iter = "selected_editable_objects"
1380             props.data_path_item = "data.offset"
1381             props.input_scale = 0.01
1382             props.header_text = "Width Size: %.3f"
1383
1384         if obj.type == 'EMPTY':
1385             layout.operator_context = 'INVOKE_REGION_WIN'
1386
1387             props = layout.operator("wm.context_modal_mouse", text="Empty Draw Size")
1388             props.data_path_iter = "selected_editable_objects"
1389             props.data_path_item = "empty_draw_size"
1390             props.input_scale = 0.01
1391             props.header_text = "Empty Draw Size: %.3f"
1392
1393         if obj.type == 'LAMP':
1394             lamp = obj.data
1395
1396             layout.operator_context = 'INVOKE_REGION_WIN'
1397
1398             if scene.render.use_shading_nodes:
1399                 try:
1400                     value = lamp.node_tree.nodes["Emission"].inputs["Strength"].default_value
1401                 except AttributeError:
1402                     value = None
1403
1404                 if value is not None:
1405                     props = layout.operator("wm.context_modal_mouse", text="Strength")
1406                     props.data_path_iter = "selected_editable_objects"
1407                     props.data_path_item = "data.node_tree.nodes[\"Emission\"].inputs[\"Strength\"].default_value"
1408                     props.header_text = "Lamp Strength: %.3f"
1409                     props.input_scale = 0.1
1410                 del value
1411
1412                 if lamp.type == 'AREA':
1413                     props = layout.operator("wm.context_modal_mouse", text="Size X")
1414                     props.data_path_iter = "selected_editable_objects"
1415                     props.data_path_item = "data.size"
1416                     props.header_text = "Lamp Size X: %.3f"
1417
1418                     if lamp.shape == 'RECTANGLE':
1419                         props = layout.operator("wm.context_modal_mouse", text="Size Y")
1420                         props.data_path_iter = "selected_editable_objects"
1421                         props.data_path_item = "data.size_y"
1422                         props.header_text = "Lamp Size Y: %.3f"
1423
1424                 elif lamp.type in {'SPOT', 'POINT', 'SUN'}:
1425                     props = layout.operator("wm.context_modal_mouse", text="Size")
1426                     props.data_path_iter = "selected_editable_objects"
1427                     props.data_path_item = "data.shadow_soft_size"
1428                     props.header_text = "Lamp Size: %.3f"
1429             else:
1430                 props = layout.operator("wm.context_modal_mouse", text="Energy")
1431                 props.data_path_iter = "selected_editable_objects"
1432                 props.data_path_item = "data.energy"
1433                 props.header_text = "Lamp Energy: %.3f"
1434
1435                 if lamp.type in {'SPOT', 'AREA', 'POINT'}:
1436                     props = layout.operator("wm.context_modal_mouse", text="Falloff Distance")
1437                     props.data_path_iter = "selected_editable_objects"
1438                     props.data_path_item = "data.distance"
1439                     props.input_scale = 0.1
1440                     props.header_text = "Lamp Falloff Distance: %.1f"
1441
1442             if lamp.type == 'SPOT':
1443                 layout.separator()
1444                 props = layout.operator("wm.context_modal_mouse", text="Spot Size")
1445                 props.data_path_iter = "selected_editable_objects"
1446                 props.data_path_item = "data.spot_size"
1447                 props.input_scale = 0.01
1448                 props.header_text = "Spot Size: %.2f"
1449
1450                 props = layout.operator("wm.context_modal_mouse", text="Spot Blend")
1451                 props.data_path_iter = "selected_editable_objects"
1452                 props.data_path_item = "data.spot_blend"
1453                 props.input_scale = -0.01
1454                 props.header_text = "Spot Blend: %.2f"
1455
1456                 if not scene.render.use_shading_nodes:
1457                     props = layout.operator("wm.context_modal_mouse", text="Clip Start")
1458                     props.data_path_iter = "selected_editable_objects"
1459                     props.data_path_item = "data.shadow_buffer_clip_start"
1460                     props.input_scale = 0.05
1461                     props.header_text = "Clip Start: %.2f"
1462
1463                     props = layout.operator("wm.context_modal_mouse", text="Clip End")
1464                     props.data_path_iter = "selected_editable_objects"
1465                     props.data_path_item = "data.shadow_buffer_clip_end"
1466                     props.input_scale = 0.05
1467                     props.header_text = "Clip End: %.2f"
1468
1469         layout.separator()
1470
1471         props = layout.operator("object.isolate_type_render")
1472         props = layout.operator("object.hide_render_clear_all")
1473
1474
1475 class VIEW3D_MT_object_apply(Menu):
1476     bl_label = "Apply"
1477
1478     def draw(self, context):
1479         layout = self.layout
1480
1481         props = layout.operator("object.transform_apply", text="Location", text_ctxt=i18n_contexts.default)
1482         props.location, props.rotation, props.scale = True, False, False
1483
1484         props = layout.operator("object.transform_apply", text="Rotation", text_ctxt=i18n_contexts.default)
1485         props.location, props.rotation, props.scale = False, True, False
1486
1487         props = layout.operator("object.transform_apply", text="Scale", text_ctxt=i18n_contexts.default)
1488         props.location, props.rotation, props.scale = False, False, True
1489         props = layout.operator("object.transform_apply", text="Rotation & Scale", text_ctxt=i18n_contexts.default)
1490         props.location, props.rotation, props.scale = False, True, True
1491
1492         layout.separator()
1493
1494         layout.operator("object.visual_transform_apply", text="Visual Transform", text_ctxt=i18n_contexts.default)
1495         layout.operator("object.duplicates_make_real")
1496
1497
1498 class VIEW3D_MT_object_parent(Menu):
1499     bl_label = "Parent"
1500
1501     def draw(self, context):
1502         layout = self.layout
1503
1504         layout.operator_enum("object.parent_set", "type")
1505         layout.separator()
1506         layout.operator_enum("object.parent_clear", "type")
1507
1508
1509 class VIEW3D_MT_object_track(Menu):
1510     bl_label = "Track"
1511
1512     def draw(self, context):
1513         layout = self.layout
1514
1515         layout.operator_enum("object.track_set", "type")
1516         layout.separator()
1517         layout.operator_enum("object.track_clear", "type")
1518
1519
1520 class VIEW3D_MT_object_group(Menu):
1521     bl_label = "Group"
1522
1523     def draw(self, context):
1524         layout = self.layout
1525
1526         layout.operator("group.create")
1527         # layout.operator_menu_enum("group.objects_remove", "group")  # BUGGY
1528         layout.operator("group.objects_remove")
1529         layout.operator("group.objects_remove_all")
1530
1531         layout.separator()
1532
1533         layout.operator("group.objects_add_active")
1534         layout.operator("group.objects_remove_active")
1535
1536
1537 class VIEW3D_MT_object_constraints(Menu):
1538     bl_label = "Constraints"
1539
1540     def draw(self, context):
1541         layout = self.layout
1542
1543         layout.operator("object.constraint_add_with_targets")
1544         layout.operator("object.constraints_copy")
1545         layout.operator("object.constraints_clear")
1546
1547
1548 class VIEW3D_MT_object_quick_effects(Menu):
1549     bl_label = "Quick Effects"
1550
1551     def draw(self, context):
1552         layout = self.layout
1553
1554         layout.operator("object.quick_fur")
1555         layout.operator("object.quick_explode")
1556         layout.operator("object.quick_smoke")
1557         layout.operator("object.quick_fluid")
1558
1559
1560 class VIEW3D_MT_object_showhide(Menu):
1561     bl_label = "Show/Hide"
1562
1563     def draw(self, context):
1564         layout = self.layout
1565
1566         layout.operator("object.hide_view_clear", text="Show Hidden")
1567         layout.operator("object.hide_view_set", text="Hide Selected").unselected = False
1568         layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
1569
1570
1571 class VIEW3D_MT_make_single_user(Menu):
1572     bl_label = "Make Single User"
1573
1574     def draw(self, context):
1575         layout = self.layout
1576
1577         props = layout.operator("object.make_single_user", text="Object")
1578         props.object = True
1579         props.obdata = props.material = props.texture = props.animation = False
1580
1581         props = layout.operator("object.make_single_user", text="Object & Data")
1582         props.object = props.obdata = True
1583         props.material = props.texture = props.animation = False
1584
1585         props = layout.operator("object.make_single_user", text="Object & Data & Materials+Tex")
1586         props.object = props.obdata = props.material = props.texture = True
1587         props.animation = False
1588
1589         props = layout.operator("object.make_single_user", text="Materials+Tex")
1590         props.material = props.texture = True
1591         props.object = props.obdata = props.animation = False
1592
1593         props = layout.operator("object.make_single_user", text="Object Animation")
1594         props.animation = True
1595         props.object = props.obdata = props.material = props.texture = False
1596
1597
1598 class VIEW3D_MT_make_links(Menu):
1599     bl_label = "Make Links"
1600
1601     def draw(self, context):
1602         layout = self.layout
1603         operator_context_default = layout.operator_context
1604         if len(bpy.data.scenes) > 10:
1605             layout.operator_context = 'INVOKE_REGION_WIN'
1606             layout.operator("object.make_links_scene", text="Objects to Scene...", icon='OUTLINER_OB_EMPTY')
1607         else:
1608             layout.operator_context = 'EXEC_REGION_WIN'
1609             layout.operator_menu_enum("object.make_links_scene", "scene", text="Objects to Scene...")
1610         layout.operator_context = operator_context_default
1611
1612         layout.operator_enum("object.make_links_data", "type")  # inline
1613
1614         layout.operator("object.join_uvs")  # stupid place to add this!
1615
1616
1617 class VIEW3D_MT_object_game(Menu):
1618     bl_label = "Game"
1619
1620     def draw(self, context):
1621         layout = self.layout
1622
1623         layout.operator("object.logic_bricks_copy", text="Copy Logic Bricks")
1624         layout.operator("object.game_physics_copy", text="Copy Physics Properties")
1625
1626         layout.separator()
1627
1628         layout.operator("object.game_property_copy", text="Replace Properties").operation = 'REPLACE'
1629         layout.operator("object.game_property_copy", text="Merge Properties").operation = 'MERGE'
1630         layout.operator_menu_enum("object.game_property_copy", "property", text="Copy Properties...")
1631
1632         layout.separator()
1633
1634         layout.operator("object.game_property_clear")
1635
1636
1637 # ********** Brush menu **********
1638 class VIEW3D_MT_brush(Menu):
1639     bl_label = "Brush"
1640
1641     def draw(self, context):
1642         layout = self.layout
1643
1644         settings = UnifiedPaintPanel.paint_settings(context)
1645         brush = settings.brush
1646
1647         ups = context.tool_settings.unified_paint_settings
1648         layout.prop(ups, "use_unified_size", text="Unified Size")
1649         layout.prop(ups, "use_unified_strength", text="Unified Strength")
1650         if context.image_paint_object or context.vertex_paint_object:
1651             layout.prop(ups, "use_unified_color", text="Unified Color")
1652         layout.separator()
1653
1654         # brush paint modes
1655         layout.menu("VIEW3D_MT_brush_paint_modes")
1656
1657         # brush tool
1658         if context.sculpt_object:
1659             layout.operator("brush.reset")
1660             layout.prop_menu_enum(brush, "sculpt_tool")
1661         elif context.image_paint_object:
1662             layout.prop_menu_enum(brush, "image_tool")
1663         elif context.vertex_paint_object or context.weight_paint_object:
1664             layout.prop_menu_enum(brush, "vertex_tool")
1665
1666         # skip if no active brush
1667         if not brush:
1668             return
1669
1670         # TODO: still missing a lot of brush options here
1671
1672         # sculpt options
1673         if context.sculpt_object:
1674
1675             sculpt_tool = brush.sculpt_tool
1676
1677             layout.separator()
1678             layout.operator_menu_enum("brush.curve_preset", "shape", text="Curve Preset")
1679             layout.separator()
1680
1681             if sculpt_tool != 'GRAB':
1682                 layout.prop_menu_enum(brush, "stroke_method")
1683
1684                 if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
1685                     layout.prop_menu_enum(brush, "direction")
1686
1687                 if sculpt_tool == 'LAYER':
1688                     layout.prop(brush, "use_persistent")
1689                     layout.operator("sculpt.set_persistent_base")
1690
1691
1692 class VIEW3D_MT_brush_paint_modes(Menu):
1693     bl_label = "Enabled Modes"
1694
1695     def draw(self, context):
1696         layout = self.layout
1697
1698         settings = UnifiedPaintPanel.paint_settings(context)
1699         brush = settings.brush
1700
1701         layout.prop(brush, "use_paint_sculpt", text="Sculpt")
1702         layout.prop(brush, "use_paint_vertex", text="Vertex Paint")
1703         layout.prop(brush, "use_paint_weight", text="Weight Paint")
1704         layout.prop(brush, "use_paint_image", text="Texture Paint")
1705
1706 # ********** Vertex paint menu **********
1707
1708
1709 class VIEW3D_MT_paint_vertex(Menu):
1710     bl_label = "Paint"
1711
1712     def draw(self, context):
1713         layout = self.layout
1714
1715         layout.operator("ed.undo")
1716         layout.operator("ed.redo")
1717
1718         layout.separator()
1719
1720         layout.operator("paint.vertex_color_set")
1721         layout.operator("paint.vertex_color_smooth")
1722         layout.operator("paint.vertex_color_dirt")
1723
1724
1725 class VIEW3D_MT_hook(Menu):
1726     bl_label = "Hooks"
1727
1728     def draw(self, context):
1729         layout = self.layout
1730         layout.operator_context = 'EXEC_AREA'
1731         layout.operator("object.hook_add_newob")
1732         layout.operator("object.hook_add_selob").use_bone = False
1733         layout.operator("object.hook_add_selob", text="Hook to Selected Object Bone").use_bone = True
1734
1735         if [mod.type == 'HOOK' for mod in context.active_object.modifiers]:
1736             layout.separator()
1737             layout.operator_menu_enum("object.hook_assign", "modifier")
1738             layout.operator_menu_enum("object.hook_remove", "modifier")
1739             layout.separator()
1740             layout.operator_menu_enum("object.hook_select", "modifier")
1741             layout.operator_menu_enum("object.hook_reset", "modifier")
1742             layout.operator_menu_enum("object.hook_recenter", "modifier")
1743
1744
1745 class VIEW3D_MT_vertex_group(Menu):
1746     bl_label = "Vertex Groups"
1747
1748     def draw(self, context):
1749         layout = self.layout
1750
1751         layout.operator_context = 'EXEC_AREA'
1752         layout.operator("object.vertex_group_assign_new")
1753
1754         ob = context.active_object
1755         if ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex):
1756             if ob.vertex_groups.active:
1757                 layout.separator()
1758                 layout.operator("object.vertex_group_assign", text="Assign to Active Group")
1759                 layout.operator("object.vertex_group_remove_from", text="Remove from Active Group").use_all_groups = False
1760                 layout.operator("object.vertex_group_remove_from", text="Remove from All").use_all_groups = True
1761                 layout.separator()
1762
1763         if ob.vertex_groups.active:
1764             layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group")
1765             layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False
1766             layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True
1767
1768 # ********** Weight paint menu **********
1769
1770
1771 class VIEW3D_MT_paint_weight(Menu):
1772     bl_label = "Weights"
1773
1774     def draw(self, context):
1775         layout = self.layout
1776
1777         layout.operator("ed.undo")
1778         layout.operator("ed.redo")
1779         layout.operator("ed.undo_history")
1780
1781         layout.separator()
1782
1783         layout.operator("paint.weight_from_bones", text="Assign Automatic From Bones").type = 'AUTOMATIC'
1784         layout.operator("paint.weight_from_bones", text="Assign From Bone Envelopes").type = 'ENVELOPES'
1785
1786         layout.separator()
1787
1788         layout.operator("object.vertex_group_normalize_all", text="Normalize All")
1789         layout.operator("object.vertex_group_normalize", text="Normalize")
1790         layout.operator("object.vertex_group_mirror", text="Mirror")
1791         layout.operator("object.vertex_group_invert", text="Invert")
1792         layout.operator("object.vertex_group_clean", text="Clean")
1793         layout.operator("object.vertex_group_quantize", text="Quantize")
1794         layout.operator("object.vertex_group_levels", text="Levels")
1795         layout.operator("object.vertex_group_smooth", text="Smooth")
1796         props = layout.operator("object.data_transfer", text="Transfer Weights")
1797         props.use_reverse_transfer = True
1798         props.data_type = 'VGROUP_WEIGHTS'
1799         layout.operator("object.vertex_group_limit_total", text="Limit Total")
1800         layout.operator("object.vertex_group_fix", text="Fix Deforms")
1801
1802         layout.separator()
1803
1804         layout.operator("paint.weight_set")
1805
1806 # ********** Sculpt menu **********
1807
1808
1809 class VIEW3D_MT_sculpt(Menu):
1810     bl_label = "Sculpt"
1811
1812     def draw(self, context):
1813         layout = self.layout
1814
1815         toolsettings = context.tool_settings
1816         sculpt = toolsettings.sculpt
1817
1818         layout.operator("ed.undo")
1819         layout.operator("ed.redo")
1820
1821         layout.separator()
1822
1823         layout.prop(sculpt, "use_symmetry_x")
1824         layout.prop(sculpt, "use_symmetry_y")
1825         layout.prop(sculpt, "use_symmetry_z")
1826         layout.separator()
1827         layout.prop(sculpt, "lock_x")
1828         layout.prop(sculpt, "lock_y")
1829         layout.prop(sculpt, "lock_z")
1830
1831         layout.separator()
1832         layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
1833         layout.prop(sculpt, "show_low_resolution")
1834         layout.prop(sculpt, "show_brush")
1835         layout.prop(sculpt, "use_deform_only")
1836         layout.prop(sculpt, "show_diffuse_color")
1837
1838
1839 class VIEW3D_MT_hide_mask(Menu):
1840     bl_label = "Hide/Mask"
1841
1842     def draw(self, context):
1843         layout = self.layout
1844
1845         props = layout.operator("paint.hide_show", text="Show All")
1846         props.action = 'SHOW'
1847         props.area = 'ALL'
1848
1849         props = layout.operator("paint.hide_show", text="Hide Bounding Box")
1850         props.action = 'HIDE'
1851         props.area = 'INSIDE'
1852
1853         props = layout.operator("paint.hide_show", text="Show Bounding Box")
1854         props.action = 'SHOW'
1855         props.area = 'INSIDE'
1856
1857         props = layout.operator("paint.hide_show", text="Hide Masked")
1858         props.area = 'MASKED'
1859         props.action = 'HIDE'
1860
1861         layout.separator()
1862
1863         props = layout.operator("paint.mask_flood_fill", text="Invert Mask")
1864         props.mode = 'INVERT'
1865
1866         props = layout.operator("paint.mask_flood_fill", text="Fill Mask")
1867         props.mode = 'VALUE'
1868         props.value = 1
1869
1870         props = layout.operator("paint.mask_flood_fill", text="Clear Mask")
1871         props.mode = 'VALUE'
1872         props.value = 0
1873
1874         props = layout.operator("view3d.select_border", text="Box Mask")
1875         props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask")
1876
1877
1878 # ********** Particle menu **********
1879
1880
1881 class VIEW3D_MT_particle(Menu):
1882     bl_label = "Particle"
1883
1884     def draw(self, context):
1885         layout = self.layout
1886
1887         particle_edit = context.tool_settings.particle_edit
1888
1889         layout.operator("ed.undo")
1890         layout.operator("ed.redo")
1891         layout.operator("ed.undo_history")
1892
1893         layout.separator()
1894
1895         layout.operator("particle.mirror")
1896
1897         layout.separator()
1898
1899         layout.operator("particle.remove_doubles")
1900         layout.operator("particle.delete")
1901
1902         if particle_edit.select_mode == 'POINT':
1903             layout.operator("particle.subdivide")
1904
1905         layout.operator("particle.unify_length")
1906         layout.operator("particle.rekey")
1907         layout.operator("particle.weight_set")
1908
1909         layout.separator()
1910
1911         layout.menu("VIEW3D_MT_particle_showhide")
1912
1913
1914 class VIEW3D_MT_particle_specials(Menu):
1915     bl_label = "Specials"
1916
1917     def draw(self, context):
1918         layout = self.layout
1919
1920         particle_edit = context.tool_settings.particle_edit
1921
1922         layout.operator("particle.rekey")
1923         layout.operator("particle.delete")
1924         layout.operator("particle.remove_doubles")
1925         layout.operator("particle.unify_length")
1926
1927         if particle_edit.select_mode == 'POINT':
1928             layout.operator("particle.subdivide")
1929
1930         layout.operator("particle.weight_set")
1931         layout.separator()
1932
1933         layout.operator("particle.mirror")
1934
1935         if particle_edit.select_mode == 'POINT':
1936             layout.separator()
1937             layout.operator("particle.select_roots")
1938             layout.operator("particle.select_tips")
1939
1940             layout.separator()
1941
1942             layout.operator("particle.select_random")
1943
1944             layout.separator()
1945
1946             layout.operator("particle.select_more")
1947             layout.operator("particle.select_less")
1948
1949             layout.separator()
1950
1951             layout.operator("particle.select_all").action = 'TOGGLE'
1952             layout.operator("particle.select_linked")
1953             layout.operator("particle.select_all", text="Inverse").action = 'INVERT'
1954
1955
1956 class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
1957     _operator_name = "particle"
1958
1959 # ********** Pose Menu **********
1960
1961
1962 class VIEW3D_MT_pose(Menu):
1963     bl_label = "Pose"
1964
1965     def draw(self, context):
1966         layout = self.layout
1967
1968         layout.operator("ed.undo")
1969         layout.operator("ed.redo")
1970         layout.operator("ed.undo_history")
1971
1972         layout.separator()
1973
1974         layout.menu("VIEW3D_MT_transform_armature")
1975
1976         layout.menu("VIEW3D_MT_pose_transform")
1977         layout.menu("VIEW3D_MT_pose_apply")
1978
1979         layout.menu("VIEW3D_MT_snap")
1980
1981         layout.separator()
1982
1983         layout.menu("VIEW3D_MT_object_animation")
1984
1985         layout.separator()
1986
1987         layout.menu("VIEW3D_MT_pose_slide")
1988         layout.menu("VIEW3D_MT_pose_propagate")
1989
1990         layout.separator()
1991
1992         layout.operator("pose.copy")
1993         layout.operator("pose.paste").flipped = False
1994         layout.operator("pose.paste", text="Paste X-Flipped Pose").flipped = True
1995
1996         layout.separator()
1997
1998         layout.menu("VIEW3D_MT_pose_library")
1999         layout.menu("VIEW3D_MT_pose_motion")
2000         layout.menu("VIEW3D_MT_pose_group")
2001
2002         layout.separator()
2003
2004         layout.menu("VIEW3D_MT_object_parent")
2005         layout.menu("VIEW3D_MT_pose_ik")
2006         layout.menu("VIEW3D_MT_pose_constraints")
2007
2008         layout.separator()
2009
2010         layout.operator_context = 'EXEC_AREA'
2011         layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS'
2012         layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS'
2013         layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS'
2014
2015         layout.operator("pose.flip_names")
2016
2017         layout.operator("pose.quaternions_flip")
2018
2019         layout.separator()
2020
2021         layout.operator_context = 'INVOKE_AREA'
2022         layout.operator("armature.armature_layers", text="Change Armature Layers...")
2023         layout.operator("pose.bone_layers", text="Change Bone Layers...")
2024
2025         layout.separator()
2026
2027         layout.menu("VIEW3D_MT_pose_showhide")
2028         layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
2029
2030
2031 class VIEW3D_MT_pose_transform(Menu):
2032     bl_label = "Clear Transform"
2033
2034     def draw(self, context):
2035         layout = self.layout
2036
2037         layout.operator("pose.transforms_clear", text="All")
2038
2039         layout.separator()
2040
2041         layout.operator("pose.loc_clear", text="Location")
2042         layout.operator("pose.rot_clear", text="Rotation")
2043         layout.operator("pose.scale_clear", text="Scale")
2044
2045         layout.separator()
2046
2047         layout.operator("pose.user_transforms_clear", text="Reset unkeyed")
2048
2049
2050 class VIEW3D_MT_pose_slide(Menu):
2051     bl_label = "In-Betweens"
2052
2053     def draw(self, context):
2054         layout = self.layout
2055
2056         layout.operator("pose.push")
2057         layout.operator("pose.relax")
2058         layout.operator("pose.breakdown")
2059
2060
2061 class VIEW3D_MT_pose_propagate(Menu):
2062     bl_label = "Propagate"
2063
2064     def draw(self, context):
2065         layout = self.layout
2066
2067         layout.operator("pose.propagate").mode = 'WHILE_HELD'
2068
2069         layout.separator()
2070
2071         layout.operator("pose.propagate", text="To Next Keyframe").mode = 'NEXT_KEY'
2072         layout.operator("pose.propagate", text="To Last Keyframe (Make Cyclic)").mode = 'LAST_KEY'
2073
2074         layout.separator()
2075
2076         layout.operator("pose.propagate", text="On Selected Keyframes").mode = 'SELECTED_KEYS'
2077
2078         layout.separator()
2079
2080         layout.operator("pose.propagate", text="On Selected Markers").mode = 'SELECTED_MARKERS'
2081
2082
2083 class VIEW3D_MT_pose_library(Menu):
2084     bl_label = "Pose Library"
2085
2086     def draw(self, context):
2087         layout = self.layout
2088
2089         layout.operator("poselib.browse_interactive", text="Browse Poses...")
2090
2091         layout.separator()
2092
2093         layout.operator("poselib.pose_add", text="Add Pose...")
2094         layout.operator("poselib.pose_rename", text="Rename Pose...")
2095         layout.operator("poselib.pose_remove", text="Remove Pose...")
2096
2097
2098 class VIEW3D_MT_pose_motion(Menu):
2099     bl_label = "Motion Paths"
2100
2101     def draw(self, context):
2102         layout = self.layout
2103
2104         layout.operator("pose.paths_calculate", text="Calculate")
2105         layout.operator("pose.paths_clear", text="Clear")
2106
2107
2108 class VIEW3D_MT_pose_group(Menu):
2109     bl_label = "Bone Groups"
2110
2111     def draw(self, context):
2112         layout = self.layout
2113
2114         pose = context.active_object.pose
2115
2116         layout.operator_context = 'EXEC_AREA'
2117         layout.operator("pose.group_assign", text="Assign to New Group").type = 0
2118         if pose.bone_groups:
2119             active_group = pose.bone_groups.active_index + 1
2120             layout.operator("pose.group_assign", text="Assign to Group").type = active_group
2121
2122             layout.separator()
2123
2124             # layout.operator_context = 'INVOKE_AREA'
2125             layout.operator("pose.group_unassign")
2126             layout.operator("pose.group_remove")
2127
2128
2129 class VIEW3D_MT_pose_ik(Menu):
2130     bl_label = "Inverse Kinematics"
2131
2132     def draw(self, context):
2133         layout = self.layout
2134
2135         layout.operator("pose.ik_add")
2136         layout.operator("pose.ik_clear")
2137
2138
2139 class VIEW3D_MT_pose_constraints(Menu):
2140     bl_label = "Constraints"
2141
2142     def draw(self, context):
2143         layout = self.layout
2144
2145         layout.operator("pose.constraint_add_with_targets", text="Add (With Targets)...")
2146         layout.operator("pose.constraints_copy")
2147         layout.operator("pose.constraints_clear")
2148
2149
2150 class VIEW3D_MT_pose_showhide(ShowHideMenu, Menu):
2151     _operator_name = "pose"
2152
2153
2154 class VIEW3D_MT_pose_apply(Menu):
2155     bl_label = "Apply"
2156
2157     def draw(self, context):
2158         layout = self.layout
2159
2160         layout.operator("pose.armature_apply")
2161         layout.operator("pose.visual_transform_apply")
2162
2163
2164 class VIEW3D_MT_pose_specials(Menu):
2165     bl_label = "Specials"
2166
2167     def draw(self, context):
2168         layout = self.layout
2169
2170         layout.operator("paint.weight_from_bones", text="Assign Automatic from Bones").type = 'AUTOMATIC'
2171         layout.operator("paint.weight_from_bones", text="Assign from Bone Envelopes").type = 'ENVELOPES'
2172
2173         layout.separator()
2174
2175         layout.operator("pose.select_constraint_target")
2176         layout.operator("pose.flip_names")
2177         layout.operator("pose.paths_calculate")
2178         layout.operator("pose.paths_clear")
2179         layout.operator("pose.user_transforms_clear")
2180         layout.operator("pose.user_transforms_clear", text="Clear User Transforms (All)").only_selected = False
2181         layout.operator("pose.relax")
2182
2183         layout.separator()
2184
2185         layout.operator_menu_enum("pose.autoside_names", "axis")
2186
2187
2188 class BoneOptions:
2189     def draw(self, context):
2190         layout = self.layout
2191
2192         options = [
2193             "show_wire",
2194             "use_deform",
2195             "use_envelope_multiply",
2196             "use_inherit_rotation",
2197             "use_inherit_scale",
2198         ]
2199
2200         if context.mode == 'EDIT_ARMATURE':
2201             bone_props = bpy.types.EditBone.bl_rna.properties
2202             data_path_iter = "selected_bones"
2203             opt_suffix = ""
2204             options.append("lock")
2205         else:  # pose-mode
2206             bone_props = bpy.types.Bone.bl_rna.properties
2207             data_path_iter = "selected_pose_bones"
2208             opt_suffix = "bone."
2209
2210         for opt in options:
2211             props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name,
2212                                     text_ctxt=i18n_contexts.default)
2213             props.data_path_iter = data_path_iter
2214             props.data_path_item = opt_suffix + opt
2215             props.type = self.type
2216
2217
2218 class VIEW3D_MT_bone_options_toggle(Menu, BoneOptions):
2219     bl_label = "Toggle Bone Options"
2220     type = 'TOGGLE'
2221
2222
2223 class VIEW3D_MT_bone_options_enable(Menu, BoneOptions):
2224     bl_label = "Enable Bone Options"
2225     type = 'ENABLE'
2226
2227
2228 class VIEW3D_MT_bone_options_disable(Menu, BoneOptions):
2229     bl_label = "Disable Bone Options"
2230     type = 'DISABLE'
2231
2232 # ********** Edit Menus, suffix from ob.type **********
2233
2234
2235 class VIEW3D_MT_edit_mesh(Menu):
2236     bl_label = "Mesh"
2237
2238     def draw(self, context):
2239         layout = self.layout
2240
2241         toolsettings = context.tool_settings
2242
2243         layout.operator("ed.undo")
2244         layout.operator("ed.redo")
2245         layout.operator("ed.undo_history")
2246
2247         layout.separator()
2248
2249         layout.menu("VIEW3D_MT_transform")
2250         layout.menu("VIEW3D_MT_mirror")
2251         layout.menu("VIEW3D_MT_snap")
2252
2253         layout.separator()
2254
2255         layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap...")
2256
2257         layout.separator()
2258
2259         layout.operator("mesh.duplicate_move")
2260         layout.menu("VIEW3D_MT_edit_mesh_extrude")
2261         layout.menu("VIEW3D_MT_edit_mesh_delete")
2262
2263         layout.separator()
2264
2265         layout.menu("VIEW3D_MT_edit_mesh_vertices")
2266         layout.menu("VIEW3D_MT_edit_mesh_edges")
2267         layout.menu("VIEW3D_MT_edit_mesh_faces")
2268         layout.menu("VIEW3D_MT_edit_mesh_normals")
2269         layout.menu("VIEW3D_MT_edit_mesh_clean")
2270
2271         layout.separator()
2272
2273         layout.operator("mesh.symmetrize")
2274         layout.operator("mesh.symmetry_snap")
2275         layout.operator("mesh.bisect")
2276         layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")
2277
2278         layout.separator()
2279
2280         layout.prop(toolsettings, "use_mesh_automerge")
2281         layout.prop_menu_enum(toolsettings, "proportional_edit")
2282         layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
2283
2284         layout.separator()
2285
2286         layout.menu("VIEW3D_MT_edit_mesh_showhide")
2287
2288
2289 class VIEW3D_MT_edit_mesh_specials(Menu):
2290     bl_label = "Specials"
2291
2292     def draw(self, context):
2293         layout = self.layout
2294
2295         layout.operator_context = 'INVOKE_REGION_WIN'
2296
2297         layout.operator("mesh.subdivide", text="Subdivide").smoothness = 0.0
2298         layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0
2299
2300         layout.separator()
2301
2302         layout.operator("mesh.merge", text="Merge...")
2303         layout.operator("mesh.remove_doubles")
2304
2305         layout.separator()
2306
2307         layout.operator("mesh.hide", text="Hide").unselected = False
2308         layout.operator("mesh.reveal", text="Reveal")
2309         layout.operator("mesh.select_all", text="Select Inverse").action = 'INVERT'
2310
2311         layout.separator()
2312
2313         layout.operator("mesh.flip_normals")
2314         layout.operator("mesh.vertices_smooth", text="Smooth")
2315         layout.operator("mesh.vertices_smooth_laplacian", text="Laplacian Smooth")
2316
2317         layout.separator()
2318
2319         layout.operator("mesh.inset")
2320         layout.operator("mesh.bevel", text="Bevel")
2321         layout.operator("mesh.bridge_edge_loops")
2322
2323         layout.separator()
2324
2325         layout.operator("mesh.faces_shade_smooth")
2326         layout.operator("mesh.faces_shade_flat")
2327
2328         layout.separator()
2329
2330         layout.operator("mesh.blend_from_shape")
2331         layout.operator("mesh.shape_propagate_to_all")
2332         layout.operator("mesh.shortest_path_select")
2333         layout.operator("mesh.sort_elements")
2334         layout.operator("mesh.symmetrize")
2335         layout.operator("mesh.symmetry_snap")
2336
2337
2338 class VIEW3D_MT_edit_mesh_select_mode(Menu):
2339     bl_label = "Mesh Select Mode"
2340
2341     def draw(self, context):
2342         layout = self.layout
2343
2344         layout.operator_context = 'INVOKE_REGION_WIN'
2345         layout.operator("mesh.select_mode", text="Vertex", icon='VERTEXSEL').type = 'VERT'
2346         layout.operator("mesh.select_mode", text="Edge", icon='EDGESEL').type = 'EDGE'
2347         layout.operator("mesh.select_mode", text="Face", icon='FACESEL').type = 'FACE'
2348
2349
2350 class VIEW3D_MT_edit_mesh_extrude(Menu):
2351     bl_label = "Extrude"
2352
2353     _extrude_funcs = {
2354         'VERT': lambda layout:
2355             layout.operator("mesh.extrude_vertices_move", text="Vertices Only"),
2356         'EDGE': lambda layout:
2357             layout.operator("mesh.extrude_edges_move", text="Edges Only"),
2358         'FACE': lambda layout:
2359             layout.operator("mesh.extrude_faces_move", text="Individual Faces"),
2360         'REGION': lambda layout:
2361             layout.operator("view3d.edit_mesh_extrude_move_normal", text="Region"),
2362         'REGION_VERT_NORMAL': lambda layout:
2363             layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Region (Vertex Normals)"),
2364     }
2365
2366     @staticmethod
2367     def extrude_options(context):
2368         mesh = context.object.data
2369         select_mode = context.tool_settings.mesh_select_mode
2370
2371         menu = []
2372         if mesh.total_face_sel:
2373             menu += ['REGION', 'REGION_VERT_NORMAL', 'FACE']
2374         if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
2375             menu += ['EDGE']
2376         if mesh.total_vert_sel and select_mode[0]:
2377             menu += ['VERT']
2378
2379         # should never get here
2380         return menu
2381
2382     def draw(self, context):
2383         layout = self.layout
2384         layout.operator_context = 'INVOKE_REGION_WIN'
2385
2386         for menu_id in self.extrude_options(context):
2387             self._extrude_funcs[menu_id](layout)
2388
2389
2390 class VIEW3D_MT_edit_mesh_vertices(Menu):
2391     bl_label = "Vertices"
2392
2393     def draw(self, context):
2394         layout = self.layout
2395         layout.operator_context = 'INVOKE_REGION_WIN'
2396
2397         layout.operator("mesh.merge")
2398         layout.operator("mesh.rip_move")
2399         layout.operator("mesh.rip_move_fill")
2400         layout.operator("mesh.rip_edge_move")
2401         layout.operator("mesh.split")
2402         layout.operator_menu_enum("mesh.separate", "type")
2403         layout.operator("mesh.vert_connect_path", text="Connect Vertex Path")
2404         layout.operator("mesh.vert_connect", text="Connect Vertices")
2405         layout.operator("transform.vert_slide", text="Slide")
2406
2407         layout.separator()
2408
2409         layout.operator("mesh.mark_sharp", text="Mark Sharp Edges").use_verts = True
2410         props = layout.operator("mesh.mark_sharp", text="Clear Sharp Edges")
2411         props.use_verts = True
2412         props.clear = True
2413
2414         layout.separator()
2415
2416         layout.operator("mesh.bevel").vertex_only = True
2417         layout.operator("mesh.convex_hull")
2418         layout.operator("mesh.vertices_smooth")
2419         layout.operator("mesh.remove_doubles")
2420
2421         layout.operator("mesh.blend_from_shape")
2422
2423         layout.operator("object.vertex_group_smooth")
2424         layout.operator("mesh.shape_propagate_to_all")
2425
2426         layout.separator()
2427
2428         layout.menu("VIEW3D_MT_vertex_group")
2429         layout.menu("VIEW3D_MT_hook")
2430
2431
2432 class VIEW3D_MT_edit_mesh_edges(Menu):
2433     bl_label = "Edges"
2434
2435     def draw(self, context):
2436         layout = self.layout
2437
2438         with_freestyle = bpy.app.build_options.freestyle
2439
2440         layout.operator_context = 'INVOKE_REGION_WIN'
2441
2442         layout.operator("mesh.edge_face_add")
2443         layout.operator("mesh.subdivide")
2444         layout.operator("mesh.unsubdivide")
2445
2446         layout.separator()
2447
2448         layout.operator("transform.edge_crease")
2449         layout.operator("transform.edge_bevelweight")
2450
2451         layout.separator()
2452
2453         layout.operator("mesh.mark_seam").clear = False
2454         layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
2455
2456         layout.separator()
2457
2458         layout.operator("mesh.mark_sharp")
2459         layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
2460
2461         layout.separator()
2462
2463         if with_freestyle:
2464             layout.operator("mesh.mark_freestyle_edge").clear = False
2465             layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
2466             layout.separator()
2467
2468         layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
2469         layout.operator("mesh.edge_rotate", text="Rotate Edge CCW").use_ccw = True
2470
2471         layout.separator()
2472
2473         layout.operator("mesh.bevel").vertex_only = False
2474         layout.operator("mesh.edge_split")
2475         layout.operator("mesh.bridge_edge_loops")
2476
2477         layout.separator()
2478
2479         layout.operator("transform.edge_slide")
2480         layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False
2481         layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True
2482         layout.operator("mesh.loop_to_region")
2483         layout.operator("mesh.region_to_loop")
2484
2485
2486 class VIEW3D_MT_edit_mesh_faces(Menu):
2487     bl_label = "Faces"
2488     bl_idname = "VIEW3D_MT_edit_mesh_faces"
2489
2490     def draw(self, context):
2491         layout = self.layout
2492
2493         with_freestyle = bpy.app.build_options.freestyle
2494
2495         layout.operator_context = 'INVOKE_REGION_WIN'
2496
2497         layout.operator("mesh.flip_normals")
2498         layout.operator("mesh.edge_face_add")
2499         layout.operator("mesh.fill")
2500         layout.operator("mesh.fill_grid")
2501         layout.operator("mesh.beautify_fill")
2502         layout.operator("mesh.inset")
2503         layout.operator("mesh.bevel").vertex_only = False
2504         layout.operator("mesh.solidify")
2505         layout.operator("mesh.intersect")
2506         layout.operator("mesh.intersect_boolean")
2507         layout.operator("mesh.wireframe")
2508
2509         layout.separator()
2510
2511         if with_freestyle:
2512             layout.operator("mesh.mark_freestyle_face").clear = False
2513             layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True
2514             layout.separator()
2515
2516         layout.operator("mesh.poke")
2517         props = layout.operator("mesh.quads_convert_to_tris")
2518         props.quad_method = props.ngon_method = 'BEAUTY'
2519         layout.operator("mesh.tris_convert_to_quads")
2520         layout.operator("mesh.face_split_by_edges")
2521
2522         layout.separator()
2523
2524         layout.operator("mesh.faces_shade_smooth")
2525         layout.operator("mesh.faces_shade_flat")
2526
2527         layout.operator("mesh.normals_make_consistent", text="Recalculate Normals").inside = False
2528
2529         layout.separator()
2530
2531         layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
2532
2533         layout.separator()
2534
2535         layout.operator("mesh.uvs_rotate")
2536         layout.operator("mesh.uvs_reverse")
2537         layout.operator("mesh.colors_rotate")
2538         layout.operator("mesh.colors_reverse")
2539
2540
2541 class VIEW3D_MT_edit_mesh_normals(Menu):
2542     bl_label = "Normals"
2543
2544     def draw(self, context):
2545         layout = self.layout
2546
2547         layout.operator("mesh.normals_make_consistent", text="Recalculate Outside").inside = False
2548         layout.operator("mesh.normals_make_consistent", text="Recalculate Inside").inside = True
2549
2550         layout.separator()
2551
2552         layout.operator("mesh.flip_normals")
2553
2554
2555 class VIEW3D_MT_edit_mesh_clean(Menu):
2556     bl_label = "Clean up"
2557
2558     def draw(self, context):
2559         layout = self.layout
2560
2561         layout.operator("mesh.delete_loose")
2562
2563         layout.separator()
2564
2565         layout.operator("mesh.dissolve_degenerate")
2566         layout.operator("mesh.dissolve_limited")
2567         layout.operator("mesh.face_make_planar")
2568         layout.operator("mesh.vert_connect_nonplanar")
2569         layout.operator("mesh.vert_connect_concave")
2570         layout.operator("mesh.fill_holes")
2571
2572
2573 class VIEW3D_MT_edit_mesh_delete(Menu):
2574     bl_label = "Delete"
2575
2576     def draw(self, context):
2577         layout = self.layout
2578
2579         layout.operator_enum("mesh.delete", "type")
2580
2581         layout.separator()
2582
2583         layout.operator("mesh.dissolve_verts")
2584         layout.operator("mesh.dissolve_edges")
2585         layout.operator("mesh.dissolve_faces")
2586
2587         layout.separator()
2588
2589         layout.operator("mesh.dissolve_limited")
2590
2591         layout.separator()
2592
2593         layout.operator("mesh.edge_collapse")
2594         layout.operator("mesh.delete_edgeloop", text="Edge Loops")
2595
2596
2597 class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu):
2598     _operator_name = "mesh"
2599
2600
2601 class VIEW3D_MT_edit_gpencil_delete(Menu):
2602     bl_label = "Delete"
2603
2604     def draw(self, context):
2605         layout = self.layout
2606
2607         layout.operator_enum("gpencil.delete", "type")
2608
2609         layout.separator()
2610
2611         layout.operator("gpencil.dissolve")
2612
2613
2614 # Edit Curve
2615 # draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface
2616
2617
2618 def draw_curve(self, context):
2619     layout = self.layout
2620
2621     toolsettings = context.tool_settings
2622
2623     layout.menu("VIEW3D_MT_transform")
2624     layout.menu("VIEW3D_MT_mirror")
2625     layout.menu("VIEW3D_MT_snap")
2626
2627     layout.separator()
2628
2629     layout.operator("curve.extrude_move")
2630     layout.operator("curve.spin")
2631     layout.operator("curve.duplicate_move")
2632     layout.operator("curve.split")
2633     layout.operator("curve.separate")
2634     layout.operator("curve.make_segment")
2635     layout.operator("curve.cyclic_toggle")
2636     layout.menu("VIEW3D_MT_edit_curve_delete")
2637
2638     layout.separator()
2639
2640     layout.menu("VIEW3D_MT_edit_curve_ctrlpoints")
2641     layout.menu("VIEW3D_MT_edit_curve_segments")
2642
2643     layout.separator()
2644
2645     layout.prop_menu_enum(toolsettings, "proportional_edit")
2646     layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
2647
2648     layout.separator()
2649
2650     layout.menu("VIEW3D_MT_edit_curve_showhide")
2651
2652
2653 class VIEW3D_MT_edit_curve(Menu):
2654     bl_label = "Curve"
2655
2656     draw = draw_curve
2657
2658
2659 class VIEW3D_MT_edit_curve_ctrlpoints(Menu):
2660     bl_label = "Control Points"
2661
2662     def draw(self, context):
2663         layout = self.layout
2664
2665         edit_object = context.edit_object
2666
2667         if edit_object.type == 'CURVE':
2668             layout.operator("transform.tilt")
2669             layout.operator("curve.tilt_clear")
2670
2671             layout.separator()
2672
2673             layout.operator_menu_enum("curve.handle_type_set", "type")
2674             layout.operator("curve.normals_make_consistent")
2675
2676             layout.separator()
2677
2678         layout.menu("VIEW3D_MT_hook")
2679
2680
2681 class VIEW3D_MT_edit_curve_segments(Menu):
2682     bl_label = "Segments"
2683
2684     def draw(self, context):
2685         layout = self.layout
2686
2687         layout.operator("curve.subdivide")
2688         layout.operator("curve.switch_direction")
2689
2690
2691 class VIEW3D_MT_edit_curve_specials(Menu):
2692     bl_label = "Specials"
2693
2694     def draw(self, context):
2695         layout = self.layout
2696
2697         layout.operator("curve.subdivide")
2698         layout.operator("curve.switch_direction")
2699         layout.operator("curve.spline_weight_set")
2700         layout.operator("curve.radius_set")
2701         layout.operator("curve.smooth")
2702         layout.operator("curve.smooth_weight")
2703         layout.operator("curve.smooth_radius")
2704         layout.operator("curve.smooth_tilt")
2705
2706
2707 class VIEW3D_MT_edit_curve_delete(Menu):
2708     bl_label = "Delete"
2709
2710     def draw(self, context):
2711         layout = self.layout
2712
2713         layout.operator_enum("curve.delete", "type")
2714
2715         layout.separator()
2716
2717         layout.operator("curve.dissolve_verts")
2718
2719
2720 class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, Menu):
2721     _operator_name = "curve"
2722
2723
2724 class VIEW3D_MT_edit_surface(Menu):
2725     bl_label = "Surface"
2726
2727     draw = draw_curve
2728
2729
2730 class VIEW3D_MT_edit_font(Menu):
2731     bl_label = "Text"
2732
2733     def draw(self, context):
2734         layout = self.layout
2735
2736         layout.menu("VIEW3D_MT_edit_text_chars")
2737
2738         layout.separator()
2739
2740         layout.operator("font.style_toggle", text="Toggle Bold").style = 'BOLD'
2741         layout.operator("font.style_toggle", text="Toggle Italic").style = 'ITALIC'
2742         layout.operator("font.style_toggle", text="Toggle Underline").style = 'UNDERLINE'
2743         layout.operator("font.style_toggle", text="Toggle Small Caps").style = 'SMALL_CAPS'
2744
2745
2746 class VIEW3D_MT_edit_text_chars(Menu):
2747     bl_label = "Special Characters"
2748
2749     def draw(self, context):
2750         layout = self.layout
2751
2752         layout.operator("font.text_insert", text="Copyright").text = "\u00A9"
2753         layout.operator("font.text_insert", text="Registered Trademark").text = "\u00AE"
2754
2755         layout.separator()
2756
2757         layout.operator("font.text_insert", text="Degree Sign").text = "\u00B0"
2758         layout.operator("font.text_insert", text="Multiplication Sign").text = "\u00D7"
2759         layout.operator("font.text_insert", text="Circle").text = "\u008A"
2760         layout.operator("font.text_insert", text="Superscript 1").text = "\u00B9"
2761         layout.operator("font.text_insert", text="Superscript 2").text = "\u00B2"
2762         layout.operator("font.text_insert", text="Superscript 3").text = "\u00B3"
2763         layout.operator("font.text_insert", text="Double >>").text = "\u00BB"
2764         layout.operator("font.text_insert", text="Double <<").text = "\u00AB"
2765         layout.operator("font.text_insert", text="Promillage").text = "\u2030"
2766
2767         layout.separator()
2768
2769         layout.operator("font.text_insert", text="Dutch Florin").text = "\u00A4"
2770         layout.operator("font.text_insert", text="British Pound").text = "\u00A3"
2771         layout.operator("font.text_insert", text="Japanese Yen").text = "\u00A5"
2772
2773         layout.separator()
2774
2775         layout.operator("font.text_insert", text="German S").text = "\u00DF"
2776         layout.operator("font.text_insert", text="Spanish Question Mark").text = "\u00BF"
2777         layout.operator("font.text_insert", text="Spanish Exclamation Mark").text = "\u00A1"
2778
2779
2780 class VIEW3D_MT_edit_meta(Menu):
2781     bl_label = "Metaball"
2782
2783     def draw(self, context):
2784         layout = self.layout
2785
2786         toolsettings = context.tool_settings
2787
2788         layout.operator("ed.undo")
2789         layout.operator("ed.redo")
2790         layout.operator("ed.undo_history")
2791
2792         layout.separator()
2793
2794         layout.menu("VIEW3D_MT_transform")
2795         layout.menu("VIEW3D_MT_mirror")
2796         layout.menu("VIEW3D_MT_snap")
2797
2798         layout.separator()
2799
2800         layout.operator("mball.delete_metaelems", text="Delete...")
2801         layout.operator("mball.duplicate_metaelems")
2802
2803         layout.separator()
2804
2805         layout.prop_menu_enum(toolsettings, "proportional_edit")
2806         layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
2807
2808         layout.separator()
2809
2810         layout.menu("VIEW3D_MT_edit_meta_showhide")
2811
2812
2813 class VIEW3D_MT_edit_meta_showhide(Menu):
2814     bl_label = "Show/Hide"
2815
2816     def draw(self, context):
2817         layout = self.layout
2818
2819         layout.operator("mball.reveal_metaelems", text="Show Hidden")
2820         layout.operator("mball.hide_metaelems", text="Hide Selected").unselected = False
2821         layout.operator("mball.hide_metaelems", text="Hide Unselected").unselected = True
2822
2823
2824 class VIEW3D_MT_edit_lattice(Menu):
2825     bl_label = "Lattice"
2826
2827     def draw(self, context):
2828         layout = self.layout
2829
2830         toolsettings = context.tool_settings
2831
2832         layout.menu("VIEW3D_MT_transform")
2833         layout.menu("VIEW3D_MT_mirror")
2834         layout.menu("VIEW3D_MT_snap")
2835         layout.operator_menu_enum("lattice.flip", "axis")
2836
2837         layout.separator()
2838
2839         layout.operator("lattice.make_regular")
2840
2841         layout.separator()
2842
2843         layout.prop_menu_enum(toolsettings, "proportional_edit")
2844         layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
2845
2846
2847 class VIEW3D_MT_edit_armature(Menu):
2848     bl_label = "Armature"
2849
2850     def draw(self, context):
2851         layout = self.layout
2852
2853         edit_object = context.edit_object
2854         arm = edit_object.data
2855
2856         layout.menu("VIEW3D_MT_transform_armature")
2857         layout.menu("VIEW3D_MT_mirror")
2858         layout.menu("VIEW3D_MT_snap")
2859         layout.menu("VIEW3D_MT_edit_armature_roll")
2860
2861         layout.separator()
2862
2863         layout.operator("armature.extrude_move")
2864
2865         if arm.use_mirror_x:
2866             layout.operator("armature.extrude_forked")
2867
2868         layout.operator("armature.duplicate_move")
2869         layout.operator("armature.merge")
2870         layout.operator("armature.fill")
2871         layout.operator("armature.delete")
2872         layout.operator("armature.split")
2873         layout.operator("armature.separate")
2874
2875         layout.separator()
2876
2877         layout.operator("armature.subdivide", text="Subdivide")
2878         layout.operator("armature.switch_direction", text="Switch Direction")
2879
2880         layout.separator()
2881
2882         layout.operator_context = 'EXEC_AREA'
2883         layout.operator("armature.symmetrize")
2884         layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
2885         layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
2886         layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
2887         layout.operator("armature.flip_names")
2888
2889         layout.separator()
2890
2891         layout.operator_context = 'INVOKE_DEFAULT'
2892         layout.operator("armature.armature_layers")
2893         layout.operator("armature.bone_layers")
2894
2895         layout.separator()
2896
2897         layout.menu("VIEW3D_MT_edit_armature_parent")
2898
2899         layout.separator()
2900
2901         layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
2902
2903
2904 class VIEW3D_MT_armature_specials(Menu):
2905     bl_label = "Specials"
2906
2907     def draw(self, context):
2908         layout = self.layout
2909
2910         layout.operator_context = 'INVOKE_REGION_WIN'
2911
2912         layout.operator("armature.subdivide", text="Subdivide")
2913         layout.operator("armature.switch_direction", text="Switch Direction")
2914
2915         layout.separator()
2916
2917         layout.operator_context = 'EXEC_REGION_WIN'
2918         layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
2919         layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
2920         layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
2921         layout.operator("armature.flip_names", text="Flip Names")
2922         layout.operator("armature.symmetrize")
2923
2924
2925 class VIEW3D_MT_edit_armature_parent(Menu):
2926     bl_label = "Parent"
2927
2928     def draw(self, context):
2929         layout = self.layout
2930
2931         layout.operator("armature.parent_set", text="Make")
2932         layout.operator("armature.parent_clear", text="Clear")
2933
2934
2935 class VIEW3D_MT_edit_armature_roll(Menu):
2936     bl_label = "Bone Roll"
2937
2938     def draw(self, context):
2939         layout = self.layout
2940
2941         layout.operator_menu_enum("armature.calculate_roll", "type")
2942
2943         layout.separator()
2944
2945         layout.operator("transform.transform", text="Set Roll").mode = 'BONE_ROLL'
2946         layout.operator("armature.roll_clear")
2947
2948
2949 class VIEW3D_MT_edit_armature_delete(Menu):
2950     bl_label = "Delete"
2951
2952     def draw(self, context):
2953         layout = self.layout
2954
2955         layout.operator("armature.delete", text="Delete Bones")
2956
2957         layout.separator()
2958
2959         layout.operator("armature.dissolve", text="Dissolve")
2960
2961
2962 # ********** GPencil Stroke Edit menu **********
2963
2964
2965 class VIEW3D_MT_edit_gpencil(Menu):
2966     bl_label = "GPencil"
2967
2968     def draw(self, context):
2969         toolsettings = context.tool_settings
2970
2971         layout = self.layout
2972
2973         layout.operator("ed.undo")
2974         layout.operator("ed.redo")
2975         layout.operator("ed.undo_history")
2976
2977         layout.separator()
2978
2979         layout.operator("gpencil.brush_paint", text="Sculpt Strokes").wait_for_input = True
2980         layout.prop_menu_enum(toolsettings.gpencil_sculpt, "tool", text="Sculpt Brush")
2981
2982         layout.separator()
2983
2984         layout.menu("VIEW3D_MT_edit_gpencil_transform")
2985         layout.operator("transform.mirror", text="Mirror")
2986         layout.menu("GPENCIL_MT_snap")
2987
2988         layout.separator()
2989
2990         layout.menu("VIEW3D_MT_object_animation")   # NOTE: provides keyingset access...
2991
2992         layout.separator()
2993
2994         layout.menu("VIEW3D_MT_edit_gpencil_delete")
2995         layout.operator("gpencil.duplicate_move", text="Duplicate")
2996
2997         layout.separator()
2998
2999         layout.operator("gpencil.copy", text="Copy")
3000         layout.operator("gpencil.paste", text="Paste")
3001
3002         layout.separator()
3003
3004         layout.prop_menu_enum(toolsettings, "proportional_edit")
3005         layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
3006
3007         layout.separator()
3008
3009         layout.operator("gpencil.reveal")
3010         layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True
3011         layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False
3012
3013         layout.separator()
3014
3015         layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
3016         layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...")
3017
3018
3019 class VIEW3D_MT_edit_gpencil_transform(Menu):
3020     bl_label = "Transform"
3021
3022     def draw(self, context):
3023         layout = self.layout
3024
3025         layout.operator("transform.translate")
3026         layout.operator("transform.rotate")
3027         layout.operator("transform.resize", text="Scale")
3028
3029         layout.separator()
3030
3031         layout.operator("transform.bend", text="Bend")
3032         layout.operator("transform.shear", text="Shear")
3033         layout.operator("transform.tosphere", text="To Sphere")
3034         layout.operator("transform.transform", text="Shrink Fatten").mode = 'GPENCIL_SHRINKFATTEN'
3035
3036
3037 # ********** Panel **********
3038
3039
3040 class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
3041     bl_space_type = 'VIEW_3D'
3042     bl_region_type = 'UI'
3043
3044     # NOTE: this is just a wrapper around the generic GP Panel
3045
3046
3047 class VIEW3D_PT_view3d_properties(Panel):
3048     bl_space_type = 'VIEW_3D'
3049     bl_region_type = 'UI'
3050     bl_label = "View"
3051
3052     @classmethod
3053     def poll(cls, context):
3054         view = context.space_data
3055         return (view)
3056
3057     def draw(self, context):
3058         layout = self.layout
3059
3060         view = context.space_data
3061
3062         col = layout.column()
3063         col.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews)
3064         col.prop(view, "lens")
3065         col.label(text="Lock to Object:")
3066         col.prop(view, "lock_object", text="")
3067         lock_object = view.lock_object
3068         if lock_object:
3069             if lock_object.type == 'ARMATURE':
3070                 col.prop_search(view, "lock_bone", lock_object.data,
3071                                 "edit_bones" if lock_object.mode == 'EDIT'
3072                                 else "bones",
3073                                 text="")
3074         else:
3075             col.prop(view, "lock_cursor", text="Lock to Cursor")
3076
3077         col = layout.column()
3078         col.prop(view, "lock_camera")
3079
3080         col = layout.column(align=True)
3081         col.label(text="Clip:")
3082         col.prop(view, "clip_start", text="Start")
3083         col.prop(view, "clip_end", text="End")
3084
3085         subcol = col.column(align=True)
3086         subcol.enabled = not view.lock_camera_and_layers
3087         subcol.label(text="Local Camera:")
3088         subcol.prop(view, "camera", text="")
3089
3090         col = layout.column(align=True)
3091         col.prop(view, "use_render_border")
3092         col.active = view.region_3d.view_perspective != 'CAMERA'
3093
3094
3095 class VIEW3D_PT_view3d_cursor(Panel):
3096     bl_space_type = 'VIEW_3D'
3097     bl_region_type = 'UI'
3098     bl_label = "3D Cursor"
3099
3100     @classmethod
3101     def poll(cls, context):
3102         view = context.space_data
3103         return (view is not None)
3104
3105     def draw(self, context):
3106         layout = self.layout
3107
3108         view = context.space_data
3109         layout.column().prop(view, "cursor_location", text="Location")
3110
3111
3112 class VIEW3D_PT_view3d_name(Panel):
3113     bl_space_type = 'VIEW_3D'
3114     bl_region_type = 'UI'
3115     bl_label = "Item"
3116
3117     @classmethod
3118     def poll(cls, context):
3119         return (context.space_data and context.active_object)
3120
3121     def draw(self, context):
3122         layout = self.layout
3123
3124         ob = context.active_object
3125         row = layout.row()
3126         row.label(text="", icon='OBJECT_DATA')
3127         row.prop(ob, "name", text="")
3128
3129         if ob.type == 'ARMATURE' and ob.mode in {'EDIT', 'POSE'}:
3130             bone = context.active_bone
3131             if bone:
3132                 row = layout.row()
3133                 row.label(text="", icon='BONE_DATA')
3134                 row.prop(bone, "name", text="")
3135
3136
3137 class VIEW3D_PT_view3d_display(Panel):
3138     bl_space_type = 'VIEW_3D'
3139     bl_region_type = 'UI'
3140     bl_label = "Display"
3141     bl_options = {'DEFAULT_CLOSED'}
3142
3143     @classmethod
3144     def poll(cls, context):
3145         view = context.space_data
3146         return (view)
3147
3148     def draw(self, context):
3149         layout = self.layout
3150
3151         view = context.space_data
3152         scene = context.scene
3153
3154         col = layout.column()
3155         col.prop(view, "show_only_render")
3156         col.prop(view, "show_world")
3157
3158         col = layout.column()
3159         display_all = not view.show_only_render
3160         col.active = display_all
3161         col.prop(view, "show_outline_selected")
3162         col.prop(view, "show_all_objects_origin")
3163         col.prop(view, "show_relationship_lines")
3164
3165         col = layout.column()
3166         col.active = display_all
3167         split = col.split(percentage=0.55)
3168         split.prop(view, "show_floor", text="Grid Floor")
3169
3170         row = split.row(align=True)
3171         row.prop(view, "show_axis_x", text="X", toggle=True)
3172         row.prop(view, "show_axis_y", text="Y", toggle=True)
3173         row.prop(view, "show_axis_z", text="Z", toggle=True)
3174
3175         sub = col.column(align=True)
3176         sub.active = (display_all and view.show_floor)
3177         sub.prop(view, "grid_lines", text="Lines")
3178         sub.prop(view, "grid_scale", text="Scale")
3179         subsub = sub.column(align=True)
3180         subsub.active = scene.unit_settings.system == 'NONE'
3181         subsub.prop(view, "grid_subdivisions", text="Subdivisions")
3182
3183         layout.separator()
3184
3185         layout.operator("screen.region_quadview", text="Toggle Quad View")
3186
3187         if view.region_quadviews:
3188             region = view.region_quadviews[2]
3189             col = layout.column()
3190             col.prop(region, "lock_rotation")
3191             row = col.row()
3192             row.enabled = region.lock_rotation
3193             row.prop(region, "show_sync_view")
3194             row = col.row()
3195             row.enabled = region.lock_rotation and region.show_sync_view
3196             row.prop(region, "use_box_clip")
3197
3198
3199 class VIEW3D_PT_view3d_stereo(Panel):
3200     bl_space_type = 'VIEW_3D'
3201     bl_region_type = 'UI'
3202     bl_label = "Stereoscopy"
3203     bl_options = {'DEFAULT_CLOSED'}
3204
3205     @classmethod
3206     def poll(cls, context):
3207         scene = context.scene
3208
3209         multiview = scene.render.use_multiview
3210         return context.space_data and multiview
3211
3212     def draw(self, context):
3213         layout = self.layout
3214         view = context.space_data
3215
3216         basic_stereo = context.scene.render.views_format == 'STEREO_3D'
3217
3218         col = layout.column()
3219         col.row().prop(view, "stereo_3d_camera", expand=True)
3220
3221         col.label(text="Display:")
3222         row = col.row()
3223         row.active = basic_stereo
3224         row.prop(view, "show_stereo_3d_cameras")
3225         row = col.row()
3226         row.active = basic_stereo
3227         split = row.split()
3228         split.prop(view, "show_stereo_3d_convergence_plane")
3229         split = row.split()
3230         split.prop(view, "stereo_3d_convergence_plane_alpha", text="Alpha")
3231         split.active = view.show_stereo_3d_convergence_plane
3232         row = col.row()
3233         split = row.split()
3234         split.prop(view, "show_stereo_3d_volume")
3235         split = row.split()
3236         split.prop(view, "stereo_3d_volume_alpha", text="Alpha")
3237
3238
3239 class VIEW3D_PT_view3d_shading(Panel):
3240     bl_space_type = 'VIEW_3D'
3241     bl_region_type = 'UI'
3242     bl_label = "Shading"
3243
3244     def draw(self, context):
3245         layout = self.layout
3246
3247         view = context.space_data
3248         scene = context.scene
3249         gs = scene.game_settings
3250         obj = context.object
3251
3252         col = layout.column()
3253
3254         if not scene.render.use_shading_nodes:
3255             col.prop(gs, "material_mode", text="")
3256
3257         if view.viewport_shade == 'SOLID':
3258             col.prop(view, "show_textured_solid")
3259             col.prop(view, "use_matcap")
3260             if view.use_matcap:
3261                 col.template_icon_view(view, "matcap_icon")
3262         if view.viewport_shade == 'TEXTURED' or context.mode == 'PAINT_TEXTURE':
3263             if scene.render.use_shading_nodes or gs.material_mode != 'GLSL':
3264                 col.prop(view, "show_textured_shadeless")
3265
3266         col.prop(view, "show_backface_culling")
3267
3268         if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
3269             if obj and obj.mode == 'EDIT':
3270                 col.prop(view, "show_occlude_wire")
3271
3272         fx_settings = view.fx_settings
3273
3274         if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
3275             sub = col.column()
3276             sub.active = view.region_3d.view_perspective == 'CAMERA'
3277             sub.prop(fx_settings, "use_dof")
3278             col.prop(fx_settings, "use_ssao", text="Ambient Occlusion")
3279             if fx_settings.use_ssao:
3280                 ssao_settings = fx_settings.ssao
3281                 subcol = col.column(align=True)
3282                 subcol.prop(ssao_settings, "factor")
3283                 subcol.prop(ssao_settings, "distance_max")
3284                 subcol.prop(ssao_settings, "attenuation")
3285                 subcol.prop(ssao_settings, "samples")
3286                 subcol.prop(ssao_settings, "color")
3287
3288
3289 class VIEW3D_PT_view3d_motion_tracking(Panel):
3290     bl_space_type = 'VIEW_3D'
3291     bl_region_type = 'UI'
3292     bl_label = "Motion Tracking"
3293     bl_options = {'DEFAULT_CLOSED'}
3294
3295     @classmethod
3296     def poll(cls, context):
3297         view = context.space_data
3298         return (view)
3299
3300     def draw_header(self, context):
3301         view = context.space_data
3302
3303         self.layout.prop(view, "show_reconstruction", text="")
3304
3305     def draw(self, context):
3306         layout = self.layout
3307
3308         view = context.space_data
3309
3310         col = layout.column()
3311         col.active = view.show_reconstruction
3312         col.prop(view, "show_camera_path", text="Camera Path")
3313         col.prop(view, "show_bundle_names", text="3D Marker Names")
3314         col.label(text="Track Type and Size:")
3315         row = col.row(align=True)
3316         row.prop(view, "tracks_draw_type", text="")
3317         row.prop(view, "tracks_draw_size", text="")
3318
3319
3320 class VIEW3D_PT_view3d_meshdisplay(Panel):
3321     bl_space_type = 'VIEW_3D'
3322     bl_region_type = 'UI'
3323     bl_label = "Mesh Display"
3324
3325     @classmethod
3326     def poll(cls, context):
3327         # The active object check is needed because of local-mode
3328         return (context.active_object and (context.mode == 'EDIT_MESH'))
3329
3330     def draw(self, context):
3331         layout = self.layout
3332         with_freestyle = bpy.app.build_options.freestyle
3333
3334         mesh = context.active_object.data
3335         scene = context.scene
3336
3337         split = layout.split()
3338
3339         col = split.column()
3340         col.label(text="Overlays:")
3341         col.prop(mesh, "show_faces", text="Faces")
3342         col.prop(mesh, "show_edges", text="Edges")
3343         col.prop(mesh, "show_edge_crease", text="Creases")
3344         if with_freestyle:
3345             col.prop(mesh, "show_edge_seams", text="Seams")
3346
3347         layout.prop(mesh, "show_weight")
3348
3349         col = split.column()
3350         col.label()
3351         if not with_freestyle:
3352             col.prop(mesh, "show_edge_seams", text="Seams")
3353         col.prop(mesh, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural)
3354         col.prop(mesh, "show_edge_bevel_weight", text="Bevel")
3355         if with_freestyle:
3356             col.prop(mesh, "show_freestyle_edge_marks", text="Edge Marks")
3357             col.prop(mesh, "show_freestyle_face_marks", text="Face Marks")
3358
3359         col = layout.column()
3360
3361         col.separator()
3362         col.label(text="Normals:")
3363         row = col.row(align=True)
3364
3365         row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
3366         row.prop(mesh, "show_normal_loop", text="", icon='LOOPSEL')
3367         row.prop(mesh, "show_normal_face", text="", icon='FACESEL')
3368
3369         sub = row.row(align=True)
3370         sub.active = mesh.show_normal_vertex or mesh.show_normal_face or mesh.show_normal_loop
3371         sub.prop(scene.tool_settings, "normal_size", text="Size")
3372
3373         col.separator()
3374         split = layout.split()
3375         col = split.column()
3376         col.label(text="Edge Info:")
3377         col.prop(mesh, "show_extra_edge_length", text="Length")
3378         col.prop(mesh, "show_extra_edge_angle", text="Angle")
3379         col = split.column()
3380         col.label(text="Face Info:")
3381         col.prop(mesh, "show_extra_face_area", text="Area")
3382         col.prop(mesh, "show_extra_face_angle", text="Angle")
3383         if bpy.app.debug:
3384             layout.prop(mesh, "show_extra_indices")
3385
3386
3387 class VIEW3D_PT_view3d_meshstatvis(Panel):
3388     bl_space_type = 'VIEW_3D'
3389     bl_region_type = 'UI'
3390     bl_label = "Mesh Analysis"
3391
3392     @classmethod
3393     def poll(cls, context):
3394         # The active object check is needed because of local-mode
3395         return (context.active_object and (context.mode == 'EDIT_MESH'))
3396
3397     def draw_header(self, context):
3398         mesh = context.active_object.data
3399
3400         self.layout.prop(mesh, "show_statvis", text="")
3401
3402     def draw(self, context):
3403         layout = self.layout
3404
3405         mesh = context.active_object.data
3406         statvis = context.tool_settings.statvis
3407         layout.active = mesh.show_statvis
3408
3409         layout.prop(statvis, "type")
3410         statvis_type = statvis.type
3411         if statvis_type == 'OVERHANG':
3412             row = layout.row(align=True)
3413             row.prop(statvis, "overhang_min", text="")
3414             row.prop(statvis, "overhang_max", text="")
3415             layout.prop(statvis, "overhang_axis", expand=True)
3416         elif statvis_type == 'THICKNESS':
3417             row = layout.row(align=True)
3418             row.prop(statvis, "thickness_min", text="")
3419             row.prop(statvis, "thickness_max", text="")
3420             layout.prop(statvis, "thickness_samples")
3421         elif statvis_type == 'INTERSECT':
3422             pass
3423         elif statvis_type == 'DISTORT':
3424             row = layout.row(align=True)
3425             row.prop(statvis, "distort_min", text="")
3426             row.prop(statvis, "distort_max", text="")
3427         elif statvis_type == 'SHARP':
3428             row = layout.row(align=True)
3429             row.prop(statvis, "sharp_min", text="")
3430             row.prop(statvis, "sharp_max", text="")
3431
3432
3433 class VIEW3D_PT_view3d_curvedisplay(Panel):
3434     bl_space_type = 'VIEW_3D'
3435     bl_region_type = 'UI'
3436     bl_label = "Curve Display"
3437
3438     @classmethod
3439     def poll(cls, context):
3440         editmesh = context.mode == 'EDIT_CURVE'
3441         return (editmesh)
3442
3443     def draw(self, context):
3444         layout = self.layout
3445
3446         curve = context.active_object.data
3447
3448         col = layout.column()
3449         row = col.row()
3450         row.prop(curve, "show_handles", text="Handles")
3451         row.prop(curve, "show_normal_face", text="Normals")
3452         col.prop(context.scene.tool_settings, "normal_size", text="Normal Size")
3453
3454
3455 class VIEW3D_PT_background_image(Panel):
3456     bl_space_type = 'VIEW_3D'
3457     bl_region_type = 'UI'
3458     bl_label = "Background Images"
3459     bl_options = {'DEFAULT_CLOSED'}
3460
3461     def draw_header(self, context):
3462         view = context.space_data
3463
3464         self.layout.prop(view, "show_background_images", text="")
3465
3466     def draw(self, context):
3467         layout = self.layout
3468
3469         view = context.space_data
3470         use_multiview = context.scene.render.use_multiview
3471
3472         col = layout.column()
3473         col.operator(