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