6
$\begingroup$

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

$\endgroup$
2
  • $\begingroup$ blender.stackexchange.com/a/8814/5113 $\endgroup$
    – Chebhou
    Jan 17 '16 at 12:44
  • $\begingroup$ @Chebhou Thanks, but template_list is not what I am looking for, it's too big and has a different and more complicated purpose than a simple dropdown list. $\endgroup$ Jan 17 '16 at 15:26
3
$\begingroup$

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:

$\endgroup$
2
  • $\begingroup$ Sure, here is the add-on. $\endgroup$ Jan 19 '16 at 11:15
  • $\begingroup$ @MikhailRachinskiy Looking great :) Thanks for sharing! $\endgroup$
    – p2or
    Jan 19 '16 at 12:08
1
$\begingroup$

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.

$\endgroup$
5
  • $\begingroup$ just out of curiosity did you look into the py script that calls such a template? $\endgroup$ Jan 16 '16 at 19:03
  • $\begingroup$ @ClaasKuhnen Sure, just press RMB on "Add new material" button and select "Edit Source" from drop down menu. $\endgroup$ Jan 17 '16 at 5:44
  • $\begingroup$ U missunderstood me me. As far as I know the templates point to other Py files where they define the layout for just UI elements. Maybe in those py files is the answer to your question. $\endgroup$ Jan 17 '16 at 17:01
  • 1
    $\begingroup$ @ClaasKuhnen As far as I know all UI elements written in C, just to check I looked in Blender's /scripts/modules folder and discovered nothing that might describe UI elements. $\endgroup$ Jan 17 '16 at 19:17
  • $\begingroup$ I am sorry - just thought this might be an option. $\endgroup$ Jan 17 '16 at 20:32

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.