2
$\begingroup$

Is there a way for me to listen for when the user has started, is dragging, and has stopped dragging a slider in a Panel in Python?

Thank you!

$\endgroup$

1 Answer 1

4
$\begingroup$

I'll show you one solution but I hope there is an easier way. Related Q&A

We're going to use a modal operator that runs when you click on the property field and loops until you release the mouse button.

import bpy


class DRAGGABLEPROP_OT_subscribe(bpy.types.Operator):
    bl_idname  = "draggableprop.subscribe"
    bl_label   = ""
    stop: bpy.props.BoolProperty()  # This is used so we don't end up in an infinite loop because we blocked the release event

    def modal(self, context, event):
        if self.stop:
            context.scene.my_prop.is_dragging = False
            print("End Dragging !")
            return {'FINISHED'}
        if event.value == 'RELEASE':  # Stop the modal on next frame. Don't block the event since we want to exit the field dragging
            self.stop = True

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        self.stop = False
        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}


class TEST_PT_draggable_prop(bpy.types.Panel):
    bl_label = "Test my draggable prop"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"

    def draw(self, context):
        layout = self.layout
        layout.prop(context.scene.my_prop, "value")
        layout.prop(context.scene.my_prop, "is_dragging")


def update_prop(self, value):
    if self.is_dragging:
        print("Dragging the slider !")
    else:
        print("Beginning dragging the slider !")
        self.is_dragging = True
        bpy.ops.draggableprop.subscribe('INVOKE_DEFAULT')


class DraggableProp(bpy.types.PropertyGroup):
    value: bpy.props.IntProperty(update=update_prop, min=0, max=100)
    is_dragging: bpy.props.BoolProperty()


if __name__ == "__main__":
    bpy.utils.register_class(DRAGGABLEPROP_OT_subscribe)  # Register modal operator
    bpy.utils.register_class(TEST_PT_draggable_prop)  # Register Panel to see what's going on
    bpy.utils.register_class(DraggableProp)  # Register our custom prop
    bpy.types.Scene.my_prop = bpy.props.PointerProperty(type=DraggableProp)  # Setup our custom prop

enter image description here

Further reading

$\endgroup$
1
  • 1
    $\begingroup$ You are very helpful. Unless someone has a better way, this appears to work well to me! $\endgroup$ Commented Dec 6, 2021 at 23:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .