import inspect import os import bpy from bpy.types import (AddonPreferences, PropertyGroup) from bpy.props import (BoolProperty, StringProperty, CollectionProperty, EnumProperty, IntProperty, PointerProperty) from .constants import PLUGINS, PLUGINS_DIR, PLUGINS_ITEMS from .core.file_utils import import_module_from_path, norm_str from .core.bl_utils import get_addon_prefs from .core.lib_utils import update_library_path def load_plugins(): from .plugins.library_plugin import LibraryPlugin print('Asset Library: Load Library Plugins') plugin_files = list(PLUGINS_DIR.glob('*.py')) # if self.plugin_directory: # user_plugin_DIR = Path(self.plugin_directory) # if user_plugin_DIR.exists(): # plugin_files += list(user_plugin_DIR.glob('*.py')) for plugin_file in plugin_files: if plugin_file.stem.startswith('_'): continue mod = import_module_from_path(plugin_file) for name, obj in inspect.getmembers(mod): if not inspect.isclass(obj) or (obj is LibraryPlugin): continue if (LibraryPlugin not in obj.__mro__) or (obj in PLUGINS): continue try: print(f'Register Plugin {name}') bpy.utils.register_class(obj) setattr(Plugins, norm_str(obj.name), PointerProperty(type=obj)) PLUGINS[obj.name] = obj except Exception as e: print(f'Could not register plugin {name}') print(e) plugins = sorted(PLUGINS.keys()) plugin_items = [('none', 'None', '', 0)] plugin_items += [(norm_str(p), p, "") for p in plugins] PLUGINS_ITEMS[:] = plugin_items return PLUGINS class Plugins(PropertyGroup): """Container holding the registed library plugins""" def __iter__(self): return (getattr(self, p) for p in self.bl_rna.properties.keys() if p not in ('rna_type', 'name')) class AssetLibrary(PropertyGroup): """Library item defining one library with his plugin and settings""" name : StringProperty(name='Name', default='', update=lambda s, c : update_library_path()) expand : BoolProperty(name='Expand', default=False) use : BoolProperty(name='Use', default=True, update=lambda s, c : update_library_path()) is_user : BoolProperty(default=True) path : StringProperty(subtype='DIR_PATH', update=lambda s, c : update_library_path()) plugins : PointerProperty(type=Plugins) plugin_name : EnumProperty(items=lambda s, c : PLUGINS_ITEMS) @property def plugin(self): return getattr(self.plugins, self.plugin_name, None) @property def index(self): prefs = get_addon_prefs() return list(prefs.libraries).index(self) """ def draw_operators(self, layout): row = layout.row(align=True) row.alignment = 'RIGHT' row.prop(self, 'plugin_name', text='') row.prop(self, 'auto_bundle', text='', icon='UV_SYNC_SELECT') row.operator("assetlibrary.diff", text='', icon='FILE_REFRESH').name = self.name op = row.operator("assetlibrary.sync", icon='MOD_BUILD', text='') op.name = self.name layout.separator(factor=3) """ def set_dict(self, data, obj=None): """"Recursive method to set all attribute from a dict to this instance""" if obj is None: obj = self # Make shure the input dict is not modidied data = data.copy() for key, value in data.items(): if isinstance(value, dict): self.set_dict(value, obj=getattr(obj, key)) elif key in obj.bl_rna.properties.keys(): if isinstance(value, str): value = os.path.expandvars(value) value = os.path.expanduser(value) setattr(obj, key, value) else: print(f'Prop {key} of {obj} not exist') def draw(self, layout): prefs = get_addon_prefs() #col = layout.column(align=True) box = layout.box() row = box.row(align=True) icon = "DISCLOSURE_TRI_DOWN" if self.expand else "DISCLOSURE_TRI_RIGHT" row.prop(self, 'expand', icon=icon, emboss=False, text='') row.prop(self, 'use', text='') #row.label(icon="ASSET_MANAGER") row.prop(self, 'name', text='') row.separator(factor=0.5) sub = row.row() sub.alignment = 'RIGHT' sub.prop(self, 'plugin_name', text='') row.separator(factor=0.5) op = row.operator("assetlibrary.synchronize", icon='UV_SYNC_SELECT', text='') op.name = self.name row.separator(factor=0.5) row.operator("assetlibrary.remove_library", icon="REMOVE", text='', emboss=False).index = self.index #self.draw_operators(row) if self.expand: col = box.column(align=False) col.use_property_split = True col.prop(self, 'path', text='Path') if self.plugin: col.separator() self.plugin.draw_prefs(col) class WindowManagerProperties(PropertyGroup): """Library item defining one library with his plugin and settings""" asset : PointerProperty(type=bpy.types.ID) classes = ( Plugins, AssetLibrary, WindowManagerProperties ) def register(): for cls in classes: bpy.utils.register_class(cls) bpy.types.WindowManager.asset_library = PointerProperty(type=WindowManagerProperties) load_plugins() def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls) del bpy.types.WindowManager.asset_library