custom_shelf/functions.py

198 lines
6.7 KiB
Python
Raw Permalink Normal View History

2022-03-04 12:28:53 +01:00
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 :
2024-10-03 12:07:33 +02:00
for panel in CustomShelfSettings.panel_list:
print(panel)
if panel.__name__ not in get_tabs():
2022-03-04 12:28:53 +01:00
try :
2024-10-03 12:07:33 +02:00
bpy.utils.unregister_class(panel)
except Exception:
2022-03-04 12:28:53 +01:00
pass
2024-10-03 12:07:33 +02:00
CustomShelfSettings.panel_list.remove(panel)
2022-03-04 12:28:53 +01:00
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)
2024-10-03 12:07:33 +02:00
setattr(CustomShelfPrefs, cat.name, PointerProperty(type=PanelProps))
2022-03-04 12:28:53 +01:00
#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) :
2024-10-03 12:07:33 +02:00
if not script.name.endswith('.py'):
continue
print(script.path)
2022-03-04 12:28:53 +01:00
script_name = splitext(script.name)[0]
info,lines = read_info(script.path)
info["description"] = info.get('description',"")
2024-10-03 12:07:33 +02:00
icon = info.get('icon', "WORDWRAP_OFF")
2022-03-04 12:28:53 +01:00
2024-10-03 12:07:33 +02:00
popup = type(script_name, (CSHELF_OT_shelf_popup,),
{"script": script.path,
'bl_description': info["description"]
})
popup.initialyse(popup, script_name, info)
2022-03-04 12:28:53 +01:00
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)