4e394839166ecf00c5acb3a3315a118376a981f8
[blender.git] / release / scripts / 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22
23 class VIEW3D_HT_header(bpy.types.Header):
24     bl_space_type = 'VIEW_3D'
25
26     def draw(self, context):
27         layout = self.layout
28
29         view = context.space_data
30         mode_string = context.mode
31         edit_object = context.edit_object
32         obj = context.active_object
33         toolsettings = context.scene.tool_settings
34
35         row = layout.row()
36         row.template_header()
37
38         sub = row.row(align=True)
39
40         # Menus
41         if context.area.show_menus:
42
43             sub.menu("VIEW3D_MT_view")
44
45             # Select Menu
46             if mode_string not in ('EDIT_TEXT', 'SCULPT', 'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'):
47                 sub.menu("VIEW3D_MT_select_%s" % mode_string.lower())
48
49             if edit_object:
50                 sub.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower())
51             elif obj:
52                 if mode_string not in ('PAINT_WEIGHT', 'PAINT_TEXTURE'):
53                     sub.menu("VIEW3D_MT_%s" % mode_string.lower())
54             else:
55                 sub.menu("VIEW3D_MT_object")
56
57         row.template_header_3D()
58
59         # Particle edit
60         if obj and obj.mode == 'PARTICLE_EDIT':
61             row.prop(toolsettings.particle_edit, "selection_mode", text="", expand=True, toggle=True)
62
63         # Occlude geometry
64         if obj and view.viewport_shading in ('SOLID', 'SHADED', 'TEXTURED') and (obj.mode == 'PARTICLE_EDIT' or (obj.mode == 'EDIT' and obj.type == 'MESH')):
65             row.prop(view, "occlude_geometry", text="")
66
67         # Proportional editing
68         if obj and obj.mode in ('OBJECT', 'EDIT', 'PARTICLE_EDIT'):
69             row = layout.row(align=True)
70             row.prop(toolsettings, "proportional_editing", text="", icon_only=True)
71             if toolsettings.proportional_editing != 'DISABLED':
72                 row.prop(toolsettings, "proportional_editing_falloff", text="", icon_only=True)
73
74         # Snap
75         row = layout.row(align=True)
76         row.prop(toolsettings, "snap", text="")
77         row.prop(toolsettings, "snap_element", text="", icon_only=True)
78         if toolsettings.snap_element != 'INCREMENT':
79             row.prop(toolsettings, "snap_target", text="")
80             if obj and obj.mode == 'OBJECT':
81                 row.prop(toolsettings, "snap_align_rotation", text="")
82         if toolsettings.snap_element == 'VOLUME':
83             row.prop(toolsettings, "snap_peel_object", text="")
84         elif toolsettings.snap_element == 'FACE':
85             row.prop(toolsettings, "snap_project", text="")
86
87         # OpenGL render
88         row = layout.row(align=True)
89         row.operator("screen.opengl_render", text="", icon='RENDER_STILL')
90         props = row.operator("screen.opengl_render", text="", icon='RENDER_ANIMATION')
91         props.animation = True
92
93         # Pose
94         if obj and obj.mode == 'POSE':
95             row = layout.row(align=True)
96             row.operator("pose.copy", text="", icon='COPYDOWN')
97             row.operator("pose.paste", text="", icon='PASTEDOWN')
98             props = row.operator("pose.paste", text="", icon='PASTEFLIPDOWN')
99             props.flipped = 1
100
101
102 # ********** Menu **********
103
104 # ********** Utilities **********
105
106
107 class VIEW3D_MT_showhide(bpy.types.Menu):
108     bl_label = "Show/Hide"
109     _operator_name = ""
110
111     def draw(self, context):
112         layout = self.layout
113
114         layout.operator("%s.reveal" % self._operator_name, text="Show Hidden")
115         layout.operator("%s.hide" % self._operator_name, text="Hide Selected")
116         layout.operator("%s.hide" % self._operator_name, text="Hide Unselected").unselected = True
117
118
119 class VIEW3D_MT_transform(bpy.types.Menu):
120     bl_label = "Transform"
121
122     # TODO: get rid of the custom text strings?
123     def draw(self, context):
124         layout = self.layout
125
126         layout.operator("transform.translate", text="Grab/Move")
127         # TODO: sub-menu for grab per axis
128         layout.operator("transform.rotate", text="Rotate")
129         # TODO: sub-menu for rot per axis
130         layout.operator("transform.resize", text="Scale")
131         # TODO: sub-menu for scale per axis
132
133         layout.separator()
134
135         layout.operator("transform.tosphere", text="To Sphere")
136         layout.operator("transform.shear", text="Shear")
137         layout.operator("transform.warp", text="Warp")
138         layout.operator("transform.transform", text="Push/Pull").mode = 'PUSHPULL'
139         if context.edit_object and context.edit_object.type == 'ARMATURE':
140             layout.operator("armature.align")
141         else:
142             layout.operator_context = 'EXEC_REGION_WIN'
143             layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN' # XXX see alignmenu() in edit.c of b2.4x to get this working
144
145         layout.separator()
146
147         layout.operator_context = 'EXEC_AREA'
148
149         layout.operator("object.origin_set", text="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
150         layout.operator("object.origin_set", text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
151         layout.operator("object.origin_set", text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
152
153
154 class VIEW3D_MT_mirror(bpy.types.Menu):
155     bl_label = "Mirror"
156
157     def draw(self, context):
158         layout = self.layout
159
160         layout.operator("transform.mirror", text="Interactive Mirror")
161
162         layout.separator()
163
164         layout.operator_context = 'INVOKE_REGION_WIN'
165
166         props = layout.operator("transform.mirror", text="X Global")
167         props.constraint_axis = (True, False, False)
168         props.constraint_orientation = 'GLOBAL'
169         props = layout.operator("transform.mirror", text="Y Global")
170         props.constraint_axis = (False, True, False)
171         props.constraint_orientation = 'GLOBAL'
172         props = layout.operator("transform.mirror", text="Z Global")
173         props.constraint_axis = (False, False, True)
174         props.constraint_orientation = 'GLOBAL'
175
176         if context.edit_object:
177             layout.separator()
178
179             props = layout.operator("transform.mirror", text="X Local")
180             props.constraint_axis = (True, False, False)
181             props.constraint_orientation = 'LOCAL'
182             props = layout.operator("transform.mirror", text="Y Local")
183             props.constraint_axis = (False, True, False)
184             props.constraint_orientation = 'LOCAL'
185             props = layout.operator("transform.mirror", text="Z Local")
186             props.constraint_axis = (False, False, True)
187             props.constraint_orientation = 'LOCAL'
188
189             layout.operator("object.vertex_group_mirror")
190
191
192 class VIEW3D_MT_snap(bpy.types.Menu):
193     bl_label = "Snap"
194
195     def draw(self, context):
196         layout = self.layout
197
198         layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid")
199         layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor")
200         layout.operator("view3d.snap_selected_to_center", text="Selection to Origin")
201
202         layout.separator()
203
204         layout.operator("view3d.snap_cursor_to_selected", text="Cursor to Selected")
205         layout.operator("view3d.snap_cursor_to_center", text="Cursor to Center")
206         layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
207         layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
208
209
210 class VIEW3D_MT_uv_map(bpy.types.Menu):
211     bl_label = "UV Mapping"
212
213     def draw(self, context):
214         layout = self.layout
215
216         layout.operator("uv.unwrap")
217         layout.operator("uv.cube_project")
218         layout.operator("uv.cylinder_project")
219         layout.operator("uv.sphere_project")
220         layout.operator("uv.project_from_view")
221         layout.operator("uv.project_from_view", text="Project from View (Bounds)").scale_to_bounds = True
222
223         layout.separator()
224
225         layout.operator("uv.reset")
226
227 # ********** View menus **********
228
229
230 class VIEW3D_MT_view(bpy.types.Menu):
231     bl_label = "View"
232
233     def draw(self, context):
234         layout = self.layout
235
236         layout.operator("view3d.properties", icon='MENU_PANEL')
237         layout.operator("view3d.toolshelf", icon='MENU_PANEL')
238
239         layout.separator()
240
241         layout.operator("view3d.viewnumpad", text="Camera").type = 'CAMERA'
242         layout.operator("view3d.viewnumpad", text="Top").type = 'TOP'
243         layout.operator("view3d.viewnumpad", text="Front").type = 'FRONT'
244         layout.operator("view3d.viewnumpad", text="Right").type = 'RIGHT'
245
246         layout.menu("VIEW3D_MT_view_cameras", text="Cameras")
247
248         layout.separator()
249
250         layout.operator("view3d.view_persportho")
251
252         layout.separator()
253
254         layout.menu("VIEW3D_MT_view_navigation")
255         layout.menu("VIEW3D_MT_view_align")
256
257         layout.separator()
258
259         layout.operator_context = 'INVOKE_REGION_WIN'
260
261         layout.operator("view3d.clip_border", text="Clipping Border...")
262         layout.operator("view3d.zoom_border", text="Zoom Border...")
263
264         layout.separator()
265
266         layout.operator("view3d.layers", text="Show All Layers").nr = 0
267
268         layout.separator()
269
270         layout.operator("view3d.localview", text="View Global/Local")
271         layout.operator("view3d.view_selected")
272         layout.operator("view3d.view_all")
273
274         layout.separator()
275
276         layout.operator("screen.animation_play", text="Playback Animation")
277
278         layout.separator()
279
280         layout.operator("screen.area_dupli")
281         layout.operator("screen.region_quadview")
282         layout.operator("screen.screen_full_area")
283
284
285 class VIEW3D_MT_view_navigation(bpy.types.Menu):
286     bl_label = "Navigation"
287
288     def draw(self, context):
289         layout = self.layout
290
291         layout.operator_enums("view3d.view_orbit", "type")
292
293         layout.separator()
294
295         layout.operator_enums("view3d.view_pan", "type")
296
297         layout.separator()
298
299         layout.operator("view3d.zoom", text="Zoom In").delta = 1
300         layout.operator("view3d.zoom", text="Zoom Out").delta = -1
301
302         layout.separator()
303
304         layout.operator("view3d.fly")
305
306
307 class VIEW3D_MT_view_align(bpy.types.Menu):
308     bl_label = "Align View"
309
310     def draw(self, context):
311         layout = self.layout
312
313         layout.menu("VIEW3D_MT_view_align_selected")
314
315         layout.separator()
316
317         layout.operator("view3d.view_all", text="Center Cursor and View All").center = True
318         layout.operator("view3d.camera_to_view", text="Align Active Camera to View")
319         layout.operator("view3d.view_selected")
320         layout.operator("view3d.view_center_cursor")
321
322
323 class VIEW3D_MT_view_align_selected(bpy.types.Menu):
324     bl_label = "Align View to Selected"
325
326     def draw(self, context):
327         layout = self.layout
328
329         props = layout.operator("view3d.viewnumpad", text="Top")
330         props.align_active = True
331         props.type = 'TOP'
332         props = layout.operator("view3d.viewnumpad", text="Bottom")
333         props.align_active = True
334         props.type = 'BOTTOM'
335         props = layout.operator("view3d.viewnumpad", text="Front")
336         props.align_active = True
337         props.type = 'FRONT'
338         props = layout.operator("view3d.viewnumpad", text="Back")
339         props.align_active = True
340         props.type = 'BACK'
341         props = layout.operator("view3d.viewnumpad", text="Right")
342         props.align_active = True
343         props.type = 'RIGHT'
344         props = layout.operator("view3d.viewnumpad", text="Left")
345         props.align_active = True
346         props.type = 'LEFT'
347
348
349 class VIEW3D_MT_view_cameras(bpy.types.Menu):
350     bl_label = "Cameras"
351
352     def draw(self, context):
353         layout = self.layout
354
355         layout.operator("view3d.object_as_camera")
356         layout.operator("view3d.viewnumpad", text="Active Camera").type = 'CAMERA'
357
358 # ********** Select menus, suffix from context.mode **********
359
360
361 class VIEW3D_MT_select_object(bpy.types.Menu):
362     bl_label = "Select"
363
364     def draw(self, context):
365         layout = self.layout
366
367         layout.operator("view3d.select_border")
368         layout.operator("view3d.select_circle")
369
370         layout.separator()
371
372         layout.operator("object.select_all", text="Select/Deselect All")
373         layout.operator("object.select_inverse", text="Inverse")
374         layout.operator("object.select_random", text="Random")
375         layout.operator("object.select_mirror", text="Mirror")
376         layout.operator("object.select_by_layer", text="Select All by Layer")
377         layout.operator_menu_enum("object.select_by_type", "type", "", text="Select All by Type...")
378
379         layout.separator()
380
381         layout.operator_menu_enum("object.select_grouped", "type", text="Grouped")
382         layout.operator_menu_enum("object.select_linked", "type", text="Linked")
383         layout.operator("object.select_pattern", text="Select Pattern...")
384
385
386 class VIEW3D_MT_select_pose(bpy.types.Menu):
387     bl_label = "Select"
388
389     def draw(self, context):
390         layout = self.layout
391
392         layout.operator("view3d.select_border")
393
394         layout.separator()
395
396         layout.operator("pose.select_all", text="Select/Deselect All")
397         layout.operator("pose.select_inverse", text="Inverse")
398         layout.operator("pose.select_constraint_target", text="Constraint Target")
399         layout.operator("pose.select_linked", text="Linked")
400
401         layout.separator()
402
403         layout.operator("pose.select_hierarchy", text="Parent").direction = 'PARENT'
404         layout.operator("pose.select_hierarchy", text="Child").direction = 'CHILD'
405
406         layout.separator()
407
408         props = layout.operator("pose.select_hierarchy", text="Extend Parent")
409         props.extend = True
410         props.direction = 'PARENT'
411
412         props = layout.operator("pose.select_hierarchy", text="Extend Child")
413         props.extend = True
414         props.direction = 'CHILD'
415
416         layout.operator("object.select_pattern", text="Select Pattern...")
417
418
419 class VIEW3D_MT_select_particle(bpy.types.Menu):
420     bl_label = "Select"
421
422     def draw(self, context):
423         layout = self.layout
424
425         layout.operator("view3d.select_border")
426
427         layout.separator()
428
429         layout.operator("particle.select_all", text="Select/Deselect All")
430         layout.operator("particle.select_linked")
431         layout.operator("particle.select_inverse")
432
433         layout.separator()
434
435         layout.operator("particle.select_more")
436         layout.operator("particle.select_less")
437
438         layout.separator()
439
440         layout.operator("particle.select_first", text="Roots")
441         layout.operator("particle.select_last", text="Tips")
442
443
444 class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
445     bl_label = "Select"
446
447     def draw(self, context):
448         layout = self.layout
449
450         layout.operator("view3d.select_border")
451         layout.operator("view3d.select_circle")
452
453         layout.separator()
454
455         layout.operator("mesh.select_all", text="Select/Deselect All")
456         layout.operator("mesh.select_inverse", text="Inverse")
457
458         layout.separator()
459
460         layout.operator("mesh.select_random", text="Random...")
461         layout.operator("mesh.select_nth", text="Select Nth...")
462         layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
463         layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
464         layout.operator("mesh.faces_select_interior", text="Interior Faces")
465         layout.operator("mesh.select_axis", text="Side of Active")
466
467         layout.separator()
468
469         layout.operator("mesh.select_by_number_vertices", text="Triangles").type = 'TRIANGLES'
470         layout.operator("mesh.select_by_number_vertices", text="Quads").type = 'QUADS'
471         layout.operator("mesh.select_by_number_vertices", text="Loose Verts/Edges").type = 'OTHER'
472         layout.operator("mesh.select_similar", text="Similar...")
473
474         layout.separator()
475
476         layout.operator("mesh.select_less", text="Less")
477         layout.operator("mesh.select_more", text="More")
478
479         layout.separator()
480
481         layout.operator("mesh.select_mirror", text="Mirror")
482
483         layout.operator("mesh.select_linked", text="Linked")
484         layout.operator("mesh.select_vertex_path", text="Vertex Path")
485         layout.operator("mesh.loop_multi_select", text="Edge Loop")
486         layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True
487
488         layout.separator()
489
490         layout.operator("mesh.loop_to_region")
491         layout.operator("mesh.region_to_loop")
492
493
494 class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
495     bl_label = "Select"
496
497     def draw(self, context):
498         layout = self.layout
499
500         layout.operator("view3d.select_border")
501         layout.operator("view3d.select_circle")
502
503         layout.separator()
504
505         layout.operator("curve.select_all", text="Select/Deselect All")
506         layout.operator("curve.select_inverse")
507         layout.operator("curve.select_random")
508         layout.operator("curve.select_every_nth")
509
510         layout.separator()
511
512         layout.operator("curve.de_select_first")
513         layout.operator("curve.de_select_last")
514         layout.operator("curve.select_next")
515         layout.operator("curve.select_previous")
516
517         layout.separator()
518
519         layout.operator("curve.select_more")
520         layout.operator("curve.select_less")
521
522
523 class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
524     bl_label = "Select"
525
526     def draw(self, context):
527         layout = self.layout
528
529         layout.operator("view3d.select_border")
530         layout.operator("view3d.select_circle")
531
532         layout.separator()
533
534         layout.operator("curve.select_all", text="Select/Deselect All")
535         layout.operator("curve.select_inverse")
536         layout.operator("curve.select_random")
537         layout.operator("curve.select_every_nth")
538
539         layout.separator()
540
541         layout.operator("curve.select_row")
542
543         layout.separator()
544
545         layout.operator("curve.select_more")
546         layout.operator("curve.select_less")
547
548
549 class VIEW3D_MT_select_edit_metaball(bpy.types.Menu):
550     bl_label = "Select"
551
552     def draw(self, context):
553         layout = self.layout
554
555         layout.operator("view3d.select_border")
556
557         layout.separator()
558
559         layout.operator("mball.select_deselect_all_metaelems")
560         layout.operator("mball.select_inverse_metaelems")
561
562         layout.separator()
563
564         layout.operator("mball.select_random_metaelems")
565
566
567 class VIEW3D_MT_select_edit_lattice(bpy.types.Menu):
568     bl_label = "Select"
569
570     def draw(self, context):
571         layout = self.layout
572
573         layout.operator("view3d.select_border")
574
575         layout.separator()
576
577         layout.operator("lattice.select_all", text="Select/Deselect All")
578
579
580 class VIEW3D_MT_select_edit_armature(bpy.types.Menu):
581     bl_label = "Select"
582
583     def draw(self, context):
584         layout = self.layout
585
586         layout.operator("view3d.select_border")
587
588
589         layout.separator()
590
591         layout.operator("armature.select_all", text="Select/Deselect All")
592         layout.operator("armature.select_inverse", text="Inverse")
593
594         layout.separator()
595
596         layout.operator("armature.select_hierarchy", text="Parent").direction = 'PARENT'
597         layout.operator("armature.select_hierarchy", text="Child").direction = 'CHILD'
598
599         layout.separator()
600
601         props = layout.operator("armature.select_hierarchy", text="Extend Parent")
602         props.extend = True
603         props.direction = 'PARENT'
604
605         props = layout.operator("armature.select_hierarchy", text="Extend Child")
606         props.extend = True
607         props.direction = 'CHILD'
608
609         layout.operator("object.select_pattern", text="Select Pattern...")
610
611
612 class VIEW3D_MT_select_face(bpy.types.Menu):# XXX no matching enum
613     bl_label = "Select"
614
615     def draw(self, context):
616         layout = self.layout
617
618         # TODO
619         # see view3d_select_faceselmenu
620
621 # ********** Object menu **********
622
623
624 class VIEW3D_MT_object(bpy.types.Menu):
625     bl_context = "objectmode"
626     bl_label = "Object"
627
628     def draw(self, context):
629         layout = self.layout
630
631         layout.menu("VIEW3D_MT_transform")
632         layout.menu("VIEW3D_MT_mirror")
633         layout.menu("VIEW3D_MT_object_clear")
634         layout.menu("VIEW3D_MT_object_apply")
635         layout.menu("VIEW3D_MT_snap")
636
637         layout.separator()
638
639         layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...")
640         layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframe...")
641
642         layout.separator()
643
644         layout.operator("object.duplicate_move")
645         layout.operator("object.duplicate_move_linked")
646         layout.operator("object.delete", text="Delete...")
647         layout.operator("object.proxy_make", text="Make Proxy...")
648         layout.menu("VIEW3D_MT_make_links", text="Make Links...")
649         layout.operator_menu_enum("object.make_local", "type", text="Make Local...")
650         layout.menu("VIEW3D_MT_make_single_user")
651
652         layout.separator()
653
654         layout.menu("VIEW3D_MT_object_parent")
655         layout.menu("VIEW3D_MT_object_track")
656         layout.menu("VIEW3D_MT_object_group")
657         layout.menu("VIEW3D_MT_object_constraints")
658
659         layout.separator()
660
661         layout.operator("object.join_shapes")
662         layout.operator("object.join_uvs")
663         layout.operator("object.join")
664
665         layout.separator()
666
667         layout.operator("object.move_to_layer", text="Move to Layer...")
668         layout.menu("VIEW3D_MT_object_showhide")
669
670         layout.operator_menu_enum("object.convert", "target")
671
672
673 class VIEW3D_MT_object_clear(bpy.types.Menu):
674     bl_label = "Clear"
675
676     def draw(self, context):
677         layout = self.layout
678
679         layout.operator("object.location_clear", text="Location")
680         layout.operator("object.rotation_clear", text="Rotation")
681         layout.operator("object.scale_clear", text="Scale")
682         layout.operator("object.origin_clear", text="Origin")
683
684
685 class VIEW3D_MT_object_apply(bpy.types.Menu):
686     bl_label = "Apply"
687
688     def draw(self, context):
689         layout = self.layout
690
691         layout.operator("object.location_apply", text="Location")
692         layout.operator("object.rotation_apply", text="Rotation")
693         layout.operator("object.scale_apply", text="Scale")
694         layout.separator()
695         layout.operator("object.visual_transform_apply", text="Visual Transform")
696         layout.operator("object.duplicates_make_real")
697
698
699 class VIEW3D_MT_object_parent(bpy.types.Menu):
700     bl_label = "Parent"
701
702     def draw(self, context):
703         layout = self.layout
704
705         layout.operator("object.parent_set", text="Set")
706         layout.operator("object.parent_clear", text="Clear")
707
708
709 class VIEW3D_MT_object_track(bpy.types.Menu):
710     bl_label = "Track"
711
712     def draw(self, context):
713         layout = self.layout
714
715         layout.operator("object.track_set", text="Set")
716         layout.operator("object.track_clear", text="Clear")
717
718
719 class VIEW3D_MT_object_group(bpy.types.Menu):
720     bl_label = "Group"
721
722     def draw(self, context):
723         layout = self.layout
724
725         layout.operator("group.create")
726         layout.operator("group.objects_remove")
727
728         layout.separator()
729
730         layout.operator("group.objects_add_active")
731         layout.operator("group.objects_remove_active")
732
733
734 class VIEW3D_MT_object_constraints(bpy.types.Menu):
735     bl_label = "Constraints"
736
737     def draw(self, context):
738         layout = self.layout
739
740         layout.operator("object.constraint_add_with_targets")
741         layout.operator("object.constraints_clear")
742
743
744 class VIEW3D_MT_object_showhide(bpy.types.Menu):
745     bl_label = "Show/Hide"
746
747     def draw(self, context):
748         layout = self.layout
749
750         layout.operator("object.restrictview_clear", text="Show Hidden")
751         layout.operator("object.restrictview_set", text="Hide Selected")
752         layout.operator("object.restrictview_set", text="Hide Unselected").unselected = True
753
754
755 class VIEW3D_MT_make_single_user(bpy.types.Menu):
756     bl_label = "Make Single User"
757
758     def draw(self, context):
759         layout = self.layout
760
761         props = layout.operator("object.make_single_user", text="Object")
762         props.object = True
763
764         props = layout.operator("object.make_single_user", text="Object & ObData")
765         props.object = props.obdata = True
766
767         props = layout.operator("object.make_single_user", text="Object & ObData & Materials+Tex")
768         props.object = props.obdata = props.material = props.texture = True
769
770         props = layout.operator("object.make_single_user", text="Materials+Tex")
771         props.material = props.texture = True
772
773         props = layout.operator("object.make_single_user", text="Animation")
774         props.animation = True
775
776
777 class VIEW3D_MT_make_links(bpy.types.Menu):
778     bl_label = "Make Links"
779
780     def draw(self, context):
781         layout = self.layout
782
783         layout.operator_menu_enum("object.make_links_scene", "type", text="Objects to Scene...")
784         layout.operator_menu_enum("marker.make_links_scene", "type", text="Markers to Scene...")
785         layout.operator_enums("object.make_links_data", property="type") # inline
786
787
788 # ********** Vertex paint menu **********
789
790
791 class VIEW3D_MT_paint_vertex(bpy.types.Menu):
792     bl_label = "Paint"
793
794     def draw(self, context):
795         layout = self.layout
796
797         layout.operator("paint.vertex_color_set")
798         layout.operator("paint.vertex_color_set", text="Set Selected Vertex Colors").selected = True
799
800
801 class VIEW3D_MT_hook(bpy.types.Menu):
802     bl_label = "Hooks"
803
804     def draw(self, context):
805         layout = self.layout
806         layout.operator_context = 'EXEC_AREA'
807         layout.operator("object.hook_add_newob")
808         layout.operator("object.hook_add_selob")
809
810         if [mod.type == 'HOOK' for mod in context.active_object.modifiers]:
811             layout.separator()
812             layout.operator_menu_enum("object.hook_assign", "modifier")
813             layout.operator_menu_enum("object.hook_remove", "modifier")
814             layout.separator()
815             layout.operator_menu_enum("object.hook_select", "modifier")
816             layout.operator_menu_enum("object.hook_reset", "modifier")
817             layout.operator_menu_enum("object.hook_recenter", "modifier")
818
819
820 class VIEW3D_MT_vertex_group(bpy.types.Menu):
821     bl_label = "Vertex Groups"
822
823     def draw(self, context):
824         layout = self.layout
825         layout.operator_context = 'EXEC_AREA'
826         layout.operator("object.vertex_group_assign", text="Assign to New Group").new = True
827
828         ob = context.active_object
829         if ob.mode == 'EDIT':
830             if ob.vertex_groups and ob.active_vertex_group:
831                 layout.separator()
832                 layout.operator("object.vertex_group_assign", text="Assign to Active Group")
833                 layout.operator("object.vertex_group_remove_from", text="Remove from Active Group")
834                 layout.operator("object.vertex_group_remove_from", text="Remove from All").all = True
835                 layout.separator()
836
837         if ob.vertex_groups and ob.active_vertex_group:
838             layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group")
839             layout.operator("object.vertex_group_remove", text="Remove Active Group")
840             layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True
841
842
843 # ********** Sculpt menu **********
844
845
846 class VIEW3D_MT_sculpt(bpy.types.Menu):
847     bl_label = "Sculpt"
848
849     def draw(self, context):
850         layout = self.layout
851
852         sculpt = context.tool_settings.sculpt
853         brush = context.tool_settings.sculpt.brush
854
855         layout.prop(sculpt, "symmetry_x")
856         layout.prop(sculpt, "symmetry_y")
857         layout.prop(sculpt, "symmetry_z")
858         layout.separator()
859         layout.prop(sculpt, "lock_x")
860         layout.prop(sculpt, "lock_y")
861         layout.prop(sculpt, "lock_z")
862         layout.separator()
863         layout.operator_menu_enum("brush.curve_preset", property="shape")
864         layout.separator()
865
866         sculpt_tool = brush.sculpt_tool
867
868         if sculpt_tool != 'GRAB':
869             layout.prop(brush, "use_airbrush")
870
871             if sculpt_tool != 'LAYER':
872                 layout.prop(brush, "use_anchor")
873
874             if sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'):
875                 layout.prop(brush, "flip_direction")
876
877             if sculpt_tool == 'LAYER':
878                 layout.prop(brush, "use_persistent")
879                 layout.operator("sculpt.set_persistent_base")
880
881 # ********** Particle menu **********
882
883
884 class VIEW3D_MT_particle(bpy.types.Menu):
885     bl_label = "Particle"
886
887     def draw(self, context):
888         layout = self.layout
889
890         particle_edit = context.tool_settings.particle_edit
891
892         layout.operator("particle.mirror")
893
894         layout.separator()
895
896         layout.operator("particle.remove_doubles")
897         layout.operator("particle.delete")
898
899         if particle_edit.selection_mode == 'POINT':
900             layout.operator("particle.subdivide")
901
902         layout.operator("particle.rekey")
903         layout.operator("particle.weight_set")
904
905         layout.separator()
906
907         layout.menu("VIEW3D_MT_particle_showhide")
908
909
910 class VIEW3D_MT_particle_specials(bpy.types.Menu):
911     bl_label = "Specials"
912
913     def draw(self, context):
914         layout = self.layout
915         particle_edit = context.tool_settings.particle_edit
916
917         layout.operator("particle.rekey")
918
919         layout.separator()
920         if particle_edit.selection_mode == 'POINT':
921             layout.operator("particle.subdivide")
922             layout.operator("particle.select_first")
923             layout.operator("particle.select_last")
924
925         layout.operator("particle.remove_doubles")
926
927
928 class VIEW3D_MT_particle_showhide(VIEW3D_MT_showhide):
929     _operator_name = "particle"
930
931 # ********** Pose Menu **********
932
933
934 class VIEW3D_MT_pose(bpy.types.Menu):
935     bl_label = "Pose"
936
937     def draw(self, context):
938         layout = self.layout
939
940         arm = context.active_object.data
941
942         layout.menu("VIEW3D_MT_transform")
943         layout.menu("VIEW3D_MT_snap")
944         if arm.drawtype in ('BBONE', 'ENVELOPE'):
945             layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONESIZE'
946
947         layout.menu("VIEW3D_MT_pose_transform")
948
949         layout.separator()
950
951         layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...")
952         layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframe...")
953
954         layout.separator()
955
956         layout.operator("pose.apply")
957         layout.operator("pose.relax")
958
959         layout.separator()
960
961         layout.operator("pose.copy")
962         layout.operator("pose.paste")
963         layout.operator("pose.paste", text="Paste X-Flipped Pose").flipped = True
964
965         layout.separator()
966
967         layout.menu("VIEW3D_MT_pose_pose")
968         layout.menu("VIEW3D_MT_pose_motion")
969         layout.menu("VIEW3D_MT_pose_group")
970
971         layout.separator()
972
973         layout.menu("VIEW3D_MT_pose_ik")
974         layout.menu("VIEW3D_MT_pose_constraints")
975
976         layout.separator()
977
978         layout.operator_context = 'EXEC_AREA'
979         layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS'
980         layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS'
981         layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS'
982
983         layout.operator("pose.flip_names")
984
985         layout.separator()
986
987         layout.operator_context = 'INVOKE_AREA'
988         layout.operator("pose.armature_layers", text="Change Armature Layers...")
989         layout.operator("pose.bone_layers", text="Change Bone Layers...")
990
991         layout.separator()
992
993         layout.menu("VIEW3D_MT_pose_showhide")
994         layout.operator_menu_enum("pose.flags_set", 'mode', text="Bone Settings")
995
996
997 class VIEW3D_MT_pose_transform(bpy.types.Menu):
998     bl_label = "Clear Transform"
999
1000     def draw(self, context):
1001         layout = self.layout
1002
1003         layout.label(text="User Transform")
1004
1005         layout.operator("pose.loc_clear", text="Location")
1006         layout.operator("pose.rot_clear", text="Rotation")
1007         layout.operator("pose.scale_clear", text="Scale")
1008
1009         layout.label(text="Origin")
1010
1011
1012 class VIEW3D_MT_pose_pose(bpy.types.Menu):
1013     bl_label = "Pose Library"
1014
1015     def draw(self, context):
1016         layout = self.layout
1017
1018         layout.operator("poselib.browse_interactive", text="Browse Poses...")
1019
1020         layout.separator()
1021
1022         layout.operator("poselib.pose_add", text="Add Pose...")
1023         layout.operator("poselib.pose_rename", text="Rename Pose...")
1024         layout.operator("poselib.pose_remove", text="Remove Pose...")
1025
1026
1027 class VIEW3D_MT_pose_motion(bpy.types.Menu):
1028     bl_label = "Motion Paths"
1029
1030     def draw(self, context):
1031         layout = self.layout
1032
1033         layout.operator("pose.paths_calculate", text="Calculate")
1034         layout.operator("pose.paths_clear", text="Clear")
1035
1036
1037 class VIEW3D_MT_pose_group(bpy.types.Menu):
1038     bl_label = "Bone Groups"
1039
1040     def draw(self, context):
1041         layout = self.layout
1042         layout.operator("pose.group_add")
1043         layout.operator("pose.group_remove")
1044
1045         layout.separator()
1046
1047         layout.operator("pose.group_assign")
1048         layout.operator("pose.group_unassign")
1049
1050
1051 class VIEW3D_MT_pose_ik(bpy.types.Menu):
1052     bl_label = "Inverse Kinematics"
1053
1054     def draw(self, context):
1055         layout = self.layout
1056
1057         layout.operator("pose.ik_add")
1058         layout.operator("pose.ik_clear")
1059
1060
1061 class VIEW3D_MT_pose_constraints(bpy.types.Menu):
1062     bl_label = "Constraints"
1063
1064     def draw(self, context):
1065         layout = self.layout
1066
1067         layout.operator("pose.constraint_add_with_targets", text="Add (With Targets)...")
1068         layout.operator("pose.constraints_clear")
1069
1070
1071 class VIEW3D_MT_pose_showhide(VIEW3D_MT_showhide):
1072     _operator_name = "pose"
1073
1074 # ********** Edit Menus, suffix from ob.type **********
1075
1076
1077 class VIEW3D_MT_edit_mesh(bpy.types.Menu):
1078     bl_label = "Mesh"
1079
1080     def draw(self, context):
1081         layout = self.layout
1082
1083         settings = context.tool_settings
1084
1085         layout.operator("ed.undo")
1086         layout.operator("ed.redo")
1087
1088         layout.separator()
1089
1090         layout.menu("VIEW3D_MT_transform")
1091         layout.menu("VIEW3D_MT_mirror")
1092         layout.menu("VIEW3D_MT_snap")
1093
1094         layout.separator()
1095
1096         layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap...")
1097
1098         layout.separator()
1099
1100         layout.operator("mesh.extrude_move")
1101         layout.operator("mesh.duplicate_move")
1102         layout.operator("mesh.delete", text="Delete...")
1103
1104         layout.separator()
1105
1106         layout.menu("VIEW3D_MT_edit_mesh_vertices")
1107         layout.menu("VIEW3D_MT_edit_mesh_edges")
1108         layout.menu("VIEW3D_MT_edit_mesh_faces")
1109         layout.menu("VIEW3D_MT_edit_mesh_normals")
1110
1111         layout.separator()
1112
1113         layout.prop(settings, "automerge_editing")
1114         layout.prop_menu_enum(settings, "proportional_editing")
1115         layout.prop_menu_enum(settings, "proportional_editing_falloff")
1116
1117         layout.separator()
1118
1119         layout.menu("VIEW3D_MT_edit_mesh_showhide")
1120
1121
1122 class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu):
1123     bl_label = "Specials"
1124
1125     def draw(self, context):
1126         layout = self.layout
1127
1128         layout.operator_context = 'INVOKE_REGION_WIN'
1129
1130         layout.operator("mesh.subdivide", text="Subdivide")
1131         layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0
1132         layout.operator("mesh.merge", text="Merge...")
1133         layout.operator("mesh.remove_doubles")
1134         layout.operator("mesh.hide", text="Hide")
1135         layout.operator("mesh.reveal", text="Reveal")
1136         layout.operator("mesh.select_inverse")
1137         layout.operator("mesh.flip_normals")
1138         layout.operator("mesh.vertices_smooth", text="Smooth")
1139         # layout.operator("mesh.bevel", text="Bevel")
1140         layout.operator("mesh.faces_shade_smooth")
1141         layout.operator("mesh.faces_shade_flat")
1142         layout.operator("mesh.blend_from_shape")
1143         layout.operator("mesh.shape_propagate_to_all")
1144         layout.operator("mesh.select_vertex_path")
1145
1146
1147 class VIEW3D_MT_edit_mesh_selection_mode(bpy.types.Menu):
1148     bl_label = "Mesh Select Mode"
1149
1150     def draw(self, context):
1151         layout = self.layout
1152
1153         layout.operator_context = 'INVOKE_REGION_WIN'
1154
1155         prop = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
1156         prop.value = "(True, False, False)"
1157         prop.path = "tool_settings.mesh_selection_mode"
1158
1159         prop = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
1160         prop.value = "(False, True, False)"
1161         prop.path = "tool_settings.mesh_selection_mode"
1162
1163         prop = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
1164         prop.value = "(False, False, True)"
1165         prop.path = "tool_settings.mesh_selection_mode"
1166
1167
1168 class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
1169     bl_label = "Vertices"
1170
1171     def draw(self, context):
1172         layout = self.layout
1173         layout.operator_context = 'INVOKE_REGION_WIN'
1174
1175         layout.operator("mesh.merge")
1176         layout.operator("mesh.rip")
1177         layout.operator("mesh.split")
1178         layout.operator("mesh.separate")
1179
1180         layout.separator()
1181
1182         layout.operator("mesh.vertices_smooth")
1183         layout.operator("mesh.remove_doubles")
1184
1185         layout.operator("mesh.select_vertex_path")
1186
1187         layout.operator("mesh.blend_from_shape")
1188
1189         layout.operator("object.vertex_group_blend")
1190         layout.operator("mesh.shape_propagate_to_all")
1191
1192         layout.separator()
1193
1194         layout.menu("VIEW3D_MT_vertex_group")
1195         layout.menu("VIEW3D_MT_hook")
1196
1197
1198 class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
1199     bl_label = "Edges"
1200
1201     def draw(self, context):
1202         layout = self.layout
1203         layout.operator_context = 'INVOKE_REGION_WIN'
1204
1205         layout.operator("mesh.edge_face_add")
1206         layout.operator("mesh.subdivide")
1207
1208         layout.separator()
1209
1210         layout.operator("mesh.mark_seam")
1211         layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
1212
1213         layout.separator()
1214
1215         layout.operator("mesh.mark_sharp")
1216         layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
1217
1218         layout.separator()
1219
1220         layout.operator("mesh.edge_rotate", text="Rotate Edge CW").direction = 'CW'
1221         layout.operator("mesh.edge_rotate", text="Rotate Edge CCW").direction = 'CCW'
1222
1223         layout.separator()
1224
1225         layout.operator("TRANSFORM_OT_edge_slide")
1226         layout.operator("TRANSFORM_OT_edge_crease")
1227         layout.operator("mesh.loop_multi_select", text="Edge Loop")
1228
1229         # uiItemO(layout, "Loopcut", 0, "mesh.loop_cut"); // CutEdgeloop(em, 1);
1230         # uiItemO(layout, "Edge Slide", 0, "mesh.edge_slide"); // EdgeSlide(em, 0,0.0);
1231
1232         layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True
1233
1234         layout.operator("mesh.loop_to_region")
1235         layout.operator("mesh.region_to_loop")
1236
1237
1238 class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
1239     bl_label = "Faces"
1240     bl_idname = "VIEW3D_MT_edit_mesh_faces"
1241
1242     def draw(self, context):
1243         layout = self.layout
1244         layout.operator_context = 'INVOKE_REGION_WIN'
1245
1246         # layout.operator("mesh.bevel")
1247         # layout.operator("mesh.bevel")
1248         layout.operator("mesh.edge_face_add")
1249         layout.operator("mesh.fill")
1250         layout.operator("mesh.beauty_fill")
1251         layout.operator("mesh.solidify")
1252
1253         layout.separator()
1254
1255         layout.operator("mesh.quads_convert_to_tris")
1256         layout.operator("mesh.tris_convert_to_quads")
1257         layout.operator("mesh.edge_flip")
1258
1259         layout.separator()
1260
1261         layout.operator("mesh.faces_shade_smooth")
1262         layout.operator("mesh.faces_shade_flat")
1263
1264         layout.separator()
1265
1266         # uiItemO(layout, NULL, 0, "mesh.face_mode"); // mesh_set_face_flags(em, 1);
1267         # uiItemBooleanO(layout, NULL, 0, "mesh.face_mode", "clear", 1); // mesh_set_face_flags(em, 0);
1268
1269         layout.operator("mesh.edge_rotate", text="Rotate Edge CW").direction = 'CW'
1270
1271         layout.separator()
1272
1273         layout.operator_menu_enum("mesh.uvs_rotate", "direction")
1274         layout.operator_menu_enum("mesh.uvs_mirror", "axis")
1275         layout.operator_menu_enum("mesh.colors_rotate", "direction")
1276         layout.operator_menu_enum("mesh.colors_mirror", "axis")
1277
1278
1279 class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu):
1280     bl_label = "Normals"
1281
1282     def draw(self, context):
1283         layout = self.layout
1284
1285         layout.operator("mesh.normals_make_consistent", text="Recalculate Outside")
1286         layout.operator("mesh.normals_make_consistent", text="Recalculate Inside").inside = True
1287
1288         layout.separator()
1289
1290         layout.operator("mesh.flip_normals")
1291
1292
1293 class VIEW3D_MT_edit_mesh_showhide(VIEW3D_MT_showhide):
1294     _operator_name = "mesh"
1295
1296 # Edit Curve
1297 # draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface
1298
1299
1300 def draw_curve(self, context):
1301     layout = self.layout
1302
1303     settings = context.tool_settings
1304
1305     layout.menu("VIEW3D_MT_transform")
1306     layout.menu("VIEW3D_MT_mirror")
1307     layout.menu("VIEW3D_MT_snap")
1308
1309     layout.separator()
1310
1311     layout.operator("curve.extrude")
1312     layout.operator("curve.duplicate")
1313     layout.operator("curve.separate")
1314     layout.operator("curve.make_segment")
1315     layout.operator("curve.cyclic_toggle")
1316     layout.operator("curve.delete", text="Delete...")
1317
1318     layout.separator()
1319
1320     layout.menu("VIEW3D_MT_edit_curve_ctrlpoints")
1321     layout.menu("VIEW3D_MT_edit_curve_segments")
1322
1323     layout.separator()
1324
1325     layout.prop_menu_enum(settings, "proportional_editing")
1326     layout.prop_menu_enum(settings, "proportional_editing_falloff")
1327
1328     layout.separator()
1329
1330     layout.menu("VIEW3D_MT_edit_curve_showhide")
1331
1332
1333 class VIEW3D_MT_edit_curve(bpy.types.Menu):
1334     bl_label = "Curve"
1335
1336     draw = draw_curve
1337
1338
1339 class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu):
1340     bl_label = "Control Points"
1341
1342     def draw(self, context):
1343         layout = self.layout
1344
1345         edit_object = context.edit_object
1346
1347         if edit_object.type == 'CURVE':
1348             layout.operator("transform.transform").mode = 'TILT'
1349             layout.operator("curve.tilt_clear")
1350             layout.operator("curve.separate")
1351
1352             layout.separator()
1353
1354             layout.operator_menu_enum("curve.handle_type_set", "type")
1355
1356             layout.separator()
1357
1358             layout.menu("VIEW3D_MT_hook")
1359
1360
1361 class VIEW3D_MT_edit_curve_segments(bpy.types.Menu):
1362     bl_label = "Segments"
1363
1364     def draw(self, context):
1365         layout = self.layout
1366
1367         layout.operator("curve.subdivide")
1368         layout.operator("curve.switch_direction")
1369
1370
1371 class VIEW3D_MT_edit_curve_specials(bpy.types.Menu):
1372     bl_label = "Specials"
1373
1374     def draw(self, context):
1375         layout = self.layout
1376
1377         layout.operator("curve.subdivide")
1378         layout.operator("curve.switch_direction")
1379         layout.operator("curve.spline_weight_set")
1380         layout.operator("curve.radius_set")
1381         layout.operator("curve.smooth")
1382         layout.operator("curve.smooth_radius")
1383
1384
1385 class VIEW3D_MT_edit_curve_showhide(VIEW3D_MT_showhide):
1386     _operator_name = "curve"
1387
1388
1389 class VIEW3D_MT_edit_surface(bpy.types.Menu):
1390     bl_label = "Surface"
1391
1392     draw = draw_curve
1393
1394
1395 class VIEW3D_MT_edit_text(bpy.types.Menu):
1396     bl_label = "Text"
1397
1398     def draw(self, context):
1399         layout = self.layout
1400
1401         layout.operator("font.file_paste")
1402
1403         layout.separator()
1404
1405         layout.menu("VIEW3D_MT_edit_text_chars")
1406
1407
1408 class VIEW3D_MT_edit_text_chars(bpy.types.Menu):
1409     bl_label = "Special Characters"
1410
1411     def draw(self, context):
1412         layout = self.layout
1413
1414         layout.operator("font.text_insert", text="Copyright|Alt C").text = b'\xC2\xA9'.decode()
1415         layout.operator("font.text_insert", text="Registered Trademark|Alt R").text = b'\xC2\xAE'.decode()
1416
1417         layout.separator()
1418
1419         layout.operator("font.text_insert", text="Degree Sign|Alt G").text = b'\xC2\xB0'.decode()
1420         layout.operator("font.text_insert", text="Multiplication Sign|Alt x").text = b'\xC3\x97'.decode()
1421         layout.operator("font.text_insert", text="Circle|Alt .").text = b'\xC2\x8A'.decode()
1422         layout.operator("font.text_insert", text="Superscript 1|Alt 1").text = b'\xC2\xB9'.decode()
1423         layout.operator("font.text_insert", text="Superscript 2|Alt 2").text = b'\xC2\xB2'.decode()
1424         layout.operator("font.text_insert", text="Superscript 3|Alt 3").text = b'\xC2\xB3'.decode()
1425         layout.operator("font.text_insert", text="Double >>|Alt >").text = b'\xC2\xBB'.decode()
1426         layout.operator("font.text_insert", text="Double <<|Alt <").text = b'\xC2\xAB'.decode()
1427         layout.operator("font.text_insert", text="Promillage|Alt %").text = b'\xE2\x80\xB0'.decode()
1428
1429         layout.separator()
1430
1431         layout.operator("font.text_insert", text="Dutch Florin|Alt F").text = b'\xC2\xA4'.decode()
1432         layout.operator("font.text_insert", text="British Pound|Alt L").text = b'\xC2\xA3'.decode()
1433         layout.operator("font.text_insert", text="Japanese Yen|Alt Y").text = b'\xC2\xA5'.decode()
1434
1435         layout.separator()
1436
1437         layout.operator("font.text_insert", text="German S|Alt S").text = b'\xC3\x9F'.decode()
1438         layout.operator("font.text_insert", text="Spanish Question Mark|Alt ?").text = b'\xC2\xBF'.decode()
1439         layout.operator("font.text_insert", text="Spanish Exclamation Mark|Alt !").text = b'\xC2\xA1'.decode()
1440
1441
1442 class VIEW3D_MT_edit_meta(bpy.types.Menu):
1443     bl_label = "Metaball"
1444
1445     def draw(self, context):
1446         layout = self.layout
1447
1448         settings = context.tool_settings
1449
1450         layout.operator("ed.undo")
1451         layout.operator("ed.redo")
1452
1453         layout.separator()
1454
1455         layout.menu("VIEW3D_MT_transform")
1456         layout.menu("VIEW3D_MT_mirror")
1457         layout.menu("VIEW3D_MT_snap")
1458
1459         layout.separator()
1460
1461         layout.operator("mball.delete_metaelems", text="Delete...")
1462         layout.operator("mball.duplicate_metaelems")
1463
1464         layout.separator()
1465
1466         layout.prop_menu_enum(settings, "proportional_editing")
1467         layout.prop_menu_enum(settings, "proportional_editing_falloff")
1468
1469         layout.separator()
1470
1471         layout.menu("VIEW3D_MT_edit_meta_showhide")
1472
1473
1474 class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu):
1475     bl_label = "Show/Hide"
1476
1477     def draw(self, context):
1478         layout = self.layout
1479
1480         layout.operator("mball.reveal_metaelems", text="Show Hidden")
1481         layout.operator("mball.hide_metaelems", text="Hide Selected")
1482         layout.operator("mball.hide_metaelems", text="Hide Unselected").unselected = True
1483
1484
1485 class VIEW3D_MT_edit_lattice(bpy.types.Menu):
1486     bl_label = "Lattice"
1487
1488     def draw(self, context):
1489         layout = self.layout
1490
1491         settings = context.tool_settings
1492
1493         layout.menu("VIEW3D_MT_transform")
1494         layout.menu("VIEW3D_MT_mirror")
1495         layout.menu("VIEW3D_MT_snap")
1496
1497         layout.separator()
1498
1499         layout.operator("lattice.make_regular")
1500
1501         layout.separator()
1502
1503         layout.prop_menu_enum(settings, "proportional_editing")
1504         layout.prop_menu_enum(settings, "proportional_editing_falloff")
1505
1506
1507 class VIEW3D_MT_edit_armature(bpy.types.Menu):
1508     bl_label = "Armature"
1509
1510     def draw(self, context):
1511         layout = self.layout
1512
1513         edit_object = context.edit_object
1514         arm = edit_object.data
1515
1516         layout.menu("VIEW3D_MT_transform")
1517         layout.menu("VIEW3D_MT_mirror")
1518         layout.menu("VIEW3D_MT_snap")
1519         layout.menu("VIEW3D_MT_edit_armature_roll")
1520
1521         if arm.drawtype == 'ENVELOPE':
1522             layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONESIZE'
1523         else:
1524             layout.operator("transform.transform", text="Scale B-Bone Width").mode = 'BONESIZE'
1525
1526         layout.separator()
1527
1528         layout.operator("armature.extrude_move")
1529
1530         if arm.x_axis_mirror:
1531             layout.operator("armature.extrude_forked")
1532
1533         layout.operator("armature.duplicate_move")
1534         layout.operator("armature.merge")
1535         layout.operator("armature.fill")
1536         layout.operator("armature.delete")
1537         layout.operator("armature.separate")
1538
1539         layout.separator()
1540
1541         layout.operator("armature.subdivide_multi", text="Subdivide")
1542         layout.operator("armature.switch_direction", text="Switch Direction")
1543
1544         layout.separator()
1545
1546         layout.operator_context = 'EXEC_AREA'
1547         layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
1548         layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
1549         layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
1550         layout.operator("armature.flip_names")
1551
1552         layout.separator()
1553
1554         layout.operator_context = 'INVOKE_DEFAULT'
1555         layout.operator("armature.armature_layers")
1556         layout.operator("armature.bone_layers")
1557
1558         layout.separator()
1559
1560         layout.menu("VIEW3D_MT_edit_armature_parent")
1561
1562         layout.separator()
1563
1564         layout.operator_menu_enum("armature.flags_set", "mode", text="Bone Settings")
1565
1566
1567 class VIEW3D_MT_armature_specials(bpy.types.Menu):
1568     bl_label = "Specials"
1569
1570     def draw(self, context):
1571         layout = self.layout
1572
1573         layout.operator_context = 'INVOKE_REGION_WIN'
1574
1575         layout.operator("armature.subdivide_multi", text="Subdivide")
1576         layout.operator("armature.switch_direction", text="Switch Direction")
1577
1578         layout.separator()
1579
1580         layout.operator_context = 'EXEC_REGION_WIN'
1581         layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
1582         layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
1583         layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
1584         layout.operator("armature.flip_names", text="Flip Names")
1585
1586
1587 class VIEW3D_MT_edit_armature_parent(bpy.types.Menu):
1588     bl_label = "Parent"
1589
1590     def draw(self, context):
1591         layout = self.layout
1592
1593         layout.operator("armature.parent_set", text="Make")
1594         layout.operator("armature.parent_clear", text="Clear")
1595
1596
1597 class VIEW3D_MT_edit_armature_roll(bpy.types.Menu):
1598     bl_label = "Bone Roll"
1599
1600     def draw(self, context):
1601         layout = self.layout
1602
1603         layout.operator("armature.calculate_roll", text="Clear Roll (Z-Axis Up)").type = 'GLOBALUP'
1604         layout.operator("armature.calculate_roll", text="Roll to Cursor").type = 'CURSOR'
1605
1606         layout.separator()
1607
1608         layout.operator("transform.transform", text="Set Roll").mode = 'BONE_ROLL'
1609
1610 # ********** Panel **********
1611
1612
1613 class VIEW3D_PT_3dview_properties(bpy.types.Panel):
1614     bl_space_type = 'VIEW_3D'
1615     bl_region_type = 'UI'
1616     bl_label = "View"
1617
1618     def poll(self, context):
1619         view = context.space_data
1620         return (view)
1621
1622     def draw(self, context):
1623         layout = self.layout
1624
1625         view = context.space_data
1626         scene = context.scene
1627
1628         col = layout.column()
1629         col.label(text="Camera:")
1630         col.prop(view, "camera", text="")
1631         col.prop(view, "lens")
1632         col.label(text="Lock to Object:")
1633         col.prop(view, "lock_object", text="")
1634         if view.lock_object and view.lock_object.type == 'ARMATURE':
1635             col.prop_object(view, "lock_bone", view.lock_object.data, "bones", text="")
1636
1637         col = layout.column(align=True)
1638         col.label(text="Clip:")
1639         col.prop(view, "clip_start", text="Start")
1640         col.prop(view, "clip_end", text="End")
1641
1642         layout.column().prop(scene, "cursor_location", text="3D Cursor:")
1643
1644
1645 class VIEW3D_PT_3dview_name(bpy.types.Panel):
1646     bl_space_type = 'VIEW_3D'
1647     bl_region_type = 'UI'
1648     bl_label = "Item"
1649
1650     def poll(self, context):
1651         return (context.space_data and context.active_object)
1652
1653     def draw(self, context):
1654         layout = self.layout
1655
1656         ob = context.active_object
1657         row = layout.row()
1658         row.label(text="", icon='OBJECT_DATA')
1659         row.prop(ob, "name", text="")
1660
1661         if ob.type == 'ARMATURE' and ob.mode in ('EDIT', 'POSE'):
1662             bone = context.active_bone
1663             if bone:
1664                 row = layout.row()
1665                 row.label(text="", icon='BONE_DATA')
1666                 row.prop(bone, "name", text="")
1667
1668
1669 class VIEW3D_PT_3dview_display(bpy.types.Panel):
1670     bl_space_type = 'VIEW_3D'
1671     bl_region_type = 'UI'
1672     bl_label = "Display"
1673     bl_default_closed = True
1674
1675     def poll(self, context):
1676         view = context.space_data
1677         return (view)
1678
1679     def draw(self, context):
1680         layout = self.layout
1681
1682         view = context.space_data
1683         gs = context.scene.game_data
1684         ob = context.object
1685
1686         col = layout.column()
1687         col.prop(view, "display_x_axis", text="X Axis")
1688         col.prop(view, "display_y_axis", text="Y Axis")
1689         col.prop(view, "display_z_axis", text="Z Axis")
1690         col.prop(view, "outline_selected")
1691         col.prop(view, "all_object_origins")
1692         col.prop(view, "relationship_lines")
1693         if ob and ob.type == 'MESH':
1694             mesh = ob.data
1695             col.prop(mesh, "all_edges")
1696
1697         col = layout.column()
1698         col.prop(view, "display_floor", text="Grid Floor")
1699         sub = col.column(align=True)
1700         sub.active = view.display_floor
1701         sub.prop(view, "grid_lines", text="Lines")
1702         sub.prop(view, "grid_spacing", text="Spacing")
1703         sub.prop(view, "grid_subdivisions", text="Subdivisions")
1704
1705         col = layout.column()
1706         col.label(text="Shading:")
1707         col.prop(gs, "material_mode", text="")
1708         col.prop(view, "textured_solid")
1709
1710 # XXX - the Quad View options don't work yet
1711 #               layout.separator()
1712 #
1713 #               layout.operator("screen.region_foursplit", text="Toggle Quad View")
1714 #               col = layout.column()
1715 #               col.prop(view, "lock_rotation")
1716 #               col.prop(view, "box_preview")
1717 #               col.prop(view, "box_clip")
1718
1719
1720 class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel):
1721     bl_space_type = 'VIEW_3D'
1722     bl_region_type = 'UI'
1723     bl_label = "Mesh Display"
1724
1725     def poll(self, context):
1726         # The active object check is needed because of localmode
1727         return (context.active_object and (context.mode == 'EDIT_MESH'))
1728
1729     def draw(self, context):
1730         layout = self.layout
1731
1732         mesh = context.active_object.data
1733
1734         col = layout.column()
1735         col.label(text="Overlays:")
1736         col.prop(mesh, "draw_edges", text="Edges")
1737         col.prop(mesh, "draw_faces", text="Faces")
1738         col.prop(mesh, "draw_creases", text="Creases")
1739         col.prop(mesh, "draw_bevel_weights", text="Bevel Weights")
1740         col.prop(mesh, "draw_seams", text="Seams")
1741         col.prop(mesh, "draw_sharp", text="Sharp")
1742
1743         col.separator()
1744         col.label(text="Normals:")
1745         col.prop(mesh, "draw_normals", text="Face")
1746         col.prop(mesh, "draw_vertex_normals", text="Vertex")
1747         col.prop(context.scene.tool_settings, "normal_size", text="Normal Size")
1748
1749         col.separator()
1750         col.label(text="Numerics:")
1751         col.prop(mesh, "draw_edge_lenght")
1752         col.prop(mesh, "draw_edge_angle")
1753         col.prop(mesh, "draw_face_area")
1754
1755
1756 class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel):
1757     bl_space_type = 'VIEW_3D'
1758     bl_region_type = 'UI'
1759     bl_label = "Curve Display"
1760
1761     def poll(self, context):
1762         editmesh = context.mode == 'EDIT_CURVE'
1763         return (editmesh)
1764
1765     def draw(self, context):
1766         layout = self.layout
1767
1768         curve = context.active_object.data
1769
1770         col = layout.column()
1771         col.label(text="Overlays:")
1772         col.prop(curve, "draw_handles", text="Handles")
1773         col.prop(curve, "draw_normals", text="Normals")
1774         col.prop(context.scene.tool_settings, "normal_size", text="Normal Size")
1775
1776
1777 class VIEW3D_PT_background_image(bpy.types.Panel):
1778     bl_space_type = 'VIEW_3D'
1779     bl_region_type = 'UI'
1780     bl_label = "Background Image"
1781     bl_default_closed = True
1782
1783     def poll(self, context):
1784         view = context.space_data
1785         # bg = context.space_data.background_image
1786         return (view)
1787
1788     def draw_header(self, context):
1789         layout = self.layout
1790         view = context.space_data
1791
1792         layout.prop(view, "display_background_image", text="")
1793
1794     def draw(self, context):
1795         layout = self.layout
1796
1797         view = context.space_data
1798         bg = view.background_image
1799
1800         if bg:
1801             layout.active = view.display_background_image
1802             box = layout.box()
1803             if (bg.image):
1804                 box.template_ID(bg, "image", open="image.open")
1805                 box.template_image(bg, "image", bg.image_user, compact=True)
1806             else:
1807                 box.template_ID(bg, "image", open="image.open")
1808             
1809             col = layout.column()
1810             col.label(text="Display Settings")
1811             
1812             col = layout.column()
1813             col.prop(bg, "size")
1814             col.prop(bg, "transparency", slider=True)
1815
1816             col = layout.column()
1817             col.label(text="Offset")
1818             col.prop(bg, "offset_x", text="X")
1819             col.prop(bg, "offset_y", text="Y")
1820
1821 class VIEW3D_PT_transform_orientations(bpy.types.Panel):
1822     bl_space_type = 'VIEW_3D'
1823     bl_region_type = 'UI'
1824     bl_label = "Transform Orientations"
1825     bl_default_closed = True
1826
1827     def poll(self, context):
1828         view = context.space_data
1829         return (view)
1830
1831     def draw(self, context):
1832         layout = self.layout
1833
1834         view = context.space_data
1835
1836         col = layout.column()
1837
1838         col.prop(view, "transform_orientation")
1839         col.operator("transform.create_orientation", text="Create")
1840
1841         orientation = view.current_orientation
1842
1843         if orientation:
1844             col.prop(orientation, "name")
1845             col.operator("transform.delete_orientation", text="Delete")
1846
1847
1848 class VIEW3D_PT_etch_a_ton(bpy.types.Panel):
1849     bl_space_type = 'VIEW_3D'
1850     bl_region_type = 'UI'
1851     bl_label = "Skeleton Sketching"
1852     bl_default_closed = True
1853
1854     def poll(self, context):
1855         scene = context.space_data
1856         ob = context.active_object
1857         return scene and ob and ob.type == 'ARMATURE' and ob.mode == 'EDIT'
1858
1859     def draw_header(self, context):
1860         layout = self.layout
1861         toolsettings = context.scene.tool_settings
1862
1863         layout.prop(toolsettings, "bone_sketching", text="")
1864
1865     def draw(self, context):
1866         layout = self.layout
1867         toolsettings = context.scene.tool_settings
1868
1869         col = layout.column()
1870
1871         col.prop(toolsettings, "etch_quick")
1872         col.prop(toolsettings, "etch_overdraw")
1873
1874         col.prop(toolsettings, "etch_convert_mode")
1875
1876         if toolsettings.etch_convert_mode == 'LENGTH':
1877             col.prop(toolsettings, "etch_length_limit")
1878         elif toolsettings.etch_convert_mode == 'ADAPTIVE':
1879             col.prop(toolsettings, "etch_adaptive_limit")
1880         elif toolsettings.etch_convert_mode == 'FIXED':
1881             col.prop(toolsettings, "etch_subdivision_number")
1882         elif toolsettings.etch_convert_mode == 'RETARGET':
1883             col.prop(toolsettings, "etch_template")
1884             col.prop(toolsettings, "etch_roll_mode")
1885             col.prop(toolsettings, "etch_autoname")
1886             col.prop(toolsettings, "etch_number")
1887             col.prop(toolsettings, "etch_side")
1888
1889
1890 class VIEW3D_PT_context_properties(bpy.types.Panel):
1891     bl_space_type = 'VIEW_3D'
1892     bl_region_type = 'UI'
1893     bl_label = "Properties"
1894     bl_default_closed = True
1895
1896     def _active_context_member(self, context):
1897         obj = context.object
1898         if obj:
1899             mode = obj.mode
1900             if mode == 'POSE':
1901                 return "active_pose_bone"
1902             elif mode == 'EDIT' and obj.type == 'ARMATURE':
1903                 return "active_bone"
1904             else:
1905                 return "object"
1906
1907         return ""
1908
1909     def poll(self, context):
1910         member = self._active_context_member(context)
1911         if member:
1912             context_member = getattr(context, member)
1913             return context_member and context_member.keys()
1914
1915         return False
1916
1917     def draw(self, context):
1918         import rna_prop_ui
1919         # reload(rna_prop_ui)
1920         member = self._active_context_member(context)
1921
1922         if member:
1923             # Draw with no edit button
1924             rna_prop_ui.draw(self.layout, context, member, False)
1925
1926
1927 bpy.types.register(VIEW3D_HT_header) # Header
1928
1929 bpy.types.register(VIEW3D_MT_view) #View Menus
1930 bpy.types.register(VIEW3D_MT_view_navigation)
1931 bpy.types.register(VIEW3D_MT_view_align)
1932 bpy.types.register(VIEW3D_MT_view_align_selected)
1933 bpy.types.register(VIEW3D_MT_view_cameras)
1934
1935 bpy.types.register(VIEW3D_MT_select_object) # Select Menus
1936 bpy.types.register(VIEW3D_MT_select_pose)
1937 bpy.types.register(VIEW3D_MT_select_particle)
1938 bpy.types.register(VIEW3D_MT_select_edit_mesh)
1939 bpy.types.register(VIEW3D_MT_select_edit_curve)
1940 bpy.types.register(VIEW3D_MT_select_edit_surface)
1941 bpy.types.register(VIEW3D_MT_select_edit_metaball)
1942 bpy.types.register(VIEW3D_MT_select_edit_lattice)
1943 bpy.types.register(VIEW3D_MT_select_edit_armature)
1944 bpy.types.register(VIEW3D_MT_select_face) # XXX todo
1945
1946 bpy.types.register(VIEW3D_MT_transform) # Object/Edit Menus
1947 bpy.types.register(VIEW3D_MT_mirror) # Object/Edit Menus
1948 bpy.types.register(VIEW3D_MT_snap) # Object/Edit Menus
1949 bpy.types.register(VIEW3D_MT_uv_map) # Edit Menus
1950
1951 bpy.types.register(VIEW3D_MT_object) # Object Menu
1952 bpy.types.register(VIEW3D_MT_object_apply)
1953 bpy.types.register(VIEW3D_MT_object_clear)
1954 bpy.types.register(VIEW3D_MT_object_parent)
1955 bpy.types.register(VIEW3D_MT_object_track)
1956 bpy.types.register(VIEW3D_MT_object_group)
1957 bpy.types.register(VIEW3D_MT_object_constraints)
1958 bpy.types.register(VIEW3D_MT_object_showhide)
1959 bpy.types.register(VIEW3D_MT_make_single_user)
1960 bpy.types.register(VIEW3D_MT_make_links)
1961
1962 bpy.types.register(VIEW3D_MT_hook)
1963 bpy.types.register(VIEW3D_MT_vertex_group)
1964
1965 bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu
1966
1967 bpy.types.register(VIEW3D_MT_paint_vertex)
1968
1969 bpy.types.register(VIEW3D_MT_particle)# Particle Menu
1970 bpy.types.register(VIEW3D_MT_particle_specials)
1971 bpy.types.register(VIEW3D_MT_particle_showhide)
1972
1973 bpy.types.register(VIEW3D_MT_pose) # POSE Menu
1974 bpy.types.register(VIEW3D_MT_pose_transform)
1975 bpy.types.register(VIEW3D_MT_pose_pose)
1976 bpy.types.register(VIEW3D_MT_pose_motion)
1977 bpy.types.register(VIEW3D_MT_pose_group)
1978 bpy.types.register(VIEW3D_MT_pose_ik)
1979 bpy.types.register(VIEW3D_MT_pose_constraints)
1980 bpy.types.register(VIEW3D_MT_pose_showhide)
1981
1982 bpy.types.register(VIEW3D_MT_edit_mesh)
1983 bpy.types.register(VIEW3D_MT_edit_mesh_specials) # Only as a menu for keybindings
1984 bpy.types.register(VIEW3D_MT_edit_mesh_selection_mode) # Only as a menu for keybindings
1985 bpy.types.register(VIEW3D_MT_edit_mesh_vertices)
1986 bpy.types.register(VIEW3D_MT_edit_mesh_edges)
1987 bpy.types.register(VIEW3D_MT_edit_mesh_faces)
1988 bpy.types.register(VIEW3D_MT_edit_mesh_normals)
1989 bpy.types.register(VIEW3D_MT_edit_mesh_showhide)
1990
1991 bpy.types.register(VIEW3D_MT_edit_curve)
1992 bpy.types.register(VIEW3D_MT_edit_curve_ctrlpoints)
1993 bpy.types.register(VIEW3D_MT_edit_curve_segments)
1994 bpy.types.register(VIEW3D_MT_edit_curve_specials)
1995 bpy.types.register(VIEW3D_MT_edit_curve_showhide)
1996
1997 bpy.types.register(VIEW3D_MT_edit_surface)
1998
1999 bpy.types.register(VIEW3D_MT_edit_text)
2000 bpy.types.register(VIEW3D_MT_edit_text_chars)
2001
2002 bpy.types.register(VIEW3D_MT_edit_meta)
2003 bpy.types.register(VIEW3D_MT_edit_meta_showhide)
2004
2005 bpy.types.register(VIEW3D_MT_edit_lattice)
2006
2007 bpy.types.register(VIEW3D_MT_edit_armature)
2008 bpy.types.register(VIEW3D_MT_edit_armature_parent)
2009 bpy.types.register(VIEW3D_MT_edit_armature_roll)
2010
2011 bpy.types.register(VIEW3D_MT_armature_specials) # Only as a menu for keybindings
2012
2013  # Panels
2014 bpy.types.register(VIEW3D_PT_3dview_properties)
2015 bpy.types.register(VIEW3D_PT_3dview_display)
2016 bpy.types.register(VIEW3D_PT_3dview_name)
2017 bpy.types.register(VIEW3D_PT_3dview_meshdisplay)
2018 bpy.types.register(VIEW3D_PT_3dview_curvedisplay)
2019 bpy.types.register(VIEW3D_PT_background_image)
2020 bpy.types.register(VIEW3D_PT_transform_orientations)
2021 bpy.types.register(VIEW3D_PT_etch_a_ton)
2022
2023 bpy.types.register(VIEW3D_PT_context_properties)