[Bf-blender-cvs] [de79d15] ui-preview-buttons: Fix bad import in __del__ context, and fix/enhance ui_previews template to only rescan when dir changes.

Bastien Montagne noreply at git.blender.org
Tue Apr 28 19:37:14 CEST 2015


Commit: de79d1572acb7d847196700c7838085bd8991e35
Author: Bastien Montagne
Date:   Tue Apr 28 19:36:29 2015 +0200
Branches: ui-preview-buttons
https://developer.blender.org/rBde79d1572acb7d847196700c7838085bd8991e35

Fix bad import in __del__ context, and fix/enhance ui_previews template to only rescan when dir changes.

===================================================================

M	release/scripts/modules/bpy/utils.py
M	release/scripts/templates_py/ui_previews.py

===================================================================

diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index c8f94f1..4fe2ae0 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -705,8 +705,7 @@ class BPyPreviewsCollection:
     """
     Fake dict-like class of previews.
     """
-    from _bpy import app
-    __slots__ = ('_previews', '_coll_name')
+    from _bpy import app as _app
 
     def __init__(self, name):
         self._previews = {}
@@ -719,27 +718,27 @@ class BPyPreviewsCollection:
         return self._coll_name + name
 
     def new(self, name):
-        from _bpy import app
+        app = self.__class__._app
         return self._previews.setdefault(name, app._previews.new(self._gen_key(name)))
-    new.__doc__ = app._previews.new.__doc__
+    new.__doc__ = _app._previews.new.__doc__
 
     def load(self, name, path, path_type, force_reload=False):
-        from _bpy import app
+        app = self.__class__._app
         pkey = self._gen_key(name)
         if force_reload:
             self._previews[name] = p = app._previews.load(pkey, path, path_type, True)
             return p
         else:
             return self._previews.setdefault(name, app._previews.load(pkey, path, path_type, False))
-    load.__doc__ = app._previews.load.__doc__
+    load.__doc__ = _app._previews.load.__doc__
 
     def release(self, name):
-        from _bpy import app
+        app = self.__class__._app
         p = self._previews.pop(name, None)
         if p is not None:
             del p
             app._previews.release(self._gen_key(name))
-    release.__doc__ = app._previews.release.__doc__
+    release.__doc__ = _app._previews.release.__doc__
 
     def __repr__(self):
         return "<PreviewsCollection '%s'>\n\tPreviews: %s" % (self._coll_name, repr(self._previews))
@@ -772,7 +771,7 @@ class BPyPreviewsCollection:
         return self._previews.get(key, default)
 
     def clear(self):
-        from _bpy import app
+        app = self.__class__._app
         for name in self._previews.keys():
             app._previews.release(self._gen_key(name))
         self._previews.clear()
diff --git a/release/scripts/templates_py/ui_previews.py b/release/scripts/templates_py/ui_previews.py
index e4bf5b6..d93843d 100644
--- a/release/scripts/templates_py/ui_previews.py
+++ b/release/scripts/templates_py/ui_previews.py
@@ -20,12 +20,18 @@ import bpy
 
 
 def get_previews_from_folder(self, context):
-
     enum_items = []
     folder_path = context.window_manager.my_previews_folderpath
-    print("rescanning folder: %s" % folder_path)
 
-    if folder_path:
+    # gets the already existing preview collection (defined in register func).
+    pcoll = bpy.utils.previews.new("PreviewsInDirectory")
+
+    if folder_path == pcoll.my_previews_folderpath:
+        return pcoll.my_previews
+
+    print("Scanning folder: %s" % folder_path)
+
+    if folder_path and os.path.exists(folder_path):
         # scan the directory for png files
         dir_contents = os.listdir(folder_path)
         image_paths = []
@@ -33,18 +39,17 @@ def get_previews_from_folder(self, context):
             if c.endswith(".png") or c.endswith(".PNG"):
                 image_paths.append(c)
 
-        # gets the already existing preview collection, otherwise it is created
-        prevs = bpy.utils.previews.new("PreviewsInDirectory")
-
         for idx, img_name in enumerate(image_paths):
             # generates a thumbnail preview for a file.
             # Also works with previews for 'MOVIE', 'BLEND' and 'FONT'
-            thumb = prevs.load(img_name, folder_path + img_name, 'IMAGE')
-            enum_items.append(
-                # enum item: (identifier, name, description, icon, number)
-                (img_name, img_name, img_name, int(thumb.icon_id), idx+1))
+            path = folder_path + img_name
+            thumb = pcoll.load(path, path, 'IMAGE')
+            # enum item: (identifier, name, description, icon, number)
+            enum_items.append((img_name, img_name, img_name, int(thumb.icon_id), idx))
 
-    return enum_items
+    pcoll.my_previews = tuple(enum_items)
+    pcoll.my_previews_folderpath = folder_path
+    return pcoll.my_previews
 
 
 class PreviewsExamplePanel(bpy.types.Panel):
@@ -77,7 +82,15 @@ def register():
     bpy.types.WindowManager.my_previews = \
         bpy.props.EnumProperty(items=get_previews_from_folder)
 
-    bpy.utils.previews.new("PreviewsInDirectory")
+    # Note that preview collections returned by bpy.utils.previews are regular py objects - you can use them
+    # to store custom data.
+    # This is especially useful here, since:
+    #     * It avoids us regenerating the whole enum over and over.
+    #     * It can store enumitems' strings (remember you have to keep those strings somewhere in py, else they get
+    #       freed and blender references invalid memory!).
+    pcoll = bpy.utils.previews.new("PreviewsInDirectory")
+    pcoll.my_previews_folderpath = ""
+    pcoll.my_previews = ()
 
     bpy.utils.register_class(PreviewsExamplePanel)




More information about the Bf-blender-cvs mailing list