diff options
Diffstat (limited to 'release/scripts/templates_py/ui_previews_dynamic_enum.py')
-rw-r--r-- | release/scripts/templates_py/ui_previews_dynamic_enum.py | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/release/scripts/templates_py/ui_previews_dynamic_enum.py b/release/scripts/templates_py/ui_previews_dynamic_enum.py new file mode 100644 index 00000000000..0cfa232116d --- /dev/null +++ b/release/scripts/templates_py/ui_previews_dynamic_enum.py @@ -0,0 +1,137 @@ +# This sample script demonstrates a dynamic EnumProperty with custom icons. +# The EnumProperty is populated dynamically with thumbnails of the contents of +# a chosen directory in 'enum_previews_from_directory_items'. +# Then, the same enum is displayed with different interfaces. Note that the +# generated icon previews do not have Blender IDs, which means that they can +# not be used with UILayout templates that require IDs, +# such as template_list and template_ID_preview. +# +# Other use cases: +# - make a fixed list of enum_items instead of calculating them in a function +# - generate isolated thumbnails to use as custom icons in buttons +# and menu items +# +# For custom icons, see the template "ui_previews_custom_icon.py". +# +# For distributable scripts, it is recommended to place the icons inside the +# script directory and access it relative to the py script file for portability: +# +# os.path.join(os.path.dirname(__file__), "images") + + +import os +import bpy + + +def enum_previews_from_directory_items(self, context): + """EnumProperty callback""" + enum_items = [] + + if context is None: + return enum_items + + wm = context.window_manager + directory = wm.my_previews_dir + + # Get the preview collection (defined in register func). + pcoll = preview_collections["main"] + + if directory == pcoll.my_previews_dir: + return pcoll.my_previews + + print("Scanning directory: %s" % directory) + + if directory and os.path.exists(directory): + # Scan the directory for png files + image_paths = [] + for fn in os.listdir(directory): + if fn.lower().endswith(".png"): + image_paths.append(fn) + + for i, name in enumerate(image_paths): + # generates a thumbnail preview for a file. + filepath = os.path.join(directory, name) + thumb = pcoll.load(filepath, filepath, 'IMAGE') + enum_items.append((name, name, "", thumb.icon_id, i)) + + pcoll.my_previews = enum_items + pcoll.my_previews_dir = directory + return pcoll.my_previews + + +class PreviewsExamplePanel(bpy.types.Panel): + """Creates a Panel in the Object properties window""" + bl_label = "Previews Example Panel" + bl_idname = "OBJECT_PT_previews" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "object" + + def draw(self, context): + layout = self.layout + wm = context.window_manager + + row = layout.row() + row.prop(wm, "my_previews_dir") + + row = layout.row() + row.template_icon_view(wm, "my_previews") + + row = layout.row() + row.prop(wm, "my_previews") + + +# We can store multiple preview collections here, +# however in this example we only store "main" +preview_collections = {} + + +def register(): + from bpy.types import WindowManager + from bpy.props import ( + StringProperty, + EnumProperty, + ) + + WindowManager.my_previews_dir = StringProperty( + name="Folder Path", + subtype='DIR_PATH', + default="" + ) + + WindowManager.my_previews = EnumProperty( + items=enum_previews_from_directory_items, + ) + + # Note that preview collections returned by bpy.utils.previews + # are regular Python 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 enum_items' strings + # (remember you have to keep those strings somewhere in py, + # else they get freed and Blender references invalid memory!). + import bpy.utils.previews + pcoll = bpy.utils.previews.new() + pcoll.my_previews_dir = "" + pcoll.my_previews = () + + preview_collections["main"] = pcoll + + bpy.utils.register_class(PreviewsExamplePanel) + + +def unregister(): + from bpy.types import WindowManager + + del WindowManager.my_previews + + for pcoll in preview_collections.values(): + bpy.utils.previews.remove(pcoll) + preview_collections.clear() + + bpy.utils.unregister_class(PreviewsExamplePanel) + + +if __name__ == "__main__": + register() |