From bec320f7077a5af6230c3df641ca97a5095fb79d Mon Sep 17 00:00:00 2001 From: doc-code Date: Tue, 3 Sep 2024 23:27:22 +0200 Subject: [PATCH] Update legacy to v.1.4.0 (and update splash screen to match Blender <=3.6 splash screen version) --- legacy/__init__.py | 15 ++++-- legacy/classes/draw.py | 9 +++- legacy/classes/ots.py | 99 +++++++++++++++++++++++++++++++--------- legacy/classes/splash.py | 32 ++++++------- 4 files changed, 109 insertions(+), 46 deletions(-) diff --git a/legacy/__init__.py b/legacy/__init__.py index deabd07..7925a08 100644 --- a/legacy/__init__.py +++ b/legacy/__init__.py @@ -14,21 +14,24 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import bpy -from .classes.draw import draw_file_new_templates, draw_file_default_operators +from .classes.draw import draw_file_new_templates, draw_file_default_operators, draw_ws_menu_add from .classes.splash import WM_MT_splash, CT_MT_splash_mode, CT_OT_splash_custom, CT_OT_splash_default -from .classes.ots import CustomTemplatesPreferences, TemplateItem, CT_OT_export_templates, CT_OT_import_templates, CT_MT_templates_menu, CT_OT_select_template_popup, CT_OT_add_template_popup, CT_OT_add, CT_OT_remove, CT_OT_move_down, CT_OT_move_up, CT_OT_open_preferences, CT_OT_add_templates_from_folder, CT_OT_clear +from .classes.ots import CustomTemplatesPreferences, TemplateItem, CT_OT_export_templates, CT_OT_import_templates, CT_MT_templates_menu, CT_OT_select_template_popup, CT_OT_add_template_popup, CT_OT_add, CT_OT_remove, CT_OT_move_down, CT_OT_move_up, CT_OT_open_preferences, CT_OT_add_templates_from_folder, CT_OT_clear, CT_MT_workspace_add, CT_OT_template_workspaces, CT_OT_add_workspace bl_info = { "id": "custom_templates", "name": "Custom Templates", "tagline": "Add your own .blend files as template options for new projects", - "blender": (2, 80, 0), + "blender": (2, 83, 0), "location": "File > New, File > Defaults, Splash Screen", "category": "System", "support": "COMMUNITY", } classes = [WM_MT_splash, + CT_OT_add_workspace, + CT_OT_template_workspaces, + CT_MT_workspace_add, TemplateItem, CT_OT_export_templates, CT_OT_import_templates, @@ -56,6 +59,7 @@ def register(): bpy.utils.register_class(c) bpy.types.TOPBAR_MT_file_new.append(draw_file_new_templates) bpy.types.TOPBAR_MT_file_defaults.append(draw_file_default_operators) + bpy.types.TOPBAR_MT_workspace_menu.append(draw_ws_menu_add) def unregister(): for c in reversed(classes): @@ -63,6 +67,7 @@ def unregister(): bpy.utils.register_class(og_splash) bpy.types.TOPBAR_MT_file_new.remove(draw_file_new_templates) bpy.types.TOPBAR_MT_file_defaults.remove(draw_file_default_operators) - + bpy.types.TOPBAR_MT_workspace_menu.remove(draw_ws_menu_add) + if __name__ == "__main__": - register() + registers() diff --git a/legacy/classes/draw.py b/legacy/classes/draw.py index 6092a60..4ed046d 100644 --- a/legacy/classes/draw.py +++ b/legacy/classes/draw.py @@ -4,7 +4,6 @@ import bpy def draw_file_new_templates(self, context): layout = self.layout - prefs = context.preferences.addons[base_package].preferences if len(prefs.projects) > 0: layout.separator() @@ -37,3 +36,11 @@ def draw_file_default_operators(self, context): if bpy.data.filepath != "": layout.operator("ct.add_template_popup", text="Use current file as template") + +def draw_ws_menu_add(self, context): + layout = self.layout + prefs = context.preferences.addons[base_package].preferences + if prefs.projects: + layout.separator() + layout.menu("CT_MT_workspace_add", text="Add from Custom Templates", icon="WORKSPACE") + \ No newline at end of file diff --git a/legacy/classes/ots.py b/legacy/classes/ots.py index 79d9669..2ef9dd8 100644 --- a/legacy/classes/ots.py +++ b/legacy/classes/ots.py @@ -2,7 +2,7 @@ from .. import __name__ as base_package import os import bpy import json -from bpy.types import Operator, PropertyGroup, AddonPreferences +from bpy.types import Operator, Menu, Header, PropertyGroup, AddonPreferences from bpy.props import StringProperty, CollectionProperty, IntProperty, BoolProperty def already_present(self, prefs, path, report=True): @@ -27,7 +27,7 @@ def on_path_update(self, context): if self.path and self.path.startswith('//'): self.path = bpy.path.abspath(self.path) context.preferences.is_dirty = True - + class TemplateItem(PropertyGroup): name: StringProperty( name="Name", description="Display name for this template") @@ -38,7 +38,7 @@ class CustomTemplatesPreferences(AddonPreferences): bl_idname = base_package override_splash: BoolProperty( - default=True, name="Override Splash Screen Templates", description="Override Splash Screen's 'New File' list with your Custom Templates") + default=True, name="Use Custom Templates", description="Override Splash Screen's 'New File' list with your Custom Templates") projects: CollectionProperty(type=TemplateItem) active_template_index: IntProperty( description="Index of the selected template") @@ -55,7 +55,8 @@ class CustomTemplatesPreferences(AddonPreferences): col = row.column(align=True) col.menu("CT_MT_templates_menu", icon='DOWNARROW_HLT', text="") col.separator() - col.operator("ct.add_templates_from_folder", text="", icon="FILE_FOLDER") + col.operator("ct.add_templates_from_folder", + text="", icon="FILE_FOLDER") col.operator("ct.add", icon='ADD', text="") col.operator("ct.remove", icon='REMOVE', text="") col.separator() @@ -66,35 +67,39 @@ class CustomTemplatesPreferences(AddonPreferences): project = self.projects[self.active_template_index] layout.prop(project, "path") layout.prop(project, "name") - - layout.prop(self, "override_splash") - box = layout.box() - if self.override_splash and len(self.projects) == 0: - box.label(text="There are currently no templates.") - elif self.override_splash: + + b = layout.box() + b.label(text="Splash Screen", icon="SETTINGS") + b.prop(self, "override_splash") + box = b.box() + if self.override_splash and self.projects: box.label(text="Custom templates will be shown in the Splash Screen.") - + if not self.override_splash or len(self.projects) == 0: box.label( - text="The default Blender list will be shown in the Splash Screen.") + text="The default Blender list will be shown in the Splash Screen.", icon=("ERROR" if not self.projects else "NONE")) if len(self.projects) > 5: box.label( text="Note: Only the first 5 templates in the list will be shown in the splash screen.") -class CT_MT_templates_menu(bpy.types.Menu): +class CT_MT_templates_menu(Menu): bl_label = "Manage your custom templates" bl_description = "Import, export, add from folder (with controllable recursion depth), clear current templates" def draw(self, context): layout = self.layout - layout.operator("ct.add_templates_from_folder", text="Add from folder", icon="ADD") - layout.operator("ct.clear", text="Clear current templates", icon="TRASH") + layout.operator("ct.add_templates_from_folder", + text="Add from folder", icon="ADD") + layout.operator( + "ct.clear", text="Clear current templates", icon="TRASH") layout.separator() - layout.operator("ct.import_templates", text="Import templates", icon="IMPORT") - layout.operator("ct.export_templates", text="Export templates", icon="EXPORT") + layout.operator("ct.import_templates", + text="Import templates", icon="IMPORT") + layout.operator("ct.export_templates", + text="Export templates", icon="EXPORT") -class CT_OT_export_templates(bpy.types.Operator): +class CT_OT_export_templates(Operator): bl_idname = "ct.export_templates" bl_label = "Export custom templates" bl_description = "Export the current list of templates to JSON file" @@ -120,7 +125,7 @@ class CT_OT_export_templates(bpy.types.Operator): def poll(cls, context): return len(context.preferences.addons[base_package].preferences.projects) > 0 -class CT_OT_import_templates(bpy.types.Operator): +class CT_OT_import_templates(Operator): bl_idname = "ct.import_templates" bl_label = "Import custom templates" bl_description = "Import a list of templates from JSON file (note that this will override the current templates list)" @@ -235,7 +240,7 @@ class CT_OT_clear(Operator): prefs.active_template_index = 0 context.preferences.is_dirty = True return {'FINISHED'} - + def invoke(self, context, event): return context.window_manager.invoke_props_dialog(self) @@ -273,7 +278,8 @@ class CT_OT_select_template_popup(Operator): bl_label = "Select a new custom template" bl_description = "Create a new template by selecting an existing .blend file" - path: StringProperty(name="Template Path", subtype="FILE_PATH", update=on_path_update) + path: StringProperty(name="Template Path", + subtype="FILE_PATH", update=on_path_update) name: StringProperty(name="Template Name") def execute(self, context): @@ -285,7 +291,7 @@ class CT_OT_select_template_popup(Operator): context.preferences.is_dirty = True self.name = '' self.path = '' - + return {'FINISHED'} def invoke(self, context, event): @@ -348,3 +354,52 @@ class CT_OT_open_preferences(Operator): context.preferences.active_section = 'ADDONS' context.window_manager.addon_search = "Custom Templates" return {'FINISHED'} + +class CT_OT_add_workspace(Operator): + bl_idname = "ct.add_workspace" + bl_label = "Add this workspace from your template" + bl_description = "Add to the current project, the selected workspace from your Custom Template" + + workspace: StringProperty(name="workspace") + path: StringProperty(name="path") + + def execute(self, context): + bpy.ops.workspace.append_activate(idname=self.workspace, filepath=self.path) + return {'FINISHED'} + +class CT_OT_template_workspaces(Operator): + bl_idname = "ct.template_workspaces" + bl_label = "Add workspace from this template" + bl_description = "Click to select one of the workspaces from this Custom Template" + + index: IntProperty(name='index', default=0) + + def draw_ws(self, s, context): + layout = s.layout + template = context.preferences.addons[base_package].preferences.projects[self.index] + with bpy.data.libraries.load(template.path) as (data, _): + for w in data.workspaces: + op = layout.operator("ct.add_workspace", text=w) + op.workspace = w + op.path = template.path + + def execute(self, context): + return {'RUNNING_MODAL'} + + def invoke(self, context, event): + wm = context.window_manager + template = context.preferences.addons[base_package].preferences.projects[self.index] + wm.popup_menu(self.draw_ws, title=f"Workspaces from '{template.name}'", icon="ADD") + return {'RUNNING_MODAL'} + +class CT_MT_workspace_add(Menu): + bl_label = "Add workspace from Custom Templates" + + def draw(self, context): + layout = self.layout + templates = context.preferences.addons[base_package].preferences.projects + layout.label(text="Add workspace from Custom Templates", icon="ADD") + layout.separator() + for i in range(len(templates)): + t = templates[i] + layout.operator("CT_OT_template_workspaces", text=t.name).index = i diff --git a/legacy/classes/splash.py b/legacy/classes/splash.py index 821d7ab..22f7b5d 100644 --- a/legacy/classes/splash.py +++ b/legacy/classes/splash.py @@ -8,30 +8,31 @@ import bpy # to switch between blender's original templates and Custom Templates. # If you have no custom templates, the default templates are displayed class WM_MT_splash(bpy.types.Menu): - bl_label="Splash" - + bl_label = "Splash" + def draw(self, context): layout = self.layout prefs = context.preferences.addons[base_package].preferences layout.operator_context = 'EXEC_DEFAULT' layout.emboss = 'PULLDOWN_MENU' + split = layout.split() # Templates - col1 = split.column() - ct_split = col1.split(factor=0.9) + colx = split.column() + ct_split = colx.split(factor=0.9) colA = ct_split.column() if prefs.override_splash and len(prefs.projects) > 0: colA.label(text="Custom Templates") - col1.operator_context = 'INVOKE_DEFAULT' - draw_templates(col1, context, True) + colx.operator_context = 'INVOKE_DEFAULT' + draw_templates(colx, context, True) else: colA.label(text="New File") # Call original code - bpy.types.TOPBAR_MT_file_new.draw_ex(col1, context, use_splash=True) + bpy.types.TOPBAR_MT_file_new.draw_ex(colx, context, use_splash=True) colB = ct_split.column() colB.menu("CT_MT_splash_mode", icon='DOWNARROW_HLT', text="") - + # Recent col2 = split.column() col2_title = col2.row() @@ -41,14 +42,13 @@ class WM_MT_splash(bpy.types.Menu): if found_recent: col2_title.label(text="Recent Files") else: - # Links if no recent files. + + # Links if no recent files col2_title.label(text="Getting Started") col2.operator("wm.url_open_preset", text="Manual", icon='URL').type = 'MANUAL' - col2.operator("wm.url_open", text="Tutorials", icon='URL').url = "https://www.blender.org/tutorials/" - col2.operator("wm.url_open", text="Support", icon='URL').url = "https://www.blender.org/support/" - col2.operator("wm.url_open", text="User Communities", icon='URL').url = "https://www.blender.org/community/" col2.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER' + col2.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS' layout.separator() @@ -62,14 +62,10 @@ class WM_MT_splash(bpy.types.Menu): col2 = split.column() - col2.operator("wm.url_open_preset", text="Donate", icon='FUND').type = 'FUND' - col2.operator("wm.url_open_preset", text="What's New", icon='URL').type = 'RELEASE_NOTES' + col2.operator("wm.url_open_preset", text="Release Notes", icon='URL').type = 'RELEASE_NOTES' + col2.operator("wm.url_open_preset", text="Development Fund", icon='FUND').type = 'FUND' layout.separator() - - if (not bpy.app.online_access) and bpy.app.online_access_override: - self.layout.label(text="Running in Offline Mode", icon='INTERNET_OFFLINE') - layout.separator() class CT_MT_splash_mode(bpy.types.Menu):