= Limit Distance Constraint - 'For Transform' Option =
[blender-staging.git] / release / scripts / startup / bl_ui / properties_object_constraint.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
22
23 class ConstraintButtonsPanel():
24     bl_space_type = 'PROPERTIES'
25     bl_region_type = 'WINDOW'
26     bl_context = "constraint"
27
28     def draw_constraint(self, context, con):
29         layout = self.layout
30
31         box = layout.template_constraint(con)
32
33         if box:
34             # match enum type to our functions, avoids a lookup table.
35             getattr(self, con.type)(context, box, con)
36
37             if con.type not in {'RIGID_BODY_JOINT', 'NULL'}:
38                 box.prop(con, "influence")
39
40     def space_template(self, layout, con, target=True, owner=True):
41         if target or owner:
42
43             split = layout.split(percentage=0.2)
44
45             split.label(text="Space:")
46             row = split.row()
47
48             if target:
49                 row.prop(con, "target_space", text="")
50
51             if target and owner:
52                 row.label(icon='ARROW_LEFTRIGHT')
53
54             if owner:
55                 row.prop(con, "owner_space", text="")
56
57     def target_template(self, layout, con, subtargets=True):
58         layout.prop(con, "target")  # XXX limiting settings for only 'curves' or some type of object
59
60         if con.target and subtargets:
61             if con.target.type == 'ARMATURE':
62                 layout.prop_search(con, "subtarget", con.target.data, "bones", text="Bone")
63
64                 if hasattr(con, "head_tail"):
65                     row = layout.row()
66                     row.label(text="Head/Tail:")
67                     row.prop(con, "head_tail", text="")
68             elif con.target.type in {'MESH', 'LATTICE'}:
69                 layout.prop_search(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
70
71     def ik_template(self, layout, con):
72         # only used for iTaSC
73         layout.prop(con, "pole_target")
74
75         if con.pole_target and con.pole_target.type == 'ARMATURE':
76             layout.prop_search(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
77
78         if con.pole_target:
79             row = layout.row()
80             row.label()
81             row.prop(con, "pole_angle")
82
83         split = layout.split(percentage=0.33)
84         col = split.column()
85         col.prop(con, "use_tail")
86         col.prop(con, "use_stretch")
87
88         col = split.column()
89         col.prop(con, "chain_count")
90         col.prop(con, "use_target")
91
92     def CHILD_OF(self, context, layout, con):
93         self.target_template(layout, con)
94
95         split = layout.split()
96
97         col = split.column()
98         col.label(text="Location:")
99         col.prop(con, "use_location_x", text="X")
100         col.prop(con, "use_location_y", text="Y")
101         col.prop(con, "use_location_z", text="Z")
102
103         col = split.column()
104         col.label(text="Rotation:")
105         col.prop(con, "use_rotation_x", text="X")
106         col.prop(con, "use_rotation_y", text="Y")
107         col.prop(con, "use_rotation_z", text="Z")
108
109         col = split.column()
110         col.label(text="Scale:")
111         col.prop(con, "use_scale_x", text="X")
112         col.prop(con, "use_scale_y", text="Y")
113         col.prop(con, "use_scale_z", text="Z")
114
115         row = layout.row()
116         row.operator("constraint.childof_set_inverse")
117         row.operator("constraint.childof_clear_inverse")
118
119     def TRACK_TO(self, context, layout, con):
120         self.target_template(layout, con)
121
122         row = layout.row()
123         row.label(text="To:")
124         row.prop(con, "track_axis", expand=True)
125
126         row = layout.row()
127         row.prop(con, "up_axis", text="Up")
128         row.prop(con, "use_target_z")
129
130         self.space_template(layout, con)
131
132     def IK(self, context, layout, con):
133         if context.object.pose.ik_solver == "ITASC":
134             layout.prop(con, "ik_type")
135             getattr(self, 'IK_' + con.ik_type)(context, layout, con)
136         else:
137             # Legacy IK constraint
138             self.target_template(layout, con)
139             layout.prop(con, "pole_target")
140
141             if con.pole_target and con.pole_target.type == 'ARMATURE':
142                 layout.prop_search(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
143
144             if con.pole_target:
145                 row = layout.row()
146                 row.prop(con, "pole_angle")
147                 row.label()
148
149             split = layout.split()
150             col = split.column()
151             col.prop(con, "iterations")
152             col.prop(con, "chain_count")
153
154             col.label(text="Weight:")
155             col.prop(con, "weight", text="Position", slider=True)
156             sub = col.column()
157             sub.active = con.use_rotation
158             sub.prop(con, "orient_weight", text="Rotation", slider=True)
159
160             col = split.column()
161             col.prop(con, "use_tail")
162             col.prop(con, "use_stretch")
163             col.separator()
164             col.prop(con, "use_target")
165             col.prop(con, "use_rotation")
166
167     def IK_COPY_POSE(self, context, layout, con):
168         self.target_template(layout, con)
169         self.ik_template(layout, con)
170
171         row = layout.row()
172         row.label(text="Axis Ref:")
173         row.prop(con, "reference_axis", expand=True)
174         split = layout.split(percentage=0.33)
175         split.row().prop(con, "use_location")
176         row = split.row()
177         row.prop(con, "weight", text="Weight", slider=True)
178         row.active = con.use_location
179         split = layout.split(percentage=0.33)
180         row = split.row()
181         row.label(text="Lock:")
182         row = split.row()
183         row.prop(con, "lock_location_x", text="X")
184         row.prop(con, "lock_location_y", text="Y")
185         row.prop(con, "lock_location_z", text="Z")
186         split.active = con.use_location
187
188         split = layout.split(percentage=0.33)
189         split.row().prop(con, "use_rotation")
190         row = split.row()
191         row.prop(con, "orient_weight", text="Weight", slider=True)
192         row.active = con.use_rotation
193         split = layout.split(percentage=0.33)
194         row = split.row()
195         row.label(text="Lock:")
196         row = split.row()
197         row.prop(con, "lock_rotation_x", text="X")
198         row.prop(con, "lock_rotation_y", text="Y")
199         row.prop(con, "lock_rotation_z", text="Z")
200         split.active = con.use_rotation
201
202     def IK_DISTANCE(self, context, layout, con):
203         self.target_template(layout, con)
204         self.ik_template(layout, con)
205
206         layout.prop(con, "limit_mode")
207
208         row = layout.row()
209         row.prop(con, "weight", text="Weight", slider=True)
210         row.prop(con, "distance", text="Distance", slider=True)
211
212     def FOLLOW_PATH(self, context, layout, con):
213         self.target_template(layout, con)
214
215         split = layout.split()
216
217         col = split.column()
218         col.prop(con, "use_curve_follow")
219         col.prop(con, "use_curve_radius")
220
221         col = split.column()
222         col.prop(con, "use_fixed_location")
223         if con.use_fixed_location:
224             col.prop(con, "offset_factor", text="Offset")
225         else:
226             col.prop(con, "offset")
227
228         row = layout.row()
229         row.label(text="Forward:")
230         row.prop(con, "forward_axis", expand=True)
231
232         row = layout.row()
233         row.prop(con, "up_axis", text="Up")
234         row.label()
235
236     def LIMIT_ROTATION(self, context, layout, con):
237
238         split = layout.split()
239
240         col = split.column(align=True)
241         col.prop(con, "use_limit_x")
242         sub = col.column()
243         sub.active = con.use_limit_x
244         sub.prop(con, "min_x", text="Min")
245         sub.prop(con, "max_x", text="Max")
246
247         col = split.column(align=True)
248         col.prop(con, "use_limit_y")
249         sub = col.column()
250         sub.active = con.use_limit_y
251         sub.prop(con, "min_y", text="Min")
252         sub.prop(con, "max_y", text="Max")
253
254         col = split.column(align=True)
255         col.prop(con, "use_limit_z")
256         sub = col.column()
257         sub.active = con.use_limit_z
258         sub.prop(con, "min_z", text="Min")
259         sub.prop(con, "max_z", text="Max")
260
261         row = layout.row()
262         row.prop(con, "use_transform_limit")
263         row.label()
264
265         row = layout.row()
266         row.label(text="Convert:")
267         row.prop(con, "owner_space", text="")
268
269     def LIMIT_LOCATION(self, context, layout, con):
270         split = layout.split()
271
272         col = split.column()
273         col.prop(con, "use_min_x")
274         sub = col.column()
275         sub.active = con.use_min_x
276         sub.prop(con, "min_x", text="")
277         col.prop(con, "use_max_x")
278         sub = col.column()
279         sub.active = con.use_max_x
280         sub.prop(con, "max_x", text="")
281
282         col = split.column()
283         col.prop(con, "use_min_y")
284         sub = col.column()
285         sub.active = con.use_min_y
286         sub.prop(con, "min_y", text="")
287         col.prop(con, "use_max_y")
288         sub = col.column()
289         sub.active = con.use_max_y
290         sub.prop(con, "max_y", text="")
291
292         col = split.column()
293         col.prop(con, "use_min_z")
294         sub = col.column()
295         sub.active = con.use_min_z
296         sub.prop(con, "min_z", text="")
297         col.prop(con, "use_max_z")
298         sub = col.column()
299         sub.active = con.use_max_z
300         sub.prop(con, "max_z", text="")
301
302         row = layout.row()
303         row.prop(con, "use_transform_limit")
304         row.label()
305
306         row = layout.row()
307         row.label(text="Convert:")
308         row.prop(con, "owner_space", text="")
309
310     def LIMIT_SCALE(self, context, layout, con):
311         split = layout.split()
312
313         col = split.column()
314         col.prop(con, "use_min_x")
315         sub = col.column()
316         sub.active = con.use_min_x
317         sub.prop(con, "min_x", text="")
318         col.prop(con, "use_max_x")
319         sub = col.column()
320         sub.active = con.use_max_x
321         sub.prop(con, "max_x", text="")
322
323         col = split.column()
324         col.prop(con, "use_min_y")
325         sub = col.column()
326         sub.active = con.use_min_y
327         sub.prop(con, "min_y", text="")
328         col.prop(con, "use_max_y")
329         sub = col.column()
330         sub.active = con.use_max_y
331         sub.prop(con, "max_y", text="")
332
333         col = split.column()
334         col.prop(con, "use_min_z")
335         sub = col.column()
336         sub.active = con.use_min_z
337         sub.prop(con, "min_z", text="")
338         col.prop(con, "use_max_z")
339         sub = col.column()
340         sub.active = con.use_max_z
341         sub.prop(con, "max_z", text="")
342
343         row = layout.row()
344         row.prop(con, "use_transform_limit")
345         row.label()
346
347         row = layout.row()
348         row.label(text="Convert:")
349         row.prop(con, "owner_space", text="")
350
351     def COPY_ROTATION(self, context, layout, con):
352         self.target_template(layout, con)
353
354         split = layout.split()
355
356         col = split.column()
357         col.prop(con, "use_x", text="X")
358         sub = col.column()
359         sub.active = con.use_x
360         sub.prop(con, "invert_x", text="Invert")
361
362         col = split.column()
363         col.prop(con, "use_y", text="Y")
364         sub = col.column()
365         sub.active = con.use_y
366         sub.prop(con, "invert_y", text="Invert")
367
368         col = split.column()
369         col.prop(con, "use_z", text="Z")
370         sub = col.column()
371         sub.active = con.use_z
372         sub.prop(con, "invert_z", text="Invert")
373
374         layout.prop(con, "use_offset")
375
376         self.space_template(layout, con)
377
378     def COPY_LOCATION(self, context, layout, con):
379         self.target_template(layout, con)
380
381         split = layout.split()
382
383         col = split.column()
384         col.prop(con, "use_x", text="X")
385         sub = col.column()
386         sub.active = con.use_x
387         sub.prop(con, "invert_x", text="Invert")
388
389         col = split.column()
390         col.prop(con, "use_y", text="Y")
391         sub = col.column()
392         sub.active = con.use_y
393         sub.prop(con, "invert_y", text="Invert")
394
395         col = split.column()
396         col.prop(con, "use_z", text="Z")
397         sub = col.column()
398         sub.active = con.use_z
399         sub.prop(con, "invert_z", text="Invert")
400
401         layout.prop(con, "use_offset")
402
403         self.space_template(layout, con)
404
405     def COPY_SCALE(self, context, layout, con):
406         self.target_template(layout, con)
407
408         row = layout.row(align=True)
409         row.prop(con, "use_x", text="X")
410         row.prop(con, "use_y", text="Y")
411         row.prop(con, "use_z", text="Z")
412
413         layout.prop(con, "use_offset")
414
415         self.space_template(layout, con)
416
417     def MAINTAIN_VOLUME(self, context, layout, con):
418
419         row = layout.row()
420         row.label(text="Free:")
421         row.prop(con, "free_axis", expand=True)
422
423         layout.prop(con, "volume")
424
425         self.space_template(layout, con)
426
427     def COPY_TRANSFORMS(self, context, layout, con):
428         self.target_template(layout, con)
429
430         self.space_template(layout, con)
431
432     #def SCRIPT(self, context, layout, con):
433
434     def ACTION(self, context, layout, con):
435         self.target_template(layout, con)
436
437         layout.prop(con, "action")
438
439         layout.prop(con, "transform_channel")
440
441         split = layout.split()
442
443         col = split.column(align=True)
444         col.label(text="Action Length:")
445         col.prop(con, "frame_start", text="Start")
446         col.prop(con, "frame_end", text="End")
447
448         col = split.column(align=True)
449         col.label(text="Target Range:")
450         col.prop(con, "min", text="Min")
451         col.prop(con, "max", text="Max")
452
453         row = layout.row()
454         row.label(text="Convert:")
455         row.prop(con, "target_space", text="")
456
457     def LOCKED_TRACK(self, context, layout, con):
458         self.target_template(layout, con)
459
460         row = layout.row()
461         row.label(text="To:")
462         row.prop(con, "track_axis", expand=True)
463
464         row = layout.row()
465         row.label(text="Lock:")
466         row.prop(con, "lock_axis", expand=True)
467
468     def LIMIT_DISTANCE(self, context, layout, con):
469         self.target_template(layout, con)
470
471         col = layout.column(align=True)
472         col.prop(con, "distance")
473         col.operator("constraint.limitdistance_reset")
474
475         row = layout.row()
476         row.label(text="Clamp Region:")
477         row.prop(con, "limit_mode", text="")
478
479         row = layout.row()
480         row.prop(con, "use_transform_limit")
481         row.label()
482
483
484     def STRETCH_TO(self, context, layout, con):
485         self.target_template(layout, con)
486
487         row = layout.row()
488         row.prop(con, "rest_length", text="Rest Length")
489         row.operator("constraint.stretchto_reset", text="Reset")
490
491         layout.prop(con, "bulge", text="Volume Variation")
492
493         row = layout.row()
494         row.label(text="Volume:")
495         row.prop(con, "volume", expand=True)
496
497         row.label(text="Plane:")
498         row.prop(con, "keep_axis", expand=True)
499
500     def FLOOR(self, context, layout, con):
501         self.target_template(layout, con)
502
503         row = layout.row()
504         row.prop(con, "use_sticky")
505         row.prop(con, "use_rotation")
506
507         layout.prop(con, "offset")
508
509         row = layout.row()
510         row.label(text="Min/Max:")
511         row.prop(con, "floor_location", expand=True)
512
513         self.space_template(layout, con)
514
515     def RIGID_BODY_JOINT(self, context, layout, con):
516         self.target_template(layout, con, subtargets=False)
517
518         layout.prop(con, "pivot_type")
519         layout.prop(con, "child")
520
521         row = layout.row()
522         row.prop(con, "use_linked_collision", text="Linked Collision")
523         row.prop(con, "show_pivot", text="Display Pivot")
524
525         split = layout.split()
526
527         col = split.column(align=True)
528         col.label(text="Pivot:")
529         col.prop(con, "pivot_x", text="X")
530         col.prop(con, "pivot_y", text="Y")
531         col.prop(con, "pivot_z", text="Z")
532
533         col = split.column(align=True)
534         col.label(text="Axis:")
535         col.prop(con, "axis_x", text="X")
536         col.prop(con, "axis_y", text="Y")
537         col.prop(con, "axis_z", text="Z")
538
539         if con.pivot_type == 'CONE_TWIST':
540             layout.label(text="Limits:")
541             split = layout.split()
542
543             col = split.column()
544             col.prop(con, "use_angular_limit_x", text="Angle X")
545             sub = col.column()
546             sub.active = con.use_angular_limit_x
547             sub.prop(con, "limit_angle_max_x", text="")
548
549             col = split.column()
550             col.prop(con, "use_angular_limit_y", text="Angle Y")
551             sub = col.column()
552             sub.active = con.use_angular_limit_y
553             sub.prop(con, "limit_angle_max_y", text="")
554
555             col = split.column()
556             col.prop(con, "use_angular_limit_z", text="Angle Z")
557             sub = col.column()
558             sub.active = con.use_angular_limit_z
559             sub.prop(con, "limit_angle_max_z", text="")
560
561         elif con.pivot_type == 'GENERIC_6_DOF':
562             layout.label(text="Limits:")
563             split = layout.split()
564
565             col = split.column(align=True)
566             col.prop(con, "use_limit_x", text="X")
567             sub = col.column()
568             sub.active = con.use_limit_x
569             sub.prop(con, "limit_min_x", text="Min")
570             sub.prop(con, "limit_max_x", text="Max")
571
572             col = split.column(align=True)
573             col.prop(con, "use_limit_y", text="Y")
574             sub = col.column()
575             sub.active = con.use_limit_y
576             sub.prop(con, "limit_min_y", text="Min")
577             sub.prop(con, "limit_max_y", text="Max")
578
579             col = split.column(align=True)
580             col.prop(con, "use_limit_z", text="Z")
581             sub = col.column()
582             sub.active = con.use_limit_z
583             sub.prop(con, "limit_min_z", text="Min")
584             sub.prop(con, "limit_max_z", text="Max")
585
586             split = layout.split()
587
588             col = split.column(align=True)
589             col.prop(con, "use_angular_limit_x", text="Angle X")
590             sub = col.column()
591             sub.active = con.use_angular_limit_x
592             sub.prop(con, "limit_angle_min_x", text="Min")
593             sub.prop(con, "limit_angle_max_x", text="Max")
594
595             col = split.column(align=True)
596             col.prop(con, "use_angular_limit_y", text="Angle Y")
597             sub = col.column()
598             sub.active = con.use_angular_limit_y
599             sub.prop(con, "limit_angle_min_y", text="Min")
600             sub.prop(con, "limit_angle_max_y", text="Max")
601
602             col = split.column(align=True)
603             col.prop(con, "use_angular_limit_z", text="Angle Z")
604             sub = col.column()
605             sub.active = con.use_angular_limit_z
606             sub.prop(con, "limit_angle_min_z", text="Min")
607             sub.prop(con, "limit_angle_max_z", text="Max")
608
609         elif con.pivot_type == 'HINGE':
610             layout.label(text="Limits:")
611             split = layout.split()
612
613             row = split.row(align=True)
614             col = row.column()
615             col.prop(con, "use_angular_limit_x", text="Angle X")
616
617             col = row.column()
618             col.active = con.use_angular_limit_x
619             col.prop(con, "limit_angle_min_x", text="Min")
620             col = row.column()
621             col.active = con.use_angular_limit_x
622             col.prop(con, "limit_angle_max_x", text="Max")
623
624     def CLAMP_TO(self, context, layout, con):
625         self.target_template(layout, con)
626
627         row = layout.row()
628         row.label(text="Main Axis:")
629         row.prop(con, "main_axis", expand=True)
630
631         layout.prop(con, "use_cyclic")
632
633     def TRANSFORM(self, context, layout, con):
634         self.target_template(layout, con)
635
636         layout.prop(con, "use_motion_extrapolate", text="Extrapolate")
637
638         col = layout.column()
639         col.row().label(text="Source:")
640         col.row().prop(con, "map_from", expand=True)
641
642         split = layout.split()
643
644         sub = split.column(align=True)
645         sub.label(text="X:")
646         sub.prop(con, "from_min_x", text="Min")
647         sub.prop(con, "from_max_x", text="Max")
648
649         sub = split.column(align=True)
650         sub.label(text="Y:")
651         sub.prop(con, "from_min_y", text="Min")
652         sub.prop(con, "from_max_y", text="Max")
653
654         sub = split.column(align=True)
655         sub.label(text="Z:")
656         sub.prop(con, "from_min_z", text="Min")
657         sub.prop(con, "from_max_z", text="Max")
658
659         col = layout.column()
660         row = col.row()
661         row.label(text="Source to Destination Mapping:")
662
663         row = col.row()
664         row.prop(con, "map_to_x_from", expand=False, text="")
665         row.label(text=" -> X")
666
667         row = col.row()
668         row.prop(con, "map_to_y_from", expand=False, text="")
669         row.label(text=" -> Y")
670
671         row = col.row()
672         row.prop(con, "map_to_z_from", expand=False, text="")
673         row.label(text=" -> Z")
674         
675         split = layout.split()
676         
677         col = split.column()
678         col.label(text="Destination:")
679         col.row().prop(con, "map_to", expand=True)
680
681         split = layout.split()
682
683         col = split.column()
684         col.label(text="X:")
685
686         sub = col.column(align=True)
687         sub.prop(con, "to_min_x", text="Min")
688         sub.prop(con, "to_max_x", text="Max")
689
690         col = split.column()
691         col.label(text="Y:")
692
693         sub = col.column(align=True)
694         sub.prop(con, "to_min_y", text="Min")
695         sub.prop(con, "to_max_y", text="Max")
696
697         col = split.column()
698         col.label(text="Z:")
699
700         sub = col.column(align=True)
701         sub.prop(con, "to_min_z", text="Min")
702         sub.prop(con, "to_max_z", text="Max")
703
704         self.space_template(layout, con)
705
706     def SHRINKWRAP(self, context, layout, con):
707         self.target_template(layout, con, False)
708
709         layout.prop(con, "distance")
710         layout.prop(con, "shrinkwrap_type")
711
712         if con.shrinkwrap_type == 'PROJECT':
713             row = layout.row(align=True)
714             row.prop(con, "use_x")
715             row.prop(con, "use_y")
716             row.prop(con, "use_z")
717
718     def DAMPED_TRACK(self, context, layout, con):
719         self.target_template(layout, con)
720
721         row = layout.row()
722         row.label(text="To:")
723         row.prop(con, "track_axis", expand=True)
724
725     def SPLINE_IK(self, context, layout, con):
726         self.target_template(layout, con)
727
728         col = layout.column()
729         col.label(text="Spline Fitting:")
730         col.prop(con, "chain_count")
731         col.prop(con, "use_even_divisions")
732         col.prop(con, "use_chain_offset")
733
734         col = layout.column()
735         col.label(text="Chain Scaling:")
736         col.prop(con, "use_y_stretch")
737         col.prop(con, "xz_scale_mode")
738         col.prop(con, "use_curve_radius")
739
740     def PIVOT(self, context, layout, con):
741         self.target_template(layout, con)
742
743         if con.target:
744             col = layout.column()
745             col.prop(con, "offset", text="Pivot Offset")
746         else:
747             col = layout.column()
748             col.prop(con, "use_relative_location")
749             if con.use_relative_location:
750                 col.prop(con, "offset", text="Relative Pivot Point")
751             else:
752                 col.prop(con, "offset", text="Absolute Pivot Point")
753
754         col = layout.column()
755         col.prop(con, "rotation_range", text="Pivot When")
756
757     def SCRIPT(self, context, layout, con):
758         layout.label("Blender 2.5 has no py-constraints")
759
760
761 class OBJECT_PT_constraints(ConstraintButtonsPanel, bpy.types.Panel):
762     bl_label = "Object Constraints"
763     bl_context = "constraint"
764
765     @classmethod
766     def poll(cls, context):
767         return (context.object)
768
769     def draw(self, context):
770         layout = self.layout
771
772         ob = context.object
773
774         if ob.mode == 'POSE':
775             box = layout.box()
776             box.alert = True
777             box.label(icon='INFO', text="See Bone Constraints tab to Add Constraints to active bone")
778         else:
779             layout.operator_menu_enum("object.constraint_add", "type")
780
781         for con in ob.constraints:
782             self.draw_constraint(context, con)
783
784
785 class BONE_PT_constraints(ConstraintButtonsPanel, bpy.types.Panel):
786     bl_label = "Bone Constraints"
787     bl_context = "bone_constraint"
788
789     @classmethod
790     def poll(cls, context):
791         return (context.pose_bone)
792
793     def draw(self, context):
794         layout = self.layout
795
796         layout.operator_menu_enum("pose.constraint_add", "type")
797
798         for con in context.pose_bone.constraints:
799             self.draw_constraint(context, con)
800
801 if __name__ == "__main__":  # only for live edit.
802     bpy.utils.register_module(__name__)