47051194fc0e1bfdb878e9c943f89a93395f53da
[blender.git] / release / scripts / startup / bl_ui / properties_data_curve.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 Panel
22 from rna_prop_ui import PropertyPanel
23 from blf import gettext as _
24
25
26 class CurveButtonsPanel():
27     bl_space_type = 'PROPERTIES'
28     bl_region_type = 'WINDOW'
29     bl_context = "data"
30
31     @classmethod
32     def poll(cls, context):
33         return (context.object and context.object.type in {'CURVE', 'SURFACE', 'FONT'} and context.curve)
34
35
36 class CurveButtonsPanelCurve(CurveButtonsPanel):
37     '''Same as above but for curves only'''
38
39     @classmethod
40     def poll(cls, context):
41         return (context.object and context.object.type == 'CURVE' and context.curve)
42
43
44 class CurveButtonsPanelActive(CurveButtonsPanel):
45     '''Same as above but for curves only'''
46
47     @classmethod
48     def poll(cls, context):
49         curve = context.curve
50         return (curve and type(curve) is not bpy.types.TextCurve and curve.splines.active)
51
52
53 class DATA_PT_context_curve(CurveButtonsPanel, Panel):
54     bl_label = ""
55     bl_options = {'HIDE_HEADER'}
56
57     def draw(self, context):
58         layout = self.layout
59
60         ob = context.object
61         curve = context.curve
62         space = context.space_data
63
64         if ob:
65             layout.template_ID(ob, "data")
66         elif curve:
67             layout.template_ID(space, "pin_id")  # XXX: broken
68
69
70 class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
71     bl_label = _("Shape")
72
73     def draw(self, context):
74         layout = self.layout
75
76         ob = context.object
77         curve = context.curve
78         is_surf = (ob.type == 'SURFACE')
79         is_curve = (ob.type == 'CURVE')
80         is_text = (ob.type == 'FONT')
81
82         if is_curve:
83             row = layout.row()
84             row.prop(curve, "dimensions", expand=True)
85
86         split = layout.split()
87
88         col = split.column()
89         col.label(text=_("Resolution:"))
90         sub = col.column(align=True)
91         sub.prop(curve, "resolution_u", text=_("Preview U"))
92         sub.prop(curve, "render_resolution_u", text=_("Render U"))
93         if is_curve:
94             col.label(text=_("Twisting:"))
95             col.prop(curve, "twist_mode", text="")
96             col.prop(curve, "twist_smooth", text=_("Smooth"))
97         if is_text:
98             col.label(text=_("Display:"))
99             col.prop(curve, "use_fast_edit", text=_("Fast Editing"))
100
101         col = split.column()
102
103         if is_surf:
104             sub = col.column()
105             sub.label(text="")
106             sub = col.column(align=True)
107             sub.prop(curve, "resolution_v", text=_("Preview V"))
108             sub.prop(curve, "render_resolution_v", text=_("Render V"))
109
110         if (is_curve or is_text):
111             col.label(text=_("Fill:"))
112             sub = col.column()
113             sub.active = (curve.dimensions == '2D' or (curve.bevel_object is None and curve.dimensions == '3D'))
114             sub.prop(curve, "fill_mode", text="")
115             col.prop(curve, "use_fill_deform", text=_("Fill Deformed"))
116
117
118 class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel):
119     bl_label = "Texture Space"
120     bl_options = {'DEFAULT_CLOSED'}
121     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
122
123     def draw(self, context):
124         layout = self.layout
125
126         curve = context.curve
127
128         row = layout.row()
129         row.prop(curve, "use_auto_texspace")
130         row.prop(curve, "use_uv_as_generated")
131
132         row = layout.row()
133         row.column().prop(curve, "texspace_location", text=_("Location"))
134         row.column().prop(curve, "texspace_size", text=_("Size"))
135
136
137 class DATA_PT_geometry_curve(CurveButtonsPanel, Panel):
138     bl_label = "Geometry"
139
140     @classmethod
141     def poll(cls, context):
142         obj = context.object
143         if obj and obj.type == 'SURFACE':
144             return False
145
146         return context.curve
147
148     def draw(self, context):
149         layout = self.layout
150
151         curve = context.curve
152
153         split = layout.split()
154
155         col = split.column()
156         col.label(text=_("Modification:"))
157         col.prop(curve, "offset")
158         col.prop(curve, "extrude")
159         col.label(text=_("Taper Object:"))
160         col.prop(curve, "taper_object", text="")
161
162         col = split.column()
163         col.label(text=_("Bevel:"))
164         col.prop(curve, "bevel_depth", text=_("Depth"))
165         col.prop(curve, "bevel_resolution", text=_("Resolution"))
166         col.label(text=_("Bevel Object:"))
167         col.prop(curve, "bevel_object", text="")
168
169
170 class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel):
171     bl_label = "Path Animation"
172
173     def draw_header(self, context):
174         curve = context.curve
175
176         self.layout.prop(curve, "use_path", text="")
177
178     def draw(self, context):
179         layout = self.layout
180
181         curve = context.curve
182
183         layout.active = curve.use_path
184
185         col = layout.column()
186         layout.prop(curve, "path_duration", text=_("Frames"))
187         layout.prop(curve, "eval_time")
188
189         split = layout.split()
190
191         col = split.column()
192         col.prop(curve, "use_path_follow")
193         col.prop(curve, "use_stretch")
194         col.prop(curve, "use_deform_bounds")
195
196         col = split.column()
197         col.prop(curve, "use_radius")
198         col.prop(curve, "use_time_offset", text=_("Offset Children"))
199
200
201 class DATA_PT_active_spline(CurveButtonsPanelActive, Panel):
202     bl_label = "Active Spline"
203
204     def draw(self, context):
205         layout = self.layout
206
207         ob = context.object
208         curve = context.curve
209         act_spline = curve.splines.active
210         is_surf = (ob.type == 'SURFACE')
211         is_poly = (act_spline.type == 'POLY')
212
213         split = layout.split()
214
215         if is_poly:
216             # These settings are below but its easier to have
217             # poly's set aside since they use so few settings
218             col = split.column()
219             col.label(text=_("Cyclic:"))
220             col.prop(act_spline, "use_smooth")
221             col = split.column()
222             col.prop(act_spline, "use_cyclic_u", text="U")
223
224         else:
225             col = split.column()
226             col.label(text=_("Cyclic:"))
227             if act_spline.type == 'NURBS':
228                 col.label(text=_("Bezier:"))
229                 col.label(text=_("Endpoint:"))
230                 col.label(text=_("Order:"))
231
232             col.label(text=_("Resolution:"))
233
234             col = split.column()
235             col.prop(act_spline, "use_cyclic_u", text="U")
236
237             if act_spline.type == 'NURBS':
238                 sub = col.column()
239                 # sub.active = (not act_spline.use_cyclic_u)
240                 sub.prop(act_spline, "use_bezier_u", text="U")
241                 sub.prop(act_spline, "use_endpoint_u", text="U")
242
243                 sub = col.column()
244                 sub.prop(act_spline, "order_u", text="U")
245             col.prop(act_spline, "resolution_u", text="U")
246
247             if is_surf:
248                 col = split.column()
249                 col.prop(act_spline, "use_cyclic_v", text="V")
250
251                 # its a surface, assume its a nurb.
252                 sub = col.column()
253                 sub.active = (not act_spline.use_cyclic_v)
254                 sub.prop(act_spline, "use_bezier_v", text="V")
255                 sub.prop(act_spline, "use_endpoint_v", text="V")
256                 sub = col.column()
257                 sub.prop(act_spline, "order_v", text="V")
258                 sub.prop(act_spline, "resolution_v", text="V")
259
260             if not is_surf:
261                 split = layout.split()
262                 col = split.column()
263                 col.active = (curve.dimensions == '3D')
264
265                 col.label(text=_("Interpolation:"))
266                 col.prop(act_spline, "tilt_interpolation", text=_("Tilt"))
267                 col.prop(act_spline, "radius_interpolation", text=_("Radius"))
268
269             layout.prop(act_spline, "use_smooth")
270
271
272 class DATA_PT_font(CurveButtonsPanel, Panel):
273     bl_label = "Font"
274
275     @classmethod
276     def poll(cls, context):
277         return (context.object and context.object.type == 'FONT' and context.curve)
278
279     def draw(self, context):
280         layout = self.layout
281
282         text = context.curve
283         char = context.curve.edit_format
284
285         row = layout.split(percentage=0.25)
286         row.label(text=_("Regular"))
287         row.template_ID(text, "font", open="font.open", unlink="font.unlink")
288         row = layout.split(percentage=0.25)
289         row.label(text=_("Bold"))
290         row.template_ID(text, "font_bold", open="font.open", unlink="font.unlink")
291         row = layout.split(percentage=0.25)
292         row.label(text=_("Italic"))
293         row.template_ID(text, "font_italic", open="font.open", unlink="font.unlink")
294         row = layout.split(percentage=0.25)
295         row.label(text=_("Bold & Italic"))
296         row.template_ID(text, "font_bold_italic", open="font.open", unlink="font.unlink")
297
298         #layout.prop(text, "font")
299
300         split = layout.split()
301
302         col = split.column()
303         col.prop(text, "size", text=_("Size"))
304         col = split.column()
305         col.prop(text, "shear")
306
307         split = layout.split()
308
309         col = split.column()
310         col.label(text=_("Object Font:"))
311         col.prop(text, "family", text="")
312
313         col = split.column()
314         col.label(text=_("Text on Curve:"))
315         col.prop(text, "follow_curve", text="")
316
317         split = layout.split()
318
319         col = split.column()
320         colsub = col.column(align=True)
321         colsub.label(text=_("Underline:"))
322         colsub.prop(text, "underline_position", text=_("Position"))
323         colsub.prop(text, "underline_height", text=_("Thickness"))
324
325         col = split.column()
326         col.label(text=_("Character:"))
327         col.prop(char, "use_bold")
328         col.prop(char, "use_italic")
329         col.prop(char, "use_underline")
330
331         row = layout.row()
332         row.prop(text, "small_caps_scale", text=_("Small Caps"))
333         row.prop(char, "use_small_caps")
334
335
336 class DATA_PT_paragraph(CurveButtonsPanel, Panel):
337     bl_label = "Paragraph"
338
339     @classmethod
340     def poll(cls, context):
341         return (context.object and context.object.type == 'FONT' and context.curve)
342
343     def draw(self, context):
344         layout = self.layout
345
346         text = context.curve
347
348         layout.label(text=_("Align:"))
349         layout.prop(text, "align", expand=True)
350
351         split = layout.split()
352
353         col = split.column(align=True)
354         col.label(text=_("Spacing:"))
355         col.prop(text, "space_character", text=_("Character"))
356         col.prop(text, "space_word", text=_("Word"))
357         col.prop(text, "space_line", text=_("Line"))
358
359         col = split.column(align=True)
360         col.label(text=_("Offset:"))
361         col.prop(text, "offset_x", text="X")
362         col.prop(text, "offset_y", text="Y")
363
364
365 class DATA_PT_text_boxes(CurveButtonsPanel, Panel):
366     bl_label = "Text Boxes"
367
368     @classmethod
369     def poll(cls, context):
370         return (context.object and context.object.type == 'FONT' and context.curve)
371
372     def draw(self, context):
373         layout = self.layout
374
375         text = context.curve
376
377         split = layout.split()
378         col = split.column()
379         col.operator("font.textbox_add", icon='ZOOMIN')
380         col = split.column()
381
382         for i, box in enumerate(text.text_boxes):
383
384             boxy = layout.box()
385
386             row = boxy.row()
387
388             split = row.split()
389
390             col = split.column(align=True)
391
392             col.label(text=_("Dimensions:"))
393             col.prop(box, "width", text=_("Width"))
394             col.prop(box, "height", text=_("Height"))
395
396             col = split.column(align=True)
397
398             col.label(text=_("Offset:"))
399             col.prop(box, "x", text="X")
400             col.prop(box, "y", text="Y")
401
402             row.operator("font.textbox_remove", text='', icon='X', emboss=False).index = i
403
404
405 class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel):
406     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
407     _context_path = "object.data"
408     _property_type = bpy.types.Curve
409
410 if __name__ == "__main__":  # only for live edit.
411     bpy.utils.register_module(__name__)