186 lines
5.7 KiB
Python
186 lines
5.7 KiB
Python
|
|
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 |