[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1757] contrib/py/scripts/addons/ system_theme_manager.py: Version 1.1.0
Bart Crouch
bartius.crouch at gmail.com
Wed Mar 30 19:52:19 CEST 2011
Revision: 1757
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=1757
Author: crouch
Date: 2011-03-30 17:52:19 +0000 (Wed, 30 Mar 2011)
Log Message:
-----------
Version 1.1.0
Added menu to select theme from within Blender (uses theme presets folder)
Modified Paths:
--------------
contrib/py/scripts/addons/system_theme_manager.py
Modified: contrib/py/scripts/addons/system_theme_manager.py
===================================================================
--- contrib/py/scripts/addons/system_theme_manager.py 2011-03-30 06:04:20 UTC (rev 1756)
+++ contrib/py/scripts/addons/system_theme_manager.py 2011-03-30 17:52:19 UTC (rev 1757)
@@ -22,9 +22,9 @@
bl_info = {
'name': "Theme manager",
'author': "Bart Crouch",
- 'version': (1, 0, 0),
+ 'version': (1, 1, 0),
'blender': (2, 5, 7),
- 'api': 35842,
+ 'api': 35850,
'location': "User Preferences > Themes > Header",
'warning': "",
'description': "Load or save a custom theme",
@@ -35,22 +35,93 @@
'category': 'System'}
+import blf
import bpy
import gzip
from io_utils import ExportHelper, ImportHelper
+import os
import pickle
+import shutil
-# load operator
-class LoadTheme(bpy.types.Operator, ImportHelper):
- bl_idname = "ui.load_theme"
- bl_label = "Load Theme"
- bl_description = "Load a theme from file"
+def get_paths():
+ # locate theme preset folder
+ paths = bpy.utils.preset_paths("theme")
+ if not paths:
+ # theme preset folder doesn't exist, so create it
+ paths = [os.path.join(bpy.utils.user_resource('SCRIPTS'), "presets",
+ "theme")]
+ if not os.path.exists(paths[0]):
+ os.makedirs(paths[0])
- filename_ext = ".blt"
- filter_glob = bpy.props.StringProperty(default="*.blt", options={'HIDDEN'})
+ return(paths)
+
+
+def load_presets():
+ # find theme files
+ paths = get_paths()
+ theme_files = []
+ for path in paths:
+ for root, dirs, files in os.walk(path):
+ for file in files:
+ if file.endswith(".blt"):
+ theme_files.append(os.path.join(root, file))
+ # read author and theme names
+ theme_list = []
+ for filename in theme_files:
+ # load file
+ try:
+ file = gzip.open(filename, mode='r')
+ dump = pickle.load(file)
+ file.close()
+ author = dump["info"]["author"]
+ theme_name = dump["info"]["theme_name"]
+ sort_name = theme_name.lower()
+ theme_list.append([sort_name, theme_name, author, filename])
+ except:
+ continue
+ theme_list.sort()
+
+ # find popup width
+ sizes = [blf.dimensions(0, theme + " by " + author)[0] + 25 for \
+ i, theme, author, path in theme_list]
+ sizes.append(blf.dimensions(0, "Install new theme")[0])
+ popup_max = 250
+ if len(sizes) > 1:
+ sizes.sort()
+ max_size = sizes[-1] + 10
+ else:
+ max_size = blf.dimensions(0, "No theme presets found")[0] + 10
+ width = min(popup_max, max_size)
+
+ # store settings in window-manager
+ bpy.context.window_manager["theme_list"] = theme_list
+ bpy.context.window_manager["theme_width"] = width
+
+
+def unload_presets():
+ # remove settings from window-manager
+ del bpy.context.window_manager["theme_list"]
+ del bpy.context.window_manager["theme_width"]
+
+
+# install operator
+class ApplyTheme(bpy.types.Operator):
+ bl_idname = "ui.apply_theme"
+ bl_label = "Apply Theme"
+ bl_description = "Apply this theme"
+
+ filepath = bpy.props.StringProperty(name="File Path",
+ description="Filepath at which theme is located", maxlen=1024,
+ default="", subtype='FILE_PATH')
+
def execute(self, context):
+ # filepath should always be given
+ if not self.filepath:
+ self.report("ERROR", "Could not find theme")
+ return{'CANCELLED'}
+
# load file
try:
file = gzip.open(self.filepath, mode='r')
@@ -58,7 +129,7 @@
file.close()
dump["info"]["script"]
except:
- self.report("ERROR", "Could not read file")
+ self.report("ERROR", "Could not read theme")
return{'CANCELLED'}
# apply theme
@@ -81,11 +152,65 @@
# report to user
author = dump["info"]["author"]
theme_name = dump["info"]["theme_name"]
- self.report('INFO', "Loaded " + theme_name + " by " + author)
+ self.report('INFO', "Applied " + theme_name + " by " + author)
return{'FINISHED'}
+# install operator
+class InstallTheme(bpy.types.Operator, ImportHelper):
+ bl_idname = "ui.install_theme"
+ bl_label = "Install new theme"
+ bl_description = "Install a new theme"
+
+ filename_ext = ".blt"
+ filter_glob = bpy.props.StringProperty(default="*.blt", options={'HIDDEN'})
+
+ def execute(self, context):
+ # apply chosen theme
+ bpy.ops.ui.apply_theme(filepath=self.filepath)
+ # copy theme to presets folder
+ filename = os.path.basename(self.filepath)
+ try:
+ shutil.copyfile(self.filepath,
+ os.path.join(get_paths()[0], filename))
+ except:
+ self.report('ERROR', "Theme applied, but installing failed")
+ return{'CANCELLED'}
+ # reload presets list
+ load_presets()
+
+ return{'FINISHED'}
+
+
+# load operator (imitates a menu)
+class LoadTheme(bpy.types.Operator):
+ bl_idname = "ui.load_theme"
+ bl_label = "Load Theme"
+ bl_options = {'REGISTER'}
+
+ def draw(self, context):
+ # menu-like interface
+ theme_list = context.window_manager["theme_list"]
+ layout = self.layout
+
+ layout.operator("ui.install_theme")
+ col = layout.column(align=True)
+ for i, theme, author, path in theme_list:
+ row = col.row(align=True)
+ row.operator("ui.apply_theme", text=theme+" by "+author)\
+ .filepath = path
+ row.operator("ui.uninstall_theme", icon="ZOOMOUT", text="")\
+ .filepath = path
+ if not theme_list:
+ col.label("No theme presets found")
+
+ def execute(self, context):
+ # invoke popup
+ width = context.window_manager["theme_width"]
+ return context.window_manager.invoke_popup(self, width=width)
+
+
# save operator
class SaveTheme(bpy.types.Operator, ExportHelper):
bl_idname = "ui.save_theme"
@@ -93,6 +218,8 @@
bl_description = "Save the current theme to a .blt file"
filename_ext = ".blt"
+ filepath = bpy.props.StringProperty(\
+ default=os.path.join(get_paths()[0], "untitled"))
filter_glob = bpy.props.StringProperty(default="*.blt", options={'HIDDEN'})
author = bpy.props.StringProperty(name="Author",
default=bpy.context.user_preferences.system.author,
@@ -181,10 +308,33 @@
file = gzip.open(filepath, mode='w')
pickle.dump(dump, file)
file.close()
+ load_presets()
return{'FINISHED'}
+# install operator
+class UninstallTheme(bpy.types.Operator):
+ bl_idname = "ui.uninstall_theme"
+ bl_label = "Uninstall theme"
+ bl_description = "Uninstall this theme preset"
+
+ filepath = bpy.props.StringProperty(name="File Path",
+ description="Filepath at which theme is located", maxlen=1024,
+ default="", subtype='FILE_PATH')
+
+ def execute(self, context):
+ try:
+ os.remove(self.filepath)
+ except:
+ self.report('ERROR', "Could not remove theme preset")
+ return{'CANCELLED'}
+ # reload presets list
+ load_presets()
+
+ return{'FINISHED'}
+
+
# draw function for integration in header
def header_func(self, context):
if context.user_preferences.active_section == 'THEMES':
@@ -193,11 +343,15 @@
self.layout.operator("ui.save_theme")
-classes = [LoadTheme,
- SaveTheme]
+classes = [ApplyTheme,
+ InstallTheme,
+ LoadTheme,
+ SaveTheme,
+ UninstallTheme]
def register():
+ load_presets()
for c in classes:
bpy.utils.register_class(c)
bpy.types.USERPREF_HT_header.append(header_func)
@@ -207,7 +361,8 @@
for c in classes:
bpy.utils.unregister_class(c)
bpy.types.USERPREF_HT_header.remove(header_func)
+ unload_presets()
if __name__ == "__main__":
- register()
\ No newline at end of file
+ register()
More information about the Bf-extensions-cvs
mailing list