1
$\begingroup$

I want to add a few options to this python template which I found inside Blender-ui_previews_dynamic_enum.py Here is the code:

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()

This code will scan and use the png files from the directory and create the thumbnails of that.

Is there a way to specify the items before, with thumbnails, and on choosing a certain option from that menu, a change in the code takes place.....

$\endgroup$
1
$\begingroup$

Try using update methods. Changing the dir would be the time to populate the list, changing the enum ... run some other code. A lot of the code in the items callback can then be removed.

import os
import bpy

preview_collections = {}

def enum_previews_from_directory_items(self, context):
    pcoll = preview_collections.get("main")
    if not pcoll:
        return []

    if self.my_previews_dir == "": # use better default
        # put some code in here to populate default list
        print("MAKE A NEW THUMB LIST HERE")
        newlist = []
        '''
        # a list of items with name, filepath to image, and unique i

        thumb = pcoll.load(filepath, filepath, 'IMAGE')
        item = (name, name, "", thumb.icon_id, i) 
        newlist.append(item)
        '''       
        return newlist

    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"


def preview_dir_update(wm, context):
    print("wm.my_previews_dir = %s" % wm.my_previews_dir)

    """EnumProperty callback"""
    enum_items = []

    wm = context.window_manager
    directory = wm.my_previews_dir

    # Get the preview collection (defined in register func).
    pcoll = preview_collections["main"]

    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 None

def preview_enum_update(wm, context):
    print("wm.my_previews = %s" % wm.my_previews)
    return None

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="",
            update=preview_dir_update,
            )

    WindowManager.my_previews = EnumProperty(
            items=enum_previews_from_directory_items,
            update=preview_enum_update,
                )

    # 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

    pcol = preview_collections.setdefault("main", bpy.utils.previews.new())

    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()

You can get fancy with the update methods using the methods outlined here https://blender.stackexchange.com/a/39624/15543

$\endgroup$
4
  • $\begingroup$ Well, I actually want there to be different options. And, I don't know how to specify those items or options in the enum_previews_from_directory_items(). Each item should have a different thumbnail $\endgroup$ – Akash Hamirwasia Dec 2 '15 at 9:48
  • $\begingroup$ Ok, I get it, but how will I check which option is selected by the user..... $\endgroup$ – Akash Hamirwasia Dec 2 '15 at 10:33
  • $\begingroup$ preview_enum_update is called when user changes selection. $\endgroup$ – batFINGER Dec 2 '15 at 10:44
  • $\begingroup$ Thanks for help, I was thinking if it was possible to remove the StringProperty from the Interface, and assign it a specific default value which will never update.... :) $\endgroup$ – Akash Hamirwasia Dec 2 '15 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.