Makie mouse events during drag

I am trying to implement a crosshair, which is updated during a mouse click but can also be “dragged”.
However, register_interaction!(ax, :my_mouse_interaction) do event::MouseEvent does not seem to yield any MouseEvents in GLMakie v0.4.4, while dragging.
Is there a way to enable mouse events during drag, or is it a bug?

1 Like

Try it exactly like it’s described here, you need two arguments for example https://makie.juliaplots.org/dev/examples/layoutables/axis/#function_interaction

Do you mean the , axis after the do keyword? Yes, this is what I did, but I forgot to paste it. The full line is register_interaction!(ax, :my_mouse_interaction) do event::MouseEvent, axis but during a drag event no mouse updates are available.

A bit more experimenting revealed the following behaviour: Starting a drag with the left mouse button yield only a Makie.MakieLayout.MouseEventTypes.leftdown event and no mouse events during the drag. Starting it with the right mouse button yields Makie.MakieLayout.MouseEventTypes.rightdragstart but no events during the drag. Starting it with the middle mouse button yields Makie.MakieLayout.MouseEventTypes.middledragstart and during the drag Makie.MakieLayout.MouseEventTypes.middledrag and the appropriate stop event. This is the way that I would have expected it also for left and right drags, but this is not what happens.

oh it must be the zoom rectangle that consumes the event, have you tried deactivating that one?

That’s a great idea.
Its a little difficult to find out how to deactivate it. Here is the problem:
All the functions accept any arguments and do not throw errors. This has sometimes bad side-effects if you have a typo, and you don’t even know, if you are trying to plug the argument into the right function. E.g., I tried plugging it into image!(rand(10,10), xrectzoom=false, yrectzoom=false) and there is no error, yet the zooming is not deactivated, which I only found out by writing an extra test program with a new figure etc. If I type ?image! there is close to no information. By trial and error I found out, that you can create an image by giving it an axis and also somewhere I found that it has the possible argument interpolate=false. Probably it has many more features, but how can I know?
Also this documentation does not give me more information.

Anyway,
I gave all the axes I created the arguments xrectzoom=false, yrectzoom=false, yet I still have the same missing events problem. Here is a simple code that shows the problem:

fig = Figure()
ax = Axis(fig[1,1], xrectzoom=false, yrectzoom=false)
image!(rand(10,10))
register_interaction!(ax, :my_mouse_interaction) do event::MouseEvent, axis
    @show event.type 
end

As you can see, the zoom is disable, yet the mouse events are still missing as described.

Alternatively you could go through the base event system. If I get it correctly, you want something like

fig, ax, p = scatter(rand(Point2f0, 100))
pos = Node([Point2f0(0)])
scatter!(ax, pos, marker = "+")

# on move, higher priority that interactions (runs first)
on(events(ax.scene).mouseposition, priority = 2) do _
    if ispressed(ax.scene, Mouse.left)
        pos[] = [mouseposition(ax.scene)]
        return Consume(true) # this would block rectangle zoom
    end
    return Consume(false)
end

# on left click/release
on(events(ax.scene).mousebutton, priority = 2) do mb
    if mb.button == Mouse.left 
        pos[] = [mouseposition(ax.scene)]
        return Consume(true)
    end
    return Consume(false)
end

don’t use xrectzoom and yrectzoom, they only lock dimensions. it’s explained here how to remove or deactivate interactions http://makie.juliaplots.org/dev/examples/layoutables/axis/#registering_and_deregistering_interactions

Thanks a lot! The base-level registration of events seems to be fine. Thanks also for the hint on xrectzoom and yrectzoom. Still not quite sure how to deregister this specific zoom interaction responsible for the rectable and whether it would stop shadowing. In the long run, should it not be advantageous when a user registration of an interaction always shadows the predefined one? After all, if the user wants to still inherit the original behaviour, this is what “Consume(false)” is meant to achieve.

Well, the base event system gives me other problems, which I don’t quite now how to deal with properly: I have 3 axes each containing 1 plot in (nested) cells. Via register_interaction the events nicely went to the correct plots, yet at base level, the first registered axis takes over everything.
I probably need to individually test, if this even is within the currently displayed range and not consume it, or is there a better solution?

Yup, you have to do something like if Makie.is_mouseinside(ax.scene) to filter the events you need.

Removing the rectangle zoom is just deregister_interaction!(ax, :rectanglezoom).

2 Likes

Drag is just annoying to implement correctly, so I recommend to use the thing I painstakingly implemented haha :slight_smile: For example, if you use naive drag, you will drag over another axis and activate it as well. It should work once you deregister or deactivate the conflicting interaction, I see no reason why it wouldn’t.

Thanks a lot. This is exactly the information I needed. The deregister did the trick. Works great!

By the way, when GLMakie starts up, I always get tons of warnings like this:

(process:18236): GLib-GIO-WARNING **: 08:00:24.504: Unexpectedly, UWP app `Evernote.Evernote_10.10.5.0_x86__q4d96b2w5wcc2' (AUMId `Evernote.Evernote_q4d96b2w5wcc2!Evernote') supports 1 extensions but has no verbs

And during operation, I sometimes get total crashes when scrolling:

julia> GLFWError (PLATFORM_ERROR): WGL: Failed to make context current: Der angeforderte Transformationsvorgang wird nicht unterstützt. 
Stacktrace:
 [1] _ErrorCallbackWrapper(code::Int32, description::Cstring)
   @ GLFW ~\.julia\packages\GLFW\BWxfF\src\callback.jl:43
 [2] MakeContextCurrent
   @ ~\.julia\packages\GLFW\BWxfF\src\glfw3.jl:694 [inlined]
 [3] make_context_current
   @ ~\.julia\packages\GLMakie\rXGL8\src\drawing_primitives.jl:46 [inlined]
 [4] fps_renderloop(screen::GLMakie.Screen, framerate::Float64)
   @ GLMakie ~\.julia\packages\GLMakie\rXGL8\src\rendering.jl:26
 [5] renderloop(screen::GLMakie.Screen; framerate::Float64)
   @ GLMakie ~\.julia\packages\GLMakie\rXGL8\src\rendering.jl:48
 [6] renderloop(screen::GLMakie.Screen)
   @ GLMakie ~\.julia\packages\GLMakie\rXGL8\src\rendering.jl:41
 [7] (::GLMakie.var"#50#52"{GLMakie.Screen})()
   @ GLMakie .\task.jl:406

I can imagine this. Yet, in my case I just wanted to be able to drag a home-written crosshair along, always centered at the mouse.
That’s a bit easier as you do not “grab” an object.