Cleanup: trailing space
[blender-addons.git] / magic_uv / preferences.py
blob6d66b308ea6f4760b3ea4b3006d7f1ec7d9298ba
1 # <pep8-80 compliant>
3 # ##### BEGIN GPL LICENSE BLOCK #####
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # ##### END GPL LICENSE BLOCK #####
21 __author__ = "Nutti <nutti.metro@gmail.com>"
22 __status__ = "production"
23 __version__ = "6.2"
24 __date__ = "31 Jul 2019"
26 import bpy
27 from bpy.props import (
28 FloatProperty,
29 FloatVectorProperty,
30 BoolProperty,
31 EnumProperty,
33 from bpy.types import AddonPreferences
35 from . import common
36 from .op.flip_rotate_uv import MUV_OT_FlipRotateUV
37 from .op.mirror_uv import MUV_OT_MirrorUV
38 from .op.move_uv import MUV_OT_MoveUV
39 from .op.unwrap_constraint import MUV_OT_UnwrapConstraint
40 from .op.pack_uv import MUV_OT_PackUV
41 from .op.smooth_uv import MUV_OT_SmoothUV
42 from .ui.VIEW3D_MT_uv_map import (
43 MUV_MT_CopyPasteUV,
44 MUV_MT_TransferUV,
45 MUV_MT_WorldScaleUV,
46 MUV_MT_PreserveUVAspect,
47 MUV_MT_TextureLock,
48 MUV_MT_TextureWrap,
49 MUV_MT_TextureProjection,
50 MUV_MT_UVW,
52 from .ui.VIEW3D_MT_object import MUV_MT_CopyPasteUV_Object
53 from .ui.IMAGE_MT_uvs import (
54 MUV_MT_CopyPasteUV_UVEdit,
55 MUV_MT_SelectUV,
56 MUV_MT_AlignUV,
57 MUV_MT_AlignUVCursor,
58 MUV_MT_UVInspection,
60 from .utils.bl_class_registry import BlClassRegistry
61 from .utils.addon_updater import AddonUpdaterManager
62 from .utils import compatibility as compat
63 from . import updater
66 def view3d_uvmap_menu_fn(self, context):
67 layout = self.layout
68 sc = context.scene
70 layout.separator()
71 layout.label(text="Copy/Paste UV", icon=compat.icon('IMAGE'))
72 # Copy/Paste UV
73 layout.menu(MUV_MT_CopyPasteUV.bl_idname, text="Copy/Paste UV")
74 # Transfer UV
75 layout.menu(MUV_MT_TransferUV.bl_idname, text="Transfer UV")
77 layout.separator()
78 layout.label(text="UV Manipulation", icon=compat.icon('IMAGE'))
79 # Flip/Rotate UV
80 ops = layout.operator(MUV_OT_FlipRotateUV.bl_idname, text="Flip/Rotate UV")
81 ops.seams = sc.muv_flip_rotate_uv_seams
82 # Mirror UV
83 ops = layout.operator(MUV_OT_MirrorUV.bl_idname, text="Mirror UV")
84 ops.axis = sc.muv_mirror_uv_axis
85 # Move UV
86 layout.operator(MUV_OT_MoveUV.bl_idname, text="Move UV")
87 # World Scale UV
88 layout.menu(MUV_MT_WorldScaleUV.bl_idname, text="World Scale UV")
89 # Preserve UV
90 layout.menu(MUV_MT_PreserveUVAspect.bl_idname, text="Preserve UV")
91 # Texture Lock
92 layout.menu(MUV_MT_TextureLock.bl_idname, text="Texture Lock")
93 # Texture Wrap
94 layout.menu(MUV_MT_TextureWrap.bl_idname, text="Texture Wrap")
95 # UV Sculpt
96 layout.prop(sc, "muv_uv_sculpt_enable", text="UV Sculpt")
98 layout.separator()
99 layout.label(text="UV Mapping", icon=compat.icon('IMAGE'))
100 # Unwrap Constraint
101 ops = layout.operator(MUV_OT_UnwrapConstraint.bl_idname,
102 text="Unwrap Constraint")
103 ops.u_const = sc.muv_unwrap_constraint_u_const
104 ops.v_const = sc.muv_unwrap_constraint_v_const
105 # Texture Projection
106 layout.menu(MUV_MT_TextureProjection.bl_idname, text="Texture Projection")
107 # UVW
108 layout.menu(MUV_MT_UVW.bl_idname, text="UVW")
111 def view3d_object_menu_fn(self, _):
112 layout = self.layout
114 layout.separator()
115 layout.label(text="Copy/Paste UV", icon=compat.icon('IMAGE'))
116 # Copy/Paste UV (Among Object)
117 layout.menu(MUV_MT_CopyPasteUV_Object.bl_idname, text="Copy/Paste UV")
120 def image_uvs_menu_fn(self, context):
121 layout = self.layout
122 sc = context.scene
124 layout.separator()
125 # Copy/Paste UV (on UV/Image Editor)
126 layout.label(text="Copy/Paste UV", icon=compat.icon('IMAGE'))
127 layout.menu(MUV_MT_CopyPasteUV_UVEdit.bl_idname, text="Copy/Paste UV")
129 layout.separator()
130 # Pack UV
131 layout.label(text="UV Manipulation", icon=compat.icon('IMAGE'))
132 ops = layout.operator(MUV_OT_PackUV.bl_idname, text="Pack UV")
133 ops.allowable_center_deviation = sc.muv_pack_uv_allowable_center_deviation
134 ops.allowable_size_deviation = sc.muv_pack_uv_allowable_size_deviation
135 # Select UV
136 layout.menu(MUV_MT_SelectUV.bl_idname, text="Select UV")
137 # Smooth UV
138 ops = layout.operator(MUV_OT_SmoothUV.bl_idname, text="Smooth")
139 ops.transmission = sc.muv_smooth_uv_transmission
140 ops.select = sc.muv_smooth_uv_select
141 ops.mesh_infl = sc.muv_smooth_uv_mesh_infl
142 # Align UV
143 layout.menu(MUV_MT_AlignUV.bl_idname, text="Align UV")
145 layout.separator()
146 # Align UV Cursor
147 layout.label(text="Editor Enhancement", icon=compat.icon('IMAGE'))
148 layout.menu(MUV_MT_AlignUVCursor.bl_idname, text="Align UV Cursor")
149 # UV Bounding Box
150 layout.prop(sc, "muv_uv_bounding_box_show", text="UV Bounding Box")
151 # UV Inspection
152 layout.menu(MUV_MT_UVInspection.bl_idname, text="UV Inspection")
155 def add_builtin_menu():
156 bpy.types.VIEW3D_MT_uv_map.append(view3d_uvmap_menu_fn)
157 bpy.types.VIEW3D_MT_object.append(view3d_object_menu_fn)
158 bpy.types.IMAGE_MT_uvs.append(image_uvs_menu_fn)
161 def remove_builtin_menu():
162 bpy.types.IMAGE_MT_uvs.remove(image_uvs_menu_fn)
163 bpy.types.VIEW3D_MT_object.remove(view3d_object_menu_fn)
164 bpy.types.VIEW3D_MT_uv_map.remove(view3d_uvmap_menu_fn)
167 def get_update_candidate_branches(_, __):
168 manager = AddonUpdaterManager.get_instance()
169 if not manager.candidate_checked():
170 return []
172 return [(name, name, "") for name in manager.get_candidate_branch_names()]
175 def set_debug_mode(self, value):
176 self['enable_debug_mode'] = value
179 def get_debug_mode(self):
180 enabled = self.get('enable_debug_mode', False)
181 if enabled:
182 common.enable_debugg_mode()
183 else:
184 common.disable_debug_mode()
185 return enabled
188 @BlClassRegistry()
189 @compat.make_annotations
190 class MUV_Preferences(AddonPreferences):
191 """Preferences class: Preferences for this add-on"""
193 bl_idname = "magic_uv"
195 def update_enable_builtin_menu(self, _):
196 if self['enable_builtin_menu']:
197 add_builtin_menu()
198 else:
199 remove_builtin_menu()
201 # enable to add features to built-in menu
202 enable_builtin_menu = BoolProperty(
203 name="Built-in Menu",
204 description="Enable built-in menu",
205 default=True,
206 update=update_enable_builtin_menu,
209 # enable debug mode
210 enable_debug_mode = BoolProperty(
211 name="Debug Mode",
212 description="Enable debugging mode",
213 default=False,
214 set=set_debug_mode,
215 get=get_debug_mode,
218 # for UV Sculpt
219 uv_sculpt_brush_color = FloatVectorProperty(
220 name="Color",
221 description="Color",
222 default=(1.0, 0.4, 0.4, 1.0),
223 min=0.0,
224 max=1.0,
225 size=4,
226 subtype='COLOR'
229 # for Overlapped UV
230 uv_inspection_overlapped_color = FloatVectorProperty(
231 name="Color",
232 description="Color",
233 default=(0.0, 0.0, 1.0, 0.3),
234 min=0.0,
235 max=1.0,
236 size=4,
237 subtype='COLOR'
240 # for Flipped UV
241 uv_inspection_flipped_color = FloatVectorProperty(
242 name="Color",
243 description="Color",
244 default=(1.0, 0.0, 0.0, 0.3),
245 min=0.0,
246 max=1.0,
247 size=4,
248 subtype='COLOR'
251 # for Texture Projection
252 texture_projection_canvas_padding = FloatVectorProperty(
253 name="Canvas Padding",
254 description="Canvas Padding",
255 size=2,
256 max=50.0,
257 min=0.0,
258 default=(20.0, 20.0))
260 # for UV Bounding Box
261 uv_bounding_box_cp_size = FloatProperty(
262 name="Size",
263 description="Control Point Size",
264 default=6.0,
265 min=3.0,
266 max=100.0)
267 uv_bounding_box_cp_react_size = FloatProperty(
268 name="React Size",
269 description="Size event fired",
270 default=10.0,
271 min=3.0,
272 max=100.0)
274 # for UI
275 category = EnumProperty(
276 name="Category",
277 description="Preferences Category",
278 items=[
279 ('INFO', "Information", "Information about this add-on"),
280 ('CONFIG', "Configuration", "Configuration about this add-on"),
281 ('UPDATE', "Update", "Update this add-on"),
283 default='INFO'
285 info_desc_expanded = BoolProperty(
286 name="Description",
287 description="Description",
288 default=False
290 info_loc_expanded = BoolProperty(
291 name="Location",
292 description="Location",
293 default=False
295 conf_uv_sculpt_expanded = BoolProperty(
296 name="UV Sculpt",
297 description="UV Sculpt",
298 default=False
300 conf_uv_inspection_expanded = BoolProperty(
301 name="UV Inspection",
302 description="UV Inspection",
303 default=False
305 conf_texture_projection_expanded = BoolProperty(
306 name="Texture Projection",
307 description="Texture Projection",
308 default=False
310 conf_uv_bounding_box_expanded = BoolProperty(
311 name="UV Bounding Box",
312 description="UV Bounding Box",
313 default=False
316 # for add-on updater
317 updater_branch_to_update = EnumProperty(
318 name="branch",
319 description="Target branch to update add-on",
320 items=get_update_candidate_branches
323 def draw(self, _):
324 layout = self.layout
326 layout.row().prop(self, "category", expand=True)
328 if self.category == 'INFO':
329 layout.separator()
331 layout.prop(
332 self, "info_desc_expanded", text="Description",
333 icon='DISCLOSURE_TRI_DOWN' if self.info_desc_expanded
334 else 'DISCLOSURE_TRI_RIGHT')
335 if self.info_desc_expanded:
336 col = layout.column(align=True)
337 col.label(text="Magic UV is composed of many UV editing" +
338 " features.")
339 col.label(text="See tutorial page if you are new to this" +
340 " add-on.")
341 col.label(text="https://github.com/nutti/Magic-UV" +
342 "/wiki/Tutorial")
344 layout.prop(
345 self, "info_loc_expanded", text="Location",
346 icon='DISCLOSURE_TRI_DOWN' if self.info_loc_expanded
347 else 'DISCLOSURE_TRI_RIGHT')
348 if self.info_loc_expanded:
349 row = layout.row(align=True)
350 sp = compat.layout_split(row, 0.5)
351 sp.label(text="3D View > Sidebar > " +
352 "Copy/Paste UV (Object mode)")
353 sp = compat.layout_split(sp, 1.0)
354 col = sp.column(align=True)
355 col.label(text="Copy/Paste UV (Among objects)")
357 row = layout.row(align=True)
358 sp = compat.layout_split(row, 0.5)
359 sp.label(text="3D View > Sidebar > " +
360 "Copy/Paste UV (Edit mode)")
361 sp = compat.layout_split(sp, 1.0)
362 col = sp.column(align=True)
363 col.label(text="Copy/Paste UV (Among faces in 3D View)")
364 col.label(text="Transfer UV")
366 row = layout.row(align=True)
367 sp = compat.layout_split(row, 0.5)
368 sp.label(text="3D View > Sidebar > " +
369 "UV Manipulation (Edit mode)")
370 sp = compat.layout_split(sp, 1.0)
371 col = sp.column(align=True)
372 col.label(text="Flip/Rotate UV")
373 col.label(text="Mirror UV")
374 col.label(text="Move UV")
375 col.label(text="World Scale UV")
376 col.label(text="Preserve UV Aspect")
377 col.label(text="Texture Lock")
378 col.label(text="Texture Wrap")
379 col.label(text="UV Sculpt")
381 row = layout.row(align=True)
382 sp = compat.layout_split(row, 0.5)
383 sp.label(text="3D View > Sidebar > " +
384 "UV Manipulation (Edit mode)")
385 sp = compat.layout_split(sp, 1.0)
386 col = sp.column(align=True)
387 col.label(text="Unwrap Constraint")
388 col.label(text="Texture Projection")
389 col.label(text="UVW")
391 row = layout.row(align=True)
392 sp = compat.layout_split(row, 0.5)
393 sp.label(text="UV/Image Editor > Sidebar > Copy/Paste UV")
394 sp = compat.layout_split(sp, 1.0)
395 col = sp.column(align=True)
396 col.label(text="Copy/Paste UV " +
397 "(Among faces in UV/Image Editor)")
399 row = layout.row(align=True)
400 sp = compat.layout_split(row, 0.5)
401 sp.label(text="UV/Image Editor > Sidebar > UV Manipulation")
402 sp = compat.layout_split(sp, 1.0)
403 col = sp.column(align=True)
404 col.label(text="Align UV")
405 col.label(text="Smooth UV")
406 col.label(text="Select UV")
407 col.label(text="Pack UV (Extension)")
409 row = layout.row(align=True)
410 sp = compat.layout_split(row, 0.5)
411 sp.label(text="UV/Image Editor > Sidebar > " +
412 "Editor Enhancement")
413 sp = compat.layout_split(sp, 1.0)
414 col = sp.column(align=True)
415 col.label(text="Align UV Cursor")
416 col.label(text="UV Cursor Location")
417 col.label(text="UV Bounding Box")
418 col.label(text="UV Inspection")
420 elif self.category == 'CONFIG':
421 layout.separator()
423 layout.prop(self, "enable_builtin_menu", text="Built-in Menu")
424 layout.prop(self, "enable_debug_mode", text="Debug Mode")
426 layout.separator()
428 layout.prop(
429 self, "conf_uv_sculpt_expanded", text="UV Sculpt",
430 icon='DISCLOSURE_TRI_DOWN' if self.conf_uv_sculpt_expanded
431 else 'DISCLOSURE_TRI_RIGHT')
432 if self.conf_uv_sculpt_expanded:
433 sp = compat.layout_split(layout, 0.05)
434 col = sp.column() # spacer
435 sp = compat.layout_split(sp, 0.3)
436 col = sp.column()
437 col.label(text="Brush Color:")
438 col.prop(self, "uv_sculpt_brush_color", text="")
439 layout.separator()
441 layout.prop(
442 self, "conf_uv_inspection_expanded", text="UV Inspection",
443 icon='DISCLOSURE_TRI_DOWN' if self.conf_uv_inspection_expanded
444 else 'DISCLOSURE_TRI_RIGHT')
445 if self.conf_uv_inspection_expanded:
446 sp = compat.layout_split(layout, 0.05)
447 col = sp.column() # spacer
448 sp = compat.layout_split(sp, 0.3)
449 col = sp.column()
450 col.label(text="Overlapped UV Color:")
451 col.prop(self, "uv_inspection_overlapped_color", text="")
452 sp = compat.layout_split(sp, 0.45)
453 col = sp.column()
454 col.label(text="Flipped UV Color:")
455 col.prop(self, "uv_inspection_flipped_color", text="")
456 layout.separator()
458 layout.prop(
459 self, "conf_texture_projection_expanded",
460 text="Texture Projection",
461 icon='DISCLOSURE_TRI_DOWN'
462 if self.conf_texture_projection_expanded
463 else 'DISCLOSURE_TRI_RIGHT')
464 if self.conf_texture_projection_expanded:
465 sp = compat.layout_split(layout, 0.05)
466 col = sp.column() # spacer
467 sp = compat.layout_split(sp, 0.3)
468 col = sp.column()
469 col.prop(self, "texture_projection_canvas_padding")
470 layout.separator()
472 layout.prop(
473 self, "conf_uv_bounding_box_expanded", text="UV Bounding Box",
474 icon='DISCLOSURE_TRI_DOWN'
475 if self.conf_uv_bounding_box_expanded
476 else 'DISCLOSURE_TRI_RIGHT')
477 if self.conf_uv_bounding_box_expanded:
478 sp = compat.layout_split(layout, 0.05)
479 col = sp.column() # spacer
480 sp = compat.layout_split(sp, 0.3)
481 col = sp.column()
482 col.label(text="Control Point:")
483 col.prop(self, "uv_bounding_box_cp_size")
484 col.prop(self, "uv_bounding_box_cp_react_size")
485 layout.separator()
487 elif self.category == 'UPDATE':
488 updater.draw_updater_ui(self)