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