Handling Mouse Events and Getting a Mouse InputDevice

I’m trying to handle two specific mouse-events, without clashing with other objects that may be handling the same events, and without DirectGUI blocking them.

To this end, I’m currently thinking to create a custom ButtonThrower to generate these events.

Creating a ButtonThrower isn’t too difficult, if I have it correctly. However, I think that the next step is to attach this thrower to a data-node, and that’s where I seem to be stuck: The data-node requires an input device, and while it’s easy enough to get one for input devices other than keyboard and mouse, I don’t see a way to get one for the mouse/keyboard-and-mouse.

For reference, this is what I’m trying to do right now, roughly speaking:

thrower = ButtonThrower("mew")
thrower.setButtonUpEvent("keyInterception")
dataNP = base.dataRoot.attachNewNode(InputDeviceNode(device, device.name))
dataNP.node().addChild(thrower)
eventObject.accept("keyInterception", callbackReference)

The problem there being the “device” variable. :/

Does anyone know how to get an InputDevice for the mouse/keyboard-and-mouse? Or have suggestions for alternate implementations of what I’m trying to do?

[edit]
I’ve found “base.win.getInputDevice(0)” as a potential source for that “device” parameter. Alas, however, substituting it in (along with “base.win.getInputDevice(0).name” for the second parameter) doesn’t seem to be working: my callback isn’t called. Hum…

[edit 2]
Ah, I’d forgotten that one can only have a single InputDeviceNode per device–but one can have multiple ButtonThrowers per InputDeviceNode.

Oddly, however, when I change my code to more or less the following:

testThrower = ButtonThrower("mew")
testThrower.setButtonUpEvent("keyInterception")
dataNP = base.dataRoot.getChild(0)
dataNP.node().addChild(testThrower)
navigationEventObject.accept("keyInterception", callbackReference)

I get my callback as expected–but while the keyboard continues to work as expected, mouse-events seem to only go to this new callback! Pre-existing mouse-events seem to no longer work! :/

[edit 3]
In fact, it seems that it’s messing with extant keyboard events, too–it’s just that the exact symptoms are slightly different. :/

[edit 4]
All right, two alternative questions, towards alternative means of implementing what I want:

  1. Is there a way to get a mouse-wheel event from a ButtonThrower via something other than the “button-up” event? (Even something like a “raw button-up” event.)

  2. Is there a way to specify that events from a given DirectObject aren’t affected by DirectGUI?

A ButtonThrower can be given a prefix, e.g.:

testThrower = ButtonThrower("mew")
testThrower.prefix = "cat_"

Then you can listen for an event thrown by it like this:

eventObject.accept("cat_keyInterception", callbackReference)

Usually, I attach a new ButtonThrower to a MouseWatcher, which in turn is parented to a data-node (e.g. the parent of ShowBase.mouseWatcher).

For the mouse wheel events, "wheel_up-up" and "wheel_down-up" should work, I think.

Hmm… I’m not sure that this helps in my situation–although it’s possible that I’m missing something!

So something like this?

testThrower = ButtonThrower("mew")
testThrower.setButtonUpEvent("keyInterception_mew")
mouseWatcher = MouseWatcher("mew")
mouseWatcher.addChild(testThrower)
base.mouseWatcher.getParent().node().addChild(mouseWatcher)
eventObject.accept("keyInterception_mew", callback)

If so, then that seem to give the same results as in “[edit 2]”, above: it functions, but it also breaks existing functionality. :/

I’ve tried just having a DirectObject “accept” the “wheel_down” and “wheel_up” events, but that runs into the problem of DirectGUI blocking them.

Yes, but you should assign a prefix:

testThrower = ButtonThrower("mew")
testThrower.setButtonUpEvent("keyInterception_mew")
testThrower.prefix = "cat_"
mouseWatcher = MouseWatcher("mew")
mouseWatcher.addChild(testThrower)
base.mouseWatcher.parent.attach_new_node(mouseWatcher)
# note the "cat_" prefix!
eventObject.accept("cat_keyInterception_mew", callback)

And you should also be able to catch the wheel events thrown (which of course will also be prefixed with "cat_"):

eventObject.accept("cat_wheel_up-up", on_wheel_up)
eventObject.accept("cat_wheel_down-up", on_wheel_down)

So instead of listening for "event_name", you should listen for "cat_event_name".

Okay, for some reason the “buttonUpEvent” approach doesn’t seem to work when the prefix is in place–but the “wheel_up-up” event does! What’s more, it doesn’t seem to be blocked by DirectGUI!

Thank you very much–I believe that you’ve solved my problem! :slight_smile:

1 Like

Hmmm, that’s strange. What about setButtonDownEvent, does that work? If so, perhaps this needs to be set in order for setButtonUpEvent to have any effect?

What you could always do is call toggleVerbose on base.messenger to see what events are being thrown when you press a button.

You’re most welcome :slight_smile: !

I haven’t tested it since my last post (I’m away from work right now), but in my previous attempts, documented above, I believe that I found that wheel-events seemed to be generated as button-up events, and not button-down events.

However, perhaps things are different with this formulation that you’ve provided!