svn merge -r39930:39947 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / release / scripts / startup / bl_ui / space_view3d_toolbar.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 Menu, Panel
22
23
24 class View3DPanel():
25     bl_space_type = 'VIEW_3D'
26     bl_region_type = 'TOOLS'
27
28
29 # **************** standard tool clusters ******************
30
31 # History/Repeat tools
32 def draw_repeat_tools(context, layout):
33     col = layout.column(align=True)
34     col.label(text="Repeat:")
35     col.operator("screen.repeat_last")
36     col.operator("screen.repeat_history", text="History...")
37
38
39 # Keyframing tools
40 def draw_keyframing_tools(context, layout):
41     col = layout.column(align=True)
42     col.label(text="Keyframes:")
43     row = col.row()
44     row.operator("anim.keyframe_insert_menu", text="Insert")
45     row.operator("anim.keyframe_delete_v3d", text="Remove")
46
47
48 # Grease Pencil tools
49 def draw_gpencil_tools(context, layout):
50     col = layout.column(align=True)
51
52     col.label(text="Grease Pencil:")
53
54     row = col.row()
55     row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
56     row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
57     row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
58
59     row = col.row()
60     row.prop(context.tool_settings, "use_grease_pencil_sessions")
61
62
63 # ********** default tools for objectmode ****************
64
65 class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
66     bl_context = "objectmode"
67     bl_label = "Object Tools"
68
69     def draw(self, context):
70         layout = self.layout
71
72         col = layout.column(align=True)
73         col.label(text="Transform:")
74         col.operator("transform.translate")
75         col.operator("transform.rotate")
76         col.operator("transform.resize", text="Scale")
77
78         col = layout.column(align=True)
79         col.operator("object.origin_set", text="Origin")
80
81         col = layout.column(align=True)
82         col.label(text="Object:")
83         col.operator("object.duplicate_move")
84         col.operator("object.delete")
85         col.operator("object.join")
86
87         active_object = context.active_object
88         if active_object and active_object.type == 'MESH':
89
90             col = layout.column(align=True)
91             col.label(text="Shading:")
92             row = col.row(align=True)
93             row.operator("object.shade_smooth", text="Smooth")
94             row.operator("object.shade_flat", text="Flat")
95
96         draw_keyframing_tools(context, layout)
97
98         col = layout.column(align=True)
99         col.label(text="Motion Paths:")
100         col.operator("object.paths_calculate", text="Calculate Paths")
101         col.operator("object.paths_clear", text="Clear Paths")
102
103         draw_repeat_tools(context, layout)
104
105         draw_gpencil_tools(context, layout)
106
107 # ********** default tools for editmode_mesh ****************
108
109
110 class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
111     bl_context = "mesh_edit"
112     bl_label = "Mesh Tools"
113
114     def draw(self, context):
115         layout = self.layout
116
117         col = layout.column(align=True)
118         col.label(text="Transform:")
119         col.operator("transform.translate")
120         col.operator("transform.rotate")
121         col.operator("transform.resize", text="Scale")
122         col.operator("transform.shrink_fatten", text="Shrink/Fatten")
123         col.operator("transform.push_pull", text="Push/Pull")
124
125         col = layout.column(align=True)
126         col.label(text="Deform:")
127         col.operator("transform.edge_slide")
128         col.operator("mesh.noise")
129         col.operator("mesh.vertices_smooth")
130
131         col = layout.column(align=True)
132         col.label(text="Add:")
133         col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region")
134         col.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
135         col.operator("mesh.subdivide")
136         col.operator("mesh.loopcut_slide")
137         col.operator("mesh.duplicate_move", text="Duplicate")
138         col.operator("mesh.spin")
139         col.operator("mesh.screw")
140
141         col = layout.column(align=True)
142         col.label(text="Remove:")
143         col.operator("mesh.delete")
144         col.operator("mesh.merge")
145         col.operator("mesh.remove_doubles")
146
147         col = layout.column(align=True)
148         col.label(text="Normals:")
149         col.operator("mesh.normals_make_consistent", text="Recalculate")
150         col.operator("mesh.flip_normals", text="Flip Direction")
151
152         col = layout.column(align=True)
153         col.label(text="UV Mapping:")
154         col.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
155         col.operator("mesh.mark_seam")
156         col.operator("mesh.mark_seam", text="Clear Seam").clear = True
157
158         col = layout.column(align=True)
159         col.label(text="Shading:")
160         row = col.row(align=True)
161         row.operator("mesh.faces_shade_smooth", text="Smooth")
162         row.operator("mesh.faces_shade_flat", text="Flat")
163
164         draw_repeat_tools(context, layout)
165
166         draw_gpencil_tools(context, layout)
167
168
169 class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
170     bl_context = "mesh_edit"
171     bl_label = "Mesh Options"
172
173     def draw(self, context):
174         layout = self.layout
175
176         ob = context.active_object
177
178         if ob:
179             mesh = ob.data
180             col = layout.column(align=True)
181             col.prop(mesh, "use_mirror_x")
182             sub = col.column()
183             sub.active = ob.data.use_mirror_x
184             sub.prop(mesh, "use_mirror_topology")
185
186             ts = context.tool_settings
187
188             col.label("Edge Select Mode")
189             col.prop(ts, "edge_path_mode", text="")
190             col.prop(context.tool_settings, "edge_path_live_unwrap")
191
192 # ********** default tools for editmode_curve ****************
193
194
195 class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
196     bl_context = "curve_edit"
197     bl_label = "Curve Tools"
198
199     def draw(self, context):
200         layout = self.layout
201
202         col = layout.column(align=True)
203         col.label(text="Transform:")
204         col.operator("transform.translate")
205         col.operator("transform.rotate")
206         col.operator("transform.resize", text="Scale")
207
208         col = layout.column(align=True)
209         col.operator("transform.transform", text="Tilt").mode = 'TILT'
210         col.operator("transform.transform", text="Shrink/Fatten").mode = 'CURVE_SHRINKFATTEN'
211
212         col = layout.column(align=True)
213         col.label(text="Curve:")
214         col.operator("curve.duplicate")
215         col.operator("curve.delete")
216         col.operator("curve.cyclic_toggle")
217         col.operator("curve.switch_direction")
218         col.operator("curve.spline_type_set")
219
220         col = layout.column(align=True)
221         col.label(text="Handles:")
222         row = col.row()
223         row.operator("curve.handle_type_set", text="Auto").type = 'AUTOMATIC'
224         row.operator("curve.handle_type_set", text="Vector").type = 'VECTOR'
225         row = col.row()
226         row.operator("curve.handle_type_set", text="Align").type = 'ALIGNED'
227         row.operator("curve.handle_type_set", text="Free").type = 'FREE_ALIGN'
228
229         col = layout.column(align=True)
230         col.label(text="Modeling:")
231         col.operator("curve.extrude")
232         col.operator("curve.subdivide")
233
234         draw_repeat_tools(context, layout)
235
236         draw_gpencil_tools(context, layout)
237
238 # ********** default tools for editmode_surface ****************
239
240
241 class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel):
242     bl_context = "surface_edit"
243     bl_label = "Surface Tools"
244
245     def draw(self, context):
246         layout = self.layout
247
248         col = layout.column(align=True)
249         col.label(text="Transform:")
250         col.operator("transform.translate")
251         col.operator("transform.rotate")
252         col.operator("transform.resize", text="Scale")
253
254         col = layout.column(align=True)
255         col.label(text="Curve:")
256         col.operator("curve.duplicate")
257         col.operator("curve.delete")
258         col.operator("curve.cyclic_toggle")
259         col.operator("curve.switch_direction")
260
261         col = layout.column(align=True)
262         col.label(text="Modeling:")
263         col.operator("curve.extrude")
264         col.operator("curve.subdivide")
265
266         draw_repeat_tools(context, layout)
267
268         draw_gpencil_tools(context, layout)
269
270 # ********** default tools for editmode_text ****************
271
272
273 class VIEW3D_PT_tools_textedit(View3DPanel, Panel):
274     bl_context = "text_edit"
275     bl_label = "Text Tools"
276
277     def draw(self, context):
278         layout = self.layout
279
280         col = layout.column(align=True)
281         col.label(text="Text Edit:")
282         col.operator("font.text_copy", text="Copy")
283         col.operator("font.text_cut", text="Cut")
284         col.operator("font.text_paste", text="Paste")
285
286         col = layout.column(align=True)
287         col.label(text="Set Case:")
288         col.operator("font.case_set", text="To Upper").case = 'UPPER'
289         col.operator("font.case_set", text="To Lower").case = 'LOWER'
290
291         col = layout.column(align=True)
292         col.label(text="Style:")
293         col.operator("font.style_toggle", text="Bold").style = 'BOLD'
294         col.operator("font.style_toggle", text="Italic").style = 'ITALIC'
295         col.operator("font.style_toggle", text="Underline").style = 'UNDERLINE'
296
297         draw_repeat_tools(context, layout)
298
299
300 # ********** default tools for editmode_armature ****************
301
302
303 class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
304     bl_context = "armature_edit"
305     bl_label = "Armature Tools"
306
307     def draw(self, context):
308         layout = self.layout
309
310         col = layout.column(align=True)
311         col.label(text="Transform:")
312         col.operator("transform.translate")
313         col.operator("transform.rotate")
314         col.operator("transform.resize", text="Scale")
315
316         col = layout.column(align=True)
317         col.label(text="Bones:")
318         col.operator("armature.bone_primitive_add", text="Add")
319         col.operator("armature.duplicate_move", text="Duplicate")
320         col.operator("armature.delete", text="Delete")
321
322         col = layout.column(align=True)
323         col.label(text="Modeling:")
324         col.operator("armature.extrude_move")
325         col.operator("armature.subdivide", text="Subdivide")
326
327         draw_repeat_tools(context, layout)
328
329         draw_gpencil_tools(context, layout)
330
331
332 class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
333     bl_context = "armature_edit"
334     bl_label = "Armature Options"
335
336     def draw(self, context):
337         arm = context.active_object.data
338
339         self.layout.prop(arm, "use_mirror_x")
340
341 # ********** default tools for editmode_mball ****************
342
343
344 class VIEW3D_PT_tools_mballedit(View3DPanel, Panel):
345     bl_context = "mball_edit"
346     bl_label = "Meta Tools"
347
348     def draw(self, context):
349         layout = self.layout
350
351         col = layout.column(align=True)
352         col.label(text="Transform:")
353         col.operator("transform.translate")
354         col.operator("transform.rotate")
355         col.operator("transform.resize", text="Scale")
356
357         draw_repeat_tools(context, layout)
358
359         draw_gpencil_tools(context, layout)
360
361 # ********** default tools for editmode_lattice ****************
362
363
364 class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel):
365     bl_context = "lattice_edit"
366     bl_label = "Lattice Tools"
367
368     def draw(self, context):
369         layout = self.layout
370
371         col = layout.column(align=True)
372         col.label(text="Transform:")
373         col.operator("transform.translate")
374         col.operator("transform.rotate")
375         col.operator("transform.resize", text="Scale")
376
377         col = layout.column(align=True)
378         col.operator("lattice.make_regular")
379
380         draw_repeat_tools(context, layout)
381
382         draw_gpencil_tools(context, layout)
383
384
385 # ********** default tools for posemode ****************
386
387
388 class VIEW3D_PT_tools_posemode(View3DPanel, Panel):
389     bl_context = "posemode"
390     bl_label = "Pose Tools"
391
392     def draw(self, context):
393         layout = self.layout
394
395         col = layout.column(align=True)
396         col.label(text="Transform:")
397         col.operator("transform.translate")
398         col.operator("transform.rotate")
399         col.operator("transform.resize", text="Scale")
400
401         col = layout.column(align=True)
402         col.label(text="In-Between:")
403         row = col.row()
404         row.operator("pose.push", text="Push")
405         row.operator("pose.relax", text="Relax")
406         col.operator("pose.breakdown", text="Breakdowner")
407
408         col = layout.column(align=True)
409         col.label(text="Pose:")
410         row = col.row()
411         row.operator("pose.copy", text="Copy")
412         row.operator("pose.paste", text="Paste")
413
414         col = layout.column(align=True)
415         col.operator("poselib.pose_add", text="Add To Library")
416
417         draw_keyframing_tools(context, layout)
418
419         col = layout.column(align=True)
420         col.label(text="Motion Paths:")
421         col.operator("pose.paths_calculate", text="Calculate Paths")
422         col.operator("pose.paths_clear", text="Clear Paths")
423
424         draw_repeat_tools(context, layout)
425
426         draw_gpencil_tools(context, layout)
427
428
429 class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
430     bl_context = "posemode"
431     bl_label = "Pose Options"
432
433     def draw(self, context):
434         arm = context.active_object.data
435
436         self.layout.prop(arm, "use_auto_ik")
437
438 # ********** default tools for paint modes ****************
439
440
441 class PaintPanel():
442     bl_space_type = 'VIEW_3D'
443     bl_region_type = 'TOOLS'
444
445     @staticmethod
446     def paint_settings(context):
447         ts = context.tool_settings
448
449         if context.sculpt_object:
450             return ts.sculpt
451         elif context.vertex_paint_object:
452             return ts.vertex_paint
453         elif context.weight_paint_object:
454             return ts.weight_paint
455         elif context.image_paint_object:
456             return ts.image_paint
457         elif context.particle_edit_object:
458             return ts.particle_edit
459
460         return None
461
462
463 class VIEW3D_PT_tools_brush(PaintPanel, Panel):
464     bl_label = "Brush"
465
466     @classmethod
467     def poll(cls, context):
468         return cls.paint_settings(context)
469
470     def draw(self, context):
471         layout = self.layout
472
473         settings = self.paint_settings(context)
474         brush = settings.brush
475
476         if not context.particle_edit_object:
477             col = layout.split().column()
478             col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
479
480         # Particle Mode #
481
482         # XXX This needs a check if psys is editable.
483         if context.particle_edit_object:
484             # XXX Select Particle System
485             layout.column().prop(settings, "tool", expand=True)
486
487             if settings.tool != 'NONE':
488                 col = layout.column()
489                 col.prop(brush, "size", slider=True)
490                 if settings.tool != 'ADD':
491                     col.prop(brush, "strength", slider=True)
492
493             if settings.tool == 'ADD':
494                 col.prop(brush, "count")
495                 col = layout.column()
496                 col.prop(settings, "use_default_interpolate")
497                 sub = col.column(align=True)
498                 sub.active = settings.use_default_interpolate
499                 sub.prop(brush, "steps", slider=True)
500                 sub.prop(settings, "default_key_count", slider=True)
501             elif settings.tool == 'LENGTH':
502                 layout.prop(brush, "length_mode", expand=True)
503             elif settings.tool == 'PUFF':
504                 layout.prop(brush, "puff_mode", expand=True)
505                 layout.prop(brush, "use_puff_volume")
506
507         # Sculpt Mode #
508
509         elif context.sculpt_object and brush:
510
511             col = layout.column()
512
513             col.separator()
514
515             row = col.row(align=True)
516
517             if brush.use_locked_size:
518                 row.prop(brush, "use_locked_size", toggle=True, text="", icon='LOCKED')
519                 row.prop(brush, "unprojected_radius", text="Radius", slider=True)
520             else:
521                 row.prop(brush, "use_locked_size", toggle=True, text="", icon='UNLOCKED')
522                 row.prop(brush, "size", slider=True)
523
524             row.prop(brush, "use_pressure_size", toggle=True, text="")
525
526             if brush.sculpt_tool not in {'SNAKE_HOOK', 'GRAB', 'ROTATE'}:
527                 col.separator()
528
529                 row = col.row(align=True)
530
531                 if brush.use_space and brush.sculpt_tool not in {'SMOOTH'}:
532                     if brush.use_space_atten:
533                         row.prop(brush, "use_space_atten", toggle=True, text="", icon='LOCKED')
534                     else:
535                         row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
536
537                 row.prop(brush, "strength", text="Strength", slider=True)
538                 row.prop(brush, "use_pressure_strength", text="")
539
540             if brush.sculpt_tool not in {'SMOOTH'}:
541                 col.separator()
542
543                 row = col.row(align=True)
544                 row.prop(brush, "auto_smooth_factor", slider=True)
545                 row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
546
547             if brush.sculpt_tool in {'GRAB', 'SNAKE_HOOK'}:
548                 col.separator()
549
550                 row = col.row(align=True)
551                 row.prop(brush, "normal_weight", slider=True)
552
553             if brush.sculpt_tool in {'CREASE', 'BLOB'}:
554                 col.separator()
555
556                 row = col.row(align=True)
557                 row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
558
559             if brush.sculpt_tool not in {'PINCH', 'INFLATE', 'SMOOTH'}:
560                 row = col.row(align=True)
561
562                 col.separator()
563
564                 if brush.use_original_normal:
565                     row.prop(brush, "use_original_normal", toggle=True, text="", icon='LOCKED')
566                 else:
567                     row.prop(brush, "use_original_normal", toggle=True, text="", icon='UNLOCKED')
568
569                 row.prop(brush, "sculpt_plane", text="")
570
571             #if brush.sculpt_tool in {'CLAY', 'CLAY_TUBES', 'FLATTEN', 'FILL', 'SCRAPE'}:
572             if brush.sculpt_tool in {'CLAY', 'FLATTEN', 'FILL', 'SCRAPE'}:
573                 row = col.row(align=True)
574                 row.prop(brush, "plane_offset", slider=True)
575                 row.prop(brush, "use_offset_pressure", text="")
576
577                 col.separator()
578
579                 row = col.row()
580                 row.prop(brush, "use_plane_trim", text="Trim")
581                 row = col.row()
582                 row.active = brush.use_plane_trim
583                 row.prop(brush, "plane_trim", slider=True, text="Distance")
584
585             if brush.sculpt_tool == 'LAYER':
586                 row = col.row()
587                 row.prop(brush, "height", slider=True, text="Height")
588
589             col.separator()
590
591             row = col.row()
592             row.prop(brush, "use_frontface", text="Front Faces Only")
593
594             col.separator()
595             col.row().prop(brush, "direction", expand=True)
596
597             if brush.sculpt_tool in {'DRAW', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY'}:
598                 col.separator()
599
600                 col.prop(brush, "use_accumulate")
601
602             if brush.sculpt_tool == 'LAYER':
603                 col.separator()
604
605                 ob = context.sculpt_object
606                 do_persistent = True
607
608                 # not supported yet for this case
609                 for md in ob.modifiers:
610                     if md.type == 'MULTIRES':
611                         do_persistent = False
612
613                 if do_persistent:
614                     col.prop(brush, "use_persistent")
615                     col.operator("sculpt.set_persistent_base")
616
617         # Texture Paint Mode #
618
619         elif context.image_paint_object and brush:
620             col = layout.column()
621             col.template_color_wheel(brush, "color", value_slider=True)
622             col.prop(brush, "color", text="")
623
624             row = col.row(align=True)
625             row.prop(brush, "size", slider=True)
626             row.prop(brush, "use_pressure_size", toggle=True, text="")
627
628             row = col.row(align=True)
629             row.prop(brush, "strength", text="Strength", slider=True)
630             row.prop(brush, "use_pressure_strength", toggle=True, text="")
631
632             row = col.row(align=True)
633             row.prop(brush, "jitter", slider=True)
634             row.prop(brush, "use_pressure_jitter", toggle=True, text="")
635
636             col.prop(brush, "blend", text="Blend")
637
638             col = layout.column()
639             col.active = (brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'})
640             col.prop(brush, "use_alpha")
641
642         # Weight Paint Mode #
643         elif context.weight_paint_object and brush:
644             layout.prop(context.tool_settings, "vertex_group_weight", text="Weight", slider=True)
645             layout.prop(context.tool_settings, "use_auto_normalize", text="Auto Normalize")
646
647             col = layout.column()
648
649             row = col.row(align=True)
650             row.prop(brush, "size", slider=True)
651             row.prop(brush, "use_pressure_size", toggle=True, text="")
652
653             row = col.row(align=True)
654             row.prop(brush, "strength", text="Strength", slider=True)
655             row.prop(brush, "use_pressure_strength", toggle=True, text="")
656
657             row = col.row(align=True)
658             row.prop(brush, "jitter", slider=True)
659             row.prop(brush, "use_pressure_jitter", toggle=True, text="")
660
661         # Vertex Paint Mode #
662         elif context.vertex_paint_object and brush:
663             col = layout.column()
664             col.template_color_wheel(brush, "color", value_slider=True)
665             col.prop(brush, "color", text="")
666
667             row = col.row(align=True)
668             row.prop(brush, "size", slider=True)
669             row.prop(brush, "use_pressure_size", toggle=True, text="")
670
671             row = col.row(align=True)
672             row.prop(brush, "strength", text="Strength", slider=True)
673             row.prop(brush, "use_pressure_strength", toggle=True, text="")
674
675             # XXX - TODO
676             #row = col.row(align=True)
677             #row.prop(brush, "jitter", slider=True)
678             #row.prop(brush, "use_pressure_jitter", toggle=True, text="")
679
680
681 class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel):
682     bl_label = "Texture"
683     bl_options = {'DEFAULT_CLOSED'}
684
685     @classmethod
686     def poll(cls, context):
687         settings = cls.paint_settings(context)
688         return (settings and settings.brush and (context.sculpt_object or
689                              context.image_paint_object))
690
691     def draw(self, context):
692         layout = self.layout
693
694         settings = self.paint_settings(context)
695         brush = settings.brush
696         tex_slot = brush.texture_slot
697
698         col = layout.column()
699
700         col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
701         if brush.use_paint_image:
702             col.prop(brush, "use_fixed_texture")
703
704         if context.sculpt_object:
705             #XXX duplicated from properties_texture.py
706
707             col.separator()
708
709             col.label(text="Brush Mapping:")
710             row = col.row(align=True)
711             row.prop(tex_slot, "map_mode", expand=True)
712
713             col.separator()
714
715             col = layout.column()
716             col.active = tex_slot.map_mode in {'FIXED'}
717             col.label(text="Angle:")
718
719             col = layout.column()
720             if not brush.use_anchor and brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'} and tex_slot.map_mode in {'FIXED'}:
721                 col.prop(brush, "texture_angle_source_random", text="")
722             else:
723                 col.prop(brush, "texture_angle_source_no_random", text="")
724
725             #row = col.row(align=True)
726             #row.label(text="Angle:")
727             #row.active = tex_slot.map_mode in {'FIXED', 'TILED'}
728
729             #row = col.row(align=True)
730
731             #col = row.column()
732             #col.active = tex_slot.map_mode in {'FIXED'}
733             #col.prop(brush, "use_rake", toggle=True, icon='PARTICLEMODE', text="")
734
735             col = layout.column()
736             col.prop(tex_slot, "angle", text="")
737             col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
738
739             #col = layout.column()
740             #col.prop(brush, "use_random_rotation")
741             #col.active = (not brush.use_rake) and (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'}) and tex_slot.map_mode in {'FIXED'}
742
743             split = layout.split()
744
745             col = split.column()
746             col.prop(tex_slot, "offset")
747
748             col = split.column()
749
750             col.prop(tex_slot, "scale")
751
752             col = layout.column()
753
754             row = col.row(align=True)
755             row.label(text="Sample Bias:")
756             row = col.row(align=True)
757             row.prop(brush, "texture_sample_bias", slider=True, text="")
758
759             row = col.row(align=True)
760             row.label(text="Overlay:")
761             row.active = tex_slot.map_mode in {'FIXED', 'TILED'}
762
763             row = col.row(align=True)
764
765             col = row.column()
766
767             if brush.use_texture_overlay:
768                 col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_OFF')
769             else:
770                 col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_ON')
771
772             col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
773
774             col = row.column()
775             col.prop(brush, "texture_overlay_alpha", text="Alpha")
776             col.active = tex_slot.map_mode in {'FIXED', 'TILED'} and brush.use_texture_overlay
777
778
779 class VIEW3D_PT_tools_brush_tool(PaintPanel, Panel):
780     bl_label = "Tool"
781     bl_options = {'DEFAULT_CLOSED'}
782
783     @classmethod
784     def poll(cls, context):
785         settings = cls.paint_settings(context)
786         return (settings and settings.brush and
787             (context.sculpt_object or context.image_paint_object or
788             context.vertex_paint_object or context.weight_paint_object))
789
790     def draw(self, context):
791         layout = self.layout
792
793         settings = self.paint_settings(context)
794         brush = settings.brush
795
796         col = layout.column(align=True)
797
798         if context.sculpt_object:
799             col.prop(brush, "sculpt_tool", expand=False, text="")
800             col.operator("brush.reset")
801         elif context.image_paint_object:
802             col.prop(brush, "image_tool", expand=False, text="")
803         elif context.vertex_paint_object or context.weight_paint_object:
804             col.prop(brush, "vertex_tool", expand=False, text="")
805
806         row = layout.row(align=True)
807         row.prop(brush, "use_paint_sculpt", text="", icon='SCULPTMODE_HLT')
808         row.prop(brush, "use_paint_vertex", text="", icon='VPAINT_HLT')
809         row.prop(brush, "use_paint_weight", text="", icon='WPAINT_HLT')
810         row.prop(brush, "use_paint_image", text="", icon='TPAINT_HLT')
811
812
813 class VIEW3D_PT_tools_brush_stroke(PaintPanel, Panel):
814     bl_label = "Stroke"
815     bl_options = {'DEFAULT_CLOSED'}
816
817     @classmethod
818     def poll(cls, context):
819         settings = cls.paint_settings(context)
820         return (settings and settings.brush and (context.sculpt_object or
821                              context.vertex_paint_object or
822                              context.weight_paint_object or
823                              context.image_paint_object))
824
825     def draw(self, context):
826         layout = self.layout
827
828         settings = self.paint_settings(context)
829         brush = settings.brush
830         image_paint = context.image_paint_object
831
832         col = layout.column()
833
834         if context.sculpt_object:
835             col.label(text="Stroke Method:")
836             col.prop(brush, "stroke_method", text="")
837
838             if brush.use_anchor:
839                 col.separator()
840                 row = col.row()
841                 row.prop(brush, "use_edge_to_edge", "Edge To Edge")
842
843             if brush.use_airbrush:
844                 col.separator()
845                 row = col.row()
846                 row.prop(brush, "rate", text="Rate", slider=True)
847
848             if brush.use_space:
849                 col.separator()
850                 row = col.row()
851                 row.active = brush.use_space
852                 row.prop(brush, "spacing", text="Spacing")
853
854             if (brush.sculpt_tool not in {'GRAB', 'THUMB', 'SNAKE_HOOK', 'ROTATE'}) and (not brush.use_anchor) and (not brush.use_restore_mesh):
855                 col = layout.column()
856                 col.separator()
857
858                 col.prop(brush, "use_smooth_stroke")
859
860                 sub = col.column()
861                 sub.active = brush.use_smooth_stroke
862                 sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
863                 sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
864
865                 col.separator()
866
867                 row = col.row(align=True)
868                 row.prop(brush, "jitter", slider=True)
869                 row.prop(brush, "use_pressure_jitter", toggle=True, text="")
870
871         else:
872             row = col.row()
873             row.prop(brush, "use_airbrush")
874
875             row = col.row()
876             row.active = brush.use_airbrush and (not brush.use_space) and (not brush.use_anchor)
877             row.prop(brush, "rate", slider=True)
878
879             col.separator()
880
881             if not image_paint:
882                 row = col.row()
883                 row.prop(brush, "use_smooth_stroke")
884
885                 col = layout.column()
886                 col.active = brush.use_smooth_stroke
887                 col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
888                 col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
889
890             col.separator()
891
892             col = layout.column()
893             col.active = (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'THUMB', 'ROTATE', 'SNAKE_HOOK'})
894
895             row = col.row()
896             row.prop(brush, "use_space")
897
898             row = col.row()
899             row.active = brush.use_space
900             row.prop(brush, "spacing", text="Spacing")
901
902             #col.prop(brush, "use_space_atten", text="Adaptive Strength")
903             #col.prop(brush, "use_adaptive_space", text="Adaptive Spacing")
904
905             #col.separator()
906
907             #if image_paint:
908             #    row.prop(brush, "use_pressure_spacing", toggle=True, text="")
909
910
911 class VIEW3D_PT_tools_brush_curve(PaintPanel, Panel):
912     bl_label = "Curve"
913     bl_options = {'DEFAULT_CLOSED'}
914
915     @classmethod
916     def poll(cls, context):
917         settings = cls.paint_settings(context)
918         return (settings and settings.brush and settings.brush.curve)
919
920     def draw(self, context):
921         layout = self.layout
922
923         settings = self.paint_settings(context)
924
925         brush = settings.brush
926
927         layout.template_curve_mapping(brush, "curve", brush=True)
928
929         row = layout.row(align=True)
930         row.operator("brush.curve_preset", icon="SMOOTHCURVE", text="").shape = 'SMOOTH'
931         row.operator("brush.curve_preset", icon="SPHERECURVE", text="").shape = 'ROUND'
932         row.operator("brush.curve_preset", icon="ROOTCURVE", text="").shape = 'ROOT'
933         row.operator("brush.curve_preset", icon="SHARPCURVE", text="").shape = 'SHARP'
934         row.operator("brush.curve_preset", icon="LINCURVE", text="").shape = 'LINE'
935         row.operator("brush.curve_preset", icon="NOCURVE", text="").shape = 'MAX'
936
937
938 class VIEW3D_PT_sculpt_options(PaintPanel, Panel):
939     bl_label = "Options"
940     bl_options = {'DEFAULT_CLOSED'}
941
942     @classmethod
943     def poll(cls, context):
944         return (context.sculpt_object and context.tool_settings.sculpt)
945
946     def draw(self, context):
947         layout = self.layout
948
949         tool_settings = context.tool_settings
950         sculpt = tool_settings.sculpt
951
952         layout.label(text="Lock:")
953         row = layout.row(align=True)
954         row.prop(sculpt, "lock_x", text="X", toggle=True)
955         row.prop(sculpt, "lock_y", text="Y", toggle=True)
956         row.prop(sculpt, "lock_z", text="Z", toggle=True)
957
958         layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
959         layout.prop(sculpt, "show_low_resolution")
960         layout.prop(sculpt, "show_brush")
961         layout.prop(sculpt, "use_deform_only")
962
963         layout.label(text="Unified Settings:")
964         layout.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
965         layout.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
966
967
968 class VIEW3D_PT_sculpt_symmetry(PaintPanel, Panel):
969     bl_label = "Symmetry"
970     bl_options = {'DEFAULT_CLOSED'}
971
972     @classmethod
973     def poll(cls, context):
974         return (context.sculpt_object and context.tool_settings.sculpt)
975
976     def draw(self, context):
977         layout = self.layout
978
979         sculpt = context.tool_settings.sculpt
980
981         split = layout.split()
982
983         col = split.column()
984         col.label(text="Mirror:")
985         col.prop(sculpt, "use_symmetry_x", text="X")
986         col.prop(sculpt, "use_symmetry_y", text="Y")
987         col.prop(sculpt, "use_symmetry_z", text="Z")
988
989         split.prop(sculpt, "radial_symmetry", text="Radial")
990
991         layout.separator()
992
993         layout.prop(sculpt, "use_symmetry_feather", text="Feather")
994
995
996 class VIEW3D_PT_tools_brush_appearance(PaintPanel, Panel):
997     bl_label = "Appearance"
998     bl_options = {'DEFAULT_CLOSED'}
999
1000     @classmethod
1001     def poll(cls, context):
1002         ts = context.tool_settings
1003         return ((context.sculpt_object and ts.sculpt) or
1004                 (context.vertex_paint_object and ts.vertex_paint) or
1005                 (context.weight_paint_object and ts.weight_paint) or
1006                 (context.image_paint_object and ts.image_paint))
1007
1008     def draw(self, context):
1009         layout = self.layout
1010
1011         settings = self.paint_settings(context)
1012         brush = settings.brush
1013
1014         if brush is None:  # unlikely but can happen
1015             layout.label(text="Brush Unset")
1016             return
1017
1018         col = layout.column()
1019
1020         if context.sculpt_object and context.tool_settings.sculpt:
1021             #if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE', 'CLAY_TUBES'}:
1022             if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'}:
1023                 col.prop(brush, "cursor_color_add", text="Add Color")
1024                 col.prop(brush, "cursor_color_subtract", text="Subtract Color")
1025             else:
1026                 col.prop(brush, "cursor_color_add", text="Color")
1027         else:
1028             col.prop(brush, "cursor_color_add", text="Color")
1029
1030         col = layout.column()
1031         col.label(text="Icon:")
1032
1033         row = col.row(align=True)
1034         row.prop(brush, "use_custom_icon")
1035         if brush.use_custom_icon:
1036             row = col.row(align=True)
1037             row.prop(brush, "icon_filepath", text="")
1038
1039 # ********** default tools for weightpaint ****************
1040
1041
1042 class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
1043     bl_context = "weightpaint"
1044     bl_label = "Weight Tools"
1045
1046     def draw(self, context):
1047         layout = self.layout
1048
1049         ob = context.active_object
1050
1051         col = layout.column()
1052         col.active = ob.vertex_groups.active is not None
1053         col.operator("object.vertex_group_normalize_all", text="Normalize All")
1054         col.operator("object.vertex_group_normalize", text="Normalize")
1055         col.operator("object.vertex_group_invert", text="Invert")
1056         col.operator("object.vertex_group_clean", text="Clean")
1057         col.operator("object.vertex_group_levels", text="Levels")
1058
1059
1060 class VIEW3D_PT_tools_weightpaint_options(View3DPanel, Panel):
1061     bl_context = "weightpaint"
1062     bl_label = "Options"
1063
1064     def draw(self, context):
1065         layout = self.layout
1066
1067         tool_settings = context.tool_settings
1068         wpaint = tool_settings.weight_paint
1069
1070         col = layout.column()
1071         col.prop(wpaint, "use_all_faces")
1072         col.prop(wpaint, "use_normal")
1073         col.prop(wpaint, "use_spray")
1074
1075         obj = context.weight_paint_object
1076         if obj.type == 'MESH':
1077             mesh = obj.data
1078             col.prop(mesh, "use_mirror_x")
1079             col.prop(mesh, "use_mirror_topology")
1080
1081         col.label(text="Unified Settings:")
1082         col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
1083         col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
1084
1085 # Commented out because the Apply button isn't an operator yet, making these settings useless
1086 #               col.label(text="Gamma:")
1087 #               col.prop(wpaint, "gamma", text="")
1088 #               col.label(text="Multiply:")
1089 #               col.prop(wpaint, "mul", text="")
1090
1091 # Also missing now:
1092 # Soft, Vgroup, X-Mirror and "Clear" Operator.
1093
1094 # ********** default tools for vertexpaint ****************
1095
1096
1097 class VIEW3D_PT_tools_vertexpaint(View3DPanel, Panel):
1098     bl_context = "vertexpaint"
1099     bl_label = "Options"
1100
1101     def draw(self, context):
1102         layout = self.layout
1103
1104         tool_settings = context.tool_settings
1105         vpaint = tool_settings.vertex_paint
1106
1107         col = layout.column()
1108         #col.prop(vpaint, "mode", text="")
1109         col.prop(vpaint, "use_all_faces")
1110         col.prop(vpaint, "use_normal")
1111         col.prop(vpaint, "use_spray")
1112
1113         col.label(text="Unified Settings:")
1114         col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
1115         col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
1116
1117 # Commented out because the Apply button isn't an operator yet, making these settings useless
1118 #               col.label(text="Gamma:")
1119 #               col.prop(vpaint, "gamma", text="")
1120 #               col.label(text="Multiply:")
1121 #               col.prop(vpaint, "mul", text="")
1122
1123 # ********** default tools for texturepaint ****************
1124
1125
1126 class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
1127     bl_context = "imagepaint"
1128     bl_label = "Project Paint"
1129
1130     @classmethod
1131     def poll(cls, context):
1132         brush = context.tool_settings.image_paint.brush
1133         return (brush and brush.image_tool != 'SOFTEN')
1134
1135     def draw_header(self, context):
1136         ipaint = context.tool_settings.image_paint
1137
1138         self.layout.prop(ipaint, "use_projection", text="")
1139
1140     def draw(self, context):
1141         layout = self.layout
1142
1143         ob = context.active_object
1144         mesh = ob.data
1145         ipaint = context.tool_settings.image_paint
1146         settings = context.tool_settings.image_paint
1147         use_projection = ipaint.use_projection
1148
1149         col = layout.column()
1150         sub = col.column()
1151         sub.active = use_projection
1152         sub.prop(ipaint, "use_occlude")
1153         sub.prop(ipaint, "use_backface_culling")
1154
1155         split = layout.split()
1156
1157         col = split.column()
1158         col.active = (use_projection)
1159         col.prop(ipaint, "use_normal_falloff")
1160
1161         col = split.column()
1162         col.active = (ipaint.use_normal_falloff and use_projection)
1163         col.prop(ipaint, "normal_angle", text="")
1164
1165         col = layout.column(align=False)
1166         row = col.row()
1167         row.active = (use_projection)
1168         row.prop(ipaint, "use_stencil_layer", text="Stencil")
1169
1170         row2 = row.row(align=False)
1171         row2.active = (use_projection and ipaint.use_stencil_layer)
1172         row2.menu("VIEW3D_MT_tools_projectpaint_stencil", text=mesh.uv_texture_stencil.name)
1173         row2.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
1174
1175         col = layout.column()
1176         sub = col.column()
1177         row = sub.row()
1178         row.active = (settings.brush.image_tool == 'CLONE')
1179
1180         row.prop(ipaint, "use_clone_layer", text="Layer")
1181         row.menu("VIEW3D_MT_tools_projectpaint_clone", text=mesh.uv_texture_clone.name)
1182
1183         sub = col.column()
1184         sub.prop(ipaint, "seam_bleed")
1185
1186         col.label(text="External Editing")
1187         row = col.split(align=True, percentage=0.55)
1188         row.operator("image.project_edit", text="Quick Edit")
1189         row.operator("image.project_apply", text="Apply")
1190         row = col.row(align=True)
1191         row.prop(ipaint, "screen_grab_size", text="")
1192
1193         sub = col.column()
1194         sub.operator("paint.project_image", text="Apply Camera Image")
1195
1196         sub.operator("image.save_dirty", text="Save All Edited")
1197
1198
1199 class VIEW3D_PT_imagepaint_options(PaintPanel):
1200     bl_label = "Options"
1201     bl_options = {'DEFAULT_CLOSED'}
1202
1203     @classmethod
1204     def poll(cls, context):
1205         return (context.image_paint_object and context.tool_settings.image_paint)
1206
1207     def draw(self, context):
1208         layout = self.layout
1209
1210         tool_settings = context.tool_settings
1211
1212         col = layout.column()
1213         col.label(text="Unified Settings:")
1214         col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
1215         col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
1216
1217
1218 class VIEW3D_MT_tools_projectpaint_clone(Menu):
1219     bl_label = "Clone Layer"
1220
1221     def draw(self, context):
1222         layout = self.layout
1223         for i, tex in enumerate(context.active_object.data.uv_textures):
1224             prop = layout.operator("wm.context_set_int", text=tex.name)
1225             prop.data_path = "active_object.data.uv_texture_clone_index"
1226             prop.value = i
1227
1228
1229 class VIEW3D_MT_tools_projectpaint_stencil(Menu):
1230     bl_label = "Mask Layer"
1231
1232     def draw(self, context):
1233         layout = self.layout
1234         for i, tex in enumerate(context.active_object.data.uv_textures):
1235             prop = layout.operator("wm.context_set_int", text=tex.name)
1236             prop.data_path = "active_object.data.uv_texture_stencil_index"
1237             prop.value = i
1238
1239
1240 class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
1241     '''default tools for particle mode'''
1242     bl_context = "particlemode"
1243     bl_label = "Options"
1244
1245     def draw(self, context):
1246         layout = self.layout
1247
1248         pe = context.tool_settings.particle_edit
1249         ob = pe.object
1250
1251         layout.prop(pe, "type", text="")
1252
1253         ptcache = None
1254
1255         if pe.type == 'PARTICLES':
1256             if ob.particle_systems:
1257                 if len(ob.particle_systems) > 1:
1258                     layout.template_list(ob, "particle_systems", ob.particle_systems, "active_index", rows=2, maxrows=3)
1259
1260                 ptcache = ob.particle_systems.active.point_cache
1261         else:
1262             for md in ob.modifiers:
1263                 if md.type == pe.type:
1264                     ptcache = md.point_cache
1265
1266         if ptcache and len(ptcache.point_caches) > 1:
1267             layout.template_list(ptcache, "point_caches", ptcache.point_caches, "active_index", rows=2, maxrows=3)
1268
1269         if not pe.is_editable:
1270             layout.label(text="Point cache must be baked")
1271             layout.label(text="in memory to enable editing!")
1272
1273         col = layout.column(align=True)
1274         if pe.is_hair:
1275             col.active = pe.is_editable
1276             col.prop(pe, "use_emitter_deflect", text="Deflect emitter")
1277             sub = col.row()
1278             sub.active = pe.use_emitter_deflect
1279             sub.prop(pe, "emitter_distance", text="Distance")
1280
1281         col = layout.column(align=True)
1282         col.active = pe.is_editable
1283         col.label(text="Keep:")
1284         col.prop(pe, "use_preserve_length", text="Lengths")
1285         col.prop(pe, "use_preserve_root", text="Root")
1286         if not pe.is_hair:
1287             col.label(text="Correct:")
1288             col.prop(pe, "use_auto_velocity", text="Velocity")
1289         col.prop(ob.data, "use_mirror_x")
1290
1291         col = layout.column(align=True)
1292         col.active = pe.is_editable
1293         col.label(text="Draw:")
1294         col.prop(pe, "draw_step", text="Path Steps")
1295         if pe.is_hair:
1296             col.prop(pe, "show_particles", text="Children")
1297         else:
1298             if pe.type == 'PARTICLES':
1299                 col.prop(pe, "show_particles", text="Particles")
1300             col.prop(pe, "use_fade_time")
1301             sub = col.row()
1302             sub.active = pe.use_fade_time
1303             sub.prop(pe, "fade_frames", slider=True)
1304
1305 if __name__ == "__main__":  # only for live edit.
1306     bpy.utils.register_module(__name__)