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