asset_library/properties.py

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