1 # SPDX-FileCopyrightText: 2016-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # Contributed to by meta-androcto, pitiwazou, chromoly, italic, kc98
8 from bpy
.props
import (
12 from bpy
.types
import (
19 "name": "3D Viewport Pie Menus",
20 "author": "meta-androcto",
22 "blender": (2, 80, 0),
23 "description": "Pie Menu Activation",
24 "location": "Addons Preferences",
26 "doc_url": "{BLENDER_MANUAL_URL}/addons/interface/viewport_pies.html",
27 "category": "Interface"
32 "pie_views_numpad_menu",
35 "pie_manipulator_menu",
39 "pie_apply_transform_menu",
43 "pie_editor_switch_menu",
45 "pie_proportional_menu",
49 sub_modules
= [__import__(__package__
+ "." + submod
, {}, {}, submod
) for submod
in sub_modules_names
]
50 sub_modules
.sort(key
=lambda mod
: (mod
.bl_info
['category'], mod
.bl_info
['name']))
53 def _get_pref_class(mod
):
56 for obj
in vars(mod
).values():
57 if inspect
.isclass(obj
) and issubclass(obj
, PropertyGroup
):
58 if hasattr(obj
, 'bl_idname') and obj
.bl_idname
== mod
.__name
__:
62 def get_addon_preferences(name
=''):
63 """Acquisition and registration"""
64 addons
= bpy
.context
.preferences
.addons
65 if __name__
not in addons
: # wm.read_factory_settings()
67 addon_prefs
= addons
[__name__
].preferences
69 if not hasattr(addon_prefs
, name
):
70 for mod
in sub_modules
:
71 if mod
.__name
__.split('.')[-1] == name
:
72 cls
= _get_pref_class(mod
)
74 prop
= PointerProperty(type=cls
)
75 create_property(PIEToolsPreferences
, name
, prop
)
76 bpy
.utils
.unregister_class(PIEToolsPreferences
)
77 bpy
.utils
.register_class(PIEToolsPreferences
)
78 return getattr(addon_prefs
, name
, None)
83 def create_property(cls
, name
, prop
):
84 if not hasattr(cls
, '__annotations__'):
85 cls
.__annotations
__ = dict()
86 cls
.__annotations
__[name
] = prop
89 def register_submodule(mod
):
91 mod
.__addon
_enabled
__ = True
94 def unregister_submodule(mod
):
95 if mod
.__addon
_enabled
__:
97 mod
.__addon
_enabled
__ = False
99 prefs
= get_addon_preferences()
100 name
= mod
.__name
__.split('.')[-1]
101 if hasattr(PIEToolsPreferences
, name
):
102 delattr(PIEToolsPreferences
, name
)
104 bpy
.utils
.unregister_class(PIEToolsPreferences
)
105 bpy
.utils
.register_class(PIEToolsPreferences
)
110 class PIEToolsPreferences(AddonPreferences
):
113 def draw(self
, context
):
116 for mod
in sub_modules
:
117 mod_name
= mod
.__name
__.split('.')[-1]
119 column
= layout
.column()
123 expand
= getattr(self
, 'show_expanded_' + mod_name
)
124 icon
= 'TRIA_DOWN' if expand
else 'TRIA_RIGHT'
128 sub
.context_pointer_set('addon_prefs', self
)
129 op
= sub
.operator('wm.context_toggle', text
='', icon
=icon
,
131 op
.data_path
= 'addon_prefs.show_expanded_' + mod_name
132 sub
.label(text
='{}: {}'.format(info
['category'], info
['name']))
134 sub
.alignment
= 'RIGHT'
135 if info
.get('warning'):
136 sub
.label(text
='', icon
='ERROR')
137 sub
.prop(self
, 'use_' + mod_name
, text
='')
141 if info
.get('description'):
142 split
= col
.row().split(factor
=0.15)
143 split
.label(text
='Description:')
144 split
.label(text
=info
['description'])
145 if info
.get('location'):
146 split
= col
.row().split(factor
=0.15)
147 split
.label(text
='Location:')
148 split
.label(text
=info
['location'])
150 if info.get('author'):
151 split = col.row().split(factor=0.15)
152 split.label(text='Author:')
153 split.label(text=info['author'])
155 if info
.get('version'):
156 split
= col
.row().split(factor
=0.15)
157 split
.label(text
='Version:')
158 split
.label(text
='.'.join(str(x
) for x
in info
['version']),
160 if info
.get('warning'):
161 split
= col
.row().split(factor
=0.15)
162 split
.label(text
='Warning:')
163 split
.label(text
=' ' + info
['warning'], icon
='ERROR')
165 tot_row
= int(bool(info
.get('doc_url')))
167 split
= col
.row().split(factor
=0.15)
168 split
.label(text
='Internet:')
169 if info
.get('doc_url'):
170 op
= split
.operator('wm.url_open',
171 text
='Documentation', icon
='HELP')
172 op
.url
= info
.get('doc_url')
173 for i
in range(4 - tot_row
):
176 # Details and settings
177 if getattr(self
, 'use_' + mod_name
):
178 prefs
= get_addon_preferences(mod_name
)
180 if prefs
and hasattr(prefs
, 'draw'):
187 traceback
.print_exc()
188 box
.label(text
='Error (see console)', icon
='ERROR')
192 row
.label(text
="End of Pie Menu Activations", icon
="FILE_PARENT")
195 for mod
in sub_modules
:
197 mod_name
= mod
.__name
__.split('.')[-1]
200 def update(self
, context
):
201 enabled
= getattr(self
, 'use_' + mod
.__name
__.split('.')[-1])
203 register_submodule(mod
)
205 unregister_submodule(mod
)
206 mod
.__addon
_enabled
__ = enabled
214 description
=info
.get('description', ''),
215 update
=gen_update(mod
),
221 'show_expanded_' + mod_name
,
232 bpy
.utils
.register_class(cls
)
234 prefs
= get_addon_preferences()
235 for mod
in sub_modules
:
236 if not hasattr(mod
, '__addon_enabled__'):
237 mod
.__addon
_enabled
__ = False
238 name
= mod
.__name
__.split('.')[-1]
239 if getattr(prefs
, 'use_' + name
):
240 register_submodule(mod
)
244 for mod
in sub_modules
:
245 if mod
.__addon
_enabled
__:
246 unregister_submodule(mod
)
248 for cls
in reversed(classes
):
249 bpy
.utils
.unregister_class(cls
)
252 if __name__
== "__main__":