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.
int MyApp::FilterEvent(wxEvent &event)
{
if( event.GetEventType() == wxEVT_KEY_DOWN /* || event.GetEventType() == wxEVT_KEY_UP */ )
{
wxWindow *focusWindow = wxWindow::FindFocus();
if( focusWindow != NULL ) {
const wxString &className = focusWindow->GetClassInfo()->GetClassName();
// if textctrl has focus, let all keys through
if( className == wxT("wxTextCtrl") )
return wxEventFilter::Event_Skip;
}
wxKeyEvent *ke = wxDynamicCast( &event, wxKeyEvent );
if( ke != NULL )
{
switch( ke->GetKeyCode() )
{
case ' ':
//wxLogMessage("space pressed - do something here");
wxLogDebug("space pressed - do something here");
return wxEventFilter::Event_Processed;
break;
}
}
}
return -1;
}
This just demonstrates the general idea, in practice, you'll probably have to deal with quite a few edge cases.
For communication between the app and the submodules, i'd suggest some kind of signal-slot mechanism, so that you don't have to introduce too many global dependencies, e.g. http://sigslot.sourceforge.net/
Do I need to Bind/Connect this to the frame? If so, what should be the event handler, as this does not work,
You don't need Connect/Bind for this, it's a global event filter, that all events pass through. But it only works in the wxApp object, not any frame or window.
doublemax@work wrote: ↑Mon May 10, 2021 11:50 am
You don't need Connect/Bind for this, it's a global event filter, that all events pass through. But it only works in the wxApp object, not any frame or window.
Okay, moving the method to wxApp class works, but when I have focus on wxDataViewListCtrl all keys except the space key works, wxSearchCtrl is able to filter all keys fine, which is nice. Space key works everywhere else though.
Also, the case statement for what key is pressed, I just call the method for the button or widget, that I want to trigger the action for?, with the key code, like,
If it's not Windows, wxDVC is a native control, and if that consumes any presses of the space key, i don't think there is anything you can do about it.
doublemax@work wrote:
Strange. Remind me what platform you're on?
I'm using Arch Linux.
doublemax@work wrote:
If it's not Windows, wxDVC is a native control, and if that consumes any presses of the space key, i don't think there is anything you can do about it.
I see, I guess I have to use a different keybind in place of space key. BTW, in those switch statements, what do I do now to trigger the action? Do I simply call the function, for example to trigger a action for a wxButton PlayButton, I just call its function OnClickPlayButton()? If so, how would the argument be handled here, as a wxButton takes wxCommandEvent& as its argument.
apoorv569 wrote: ↑Tue May 11, 2021 9:51 am
BTW, in those switch statements, what do I do now to trigger the action? Do I simply call the function, for example to trigger a action for a wxButton PlayButton, I just call its function OnClickPlayButton()? If so, how would the argument be handled here, as a wxButton takes wxCommandEvent& as its argument.
If you want to hardwire everything from inside the filter event handler, then yes. Move the actual code from OnClickPlayButton() into a separate void method. Then you can call this method from the "normal" button event handler (do you even still need this?), or from the filter event handler.
apoorv569 wrote: ↑Tue May 11, 2021 9:51 am
BTW, in those switch statements, what do I do now to trigger the action? Do I simply call the function, for example to trigger a action for a wxButton PlayButton, I just call its function OnClickPlayButton()? If so, how would the argument be handled here, as a wxButton takes wxCommandEvent& as its argument.
If you want to hardwire everything from inside the filter event handler, then yes. Move the actual code from OnClickPlayButton() into a separate void method. Then you can call this method from the "normal" button event handler (do you even still need this?), or from the filter event handler.
And there is another way? What do you mean by hardwire? Is this a wrong way to deal with this?
apoorv569 wrote: ↑Tue May 11, 2021 10:59 am
And there is another way? What do you mean by hardwire? Is this a wrong way to deal with this?
Having a global event handler is always a little messy. A nicer way would be to broadcast an event which could then be received by anyone who's interested in it. But wxWidgets doesn't have that.
If it's only about redirecting a few events to a single control, i would probably do it the same way like you're doing it now.
apoorv569 wrote: ↑Tue May 11, 2021 10:59 am
And there is another way? What do you mean by hardwire? Is this a wrong way to deal with this?
Having a global event handler is always a little messy. A nicer way would be to broadcast an event which could then be received by anyone who's interested in it. But wxWidgets doesn't have that.
If it's only about redirecting a few events to a single control, i would probably do it the same way like you're doing it now.
I want to bind 3 wxButton, 2 wxToggleButton, and 1 wxCheckBox. For this I have move quite a lot of code, as my Browser class, the class where all GUI elements/widgets are defined, has a lot of other things it fetches in these functions from other classes and so on. It is not really convenient to do so, as it might break some stuff, and/or cause bugs in the application. Is there really no other way to be able to do this? So I don't have to mess with existing (working) code.
If these controls lie in the same frame, and the frame handles the events, you could create a wxCommandEvent, fill its members and send it to the frame, mimicking "real" events. Ugly, but should work.
I combined my MainFrame and Browser class to just one class MainFrame, before in MainFrame I was just initializing the wxFrame, and Browser class was inheriting from wxPanel. Tried a couple things, nothing seems to be changed now.
doublemax wrote: ↑Tue May 11, 2021 3:47 pm
If these controls lie in the same frame, and the frame handles the events, you could create a wxCommandEvent, fill its members and send it to the frame, mimicking "real" events. Ugly, but should work.
The method works, I had to make the OnClickPlay() and other method in the above code public, but this method won't let me toggle wxToggleButton and wxCheckBox, Also spacebar does not work still when the focus is on wxDataViewListCtrl. Looks like I have to drop the plan for assigning keybindings. As somethings are simply not working.
wxCommandEvent evt(wxEVT_BUTTON);
// this two are not always needed, depends on your event binding and
// whether the event handlers use these values
evt.SetId( /* control id */ );
evt.SetEventObject( /* control pointer */ );
m_Frame->AddPendingEvent(evt);
wxCommandEvent evt(wxEVT_BUTTON);
// this two are not always needed, depends on your event binding and
// whether the event handlers use these values
evt.SetId( /* control id */ );
evt.SetEventObject( /* control pointer */ );
m_Frame->AddPendingEvent(evt);
This is giving me similar result, only wxButton are able to be assigned, wxToggleButton does not work, also spacebar still won't work if focus is on wxDataViewListCtrl, however I noticed, if I have autoplay (wxCheckBox) checked, then spacebar works. BTW my LoopButton (wxToggleButton) method looking like this,