Cleanup: doxy grouping for mesh runtime API
[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
24 from bpy.types import Curve, SurfaceCurve, TextCurve
25
26
27 class CurveButtonsPanel:
28     bl_space_type = 'PROPERTIES'
29     bl_region_type = 'WINDOW'
30     bl_context = "data"
31
32     @classmethod
33     def poll(cls, context):
34         return (context.curve is not None)
35
36
37 class CurveButtonsPanelCurve(CurveButtonsPanel):
38     @classmethod
39     def poll(cls, context):
40         return (type(context.curve) is Curve)
41
42
43 class CurveButtonsPanelSurface(CurveButtonsPanel):
44     @classmethod
45     def poll(cls, context):
46         return (type(context.curve) is SurfaceCurve)
47
48
49 class CurveButtonsPanelText(CurveButtonsPanel):
50     @classmethod
51     def poll(cls, context):
52         return (type(context.curve) is TextCurve)
53
54
55 class CurveButtonsPanelActive(CurveButtonsPanel):
56     """Same as above but for curves only"""
57
58     @classmethod
59     def poll(cls, context):
60         curve = context.curve
61         return (curve and type(curve) is not TextCurve and curve.splines.active)
62
63
64 class DATA_PT_context_curve(CurveButtonsPanel, Panel):
65     bl_label = ""
66     bl_options = {'HIDE_HEADER'}
67
68     def draw(self, context):
69         layout = self.layout
70
71         obj = context.object
72         curve = context.curve
73         space = context.space_data
74
75         if obj:
76             layout.template_ID(obj, "data")
77         elif curve:
78             layout.template_ID(space, "pin_id")
79
80
81 class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
82     bl_label = "Shape"
83
84     def draw(self, context):
85         layout = self.layout
86
87         curve = context.curve
88         is_surf = type(curve) is SurfaceCurve
89         is_curve = type(curve) is Curve
90         is_text = type(curve) is TextCurve
91
92         if is_curve:
93             row = layout.row()
94             row.prop(curve, "dimensions", expand=True)
95
96         layout.use_property_split = True
97
98         col = layout.column()
99         sub = col.column(align=True)
100         sub.prop(curve, "resolution_u", text="Resolution Preview U")
101         if is_surf:
102             sub.prop(curve, "resolution_v", text="V")
103
104         sub = col.column(align=True)
105         sub.prop(curve, "render_resolution_u", text="Render U")
106         if is_surf:
107             sub.prop(curve, "render_resolution_v", text="V")
108         col.separator()
109
110         if is_curve:
111             col.prop(curve, "twist_mode")
112             col.prop(curve, "twist_smooth", text="Smooth")
113         elif is_text:
114             col.prop(curve, "use_fast_edit", text="Fast Editing")
115
116         if is_curve or is_text:
117             col = layout.column()
118             col.separator()
119
120             sub = col.column()
121             sub.active = (curve.dimensions == '2D' or (curve.bevel_object is None and curve.dimensions == '3D'))
122             sub.prop(curve, "fill_mode")
123             col.prop(curve, "use_fill_deform")
124
125         if is_curve:
126             col = layout.column()
127             col.separator()
128
129             sub = col.column()
130             sub.prop(curve, "use_radius")
131             sub.prop(curve, "use_stretch")
132             sub.prop(curve, "use_deform_bounds")
133
134
135 class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel):
136     bl_label = "Texture Space"
137     bl_options = {'DEFAULT_CLOSED'}
138     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
139
140     def draw(self, context):
141         layout = self.layout
142         layout.use_property_split = True
143
144         curve = context.curve
145
146         col = layout.column()
147         col.prop(curve, "use_uv_as_generated")
148         col.prop(curve, "use_auto_texspace")
149
150         col = layout.column()
151         col.prop(curve, "texspace_location")
152         col.prop(curve, "texspace_size")
153
154         layout.operator("curve.match_texture_space")
155
156
157 class DATA_PT_geometry_curve(CurveButtonsPanelCurve, Panel):
158     bl_label = "Geometry"
159
160     @classmethod
161     def poll(cls, context):
162         return (type(context.curve) in {Curve, TextCurve})
163
164     def draw(self, context):
165         layout = self.layout
166         layout.use_property_split = True
167
168         curve = context.curve
169
170         col = layout.column()
171         col.prop(curve, "offset")
172
173         sub = col.column()
174         sub.active = (curve.bevel_object is None)
175         sub.prop(curve, "extrude")
176
177         col.prop(curve, "taper_object")
178
179         sub = col.column()
180         sub.active = curve.taper_object is not None
181         sub.prop(curve, "use_map_taper")
182
183 class DATA_PT_geometry_curve_bevel(CurveButtonsPanelCurve, Panel):
184     bl_label = "Bevel"
185     bl_parent_id = "DATA_PT_geometry_curve"
186
187     @classmethod
188     def poll(cls, context):
189         return (type(context.curve) in {Curve, TextCurve})
190
191     def draw(self, context):
192         layout = self.layout
193         layout.use_property_split = True
194
195         curve = context.curve
196
197         col = layout.column()
198         sub = col.column()
199         sub.active = (curve.bevel_object is None)
200         sub.prop(curve, "bevel_depth", text="Depth")
201         sub.prop(curve, "bevel_resolution", text="Resolution")
202
203         col.prop(curve, "bevel_object", text="Object")
204
205         sub = col.column()
206         sub.active = curve.bevel_object is not None
207         sub.prop(curve, "use_fill_caps")
208
209         if type(curve) is not TextCurve:
210
211             col = layout.column()
212             col.active = (
213                 (curve.bevel_depth > 0.0) or
214                 (curve.extrude > 0.0) or
215                 (curve.bevel_object is not None)
216             )
217             sub = col.column(align=True)
218             sub.prop(curve, "bevel_factor_start", text="Bevel Start")
219             sub.prop(curve, "bevel_factor_end", text="End")
220
221             sub = col.column(align=True)
222             sub.prop(curve, "bevel_factor_mapping_start", text="Bevel Mapping Start")
223             sub.prop(curve, "bevel_factor_mapping_end", text="End")
224
225
226 class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel):
227     bl_label = "Path Animation"
228
229     def draw_header(self, context):
230         curve = context.curve
231
232         self.layout.prop(curve, "use_path", text="")
233
234     def draw(self, context):
235         layout = self.layout
236         layout.use_property_split = True
237
238         curve = context.curve
239
240         layout.active = curve.use_path
241
242         col = layout.column()
243         col.prop(curve, "path_duration", text="Frames")
244         col.prop(curve, "eval_time")
245
246         # these are for paths only
247         col.separator()
248
249         col.prop(curve, "use_path_follow")
250
251
252 class DATA_PT_active_spline(CurveButtonsPanelActive, Panel):
253     bl_label = "Active Spline"
254
255     def draw(self, context):
256         layout = self.layout
257         layout.use_property_split = True
258
259         curve = context.curve
260         act_spline = curve.splines.active
261         is_surf = type(curve) is SurfaceCurve
262         is_poly = (act_spline.type == 'POLY')
263
264         col = layout.column()
265
266         if is_poly:
267             # These settings are below but its easier to have
268             # polys set aside since they use so few settings
269
270             col.prop(act_spline, "use_cyclic_u")
271             col.prop(act_spline, "use_smooth")
272         else:
273
274             sub = col.column(align=True)
275             sub.prop(act_spline, "use_cyclic_u")
276             if is_surf:
277                 sub.prop(act_spline, "use_cyclic_v", text="V")
278
279             if act_spline.type == 'NURBS':
280                 sub = col.column(align=True)
281                 # sub.active = (not act_spline.use_cyclic_u)
282                 sub.prop(act_spline, "use_bezier_u", text="Bezier U")
283
284                 if is_surf:
285                     subsub = sub.column()
286                     subsub.active = (not act_spline.use_cyclic_v)
287                     subsub.prop(act_spline, "use_bezier_v", text="V")
288
289                 sub = col.column(align=True)
290                 sub.prop(act_spline, "use_endpoint_u", text="Endpoint U")
291
292                 if is_surf:
293                     subsub = sub.column()
294                     subsub.active = (not act_spline.use_cyclic_v)
295                     subsub.prop(act_spline, "use_endpoint_v", text="V")
296
297                 sub = col.column(align=True)
298                 sub.prop(act_spline, "order_u", text="Order U")
299
300                 if is_surf:
301                     sub.prop(act_spline, "order_v", text="V")
302
303             sub = col.column(align=True)
304             sub.prop(act_spline, "resolution_u", text="Resolution U")
305             if is_surf:
306                 sub.prop(act_spline, "resolution_v", text="V")
307
308             if act_spline.type == 'BEZIER':
309
310                 col.separator()
311
312                 sub = col.column()
313                 sub.active = (curve.dimensions == '3D')
314                 sub.prop(act_spline, "tilt_interpolation", text="Interpolation Tilt")
315
316                 col.prop(act_spline, "radius_interpolation", text="Radius")
317
318             layout.prop(act_spline, "use_smooth")
319
320
321 class DATA_PT_font(CurveButtonsPanelText, Panel):
322     bl_label = "Font"
323
324     def draw(self, context):
325         layout = self.layout
326
327         text = context.curve
328         char = context.curve.edit_format
329
330         row = layout.split(percentage=0.25)
331         row.label(text="Regular")
332         row.template_ID(text, "font", open="font.open", unlink="font.unlink")
333         row = layout.split(percentage=0.25)
334         row.label(text="Bold")
335         row.template_ID(text, "font_bold", open="font.open", unlink="font.unlink")
336         row = layout.split(percentage=0.25)
337         row.label(text="Italic")
338         row.template_ID(text, "font_italic", open="font.open", unlink="font.unlink")
339         row = layout.split(percentage=0.25)
340         row.label(text="Bold & Italic")
341         row.template_ID(text, "font_bold_italic", open="font.open", unlink="font.unlink")
342
343         layout.separator()
344
345         row = layout.row(align=True)
346         row.prop(char, "use_bold", toggle=True)
347         row.prop(char, "use_italic", toggle=True)
348         row.prop(char, "use_underline", toggle=True)
349         row.prop(char, "use_small_caps", toggle=True)
350
351 class DATA_PT_font_transform(CurveButtonsPanelText, Panel):
352     bl_label = "Transform"
353     bl_parent_id = "DATA_PT_font"
354
355     def draw(self, context):
356         layout = self.layout
357
358         text = context.curve
359         char = context.curve.edit_format
360
361         layout.use_property_split = True
362
363         col = layout.column()
364
365         col.separator()
366
367         col.prop(text, "size", text="Size")
368         col.prop(text, "shear")
369
370         col.separator()
371
372         col.prop(text, "family")
373         col.prop(text, "follow_curve")
374
375         col.separator()
376
377         sub = col.column(align=True)
378         sub.prop(text, "underline_position", text="Underline Position")
379         sub.prop(text, "underline_height", text="Underline Thickness")
380
381         col.prop(text, "small_caps_scale", text="Small Caps Scale")
382
383
384 class DATA_PT_paragraph(CurveButtonsPanelText, Panel):
385     bl_label = "Paragraph"
386
387     def draw(self, context):
388         layout = self.layout
389
390         text = context.curve
391
392
393 class DATA_PT_paragraph_alignment(CurveButtonsPanelText, Panel):
394     bl_parent_id = "DATA_PT_paragraph"
395     bl_label = "Alignment"
396
397     def draw(self, context):
398         layout = self.layout
399         layout.use_property_split = False
400
401         text = context.curve
402
403         layout.row().prop(text, "align_x", expand=True)
404         layout.row().prop(text, "align_y", expand=True)
405
406
407
408 class DATA_PT_paragraph_spacing(CurveButtonsPanelText, Panel):
409     bl_parent_id = "DATA_PT_paragraph"
410     bl_label = "Spacing"
411
412     def draw(self, context):
413         layout = self.layout
414         layout.use_property_split = True
415
416         text = context.curve
417
418         col = layout.column(align=True)
419         col.prop(text, "space_character", text="Character Spacing")
420         col.prop(text, "space_word", text="Word Spacing")
421         col.prop(text, "space_line", text="Line Spacing")
422
423         layout.separator()
424
425         col = layout.column(align=True)
426         col.prop(text, "offset_x", text="Offset X")
427         col.prop(text, "offset_y", text="Y")
428
429
430 class DATA_PT_text_boxes(CurveButtonsPanelText, Panel):
431     bl_label = "Text Boxes"
432
433     def draw(self, context):
434         layout = self.layout
435
436         text = context.curve
437
438         layout.operator("font.textbox_add", icon='ZOOMIN')
439
440         for i, box in enumerate(text.text_boxes):
441
442             boxy = layout.box()
443
444             row = boxy.row()
445
446             col = row.column()
447             col.use_property_split = True
448
449             sub = col.column(align=True)
450             sub.prop(box, "width", text="Size X")
451             sub.prop(box, "height", text="Y")
452
453             sub = col.column(align=True)
454             sub.prop(box, "x", text="Offset X")
455             sub.prop(box, "y", text="Y")
456
457             row.operator("font.textbox_remove", text="", icon='X', emboss=False).index = i
458
459
460 class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel):
461     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
462     _context_path = "object.data"
463     _property_type = bpy.types.Curve
464
465
466 classes = (
467     DATA_PT_context_curve,
468     DATA_PT_shape_curve,
469     DATA_PT_curve_texture_space,
470     DATA_PT_geometry_curve,
471     DATA_PT_geometry_curve_bevel,
472     DATA_PT_pathanim,
473     DATA_PT_active_spline,
474     DATA_PT_font,
475     DATA_PT_font_transform,
476     DATA_PT_paragraph,
477     DATA_PT_paragraph_alignment,
478     DATA_PT_paragraph_spacing,
479     DATA_PT_text_boxes,
480     DATA_PT_custom_props_curve,
481 )
482
483 if __name__ == "__main__":  # only for live edit.
484     from bpy.utils import register_class
485     for cls in classes:
486         register_class(cls)