Dynamic popup

Hi,

this sounds unbelievably simple, and maybe I’ve missed something; but I can’t figure how to make a dynamic dropdown menu/combo.

I know how to make a dropdown using “bpy.props.EnumProperty”. But it appears that you need to set the possible values when creating the property. What if the possible values change over time? (I tried overwriting the EnumProperty with new values but this just results in blender crashing).

So is anyone aware of a strategy to achieve this seemingly simple task?
Thanks

There are several ways - but the simplest, and non-Blender related, is:

Create a list with more than you expect to use. Only show those that you are using…

Very common strategy when creating structures to allow for modification in future releases. Make space for options that you haven’t implemented yet and the read/write ops won’t change just the details of how the structure is handled.

HTH/makes sense.

Can anyone tell me “what is dynamic popups?”

A popup menu in which the elements are different over time (determined dynamically). At this time I only know how to make a popup with static contents (contents doesn’t change)

@Jambay:
this is somewhat interesting, but in my case I don’t think this is a feasible approach; I need to build the list of items from the scene created by the user, so I can’t know the possibilities in advance

you could use a menu list which can be upated dynamically and put in your dynamic pop up window!

salutations

RickyBlender, maybe you can be a little more specific? The closest I have managed to obtain so far is :


import bpy

l = []
for curr in bpy.data.objects:
    l.append( (curr.name, curr.name, curr.name) )

class ObjectPickerCombo(bpy.types.Operator):
    bl_idname = "screen.stk_object_picker"
    bl_label  = ("SuperTuxKart object picker")
    m_property_id = id
    
    m_obj = ""
    m_props = []
    
    value = bpy.props.EnumProperty(attr="value", name="value", default=l[0][0],
                                   items=l)
    
    def invoke(self, context, event):
        
        print("Outer invoke")
        
        l = []
        for curr in bpy.data.objects:
            l.append( (curr.name, curr.name + " (updated)", curr.name + " (updated)") )
        ObjectPickerCombo.value = bpy.props.EnumProperty(attr="value", name="value", default=l[0][0],
                                   items=l)
        context.region.tag_redraw()
        upper = self
        
        class ObjectPickerDialog(bpy.types.Operator):
          
            bl_idname = "screen.stk_object_picker_dialog"
            bl_label  = ("SuperTuxKart select object")
    
            m_upper = upper
            the_list = l
    
            def execute(self, context):
                print("Exec inner")
                context.region.tag_redraw()
                context.window_manager.invoke_props_dialog(self)
                context.region.tag_redraw()
                return {'FINISHED'}
                
            def draw(self, context):
                self.m_props = []
                
                layout = self.layout
                
                for curr in self.the_list:
                    layout.prop_enum(self.m_upper, "value", curr[0])
        
        self.l = l
        
        #context.window_manager.invoke_props_dialog(self)
        bpy.utils.register_class(ObjectPickerDialog)
        
        context.region.tag_redraw()
        bpy.ops.screen.stk_object_picker_dialog()
        context.region.tag_redraw()
        return {'RUNNING_MODAL'}
    
    def execute(self, context):
        context.region.tag_redraw()
        print("Exec")
        return {'FINISHED'}

bpy.utils.register_class(ObjectPickerCombo)


class HelloWorldPanel(bpy.types.Panel):
    bl_idname = "OBJECT_PT_hello_world"
    bl_label = "Hello World"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        self.layout.label(text="Hello World")
        
        self.layout.operator("screen.stk_object_picker", text="", icon="TRIA_DOWN")


bpy.utils.register_class(HelloWorldPanel)

Apart from being surprisingly complicated, this little snippet also crashes blender. Maybe you can see what I’m doing wrong?

OK thanks a lot for pointing me this link :slight_smile:

By modifying the example in the link, I finally obtained this, which is exactly what I wanted :


import bpy

class SelectObjectOperator(bpy.types.Operator):
    bl_idname = "scene.select_object"
    bl_label = "Select Object Operator"

    name = bpy.props.StringProperty()

    def execute(self, context):
        context.scene["selection"] = self.name
        print("Executing", self.name)
        return {'FINISHED'}

bpy.utils.register_class(SelectObjectOperator)

class BranchMenu(bpy.types.Menu):
    bl_idname = "mocapmadness.branchmenu"
    bl_label = "Branch to Action"

    def draw(self, context):
        objects = context.scene.objects
        
        layout = self.layout
        for object in objects:
            
            if object.type != "MESH": continue

            text = object.name  
            layout.operator("scene.select_object", text=text).name=text

               
class OBJECT_PT_hello(bpy.types.Panel):
    bl_label = "Hello World Panel"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"


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

        obj = context.object

        row = layout.row()
        row.prop(context.scene, '["selection"]')
        row.menu("mocapmadness.branchmenu",text="", icon="TRIA_DOWN")

def register():
    bpy.utils.register_class(BranchMenu)
    bpy.utils.register_class(OBJECT_PT_hello)
def unregister():
    bpy.utils.unregister_class(OBJECT_PT_hello)

if __name__ == "__main__":
    register()

Thanks!

so your talking about a menu button not a pop up window !

now this add only a panel in object panel propertie on the right

i mean if you select several objects then i can see the dynamic menu with only an arrow

but would be nicer if this was like a menu button ?

glad i could help

happy 2.5

Nice… I’d call this a drop down combo (even though it didn’t drop down in my case)