2
$\begingroup$

In sculpt mode you get this menu with a right click:

enter image description here

The UI elements in this menu are visually the same you would get by drawing a UI using bpy.types.UILayout functions. Yet, the only answers I found for drawing custom floating UI elements referred to bgl and blf, like in these two Blender StackExchange questions:

  1. How to draw shapes in the node editor with python bgl
  2. Floating UI window in 3D view

However, ideally I would use standard Blender UI elements to create something like that. Is there a way to draw standard Blender UI elements in floating windows like those in the screenshot using Python?

$\endgroup$
4
$\begingroup$

WindowManager.invoke_props_popup(operator, event)

Operator popup invoke (show operator properties and execute it automatically on changes)

Code based on How to call a confirmation dialog box?, I just replaced invoke_props_dialog by invoke_props_popup to diplay the popup without confirmation option:

enter image description here

import bpy

class SimplePropConfirmOperator(bpy.types.Operator):
    """Really?"""
    bl_idname = "my_category.custom_confirm_dialog"
    bl_label = "Do you really want to do that?"
    bl_options = {'REGISTER', 'UNDO'}

    prop1: bpy.props.BoolProperty()
    prop2: bpy.props.BoolProperty()

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        self.report({'INFO'}, "YES!")
        return {'FINISHED'}

    def invoke(self, context, event):
        return context.window_manager.invoke_props_popup(self, event)

    def draw(self, context):
        row = self.layout
        row.prop(self, "prop1", text="Property A")
        row.prop(self, "prop2", text="Property B")


class OBJECT_PT_CustomPanel(bpy.types.Panel):
    bl_label = "My Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"

    def draw(self, context):
        layout = self.layout
        layout.operator(SimplePropConfirmOperator.bl_idname)

def register():
    bpy.utils.register_class(OBJECT_PT_CustomPanel)
    bpy.utils.register_class(SimplePropConfirmOperator)

def unregister():
    bpy.utils.unregister_class(SimplePropConfirmOperator)
    bpy.utils.unregister_class(OBJECT_PT_CustomPanel)

if __name__ == "__main__":
    register()
| improve this answer | |
$\endgroup$
  • $\begingroup$ That's exactly it. Thanks! I was hoping to get more control over it, like setting it's position and the mouse distance to make it disappear though. But it's already great to have it working as in your example. $\endgroup$ – narranoid Jul 16 at 20:16
  • 1
    $\begingroup$ Cool. Unfortunately, there is nothing else you can do... in order to 'get more control', you can set the cursor before calling inkoke_props_popup(), that's it @narranoid $\endgroup$ – brockmann Jul 16 at 22:30

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.