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!
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