Event leftmouse pressed disturbed by tool selection

Hi,
I made myself a modal to add vertices with mouse.
I am trying to add vertices
from when : mouse_left is “Pressed” to when is “release” or “click”

I discovered that the tool selected in the toolbar disturb my modal,
when i click and drag, the tool start the squared-selection and that make the event mouseleft_ release disappear.

If i dont drag it work correctly.
click, start adding,
release, stop

So, i have to create a tool to select for use my modal?
I found the template ui_tool_simple.py
i dont understand how link this template to operators or anything.
Can someone explain this in extended way?

Thanks

Making a modal with mouse_press and release,
Start with the tool,
Because otherwise even click on tools and panels will sometime start the press event, but not all the buttons and panel will release the release event…
Since half of the problem get fixed using a proper tool
Start from there, (even because you will not do the work 2 times, to work with the modal events, and again the tool)

So to use a modal with the mouse click and release.
You need to create a new tool.,
Otherwise, if you run a modal on a tool like tool-select-box, your events will work fine , just click and release, but if you start a drag, and so a selection , that will completely absorb your release event, and your modal will get stuck .

Even Using a customized new tool, there are a lot of problem and i added a property for detect and set the mouse click and release.
For example, clicking on the “Perspective-ortho” overlay Ui,
Will again , start the modal with the press , but will absorb the release. leaving your modal stuck.

So i added a panel with a field for a custom property i placed in the scene.
Lined the press and release to a bool so when the modal get stuck for unknown reason i can see the boolean remain true and hit the right click (cancell the modal)

Maybe a " tool workflow tutorial " is a useful add to the templates

EDIT; I FIXED THE UPDATE OF THE PANEL TOO,
I keep the image to show the print window.
But the panel now works fine.

Here a little Modal operator with a tool and a panel,
really dont know why the panel dont update the boolean
but it show the mouse click and release with " print "

Just copy and paste the whole python in the script editor and run it 1 time.
Than you should have a tool, as seen in this image,

import bpy
from bpy.props import  BoolProperty , FloatVectorProperty
                       
from bpy.types import (Panel,
                       Menu,
                       Operator,
                       PropertyGroup,
                       )

from bpy.types import WorkSpaceTool

#   
#       TOOL       

class CustomTool(WorkSpaceTool):  
    bl_space_type = 'VIEW_3D'
    bl_context_mode = 'OBJECT'
    bl_idname = "name_addon.mycustom_tool"
    bl_label = " mouse tester "
    bl_description = (" check the status of mouse press and release ")
    bl_icon =  "ops.gpencil.draw.poly"                                     # THE ICON SHOWN IN THE TOOLBAR
    bl_widget = None 
    bl_keymap = (
        ("wm.modal_custom_printer", {"type": 'LEFTMOUSE', "value": 'PRESS'},
         {"properties": [("wait_for_input", False)]}),
        ("wm.modal_custom_printer", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
         {"properties": [("mode", 'SUB'), ("wait_for_input", False)]}),
    )
     
#   
#      PROPERTY    

class Custom_PROP(PropertyGroup):                 
    MouseL: BoolProperty() 
    MouseCoord: bpy.props.FloatVectorProperty()
                          
bpy.utils.register_class(Custom_PROP)                                      # REGISTER THE PROPERTY SO I CAN USE IT NOW
bpy.types.Scene.CUSTOM_DATA = bpy.props.PointerProperty(type=Custom_PROP)   # ADD THE CUSTOM PROPERTY IN THE SCENE
#   
#       PANEL      

class CUSTOM_Panel(Panel):   
    bl_label = "Mousetester"
    bl_idname = "OBJECT_PT_custom_mouse"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "TOOLS"
    
    def draw(self, context):  
# Horizontal ROW
        layout = self.layout  
        row = layout.row() 
        row.label( text= "Mouse " )
        row.label( text= "X " + str( context.scene.CUSTOM_DATA.MouseCoord[0] )  )
        row.label( text= "Y " +str( context.scene.CUSTOM_DATA.MouseCoord[1] )  )
        row.prop( context.scene.CUSTOM_DATA  , "MouseL" )
# Vertical COLUMN        
#        layout = self.layout  
#        col = layout.column() 
#        col.prop( context.scene.CUSTOM_DATA  , "MouseL" )
#        col.label( text= "X " + str( context.scene.CUSTOM_DATA.MouseCoord[0] )  )
#        col.label( text= "Y " +str( context.scene.CUSTOM_DATA.MouseCoord[1] )  )
        
    
#   
#  OPERATOR MODAL     
 
class CUSTOM_PRINTER(bpy.types.Operator):
    bl_idname = "wm.modal_custom_printer"
    bl_label = "test Modal printer"
 
    def modal(self, context, event):
               
        if event.type == 'ESC' :
            return {'CANCELLED'}
       
        if event.type == "LEFTMOUSE" :
                        
            if event.value == "PRESS":                   # THIS WILL NOT BE CALLED
                bpy.context.scene.CUSTOM_DATA.MouseL =1    
                print("MOUSE_LEFT---PRESS")
                print  (bpy.context.scene.CUSTOM_DATA.MouseL) 
                context.area.tag_redraw()
            if event.value == "RELEASE":
                bpy.context.scene.CUSTOM_DATA.MouseL =0
                print("MOUSE_LEFT---RELEASE")
                print  (bpy.context.scene.CUSTOM_DATA.MouseL) 
                context.area.tag_redraw()
                return {'CANCELLED'}
            if event.value == "CLICK":
                print("MOUSE_LEFT---CLICK")
                      
        if event.type == 'MOUSEMOVE':   
            print("Mouse moved to  " + str(event.mouse_region_x) + "  " + str(event.mouse_region_y)  ) 
            context.scene.CUSTOM_DATA.MouseCoord = ( event.mouse_region_x ,event.mouse_region_y, 0 )
            print  (bpy.context.scene.CUSTOM_DATA.MouseL)     
            context.area.tag_redraw()
        return {'PASS_THROUGH'}
    
    def execute(self, context):
        wm = context.window_manager       
        wm.modal_handler_add(self)
        print("THIS IS THE FIRST CLICK ")                 # FIRST CLICK
        bpy.context.scene.CUSTOM_DATA.MouseL =1           # So i set the value here 
        context.area.tag_redraw()
        print  (bpy.context.scene.CUSTOM_DATA.MouseL) 
        return {'RUNNING_MODAL'}

#   
#   REGISTRATION     
  
classes = ( # I ALREADY REGISTERED THE PROPERTY GROUP  
#    Custom_PROP ,     
    CUSTOM_Panel,
    CUSTOM_PRINTER  
    )
def register():
    for cls in classes:
        bpy.utils.register_class(cls)
        
    bpy.utils.register_tool( CustomTool , after={"builtin.scale_cage"}, separator=True, group=True)
    
def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
        
    bpy.utils.unregister_tool( CustomTool  )

if __name__ == "__main__":
    register()
1 Like