226 lines
7.1 KiB
Python
226 lines
7.1 KiB
Python
from os import scandir
|
|
from posixpath import splitext
|
|
from .utils import *
|
|
from bpy.props import *
|
|
from bpy.types import Panel, Operator
|
|
from .properties import CustomShelfSettings, CustomShelfPrefs
|
|
from .Types import *
|
|
from os.path import join, dirname, exists
|
|
|
|
|
|
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)
|