view selected now uses boundboxes of dupli-objects and ignores centerpoints of the...
[blender.git] / release / scripts / ui / properties_object.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 ObjectButtonsPanel(bpy.types.Panel):
27     bl_space_type = 'PROPERTIES'
28     bl_region_type = 'WINDOW'
29     bl_context = "object"
30
31
32 class OBJECT_PT_context_object(ObjectButtonsPanel):
33     bl_label = ""
34     bl_show_header = False
35
36     def draw(self, context):
37         layout = self.layout
38
39         ob = context.object
40
41         row = layout.row()
42         row.label(text="", icon='OBJECT_DATA')
43         row.prop(ob, "name", text="")
44
45
46 class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel):
47     _context_path = "object"
48
49
50 class OBJECT_PT_transform(ObjectButtonsPanel):
51     bl_label = "Transform"
52
53     def draw(self, context):
54         layout = self.layout
55
56         ob = context.object
57         wide_ui = context.region.width > narrowui
58
59         if wide_ui:
60             row = layout.row()
61
62             row.column().prop(ob, "location")
63             if ob.rotation_mode == 'QUATERNION':
64                 row.column().prop(ob, "rotation_quaternion", text="Rotation")
65             elif ob.rotation_mode == 'AXIS_ANGLE':
66                 #row.column().label(text="Rotation")
67                 #row.column().prop(pchan, "rotation_angle", text="Angle")
68                 #row.column().prop(pchan, "rotation_axis", text="Axis")
69                 row.column().prop(ob, "rotation_axis_angle", text="Rotation")
70             else:
71                 row.column().prop(ob, "rotation_euler", text="Rotation")
72
73             row.column().prop(ob, "scale")
74
75             layout.prop(ob, "rotation_mode")
76         else:
77             col = layout.column()
78             col.prop(ob, "location")
79             col.label(text="Rotation:")
80             col.prop(ob, "rotation_mode", text="")
81             if ob.rotation_mode == 'QUATERNION':
82                 col.prop(ob, "rotation_quaternion", text="")
83             elif ob.rotation_mode == 'AXIS_ANGLE':
84                 col.prop(ob, "rotation_axis_angle", text="")
85             else:
86                 col.prop(ob, "rotation_euler", text="")
87             col.prop(ob, "scale")
88
89
90 class OBJECT_PT_transform_locks(ObjectButtonsPanel):
91     bl_label = "Transform Locks"
92     bl_default_closed = True
93
94     def draw(self, context):
95         layout = self.layout
96
97         ob = context.object
98         # wide_ui = context.region.width > narrowui
99
100         row = layout.row()
101
102         col = row.column()
103         col.prop(ob, "lock_location", text="Location")
104
105         col = row.column()
106         if ob.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
107             col.prop(ob, "lock_rotations_4d", text="Rotation")
108             if ob.lock_rotations_4d:
109                 col.prop(ob, "lock_rotation_w", text="W")
110             col.prop(ob, "lock_rotation", text="")
111         else:
112             col.prop(ob, "lock_rotation", text="Rotation")
113
114         row.column().prop(ob, "lock_scale", text="Scale")
115
116
117 class OBJECT_PT_relations(ObjectButtonsPanel):
118     bl_label = "Relations"
119
120     def draw(self, context):
121         layout = self.layout
122
123         ob = context.object
124         wide_ui = context.region.width > narrowui
125
126         split = layout.split()
127
128         col = split.column()
129         col.prop(ob, "layers")
130         col.separator()
131         col.prop(ob, "pass_index")
132
133         if wide_ui:
134             col = split.column()
135         col.label(text="Parent:")
136         col.prop(ob, "parent", text="")
137
138         sub = col.column()
139         sub.prop(ob, "parent_type", text="")
140         parent = ob.parent
141         if parent and ob.parent_type == 'BONE' and parent.type == 'ARMATURE':
142             sub.prop_object(ob, "parent_bone", parent.data, "bones", text="")
143         sub.active = (parent is not None)
144
145
146 class OBJECT_PT_groups(ObjectButtonsPanel):
147     bl_label = "Groups"
148
149     def draw(self, context):
150         layout = self.layout
151
152         ob = context.object
153         wide_ui = context.region.width > narrowui
154
155         if wide_ui:
156             split = layout.split()
157             split.operator_menu_enum("object.group_add", "group")
158             split.label()
159         else:
160             layout.operator_menu_enum("object.group_add", "group")
161
162         index = 0
163         value = str(tuple(context.scene.cursor_location))
164         for group in bpy.data.groups:
165             if ob.name in group.objects:
166                 col = layout.column(align=True)
167
168                 col.set_context_pointer("group", group)
169
170                 row = col.box().row()
171                 row.prop(group, "name", text="")
172                 row.operator("object.group_remove", text="", icon='X')
173
174                 split = col.box().split()
175
176                 col = split.column()
177                 col.prop(group, "layer", text="Dupli")
178
179                 if wide_ui:
180                     col = split.column()
181                 col.prop(group, "dupli_offset", text="")
182
183                 prop = col.operator("wm.context_set_value", text="From Cursor")
184                 prop.path = "object.group_users[%d].dupli_offset" % index
185                 prop.value = value
186                 index += 1
187
188
189 class OBJECT_PT_display(ObjectButtonsPanel):
190     bl_label = "Display"
191
192     def draw(self, context):
193         layout = self.layout
194
195         ob = context.object
196         wide_ui = context.region.width > narrowui
197
198         split = layout.split()
199         col = split.column()
200         col.prop(ob, "max_draw_type", text="Type")
201
202         if wide_ui:
203             col = split.column()
204         row = col.row()
205         row.prop(ob, "draw_bounds", text="Bounds")
206         sub = row.row()
207         sub.active = ob.draw_bounds
208         sub.prop(ob, "draw_bounds_type", text="")
209
210         split = layout.split()
211
212         col = split.column()
213         col.prop(ob, "draw_name", text="Name")
214         col.prop(ob, "draw_axis", text="Axis")
215         col.prop(ob, "draw_wire", text="Wire")
216
217         if wide_ui:
218             col = split.column()
219         col.prop(ob, "draw_texture_space", text="Texture Space")
220         col.prop(ob, "x_ray", text="X-Ray")
221         col.prop(ob, "draw_transparent", text="Transparency")
222
223
224 class OBJECT_PT_duplication(ObjectButtonsPanel):
225     bl_label = "Duplication"
226
227     def draw(self, context):
228         layout = self.layout
229
230         ob = context.object
231         wide_ui = context.region.width > narrowui
232
233         if wide_ui:
234             layout.prop(ob, "dupli_type", expand=True)
235         else:
236             layout.prop(ob, "dupli_type", text="")
237
238         if ob.dupli_type == 'FRAMES':
239             split = layout.split()
240
241             col = split.column(align=True)
242             col.prop(ob, "dupli_frames_start", text="Start")
243             col.prop(ob, "dupli_frames_end", text="End")
244
245             if wide_ui:
246                 col = split.column(align=True)
247             col.prop(ob, "dupli_frames_on", text="On")
248             col.prop(ob, "dupli_frames_off", text="Off")
249
250             layout.prop(ob, "use_dupli_frames_speed", text="Speed")
251
252         elif ob.dupli_type == 'VERTS':
253             layout.prop(ob, "use_dupli_verts_rotation", text="Rotation")
254
255         elif ob.dupli_type == 'FACES':
256             split = layout.split()
257
258             col = split.column()
259             col.prop(ob, "use_dupli_faces_scale", text="Scale")
260
261             if wide_ui:
262                 col = split.column()
263             col.prop(ob, "dupli_faces_scale", text="Inherit Scale")
264
265         elif ob.dupli_type == 'GROUP':
266             if wide_ui:
267                 layout.prop(ob, "dupli_group", text="Group")
268             else:
269                 layout.prop(ob, "dupli_group", text="")
270
271
272 class OBJECT_PT_animation(ObjectButtonsPanel):
273     bl_label = "Animation"
274
275     def draw(self, context):
276         layout = self.layout
277
278         ob = context.object
279         wide_ui = context.region.width > narrowui
280
281         split = layout.split()
282
283         col = split.column()
284         col.label(text="Time Offset:")
285         col.prop(ob, "time_offset_edit", text="Edit")
286         row = col.row()
287         row.prop(ob, "time_offset_particle", text="Particle")
288         row.active = len(ob.particle_systems) != 0
289         row = col.row()
290         row.prop(ob, "time_offset_parent", text="Parent")
291         row.active = (ob.parent is not None)
292         row = col.row()
293         row.prop(ob, "slow_parent")
294         row.active = (ob.parent is not None)
295         col.prop(ob, "time_offset", text="Offset")
296
297         if wide_ui:
298             col = split.column()
299         col.label(text="Track:")
300         col.prop(ob, "track", text="")
301         col.prop(ob, "track_axis", text="Axis")
302         col.prop(ob, "up_axis", text="Up Axis")
303         row = col.row()
304         row.prop(ob, "track_override_parent", text="Override Parent")
305         row.active = (ob.parent is not None)
306
307
308 classes = [
309     OBJECT_PT_context_object,
310     OBJECT_PT_transform,
311     OBJECT_PT_transform_locks,
312     OBJECT_PT_relations,
313     OBJECT_PT_groups,
314     OBJECT_PT_display,
315     OBJECT_PT_duplication,
316     OBJECT_PT_animation,
317
318     OBJECT_PT_custom_props]
319
320
321 def register():
322     register = bpy.types.register
323     for cls in classes:
324         register(cls)
325
326
327 def unregister():
328     unregister = bpy.types.unregister
329     for cls in classes:
330         unregister(cls)
331
332 if __name__ == "__main__":
333     register()