Discerning a drag from a click (Desktop)

I have some canvas controls that have certain functionality when clicked, but also have different functionality when dragged and dropped to each other.

I’ve implemented the code in the MouseUp event handler to deal with “clicks” and the drag code in the MouseDrag event handler for Drag-and-drop, but the problem I’m experiencing is that MouseDrag fires every time I click, even if it’s not a drag event.

How does one tell the difference between a click and a drag?

Typically by storing the X and Y coordinates in MouseDown, then returning from the Drag event if the distance between the original (X, Y) and Drag (X, Y) is less than some value.

Here’s a quick example I tossed together. There may be one in the Xojo examples, but it was probably quicker for me to build this than go looking.


Instructions for Posterity

  1. I created a subclass of DesktopCanvas called DragCanvas.
  2. I added the following three properties:
Private Property isDragging As Boolean = False
Private Property startX As Integer
Private Property startY As Integer
  1. I added the following Event Definitions:
Event Drag(X as Integer, Y as Integer)
Event DragEnd(X as Integer, Y as Integer)
Event DragStart(X as Integer, Y as Integer)
Event Pressed()
  1. I added the following Event Handlers:
Function MouseDown(x As Integer, y As Integer) Handles MouseDown as Boolean
  startX = X
  startY = Y
  Return True
End Function
Sub MouseUp(x As Integer, y As Integer) Handles MouseUp
  if isDragging = false then
    RaiseEvent Pressed
    isDragging = False
    RaiseEvent DragEnd(X, Y)
  end if
End Sub
Sub MouseDrag(x As Integer, y As Integer) Handles MouseDrag
  if isDragging = false and (Abs(x - startX) > 5 or abs(y - startY) > 5) then
    isDragging = True
    RaiseEvent DragStart(X, Y)
  elseif isDragging then
    RaiseEvent Drag(X, Y)
  end if
End Sub

Anthony you never cease to amaze me. I was able to implement a version of this into my code and it works flawlessly. The Xojo examples were actually the first place I turned, sadly they are a bit lacking in drag and drop, only showing the very basics.

I suppose I have been spoiled in that other languages have handled this for me using their own standards for the threshold between a click and a drag, but it turns out to not be that difficult to manually implement once you wrap your head around it.

I ended up throwing a geometric distance function together to handle the calculation:

Private Function Distance(X1 as integer, Y1 as integer, X2 as integer, Y2 as Integer) As double
  '√[(x₂ - x₁)² + (y₂ - y₁)²]
  Return Sqrt((X2 - X1)^2 + (Y2 - Y1)^2)
  End Function

Been a while since I’ve had to use high-school geometry but it was a fun exercise.

Thanks again for the reply, it’s working great. Have a wonderful weekend!


Excellent! I’m happy to help!

Don’t forget to mark a solution.

1 Like