Skip to content

Instantly share code, notes, and snippets.

@batFINGER
Last active July 6, 2019 15:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save batFINGER/4eee7c1a03746c65f2611c70a9f2e2ba to your computer and use it in GitHub Desktop.
Save batFINGER/4eee7c1a03746c65f2611c70a9f2e2ba to your computer and use it in GitHub Desktop.
"addon submodules"
bl_info = {
"name": "Example Addon Preferences",
"author": "Your Name Here",
"version": (1, 0),
"blender": (2, 65, 0),
"location": "SpaceBar Search -> Addon Preferences Example",
"description": "Example Addon",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Object"}
sub_modules_names = (
"submod1",
"submod2",
"submod3",
)
sub_modules = {submod:__import__(__package__ + "." + submod, {}, {}, submod) for submod in sub_modules_names}
#sub_modules.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name']))
def _get_pref_class(mod):
import inspect
for obj in vars(mod).values():
if inspect.isclass(obj) and issubclass(obj, AddonPreferences):
if hasattr(obj, 'bl_idname'):# and obj.bl_idname == mod.__name__:
return obj
return None
import bpy
from bpy.types import Operator, AddonPreferences
from bpy.props import StringProperty, IntProperty, BoolProperty
class OBJECT_OT_addon_prefs_example(Operator):
"""Display example preferences"""
bl_idname = "object.addon_prefs_example"
bl_label = "Addon Preferences Example"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
user_preferences = context.user_preferences
addon_prefs = user_preferences.addons[__name__].preferences
info = ("Path: %s, Number: %d, Boolean %r" %
(addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean))
self.report({'INFO'}, info)
print(info)
return {'FINISHED'}
from bpy.types import PropertyGroup
from bpy.props import PointerProperty
'''
submods = {"submod1": ExampleAddonPreferences,
"submod2": ExampleAddonPreferences2}
'''
def draw_info(module, mod, layout, info, context):
colsub = layout # TODO FIX
if mod.expand:
if info["description"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Description:")
split.label(text=info["description"])
if info["location"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Location:")
split.label(text=info["location"])
if module:
split = colsub.row().split(percentage=0.15)
split.label(text="File:")
split.label(text=module.__file__, translate=False)
if info["author"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Author:")
split.label(text=info["author"], translate=False)
if info["version"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Version:")
split.label(text='.'.join(str(x) for x in info["version"]), translate=False)
if info["warning"]:
split = colsub.row().split(percentage=0.15)
split.label(text="Warning:")
split.label(text=' ' + info["warning"], icon='ERROR')
tot_row = bool(info["wiki_url"]) # + bool(user_addon)
if tot_row:
split = colsub.row().split(percentage=0.15)
split.label(text="Internet:")
if info["wiki_url"]:
split.operator("wm.url_open", text="Documentation", icon='HELP').url = info["wiki_url"]
split.operator("wm.url_open", text="Report a Bug", icon='URL').url = info.get(
"tracker_url",
"https://developer.blender.org/maniphest/task/edit/form/2")
def draw(self, context):
layout = self.layout
for k, module in sub_modules.items():
info = getattr(module, "bl_info", {})
mod = getattr(self, k)
box = layout.box()
row = box.row(align=True)
row.prop(mod, "expand", icon='TRIA_DOWN' if mod.expand else 'TRIA_RIGHT', icon_only=True, emboss=False)
row.prop(mod, "enable", icon='CHECKBOX_HLT' if mod.enable else 'CHECKBOX_DEHLT', icon_only=True, emboss=False)
sub = row.row()
sub.enabled = mod.enable
sub.label(info["description"])
if mod.expand:
col = box.column()
draw_info(module, mod, col, info, context)
if mod.enable and mod.expand and mod.has_prefs:
box.label("Preferences:")
modbox = box.box()
mod.layout = modbox
mod.draw(context)
subaddonprefs = {
"bl_idname": "test_module",
"draw": draw,
}
def register_submodule(submod):
mod = sub_modules.get(submod)
def register(self, context):
if mod is None:
return None
if self.enable:
sub_modules[submod].register()
print("%s.register()" % submod)
else:
print("%s.unregister()" % submod)
sub_modules[submod].unregister()
return None
return register
classes = []
def create_addon_prefs():
for submod, mod in sub_modules.items():
prefsclass = _get_pref_class(mod)
print("XXX", prefsclass)
#print("PREFCLASS", prefsclass)
props = {}
props["enable"] = BoolProperty(update=register_submodule(submod), default=True)
props["expand"] = BoolProperty(update=register_submodule(submod), default=False)
props["has_prefs"] = prefsclass is not None
if prefsclass:
props.update({k:v for k,v in vars(prefsclass).items() if not k.startswith("__")})
#props = {"xx": IntProperty()}
# enable disable
preferences = type("%sPreferences" % submod, (PropertyGroup,), props)
#classes.append(preferences)
bpy.utils.register_class(preferences)
classes.append(preferences)
subaddonprefs[submod] = PointerProperty(type=preferences)
# ok an addon prefs made up of all the classes.
return type("AddonPrefs", (AddonPreferences,), subaddonprefs)
# Registration
from bpy.app.handlers import persistent
@persistent
def handle_registration(dummy):
print("Register the submodules based on prefs")
if dummy:
#enable disable addons from prefs
addon = bpy.context.user_preferences.addons.get(__name__)
print(addon)
if addon is None:
bpy.app.handlers.scene_update_post.remove(handle_registration)
return None
prefs = addon.preferences
for submod, module in sub_modules.items():
print(prefs)
mod = getattr(prefs, submod, None)
if not mod:
continue
if getattr(mod, "enable", False) and hasattr(module, "register"):
try:
module.register()
print("%s.register()" % submod)
except RuntimeError:
print(RuntimeError)
return None
bpy.app.handlers.scene_update_post.remove(handle_registration)
return None
def register():
classes.clear()
print("REGISTER")
addonprefs = create_addon_prefs()
bpy.utils.register_class(OBJECT_OT_addon_prefs_example)
try:
bpy.utils.register_class(addonprefs)
except ValueError:
print(ValueError)
classes.extend([OBJECT_OT_addon_prefs_example, addonprefs])
print(classes)
bpy.app.handlers.scene_update_post.append(handle_registration)
#bpy.app.handlers.load_post.append(handle_registration)
def unregister():
print("UNREG CLASSES", classes)
for cls in classes:
print("UNREG", cls, hasattr(cls, "bl_rna"))
try:
bpy.utils.unregister_class(cls)
except RuntimeError:
print(RuntimeError)
for mod in sub_modules.values():
try:
mod.unregister()
except RuntimeError:
print(RuntimeError)
#bpy.app.handlers.load_post.remove(handle_registration)
bl_info = {
"name": "Snap Menu: Key: 'Ctrl Shift Tab'",
"description": "Snap Modes",
"author": "Antony Riakiotakis, Sebastian Koenig",
"version": (0, 1, 0),
"blender": (2, 77, 0),
"location": "Ctrl Shift Tab",
"warning": "",
"wiki_url": "",
"category": "3d View"
}
import bpy
from bpy.types import (
Menu,
Operator,
AddonPreferences
)
from bpy.props import * #lazy hack
class ExampleAddonPreferences2(AddonPreferences):
bl_idname = __name__
filepath = StringProperty(
name="Example File Path",
subtype='FILE_PATH',
)
number = IntProperty(
name="Example Number",
default=4,
)
boolean = BoolProperty(
name="Example Boolean",
default=False,
)
def draw(self, context):
layout = self.layout
layout.label(text="This is a preferences view for our addon again")
layout.prop(self, "filepath")
layout.prop(self, "number")
layout.prop(self, "boolean")
# Pie Snap Mode - . key
class VIEW3D_PIE_snap_of(Menu):
bl_label = "Snapping"
bl_idname = "view3d.snap_of"
def draw(self, context):
layout = self.layout
toolsettings = context.tool_settings
pie = layout.menu_pie()
pie.prop(toolsettings, "snap_element", expand=True)
pie.prop(toolsettings, "use_snap")
classes = [
VIEW3D_PIE_snap_of
]
addon_keymaps = []
def register():
for cls in classes:
bpy.utils.register_class(cls)
wm = bpy.context.window_manager
if wm.keyconfigs.addon:
# Align
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True, shift=True)
kmi.properties.name = "view3d.snap_of"
addon_keymaps.append((km, kmi))
def unregister():
for cls in classes:
print(cls)
bpy.utils.unregister_class(cls)
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
km = kc.keymaps['Object Non-modal']
for kmi in km.keymap_items:
if kmi.idname == 'wm.call_menu_pie':
if kmi.properties.name == "view3d.snap_of":
km.keymap_items.remove(kmi)
if __name__ == "__main__":
register()
bl_info = {
"name": "Shade Menu: Key: 'Z key'",
"description": "View Modes",
"author": "Antony Riakiotakis, Sebastian Koenig",
"version": (0, 1, 0),
"blender": (2, 77, 0),
"location": "Z key",
"warning": "",
"wiki_url": "",
"category": "3d View"
}
import bpy
from bpy.types import (
Menu,
Operator,
AddonPreferences
)
from bpy.props import * #lazy hack
class ExampleAddonPreferences(AddonPreferences):
bl_idname = __name__
filepath = StringProperty(
name="Example File Path",
subtype='FILE_PATH',
)
number = IntProperty(
name="Example Number",
default=4,
)
boolean = BoolProperty(
name="Example Boolean",
default=False,
)
def draw(self, context):
layout = self.layout
layout.label(text="This is a preferences view for our addon")
layout.prop(self, "filepath")
layout.prop(self, "number")
layout.prop(self, "boolean")
# Pie Shade Mode - Z
class VIEW3D_PIE_shade_of(Menu):
bl_label = "Shade"
bl_idname = "pie.shade_of"
def draw(self, context):
layout = self.layout
pie = layout.menu_pie()
pie.prop(context.space_data, "viewport_shade", expand=True)
if context.active_object:
if(context.mode == 'EDIT_MESH'):
pie.operator("MESH_OT_faces_shade_smooth")
pie.operator("MESH_OT_faces_shade_flat")
else:
pie.operator("OBJECT_OT_shade_smooth")
pie.operator("OBJECT_OT_shade_flat")
classes = [
VIEW3D_PIE_shade_of,
]
addon_keymaps = []
def register():
for cls in classes:
bpy.utils.register_class(cls)
wm = bpy.context.window_manager
if wm.keyconfigs.addon:
# Align
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS')
kmi.properties.name = "pie.shade_of"
addon_keymaps.append((km, kmi))
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
km = kc.keymaps['Object Non-modal']
for kmi in km.keymap_items:
if kmi.idname == 'wm.call_menu_pie':
if kmi.properties.name == "pie.shade_of":
km.keymap_items.remove(kmi)
if __name__ == "__main__":
register()
@batFINGER
Copy link
Author

addon
Screen shot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment