from .utils import * from bpy.props import * from bpy.types import Panel,Operator from .properties import CustomShelfSettings,CustomShelfPrefs from .Types import * SHELF_DIR = join(dirname(__file__),'shelves') def operator(idname,args) : op_execute = args['execute'] def execute(self, context): op_execute(context,self) return {"FINISHED"} package = __package__.replace('_','').replace('-','').lower() args['bl_idname'] = "%s.%s"%(package,idname) args['bl_label'] = title(idname) args['execute'] = execute op = type('operator',(Operator,),args) bpy.utils.register_class(op) return op def register_bl_class(bl_class,args) : a = type('test',(bl_class,),{}) a.initialyse(a,*args) bpy.utils.register_class(a) return a def filter_dir(dir_list) : return [d for d in dir_list if d.is_dir() and not d.name.startswith('_')] def get_shelves_folder(): prefs = bpy.context.preferences.addons[__package__].preferences shelves_path = prefs.global_shelves additionnal_shelves_path = [s.path for s in prefs.additionnal_shelves] return [p for p in additionnal_shelves_path+[shelves_path] if exists(p)] def get_dirs(paths) : if isinstance(paths,(tuple,list)) : dirs = [] for dir in paths: if not isinstance(dir, str) : dir = dir.path dirs += filter_dir(scandir(dir)) return dirs else : return filter_dir(scandir(paths)) def get_categories(): return [d.name for d in get_dirs(get_shelves_folder())] def get_tabs() : return [d.name for d in get_dirs(get_dirs(get_shelves_folder()))] def get_category_path(category) : category_dir = [f for f in get_shelves_folder() if category in [d.name for d in get_dirs(f)]] if category_dir : return join(category_dir[0],category) def get_category_tabs(category): return [d.name for d in get_dirs(get_category_path(category))] def read_shelves() : tag_filter_items = [] # unregister panel : for panel in CustomShelfSettings.panel_list: print(panel) if panel.__name__ not in get_tabs(): try : bpy.utils.unregister_class(panel) except Exception: pass CustomShelfSettings.panel_list.remove(panel) for cat in get_dirs(get_shelves_folder()) : cat_name = cat.name.replace('_',' ').title() header_info = { "bl_region_type" : "UI",#petit ajout pour voir si foncitonne... "bl_category" : cat_name, "bl_idname" : "%s_PT_%s_header"%(__package__.upper(),cat.name),# -> "%s.%s_header" makes _PT_ warning "cat" : cat.name, "path" : cat.path } header = type("Header",(CSHELF_PT_shelf_header,),header_info) bpy.utils.register_class(header) #enable bool prefs # panel_props = {t.name : BoolProperty(default = False) for t in get_dirs(cat.path)}# give "should be an annotation" field warning ## need annoattion type : https://blender.stackexchange.com/questions/118118/blender-2-8-field-property-declaration-and-dynamic-class-creation panel_props = {'__annotations__': {t.name : BoolProperty(default = False) for t in get_dirs(cat.path)}} PanelProps = type("CustomShelfPrefs",(PropertyGroup,),panel_props) bpy.utils.register_class(PanelProps) setattr(CustomShelfPrefs, cat.name, PointerProperty(type=PanelProps)) #search and filter props = { "search" : StringProperty(options = {"TEXTEDIT_UPDATE"}), "filter" : BoolProperty(default = True) } # Props = type("props",(PropertyGroup,), props)# annotation error Props = type("props",(PropertyGroup,),{'__annotations__': props}) bpy.utils.register_class(Props) setattr(CustomShelfSettings,cat.name,PointerProperty(type = Props)) #enable bool prefs #Prefs = type("CustomShelfPrefs",(PropertyGroup,),{}) #bpy.utils.register_class(Prefs) #setattr(CustomShelfPrefs,cat.name,PointerProperty(type = Prefs)) for tab in get_dirs(cat.path) : #get_settings settings_json = join(tab.path,'settings.json') tab_settings = {} if exists(settings_json) : tab_settings = read_json(settings_json) if not tab_settings or not tab_settings.get('tags') : continue for tag in tab_settings['tags'] : if tag not in tag_filter_items : tag_filter_items.append(tag) panel_info = { "bl_region_type" : "UI",#Added, maybe need it in 2.8+... "bl_category" : cat_name, "bl_idname" : "%s_PT_%s_%s"%(__package__.upper(),cat.name,tab.name),#"%s.%s_%s" -> makes _PT_ warning "bl_label" : tab.name.replace('_',' ').title(), "cat" : cat.name, "settings" :tab_settings } space_info = {k:v for k,v in tab_settings.items() if k in ("bl_space_type","bl_region_type")} panel_info.update(space_info) panel = type("Panel",(CSHELF_PT_shelf_panel,),panel_info) bpy.utils.register_class(panel) CustomShelfSettings.panel_list.append(panel) scripts = [] for script in scandir(tab.path) : if not script.name.endswith('.py'): continue print(script.path) script_name = splitext(script.name)[0] info,lines = read_info(script.path) info["description"] = info.get('description',"") icon = info.get('icon', "WORDWRAP_OFF") popup = type(script_name, (CSHELF_OT_shelf_popup,), {"script": script.path, 'bl_description': info["description"] }) popup.initialyse(popup, script_name, info) bpy.utils.register_class(popup) scripts.append({"operator" : popup.bl_idname,"text" : script_name,"icon" : icon}) panel.scripts = sorted(scripts,key = lambda x :x['text']) #Register tag filter enum #setattr(Pre, v) prefs = bpy.context.preferences.addons[__package__].preferences tag_filter_items.sort() tag_filter_items.insert(0, '__clear__') prefs['tag_filter_items'] = tag_filter_items #bpy.utils.unregister_class(CustomShelfPrefs) #bpy.utils.register_class(CustomShelfPrefs) #CustomShelfSettings.folders = list(get_shelves_folder().keys()) #folder_enum = EnumProperty(items = lambda s,c : [(f,f,"") for f in CustomShelfSettings.folders]) #setattr(CustomShelfSettings,'folders_enum',folder_enum)