Keeping track of the state of the input devices Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Karlovsky120
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Dec 01, 2017 7:42 pm

Keeping track of the state of the input devices

Post by Karlovsky120 »

A module in my code needs the current state of the keyboard and the mouse - which buttons are currently pressed, and which aren't.
This is the how it should work:
1. A relevant event is invoked by some change in the input devices - a key being pressed or released.
2. The current state of input (stored somewhere) is then modified to reflect the new change.
3. The new state is sent to the module to process it.
4. Process repeats with a new relevant event.

There are several problems with implementing this in wxWidgets. Firstly, wxWidgets don't store the full keyboard and mouse states anywhere, you can only get what the changes are with the event. That can be sidestepped by implementing a class which could track the changes and keep a list of all currently pressed buttons. I'm assuming that modifier key won't invoke any events, but can be checked via keyboardState wx class once another key does.

Another issue is how to put this into code. Statically linking events to a method is sufficient, but I'll have to write ten very similar but different methods to handle each of the mouse events (three per button and one for scroll wheel). Is there no way to compact this? Is there a way to handle mouse buttons on more global scale, similar to keyboard where event is invoked when any button is pressed or released with the info on the key in question?

What about custom mouse buttons? My own mouse has five more buttons on top of the standard three - how do I track their state/presses/releases? Will that further increase my method count, three per button? I assume that custom keyboard keys have their own key codes and should not pose a problem in that regard.

Lastly, I'm unsure of how mouse click events work. If they are fired, will they be fired along with the mouse up event or will they be fired instead of it?

Finally, to reiterate, the goal here is for my module to have the most recent state of all the keyboard and mouse keys/buttons each time any change with them occurs.

Am I on the right track with this? Am I doing something wrong, is there a better way? Is there a flaw with this system that I may have overlooked? Any ideas how to fix or mitigate the problems I've encountered?
New Pagodi
Super wx Problem Solver
Super wx Problem Solver
Posts: 469
Joined: Tue Jun 20, 2006 6:47 pm
Contact:

Re: Keeping track of the state of the input devices

Post by New Pagodi »

Karlovsky120 wrote:Firstly, wxWidgets don't store the full keyboard and mouse states anywhere, you can only get what the changes are with the event.
At anytime, you can call the global wxGetMouseState(). It returns a wxMouseState object that derives from wxKeyboardState which contains information about which keys, including control keys, are currently being pressed.
I'm assuming that modifier key won't invoke any events, but can be checked via keyboardState wx class once another key does.
Modifier keys (alt, ctrl, shift, windows) will generate charup/down and char hook events. You can see this in the keyboard sample.
Another issue is how to put this into code. Statically linking events to a method is sufficient, but I'll have to write ten very similar but different methods to handle each of the mouse events (three per button and one for scroll wheel). Is there no way to compact this? Is there a way to handle mouse buttons on more global scale, similar to keyboard where event is invoked when any button is pressed or released with the info on the key in question?
If you want, you can bind one handler for as many mouse events as you want and use information from the event object to decide which statements to execute.

Code: Select all

void MyFrame::OnMouse(wxMouseEvent& event)
{
    if ( event.LeftDown() )
    {
        //whatever
    }
    else if ( event.LeftDClick() )
    {
        //whatever
    }
    //and so on for other events
}
By the way, mouse events only apply to the window they're bound to and do not filter up to parent windows if they're not handled by the window.
What about custom mouse buttons? My own mouse has five more buttons on top of the standard three - how do I track their state/presses/releases? Will that further increase my method count, three per button? I assume that custom keyboard keys have their own key codes and should not pose a problem in that regard.
I'm not sure here. There are currently events for Aux1 and Aux2, but beyond that you might have to add use platform specific code here.

Lastly, I'm unsure of how mouse click events work. If they are fired, will they be fired along with the mouse up event or will they be fired instead of it?
I'm not sure I understand the question. The mouse events are generated when they're name suggests they wll be. The wxEVT_LEFT_DOWN event is fired when the left button is pressed down. The wxEVT_RIGHT_UP event is fired when the right mouse button is let up. And so on.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Keeping track of the state of the input devices

Post by doublemax »

Override wxAppConsole::FilterEvent(), where you can catch all events in one place.
http://docs.wxwidgets.org/trunk/classwx ... c6f602e20c

Just out of curiosity: Why do you need the complete input state at once? Checking individual keys (wxGetKeyState) or the mouse state (wxGetMouseState) are pretty cheap function calls.
Use the source, Luke!
Karlovsky120
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Dec 01, 2017 7:42 pm

Re: Keeping track of the state of the input devices

Post by Karlovsky120 »

Thank you for your responses. I'll look into all those things and see how best to use them.

About the wxAppConsole::FilterEvent(), is it possible to use it on a scale of a component? It would be nice if I could intercept all input from a panel and kind of isolate it that way. It might not be the best way, I'll have to think it through still. I'm still curious if it's possible though.

I have a openGLPane within which I run independent openGL code (engine) that is unaware of wxWidgets. There'd be a series of actions within the openGL module that can be invoked as a result of input. Depending on the state wxWidgets is in (which tool is active, etc) a different action would be invoked by possibly the same input.

I also wanted to make a hybrid, use continuous repainting with incremental changes (eg. scene moving), but then repaint only once on singular events (eg. user selecting a tile).

I would also like to be able to change the key bindings, so I'll need an additional level of abstraction, but that is easily done.

I was rethinking the design I proposed even before asking this question, but once I wrote it out, I thought that answers might be useful even if I don't use it. Most of questions asked might come up in a different design as well. I need to start writing the code a bit to get the better idea of what I'd need to make it work, and what would be overkill.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Keeping track of the state of the input devices

Post by doublemax »

About the wxAppConsole::FilterEvent(), is it possible to use it on a scale of a component?
Not directly. But you could catch all events in FilterEvent, and then feed the input state into a singleton class that you can use from everywhere.
Use the source, Luke!
Karlovsky120
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Dec 01, 2017 7:42 pm

Re: Keeping track of the state of the input devices

Post by Karlovsky120 »

Yeah, but the idea was to do it in a way to not add any overhead to events while the panel is not in focus. I could check if the component is in the focus the very first thing and then just pass the event if it isn't. I'm assuming I can't somehow override it only when the desired component has the focus? Or is the overhead so negligible that it doesn't even matter?
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Keeping track of the state of the input devices

Post by doublemax »

If you ignore the mouse motion events and only run your code when a keyboard or mouse key is pressed, i'm sure the overhead is unnoticeable.
Use the source, Luke!
Karlovsky120
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Dec 01, 2017 7:42 pm

Re: Keeping track of the state of the input devices

Post by Karlovsky120 »

Yeah. Okay, I'll mark this as solved, I now have enough info to figure the rest of it on my own. I really appreciate the time and help.
Post Reply