1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # Contributed to by meta-androcto, pitiwazou, chromoly, italic
6 from bpy
.props
import (
10 from bpy
.types
import (
17 "name": "3D Viewport Pie Menus",
18 "author": "meta-androcto",
20 "blender": (2, 80, 0),
21 "description": "Pie Menu Activation",
22 "location": "Addons Preferences",
24 "doc_url": "{BLENDER_MANUAL_URL}/addons/interface/viewport_pies.html",
25 "category": "Interface"
30 "pie_views_numpad_menu",
33 "pie_manipulator_menu",
37 "pie_apply_transform_menu",
41 "pie_editor_switch_menu",
43 "pie_proportional_menu",
47 sub_modules
= [__import__(__package__
+ "." + submod
, {}, {}, submod
) for submod
in sub_modules_names
]
48 sub_modules
.sort(key
=lambda mod
: (mod
.bl_info
['category'], mod
.bl_info
['name']))
51 def _get_pref_class(mod
):
54 for obj
in vars(mod
).values():
55 if inspect
.isclass(obj
) and issubclass(obj
, PropertyGroup
):
56 if hasattr(obj
, 'bl_idname') and obj
.bl_idname
== mod
.__name
__:
60 def get_addon_preferences(name
=''):
61 """Acquisition and registration"""
62 addons
= bpy
.context
.preferences
.addons
63 if __name__
not in addons
: # wm.read_factory_settings()
65 addon_prefs
= addons
[__name__
].preferences
67 if not hasattr(addon_prefs
, name
):
68 for mod
in sub_modules
:
69 if mod
.__name
__.split('.')[-1] == name
:
70 cls
= _get_pref_class(mod
)
72 prop
= PointerProperty(type=cls
)
73 create_property(PIEToolsPreferences
, name
, prop
)
74 bpy
.utils
.unregister_class(PIEToolsPreferences
)
75 bpy
.utils
.register_class(PIEToolsPreferences
)
76 return getattr(addon_prefs
, name
, None)
80 def create_property(cls
, name
, prop
):
81 if not hasattr(cls
, '__annotations__'):
82 cls
.__annotations
__ = dict()
83 cls
.__annotations
__[name
] = prop
86 def register_submodule(mod
):
88 mod
.__addon
_enabled
__ = True
91 def unregister_submodule(mod
):
92 if mod
.__addon
_enabled
__:
94 mod
.__addon
_enabled
__ = False
96 prefs
= get_addon_preferences()
97 name
= mod
.__name
__.split('.')[-1]
98 if hasattr(PIEToolsPreferences
, name
):
99 delattr(PIEToolsPreferences
, name
)
101 bpy
.utils
.unregister_class(PIEToolsPreferences
)
102 bpy
.utils
.register_class(PIEToolsPreferences
)
107 class PIEToolsPreferences(AddonPreferences
):
110 def draw(self
, context
):
113 for mod
in sub_modules
:
114 mod_name
= mod
.__name
__.split('.')[-1]
116 column
= layout
.column()
120 expand
= getattr(self
, 'show_expanded_' + mod_name
)
121 icon
= 'TRIA_DOWN' if expand
else 'TRIA_RIGHT'
125 sub
.context_pointer_set('addon_prefs', self
)
126 op
= sub
.operator('wm.context_toggle', text
='', icon
=icon
,
128 op
.data_path
= 'addon_prefs.show_expanded_' + mod_name
129 sub
.label(text
='{}: {}'.format(info
['category'], info
['name']))
131 sub
.alignment
= 'RIGHT'
132 if info
.get('warning'):
133 sub
.label(text
='', icon
='ERROR')
134 sub
.prop(self
, 'use_' + mod_name
, text
='')
138 if info
.get('description'):
139 split
= col
.row().split(factor
=0.15)
140 split
.label(text
='Description:')
141 split
.label(text
=info
['description'])
142 if info
.get('location'):
143 split
= col
.row().split(factor
=0.15)
144 split
.label(text
='Location:')
145 split
.label(text
=info
['location'])
147 if info.get('author'):
148 split = col.row().split(factor=0.15)
149 split.label(text='Author:')
150 split.label(text=info['author'])
152 if info
.get('version'):
153 split
= col
.row().split(factor
=0.15)
154 split
.label(text
='Version:')
155 split
.label(text
='.'.join(str(x
) for x
in info
['version']),
157 if info
.get('warning'):
158 split
= col
.row().split(factor
=0.15)
159 split
.label(text
='Warning:')
160 split
.label(text
=' ' + info
['warning'], icon
='ERROR')
162 tot_row
= int(bool(info
.get('doc_url')))
164 split
= col
.row().split(factor
=0.15)
165 split
.label(text
='Internet:')
166 if info
.get('doc_url'):
167 op
= split
.operator('wm.url_open',
168 text
='Documentation', icon
='HELP')
169 op
.url
= info
.get('doc_url')
170 for i
in range(4 - tot_row
):
173 # Details and settings
174 if getattr(self
, 'use_' + mod_name
):
175 prefs
= get_addon_preferences(mod_name
)
177 if prefs
and hasattr(prefs
, 'draw'):
184 traceback
.print_exc()
185 box
.label(text
='Error (see console)', icon
='ERROR')
189 row
.label(text
="End of Pie Menu Activations", icon
="FILE_PARENT")
192 for mod
in sub_modules
:
194 mod_name
= mod
.__name
__.split('.')[-1]
197 def update(self
, context
):
198 enabled
= getattr(self
, 'use_' + mod
.__name
__.split('.')[-1])
200 register_submodule(mod
)
202 unregister_submodule(mod
)
203 mod
.__addon
_enabled
__ = enabled
211 description
=info
.get('description', ''),
212 update
=gen_update(mod
),
218 'show_expanded_' + mod_name
,
229 bpy
.utils
.register_class(cls
)
231 prefs
= get_addon_preferences()
232 for mod
in sub_modules
:
233 if not hasattr(mod
, '__addon_enabled__'):
234 mod
.__addon
_enabled
__ = False
235 name
= mod
.__name
__.split('.')[-1]
236 if getattr(prefs
, 'use_' + name
):
237 register_submodule(mod
)
241 for mod
in sub_modules
:
242 if mod
.__addon
_enabled
__:
243 unregister_submodule(mod
)
245 for cls
in reversed(classes
):
246 bpy
.utils
.unregister_class(cls
)
249 if __name__
== "__main__":