6

Is there a way to add search functionality to EnumProperty in my add-on, similar to material search?
Or maybe there is another property with search functionality that I could use?

enter image description here

Mikhail Rachinskiy
  • 1,069
  • 8
  • 22

2 Answers2

5

As of Blender 2.79+ you can use a PointerProperty:

Demo based on @batFINGERs answer to Object selection box with eyedropper

import bpy
from bpy.props import PointerProperty

class TEST_PT_layout_panel(bpy.types.Panel): bl_label = "Prop Panels" bl_category = "Test Panel" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "scene"

def draw(self, context):
    scene = context.scene
    layout = self.layout

    col = layout.column()
    col.prop_search(scene, "prop_obj", context.scene, "objects")
    #or 
    col.prop(scene, "prop_obj")
    col.prop(scene, "prop_mat")


def register(): bpy.types.Scene.prop_obj = PointerProperty(type=bpy.types.Object) bpy.types.Scene.prop_mat = PointerProperty(type=bpy.types.Material) bpy.utils.register_class(TEST_PT_layout_panel)

def unregister(): bpy.utils.unregister_class(TEST_PT_layout_panel) del bpy.types.Scene.prop_obj del bpy.types.Scene.prop_mat

if name == "main": register() bpy.ops.wm.call_panel(name="TEST_PT_layout_panel")


Alternatively you can use a Search Popup. The following operator example lists all objects in the scene and returns the selected object name:

enter image description here

Blender 2.8+

bl_info = {
    "name": "Search Popup",
    "version": (0, 0, 1),
    "blender": (2, 80, 0),
    "category": "Development"
}

import bpy

from bpy.props import EnumProperty from bpy.types import Operator

------------------------------------------------------------------------

Operator

------------------------------------------------------------------------

def my_callback(scene, context): objs = ([o.name for o in bpy.context.scene.objects]) return [(y.upper(), y, "", x) for x, y in enumerate(objs)]

class MYCAT_OT_searchPopup(Operator): """Tooltip""" bl_idname = "object.search_popup" bl_label = "Search Popup" bl_property = "my_enum"

my_enum: EnumProperty(name="Objects", description="", items=my_callback)

def execute(self, context):
    self.report({'INFO'}, "You've selected: %s" % self.my_enum)
    return {'FINISHED'}

def invoke(self, context, event):
    wm = context.window_manager
    wm.invoke_search_popup(self)
    return {'FINISHED'}


------------------------------------------------------------------------

Register

------------------------------------------------------------------------

def register(): bpy.utils.register_class(MYCAT_OT_searchPopup)

def unregister(): bpy.utils.unregister_class(MYCAT_OT_searchPopup)

if name == "main": register()

# test call
bpy.ops.object.search_popup('INVOKE_DEFAULT')

Blender 2.7x

bl_info = {
    "name": "Search Popup",
    "version": (0, 0, 1),
    "blender": (2, 75, 0),
    "category": "Test"
}

import bpy

from bpy.props import (EnumProperty, PointerProperty, ) from bpy.types import (Operator, AddonPreferences, PropertyGroup, )

------------------------------------------------------------------------

store properties in the active scene

------------------------------------------------------------------------

def my_callback(scene, context): objs = ([o.name for o in bpy.context.scene.objects]) return [(y.upper(), y, "", x) for x, y in enumerate(objs)]

class MySettings(PropertyGroup):

objs = EnumProperty(
    name="Objects",
    description="",
    items=my_callback
    )

------------------------------------------------------------------------

operator

------------------------------------------------------------------------

class MyOperator(Operator): """Tooltip""" bl_idname = "object.search_popup" bl_label = "Search Popup" bl_property = "my_enum"

my_enum = MySettings.objs

def execute(self, context):
    self.report({'INFO'}, "You've selected: %s" % self.my_enum)
    return {'FINISHED'}

def invoke(self, context, event):
    wm = context.window_manager
    wm.invoke_search_popup(self)
    return {'FINISHED'}

------------------------------------------------------------------------

register and unregister functions

------------------------------------------------------------------------

def register(): bpy.utils.register_module(name) bpy.types.Scene.my_tool = PointerProperty(type=MySettings)

def unregister(): bpy.utils.unregister_module(name) del bpy.types.Scene.my_tool

if name == "main": register()

# test call
bpy.ops.object.search_popup('INVOKE_DEFAULT')

Related:

brockmann
  • 12,613
  • 4
  • 50
  • 93
p2or
  • 15,860
  • 10
  • 83
  • 143
1

One can use bpy.types.UILayout.template_ID to get this UI element, but it works only with datablocks, enums won't work with it.

Mikhail Rachinskiy
  • 1,069
  • 8
  • 22