custom_shelf/operators.py
2025-12-01 17:26:08 +01:00

405 lines
11 KiB
Python

from .utils import *
from .functions import *
from bpy.types import AddonPreferences, Operator, PropertyGroup
from bpy.props import *
from bpy.props import CollectionProperty
from .properties import CustomShelfSettings
class CSHELF_OT_refresh(Operator):
bl_idname = "customshelf.refresh"
bl_label = "Refresh Shelves"
def execute(self, context):
read_shelves()
return {"FINISHED"}
def get_tag_items(self, context):
prefs = bpy.context.preferences.addons[__package__].preferences
return [(i, i.title(), "") for i in prefs["tag_filter_items"]]
class CSHELF_OT_set_tag_filter(Operator):
bl_idname = "customshelf.set_tag_filter"
bl_label = "Refresh Shelves"
tag_filter: EnumProperty(items=get_tag_items)
def execute(self, context):
prefs = bpy.context.preferences.addons[__package__].preferences
tag_filter = self.tag_filter
if tag_filter == "__clear__":
tag_filter = ""
prefs.tag_filter = tag_filter
return {"FINISHED"}
class CSHELF_OT_add_shelf_folder(Operator):
bl_idname = "customshelf.add_shelves_folder"
bl_label = "Refresh Shelves"
def execute(self, context):
prefs = bpy.context.preferences.addons[__package__].preferences
path = prefs.additionnal_shelves.add()
return {"FINISHED"}
class CSHELF_OT_remove_shelf_folder(Operator):
bl_idname = "customshelf.remove_shelves_folder"
bl_label = "Refresh Shelves"
index: IntProperty()
def execute(self, context):
prefs = bpy.context.preferences.addons[__package__].preferences
prefs.additionnal_shelves.remove(self.index)
return {"FINISHED"}
class CSHELF_OT_open_shelf_folder(Operator):
bl_idname = "customshelf.open_shelf_folder"
bl_label = "Run Function"
path: StringProperty()
def execute(self, context):
open_folder(self.path)
return {"FINISHED"}
class CSHELF_OT_add_script(Operator):
bl_idname = "customshelf.add_script"
bl_label = "Add script to a shelf"
add_category: BoolProperty()
add_tab: BoolProperty()
new_category: StringProperty()
new_tab: StringProperty()
name: StringProperty()
description: StringProperty()
icon: StringProperty()
show_icons: BoolProperty()
@classmethod
def poll(cls, context):
return context.area.type == "TEXT_EDITOR" and context.space_data.text
def add_folder(self, context, op):
folder = self.folder.add()
folder.name = self.name
# CustomShelfSettings
def remove_folder(self, context, op):
bl_props = context.scene.CustomShelf
index = self.folders.find(self.folders_enum)
self.folders.remove(index)
def get_all_icons(self):
ui_layout = bpy.types.UILayout
icons = ui_layout.bl_rna.functions["prop"].parameters["icon"].enum_items.keys()
prefixes = ("BRUSH_", "MATCAP_", "COLORSET_")
exception = "BRUSH_DATA"
return [i for i in icons if not i.startswith(prefixes) or i in exception]
def get_icons(self, context, op):
icons = [
[
"SCENE_DATA",
"RENDERLAYERS",
"MATERIAL_DATA",
"GROUP_UVS",
"TEXTURE",
"WORLD",
"SPEAKER",
"TEXT",
"NODETREE",
"NODE_INSERT_OFF",
"PARTICLES",
"SORTALPHA",
],
[
"MODIFIER",
"MOD_WAVE",
"MOD_SUBSURF",
"MOD_FLUIDSIM",
"MOD_OCEAN",
"BLANK1",
"ARMATURE_DATA",
"BONE_DATA",
"GROUP_BONE",
],
[
"SEQUENCE",
"CAMERA_DATA",
"SCENE",
"BLANK1",
"FILE_NEW",
"CONSOLE",
"BLENDER",
"APPEND_BLEND",
],
[
"GROUP",
"MESH_CUBE",
"MESH_PLANE",
"MESH_CIRCLE",
"MESH_UVSPHERE",
"MESH_GRID",
"EMPTY_DATA",
"OUTLINER_DATA_MESH",
"LIGHT_SUN",
"LIGHT_SPOT",
"LIGHT",
],
[
"TRIA_RIGHT_BAR",
"REC",
"PLAY",
"PREV_KEYFRAME",
"NEXT_KEYFRAME",
"PAUSE",
"X",
"ADD",
"REMOVE",
"RESTRICT_VIEW_OFF",
"RESTRICT_VIEW_ON",
"RESTRICT_SELECT_OFF",
],
[
"BRUSH_DATA",
"GREASEPENCIL",
"LINE_DATA",
"PARTICLEMODE",
"SCULPTMODE_HLT",
"WPAINT_HLT",
"TPAINT_HLT",
"VIEWZOOM",
"HAND",
"KEY_HLT",
"KEY_DEHLT",
],
[
"PLUGIN",
"SCRIPT",
"PREFERENCES",
"ACTION",
"SOLO_OFF",
"RNDCURVE",
"SNAP_ON",
"FORCE_WIND",
"COPY_ID",
"EYEDROPPER",
"AUTO",
"UNLOCKED",
"LOCKED",
"UNPINNED",
"PINNED",
"PLUGIN",
"HELP",
"GHOST_ENABLED",
"GHOST_DISABLED",
"COLOR",
"LINKED",
"UNLINKED",
"LINKED",
"ZOOM_ALL",
"FREEZE",
"STYLUS_PRESSURE",
"FILE_TICK",
"QUIT",
"RECOVER_LAST",
"TIME",
"PREVIEW_RANGE",
"OUTLINER",
"NLA",
"EDITMODE_HLT",
"BOIDS",
"RNA",
"CAMERA_STEREO",
],
]
self.icons = icons
def set_icon(self, context, op):
# bl_props = context.scene.CustomShelf
self.icon = op.icon
self.icons = []
def draw(self, context):
bl_props = context.scene.CustomShelf
layout = self.layout
row = layout.row()
row.operator("customshelf.get_icons", text="", icon=self.icon)
row.prop(self, "name", text="")
col = layout.column(align=True)
for icon_list in self.icons:
i = 0
for icon in icon_list:
if not i % 12:
row = col.row(align=True)
row.operator(
"customshelf.set_icon", icon=icon, emboss=False, text=""
).icon = icon
i += 1
row = col.row(align=True)
layout.prop(self, "description", text="")
layout.separator()
# Category Row
folder_row = layout.row(align=True)
folder_row.label(text="", icon="FILE_FOLDER")
folder_row.separator()
if not self.add_category:
folder_row.prop(bl_props, "category_enum", expand=True)
else:
folder_row.prop(self, "new_category", text="")
folder_row.prop(self, "add_category", icon="ADD", text="")
# Tabs row
tab_row = layout.row(align=True)
tab_row.label(text="", icon="MENU_PANEL")
tab_row.separator()
if not self.add_tab:
category_tabs = get_category_tabs(bl_props.category_enum)
for t in [t for t in category_tabs if t in self.tabs]:
tab_row.prop_enum(bl_props, "tab_enum", t)
else:
tab_row.prop(self, "new_tab", text="")
tab_row.prop(self, "add_tab", icon="ADD", text="")
# folder_row.operator("customshelf.remove_folder",icon = 'REMOVE',text='')
def write_script(self, f):
keys = ["icon", "description"]
keys += [k for k in self.info if k not in keys]
f.write("info = " + dic_to_str(self.info, keys))
print(self.lines)
f.write("\n".join(self.lines))
def execute(self, context):
preferences = context.preferences
bl_props = context.scene.CustomShelf
addon_prefs = preferences.addons[__package__].preferences
if self.new_category:
category_path = get_category_path(self.new_category)
if not exists(category_path):
mkdir(new_category)
else:
category_path = get_category_path(bl_props.category_enum)
if self.new_tab:
tab_path = join(category_path, self.new_tab)
if not exists(tab_path):
mkdir(tab_path)
else:
tab_path = join(category_path, bl_props.tab_enum)
script_name = self.name.replace(" ", "_").replace("-", "_")
script_path = join(tab_path, script_name + ".py")
if os.path.exists(script_path):
os.remove(script_path)
self.info["icon"] = self.icon
self.info["description"] = self.description
with open(script_path, "w") as f:
self.write_script(f)
line_index = self.active_text.current_line_index
bpy.data.texts.remove(self.active_text)
text = bpy.data.texts.load(script_path)
text.current_line_index = line_index
context.space_data.text = text
read_shelves()
return {"FINISHED"}
def check(self, context):
return True
def invoke(self, context, event):
bl_props = context.scene.CustomShelf
self.active_text = context.space_data.text
self.info, self.lines = read_info([l.body for l in self.active_text.lines])
icon = "LONGDISPLAY"
if self.info.get("icon"):
icon = self.info["icon"]
description = "Some description"
if self.info.get("description"):
description = self.info["description"]
self.icon = icon
self.name = splitext(self.active_text.name)[0]
self.show_icons = False
self.description = description
self.add_shelf = False
self.new_shelf = ""
self.icons = []
operator("get_icons", {"execute": self.get_icons})
operator(
"set_icon",
{"execute": self.set_icon, "__annotations__": {"icon": StringProperty()}},
)
operator("add_folder", {"execute": self.add_folder})
# operator("remove_folder",{'execute':self.remove_folder})
self.tabs = get_tabs()
self.categories = get_categories()
CustomShelfSettings.category_enum = EnumProperty(
items=[(i, i, "") for i in self.categories]
)
CustomShelfSettings.tab_enum = EnumProperty(
items=[(i, i, "") for i in self.tabs]
)
if self.active_text.filepath:
tab_path = dirname(self.active_text.filepath)
category = basename(dirname(tab_path))
tab = basename(tab_path)
if category in self.categories:
bl_props.category_enum = category
if tab in self.tabs:
bl_props.tab_enum = tab
return context.window_manager.invoke_props_dialog(self, width=500)
class TagFilterItem(PropertyGroup):
value: StringProperty(name="Tag")
class CustomShelfAddonPreferences(AddonPreferences):
bl_idname = __name__
tag_filter_items: CollectionProperty(type=TagFilterItem)