1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
21 # Contributed to by meta-androcto, pitiwazou, chromoly, italic
24 from bpy
.props
import (
28 from bpy
.types
import (
35 "name": "3D Viewport Pie Menus",
36 "author": "meta-androcto",
38 "blender": (2, 80, 0),
39 "description": "Pie Menu Activation",
40 "location": "Addons Preferences",
42 "doc_url": "{BLENDER_MANUAL_URL}/addons/interface/viewport_pies.html",
43 "category": "Interface"
48 "pie_views_numpad_menu",
51 "pie_manipulator_menu",
55 "pie_apply_transform_menu",
59 "pie_editor_switch_menu",
61 "pie_proportional_menu",
65 sub_modules
= [__import__(__package__
+ "." + submod
, {}, {}, submod
) for submod
in sub_modules_names
]
66 sub_modules
.sort(key
=lambda mod
: (mod
.bl_info
['category'], mod
.bl_info
['name']))
69 def _get_pref_class(mod
):
72 for obj
in vars(mod
).values():
73 if inspect
.isclass(obj
) and issubclass(obj
, PropertyGroup
):
74 if hasattr(obj
, 'bl_idname') and obj
.bl_idname
== mod
.__name
__:
78 def get_addon_preferences(name
=''):
79 """Acquisition and registration"""
80 addons
= bpy
.context
.preferences
.addons
81 if __name__
not in addons
: # wm.read_factory_settings()
83 addon_prefs
= addons
[__name__
].preferences
85 if not hasattr(addon_prefs
, name
):
86 for mod
in sub_modules
:
87 if mod
.__name
__.split('.')[-1] == name
:
88 cls
= _get_pref_class(mod
)
90 prop
= PointerProperty(type=cls
)
91 create_property(PIEToolsPreferences
, name
, prop
)
92 bpy
.utils
.unregister_class(PIEToolsPreferences
)
93 bpy
.utils
.register_class(PIEToolsPreferences
)
94 return getattr(addon_prefs
, name
, None)
98 def create_property(cls
, name
, prop
):
99 if not hasattr(cls
, '__annotations__'):
100 cls
.__annotations
__ = dict()
101 cls
.__annotations
__[name
] = prop
104 def register_submodule(mod
):
106 mod
.__addon
_enabled
__ = True
109 def unregister_submodule(mod
):
110 if mod
.__addon
_enabled
__:
112 mod
.__addon
_enabled
__ = False
114 prefs
= get_addon_preferences()
115 name
= mod
.__name
__.split('.')[-1]
116 if hasattr(PIEToolsPreferences
, name
):
117 delattr(PIEToolsPreferences
, name
)
119 bpy
.utils
.unregister_class(PIEToolsPreferences
)
120 bpy
.utils
.register_class(PIEToolsPreferences
)
125 class PIEToolsPreferences(AddonPreferences
):
128 def draw(self
, context
):
131 for mod
in sub_modules
:
132 mod_name
= mod
.__name
__.split('.')[-1]
134 column
= layout
.column()
138 expand
= getattr(self
, 'show_expanded_' + mod_name
)
139 icon
= 'TRIA_DOWN' if expand
else 'TRIA_RIGHT'
143 sub
.context_pointer_set('addon_prefs', self
)
144 op
= sub
.operator('wm.context_toggle', text
='', icon
=icon
,
146 op
.data_path
= 'addon_prefs.show_expanded_' + mod_name
147 sub
.label(text
='{}: {}'.format(info
['category'], info
['name']))
149 sub
.alignment
= 'RIGHT'
150 if info
.get('warning'):
151 sub
.label(text
='', icon
='ERROR')
152 sub
.prop(self
, 'use_' + mod_name
, text
='')
156 if info
.get('description'):
157 split
= col
.row().split(factor
=0.15)
158 split
.label(text
='Description:')
159 split
.label(text
=info
['description'])
160 if info
.get('location'):
161 split
= col
.row().split(factor
=0.15)
162 split
.label(text
='Location:')
163 split
.label(text
=info
['location'])
165 if info.get('author'):
166 split = col.row().split(factor=0.15)
167 split.label(text='Author:')
168 split.label(text=info['author'])
170 if info
.get('version'):
171 split
= col
.row().split(factor
=0.15)
172 split
.label(text
='Version:')
173 split
.label(text
='.'.join(str(x
) for x
in info
['version']),
175 if info
.get('warning'):
176 split
= col
.row().split(factor
=0.15)
177 split
.label(text
='Warning:')
178 split
.label(text
=' ' + info
['warning'], icon
='ERROR')
180 tot_row
= int(bool(info
.get('doc_url')))
182 split
= col
.row().split(factor
=0.15)
183 split
.label(text
='Internet:')
184 if info
.get('doc_url'):
185 op
= split
.operator('wm.url_open',
186 text
='Documentation', icon
='HELP')
187 op
.url
= info
.get('doc_url')
188 for i
in range(4 - tot_row
):
191 # Details and settings
192 if getattr(self
, 'use_' + mod_name
):
193 prefs
= get_addon_preferences(mod_name
)
195 if prefs
and hasattr(prefs
, 'draw'):
202 traceback
.print_exc()
203 box
.label(text
='Error (see console)', icon
='ERROR')
207 row
.label(text
="End of Pie Menu Activations", icon
="FILE_PARENT")
210 for mod
in sub_modules
:
212 mod_name
= mod
.__name
__.split('.')[-1]
215 def update(self
, context
):
216 enabled
= getattr(self
, 'use_' + mod
.__name
__.split('.')[-1])
218 register_submodule(mod
)
220 unregister_submodule(mod
)
221 mod
.__addon
_enabled
__ = enabled
229 description
=info
.get('description', ''),
230 update
=gen_update(mod
),
236 'show_expanded_' + mod_name
,
247 bpy
.utils
.register_class(cls
)
249 prefs
= get_addon_preferences()
250 for mod
in sub_modules
:
251 if not hasattr(mod
, '__addon_enabled__'):
252 mod
.__addon
_enabled
__ = False
253 name
= mod
.__name
__.split('.')[-1]
254 if getattr(prefs
, 'use_' + name
):
255 register_submodule(mod
)
259 for mod
in sub_modules
:
260 if mod
.__addon
_enabled
__:
261 unregister_submodule(mod
)
263 for cls
in reversed(classes
):
264 bpy
.utils
.unregister_class(cls
)
267 if __name__
== "__main__":