How to do Mouse Drag Threshold in a modal

In the script below, on left button I toggle selection, and if I press and drag it’s doing a select box.
but there is no threshold. like this in blender. (to avoid to have the drag even on very little mouse move)


I tried with mouse position but with no results

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"
    
    _escape = {'SPACE', 'RET', 'ESC'}

    def modal(self, context, event):
    # toggle select / select box 
        if event.type == 'LEFTMOUSE' and context.mode == 'OBJECT':
            self.left_press = event.value == 'PRESS'
            self.left_release = event.value == 'RELEASE'
        if self.left_press:
            if event.type == 'MOUSEMOVE':
                if not event.shift:
                    bpy.ops.view3d.select_box('INVOKE_DEFAULT',mode='SET',wait_for_input=False)
                else:
                    bpy.ops.view3d.select_box('INVOKE_DEFAULT',mode='XOR',wait_for_input=False)
                    
                self.left_press = None
                
        if self.left_release:
            if not event.type == 'MOUSEMOVE':
                bpy.ops.object.select_all(action='TOGGLE')
                self.left_release = None
        
        if event.type in self._escape:
            return {'FINISHED'}

        return {'RUNNING_MODAL'}

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


def register():
    bpy.utils.register_class(ModalOperator)

if '__main__' in __name__:
    register()

ok I get it, much simpler to find from a simple script…

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"
    
    _escape = {'SPACE', 'RET', 'ESC'}

    def modal(self, context, event):
    # toggle select / select box 
        if event.type == 'LEFTMOUSE' and context.mode == 'OBJECT':
            self.left_press = event.value == 'PRESS'
            self.left_release = event.value == 'RELEASE'
            self.pos = (event.mouse_region_x, event.mouse_region_y)

        if self.left_press:
            if event.type == 'MOUSEMOVE' and self.pos:

                if abs(event.mouse_region_x) > self.pos[0]+5 or abs(event.mouse_region_y) > self.pos[1]+5:
                    if not event.shift:
                        bpy.ops.view3d.select_box('INVOKE_DEFAULT',mode='SET',wait_for_input=False)
                    else:
                        bpy.ops.view3d.select_box('INVOKE_DEFAULT',mode='XOR',wait_for_input=False)
                        
                    self.left_press = None
                    self.pos = None
                
        if self.left_release:
            if not event.type == 'MOUSEMOVE':
                bpy.ops.object.select_all(action='TOGGLE')
                self.left_release = None
        
        if event.type in self._escape:
            return {'FINISHED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        self.left_press = False
        self.left_release = False
        self.pos = None
        
        wm = context.window_manager
        wm.modal_handler_add(self)
        return {'RUNNING_MODAL'}


def register():
    bpy.utils.register_class(ModalOperator)

if '__main__' in __name__:
    register()
1 Like