0

Here I have a simple imaginary addon that is able to append 2 cubes from a blendfile. Instead of having buttons, I want to use a preview of the cubes. Such a preview you see in asset managers. (Tried to analyse their code, but got stuck). Here is the simple addon:

import bpy

# Here comes bl_info

# Add cube 1 to scene
class ADD_OT_cube1(bpy.types.Operator):
    bl_idname = 'add.cube1'
    bl_description = 'Adds a cube. Blue, small.'
    bl_category = 'SuperCube'
    bl_label = 'Add Blue Cube'

    def execute(self, context):
        path = os.path.dirname(__file__) + "/ojbects/cubes.blend\\Collection\\"
        object_name = "cube_01"
        bpy.ops.wm.append(filename=object_name, directory=path)
        return {"FINISHED"}

# Add cube 2 to scene
class ADD_OT_cube2(bpy.types.Operator):
    bl_idname = 'add.cube2'
    bl_description = 'Adds a cube. Red, Eating a banana.'
    bl_category = 'SuperCube'
    bl_label = 'Add Grazy Cube'

    def execute(self, context):
        path = os.path.dirname(__file__) + "/ojbects/cubes.blend\\Collection\\"
        object_name = "cube_02"
        bpy.ops.wm.append(filename=object_name, directory=path)
        return {"FINISHED"}


# The menu in the N-Panel 
class ADD_MT_menu(bpy.types.Menu):
    bl_label = "Add Cubes"
    bl_idname = "ADD_MT_menu"

    def draw(self, context):
        layout = self.layout
        layout.operator("add.cube1")
        layout.operator("add.cube2")



# Register Classes
classes = (
    ADD_OT_cube1,
    ADD_OT_cube2,
    ADD_MT_menu)

def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)

def unregister():
    from bpy.utils import unregister_class
    for cls in classes:
        unregister_class(cls)

if __name__ == "__main__":
    register()

I suppose we can use the template_icon_view as documented on https://docs.blender.org/api/blender2.8/bpy.types.UILayout.html?highlight=template_icon_view#bpy.types.UILayout.template_icon_view but so far I didn’t get a clue.

David
  • 49,291
  • 38
  • 159
  • 317
  • What's your actual goal? Is your question about how to add an object to the scene? If so, I think you're pretty close. Just display the operators as buttons and check what's the actual value of the enum is... – brockmann Apr 17 '19 at 12:19
  • Goal: Instead of having buttons, I want to use a preview of the cubes. Such a preview you as you see in asset managers (Simple asset manager, Asset manager by pitiwazou, KITOPS etc). Sorry I don't have a clue what you mean with "Just display the operators as buttons and check what's the actual value of the enum is.." I don't want buttons. –  Apr 17 '19 at 12:49
  • Check out https://twitter.com/blenderdev/status/992095992269783045?lang=en – batFINGER Apr 17 '19 at 14:23
  • "I'm voting to close this question as off-topic because it's not a question" : more focus on correctness, protocols, guidelines than focus on trying to understand what the user is asking. For example if I was a fireman and someone calls me up saying "my house is on fair". then answer with: I don't know what you mean with fair. How could your house be on fair.

    That is al right, but the fireman could include: In case you mean that your house is on fire, tell me your address then I come and help you out. Or better: I understand your house is on fire, Am I correct? What is your address?

    –  Apr 17 '19 at 14:47
  • @batFINGER Thanks! –  Apr 17 '19 at 14:50
  • 2
    @RobWesseling removed the comment, I only saw the first edit with the title "Testing 123" and no content. – TLousky Apr 17 '19 at 15:07
  • So I understand most effort on this forum is: tracking duplicates, mentioning users how to use Blender Exchange, etc, that kind of stuff? Glad my account will get deleted in 21 hours. This is not a place for me. A place for me is where people trying to understand each other. The whole setup of this Exchange is way to formal / to many rules or guidelines / protocols. –  Apr 17 '19 at 15:19
  • @RobWesseling - Stackexchange is not a forum. It's a q&a site. We do things here this way, because it has proven to be effective. You can take the tour, if you want to learn more about Blender Stackexchange - or Stackexchange in general. – metaphor_set Apr 18 '19 at 04:55
  • @metaphor_set. Yes I see it's very effective now. I know now how to use the template_icon_view in Blender 2.80. Thanks for the solutions. –  Apr 18 '19 at 11:32
  • Succes guys with the proven to be effective site. My account here will be closed in one hour. Thumbs up! –  Apr 18 '19 at 11:36
  • @RobWesseling- k, bye. – metaphor_set Apr 18 '19 at 12:09

1 Answers1

1

There is an example burred in the blender source code repo

release/scripts/templates_py/ui_previews_dynamic_enum.py

tldr, its very similar to layout prop

class MyPanel(bpy.types.Panel):
    ...
def draw(self, context):
    layout = self.layout
    wm = context.window_manager

    row = self.layout.row()
    row.template_icon_view(wm, "my_previews", show_labels=True)

    row = self.layout.row()
    row.prop(wm, "my_previews")

that doesn't clarify much so some extra notes,

  • the EnumProperty must be on the RNA of something built in . i tried it on PropertyGroup and that didn't seem to work, WindowManager is used in the example
  • if the EnumProperty is defined as the result of a function, that function must be a top level function, methods are not allowed
  • if the EnumProperty is defined as the result of a function, the 4th index into the enum (the last int) is the index of this enum's value inside the whole enum, populating this number with for index, myvar in enumerate(mylist): ... ret.append((myvar, myvar, '', 0, index)) is appropriate.
  • if the EnumProperty is defined as the result of a function, the 3th index into the enum (the 2nd to last int) is the icon_id which can be a custom icon, be aware custom icons require care, if python's objects holding load custom icons get de-referenced that can cause icons to break.

the example linked above is quite a good example.

def get_my_enum(self, context) -> list[tuple[str, str, str, int int]]:
    if not context: return None
    return [
      ('foo', 'foo', '', 0, 0),
      ('bar' 'bar', '', 0, 1),
    ]

def register(): bpy.types.WindowManager.my_enum = bpy.props.EnumProperty(items=get_my_enum)

I would love to find docs on what this magic tuple is, maybe its a standard enum property item but the docs don't clarify argument to attribute ordering there

ThorSummoner
  • 344
  • 3
  • 14