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)