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
- I created a subclass of DesktopCanvas called DragCanvas.
- I added the following three properties:
Private Property isDragging As Boolean = False
Private Property startX As Integer
Private Property startY As Integer
- 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)
- I added the following Event Handlers:
Function MouseDown(x As Integer, y As Integer) Handles MouseDown as Boolean
startX = X
startY = Y
Sub MouseUp(x As Integer, y As Integer) Handles MouseUp
if isDragging = false then
isDragging = False
RaiseEvent DragEnd(X, Y)
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)
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)
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.