Use EventFilter strategy on GTK; leave FocusLost for MSW & OSX.

This commit is contained in:
Jeff Young 2018-09-27 20:42:59 +01:00
parent 136525b870
commit 453dadbc3c
1 changed files with 43 additions and 7 deletions

View File

@ -48,6 +48,38 @@ wxDEFINE_EVENT( NET_SELECTED, wxCommandEvent );
#define NO_NET _( "<no net>" ) #define NO_NET _( "<no net>" )
class POPUP_EVENTFILTER : public wxEventFilter
{
public:
POPUP_EVENTFILTER( wxDialog* aPopup ) :
m_popup( aPopup )
{
wxEvtHandler::AddFilter( this );
}
~POPUP_EVENTFILTER() override
{
wxEvtHandler::RemoveFilter( this );
}
int FilterEvent( wxEvent& aEvent ) override
{
// Click outside popup cancels
if( aEvent.GetEventType() == wxEVT_LEFT_DOWN
&& !m_popup->GetScreenRect().Contains( wxGetMousePosition() ) )
{
m_popup->EndModal( wxID_CANCEL );
return Event_Processed;
}
return Event_Skip;
}
private:
wxDialog* m_popup;
};
class NET_SELECTOR_POPUP : public wxDialog class NET_SELECTOR_POPUP : public wxDialog
{ {
public: public:
@ -112,6 +144,8 @@ public:
// to catch mouse and key events outside our window. // to catch mouse and key events outside our window.
int ShowModal() override int ShowModal() override
{ {
POPUP_EVENTFILTER filter( this );
Show( true ); Show( true );
while( !m_retCode ) while( !m_retCode )
@ -123,10 +157,10 @@ public:
void EndModal( int aReason ) override void EndModal( int aReason ) override
{ {
if( IsShown() ) if( IsShown() )
Show( false ); Show( false );
if( !m_retCode ) if( !m_retCode )
m_retCode = aReason; m_retCode = aReason;
} }
protected: protected:
@ -188,6 +222,7 @@ protected:
onMouseMoved( screenPos ); onMouseMoved( screenPos );
} }
#ifndef __WXGTK__
// Check for loss of focus. This will indicate that a window manager processed // Check for loss of focus. This will indicate that a window manager processed
// an activate event without fully involving wxWidgets (and thus our EventFilter // an activate event without fully involving wxWidgets (and thus our EventFilter
// never got notified of the click). // never got notified of the click).
@ -197,11 +232,12 @@ protected:
if( m_initialized && focus != this && focus != m_netListBox && focus != m_filterCtrl ) if( m_initialized && focus != this && focus != m_netListBox && focus != m_filterCtrl )
EndModal( wxID_CANCEL ); EndModal( wxID_CANCEL );
#endif
} }
// Hot-track the mouse (for focus and listbox selection) // Hot-track the mouse (for focus and listbox selection)
void onMouseMoved( const wxPoint aScreenPos ) void onMouseMoved( const wxPoint aScreenPos )
{ {
if( m_netListBox->GetScreenRect().Contains( aScreenPos ) ) if( m_netListBox->GetScreenRect().Contains( aScreenPos ) )
{ {
doSetFocus( m_netListBox ); doSetFocus( m_netListBox );
@ -217,10 +253,10 @@ protected:
doSetFocus( m_filterCtrl ); doSetFocus( m_filterCtrl );
} }
else if( !m_initialized ) else if( !m_initialized )
{ {
doSetFocus( m_netListBox ); doSetFocus( m_netListBox );
m_initialized = true; m_initialized = true;
} }
} }
void onKeyDown( wxKeyEvent& aEvent ) void onKeyDown( wxKeyEvent& aEvent )
@ -254,9 +290,9 @@ protected:
// textCtrl has focus. Here we pass them directly to the textCtrl. // textCtrl has focus. Here we pass them directly to the textCtrl.
aEvent.SetEventType( wxEVT_KEY_DOWN ); aEvent.SetEventType( wxEVT_KEY_DOWN );
m_filterCtrl->GetEventHandler()->ProcessEventLocally( aEvent ); m_filterCtrl->GetEventHandler()->ProcessEventLocally( aEvent );
} }
break; break;
} }
} }
void onFilterEdit( wxCommandEvent& aEvent ) void onFilterEdit( wxCommandEvent& aEvent )