change python scripts so modules which register with blender have a register() functi...
[blender.git] / release / scripts / ui / properties_data_armature.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 rna_prop_ui import PropertyPanel
22
23 narrowui = 180
24
25
26 class DataButtonsPanel(bpy.types.Panel):
27     bl_space_type = 'PROPERTIES'
28     bl_region_type = 'WINDOW'
29     bl_context = "data"
30
31     def poll(self, context):
32         return context.armature
33
34
35 class DATA_PT_context_arm(DataButtonsPanel):
36     bl_label = ""
37     bl_show_header = False
38
39     def draw(self, context):
40         layout = self.layout
41
42         ob = context.object
43         arm = context.armature
44         space = context.space_data
45         wide_ui = context.region.width > narrowui
46
47         if wide_ui:
48             split = layout.split(percentage=0.65)
49             if ob:
50                 split.template_ID(ob, "data")
51                 split.separator()
52             elif arm:
53                 split.template_ID(space, "pin_id")
54                 split.separator()
55         else:
56             layout.template_ID(ob, "data")
57
58
59 class DATA_PT_custom_props_arm(DataButtonsPanel, PropertyPanel):
60     _context_path = "object.data"
61
62
63 class DATA_PT_skeleton(DataButtonsPanel):
64     bl_label = "Skeleton"
65
66     def draw(self, context):
67         layout = self.layout
68
69         arm = context.armature
70         wide_ui = context.region.width > narrowui
71
72         layout.prop(arm, "pose_position", expand=True)
73
74         split = layout.split()
75
76         col = split.column()
77         col.label(text="Layers:")
78         col.prop(arm, "layer", text="")
79         col.label(text="Protected Layers:")
80         col.prop(arm, "layer_protection", text="")
81
82         if wide_ui:
83             col = split.column()
84         col.label(text="Deform:")
85         col.prop(arm, "deform_vertexgroups", text="Vertex Groups")
86         col.prop(arm, "deform_envelope", text="Envelopes")
87         col.prop(arm, "deform_quaternion", text="Quaternion")
88         col.prop(arm, "deform_bbone_rest", text="B-Bones Rest")
89
90
91 class DATA_PT_display(DataButtonsPanel):
92     bl_label = "Display"
93
94     def draw(self, context):
95         layout = self.layout
96
97         ob = context.object
98         arm = context.armature
99         wide_ui = context.region.width > narrowui
100
101         if wide_ui:
102             layout.row().prop(arm, "drawtype", expand=True)
103         else:
104             layout.row().prop(arm, "drawtype", text="")
105
106         split = layout.split()
107
108         col = split.column()
109         col.prop(arm, "draw_names", text="Names")
110         col.prop(arm, "draw_axes", text="Axes")
111         col.prop(arm, "draw_custom_bone_shapes", text="Shapes")
112
113         if wide_ui:
114             col = split.column()
115         col.prop(arm, "draw_group_colors", text="Colors")
116         col.prop(arm, "delay_deform", text="Delay Refresh")
117         col.prop(ob, "x_ray", text="X-Ray (Object)")
118
119
120 class DATA_PT_bone_groups(DataButtonsPanel):
121     bl_label = "Bone Groups"
122
123     def poll(self, context):
124         return (context.object and context.object.type == 'ARMATURE' and context.object.pose)
125
126     def draw(self, context):
127         layout = self.layout
128
129         ob = context.object
130         pose = ob.pose
131         wide_ui = context.region.width > narrowui
132
133         row = layout.row()
134         row.template_list(pose, "bone_groups", pose, "active_bone_group_index", rows=2)
135
136         col = row.column(align=True)
137         col.active = (ob.proxy is None)
138         col.operator("pose.group_add", icon='ZOOMIN', text="")
139         col.operator("pose.group_remove", icon='ZOOMOUT', text="")
140
141         group = pose.active_bone_group
142         if group:
143             col = layout.column()
144             col.active = (ob.proxy is None)
145             col.prop(group, "name")
146
147             split = layout.split()
148             split.active = (ob.proxy is None)
149
150             col = split.column()
151             col.prop(group, "color_set")
152             if group.color_set:
153                 if wide_ui:
154                     col = split.column()
155                 col.template_triColorSet(group, "colors")
156
157         row = layout.row(align=True)
158         row.active = (ob.proxy is None)
159
160         row.operator("pose.group_assign", text="Assign")
161         row.operator("pose.group_unassign", text="Remove") #row.operator("pose.bone_group_remove_from", text="Remove")
162         #row.operator("object.bone_group_select", text="Select")
163         #row.operator("object.bone_group_deselect", text="Deselect")
164
165
166 # TODO: this panel will soon be depreceated too
167
168
169 class DATA_PT_ghost(DataButtonsPanel):
170     bl_label = "Ghost"
171
172     def draw(self, context):
173         layout = self.layout
174
175         arm = context.armature
176         wide_ui = context.region.width > narrowui
177
178         if wide_ui:
179             layout.prop(arm, "ghost_type", expand=True)
180         else:
181             layout.prop(arm, "ghost_type", text="")
182
183         split = layout.split()
184
185         col = split.column()
186
187         sub = col.column(align=True)
188         if arm.ghost_type == 'RANGE':
189             sub.prop(arm, "ghost_start_frame", text="Start")
190             sub.prop(arm, "ghost_end_frame", text="End")
191             sub.prop(arm, "ghost_size", text="Step")
192         elif arm.ghost_type == 'CURRENT_FRAME':
193             sub.prop(arm, "ghost_step", text="Range")
194             sub.prop(arm, "ghost_size", text="Step")
195
196         if wide_ui:
197             col = split.column()
198         col.label(text="Display:")
199         col.prop(arm, "ghost_only_selected", text="Selected Only")
200
201
202 class DATA_PT_iksolver_itasc(DataButtonsPanel):
203     bl_label = "iTaSC parameters"
204     bl_default_closed = True
205
206     def poll(self, context):
207         ob = context.object
208         return (ob and ob.pose)
209
210     def draw(self, context):
211         layout = self.layout
212
213         ob = context.object
214
215         itasc = ob.pose.ik_param
216         wide_ui = (context.region.width > narrowui)
217
218         row = layout.row()
219         row.prop(ob.pose, "ik_solver")
220
221         if itasc:
222             layout.prop(itasc, "mode", expand=True)
223             simulation = (itasc.mode == 'SIMULATION')
224             if simulation:
225                 layout.label(text="Reiteration:")
226                 layout.prop(itasc, "reiteration", expand=True)
227
228             split = layout.split()
229             split.active = not simulation or itasc.reiteration != 'NEVER'
230             col = split.column()
231             col.prop(itasc, "precision")
232
233             if wide_ui:
234                 col = split.column()
235             col.prop(itasc, "num_iter")
236
237
238             if simulation:
239                 layout.prop(itasc, "auto_step")
240                 row = layout.row()
241                 if itasc.auto_step:
242                     row.prop(itasc, "min_step", text="Min")
243                     row.prop(itasc, "max_step", text="Max")
244                 else:
245                     row.prop(itasc, "num_step")
246
247             layout.prop(itasc, "solver")
248             if simulation:
249                 layout.prop(itasc, "feedback")
250                 layout.prop(itasc, "max_velocity")
251             if itasc.solver == 'DLS':
252                 row = layout.row()
253                 row.prop(itasc, "dampmax", text="Damp", slider=True)
254                 row.prop(itasc, "dampeps", text="Eps", slider=True)
255
256 classes = [
257     DATA_PT_context_arm,
258     DATA_PT_skeleton,
259     DATA_PT_display,
260     DATA_PT_bone_groups,
261     DATA_PT_ghost,
262     DATA_PT_iksolver_itasc,
263
264     DATA_PT_custom_props_arm]
265
266 def register():
267     register = bpy.types.register
268     for cls in classes:
269         register(cls)
270
271 def unregister():
272     unregister = bpy.types.unregister
273     for cls in classes:
274         unregister(cls)