1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # Contributed to by meta-androcto, pitiwazou, chromoly, italic, kc98
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)
81 def create_property(cls
, name
, prop
):
82 if not hasattr(cls
, '__annotations__'):
83 cls
.__annotations
__ = dict()
84 cls
.__annotations
__[name
] = prop
87 def register_submodule(mod
):
89 mod
.__addon
_enabled
__ = True
92 def unregister_submodule(mod
):
93 if mod
.__addon
_enabled
__:
95 mod
.__addon
_enabled
__ = False
97 prefs
= get_addon_preferences()
98 name
= mod
.__name
__.split('.')[-1]
99 if hasattr(PIEToolsPreferences
, name
):
100 delattr(PIEToolsPreferences
, name
)
102 bpy
.utils
.unregister_class(PIEToolsPreferences
)
103 bpy
.utils
.register_class(PIEToolsPreferences
)
108 class PIEToolsPreferences(AddonPreferences
):
111 def draw(self
, context
):
114 for mod
in sub_modules
:
115 mod_name
= mod
.__name
__.split('.')[-1]
117 column
= layout
.column()
121 expand
= getattr(self
, 'show_expanded_' + mod_name
)
122 icon
= 'TRIA_DOWN' if expand
else 'TRIA_RIGHT'
126 sub
.context_pointer_set('addon_prefs', self
)
127 op
= sub
.operator('wm.context_toggle', text
='', icon
=icon
,
129 op
.data_path
= 'addon_prefs.show_expanded_' + mod_name
130 sub
.label(text
='{}: {}'.format(info
['category'], info
['name']))
132 sub
.alignment
= 'RIGHT'
133 if info
.get('warning'):
134 sub
.label(text
='', icon
='ERROR')
135 sub
.prop(self
, 'use_' + mod_name
, text
='')
139 if info
.get('description'):
140 split
= col
.row().split(factor
=0.15)
141 split
.label(text
='Description:')
142 split
.label(text
=info
['description'])
143 if info
.get('location'):
144 split
= col
.row().split(factor
=0.15)
145 split
.label(text
='Location:')
146 split
.label(text
=info
['location'])
148 if info.get('author'):
149 split = col.row().split(factor=0.15)
150 split.label(text='Author:')
151 split.label(text=info['author'])
153 if info
.get('version'):
154 split
= col
.row().split(factor
=0.15)
155 split
.label(text
='Version:')
156 split
.label(text
='.'.join(str(x
) for x
in info
['version']),
158 if info
.get('warning'):
159 split
= col
.row().split(factor
=0.15)
160 split
.label(text
='Warning:')
161 split
.label(text
=' ' + info
['warning'], icon
='ERROR')
163 tot_row
= int(bool(info
.get('doc_url')))
165 split
= col
.row().split(factor
=0.15)
166 split
.label(text
='Internet:')
167 if info
.get('doc_url'):
168 op
= split
.operator('wm.url_open',
169 text
='Documentation', icon
='HELP')
170 op
.url
= info
.get('doc_url')
171 for i
in range(4 - tot_row
):
174 # Details and settings
175 if getattr(self
, 'use_' + mod_name
):
176 prefs
= get_addon_preferences(mod_name
)
178 if prefs
and hasattr(prefs
, 'draw'):
185 traceback
.print_exc()
186 box
.label(text
='Error (see console)', icon
='ERROR')
190 row
.label(text
="End of Pie Menu Activations", icon
="FILE_PARENT")
193 for mod
in sub_modules
:
195 mod_name
= mod
.__name
__.split('.')[-1]
198 def update(self
, context
):
199 enabled
= getattr(self
, 'use_' + mod
.__name
__.split('.')[-1])
201 register_submodule(mod
)
203 unregister_submodule(mod
)
204 mod
.__addon
_enabled
__ = enabled
212 description
=info
.get('description', ''),
213 update
=gen_update(mod
),
219 'show_expanded_' + mod_name
,
230 bpy
.utils
.register_class(cls
)
232 prefs
= get_addon_preferences()
233 for mod
in sub_modules
:
234 if not hasattr(mod
, '__addon_enabled__'):
235 mod
.__addon
_enabled
__ = False
236 name
= mod
.__name
__.split('.')[-1]
237 if getattr(prefs
, 'use_' + name
):
238 register_submodule(mod
)
242 for mod
in sub_modules
:
243 if mod
.__addon
_enabled
__:
244 unregister_submodule(mod
)
246 for cls
in reversed(classes
):
247 bpy
.utils
.unregister_class(cls
)
250 if __name__
== "__main__":