Another attempt to catch enter on GTK, and better button processing.
This commit is contained in:
parent
704615721f
commit
0a43584c5c
|
@ -51,8 +51,10 @@ wxDEFINE_EVENT( NET_SELECTED, wxCommandEvent );
|
||||||
class POPUP_EVENTFILTER : public wxEventFilter
|
class POPUP_EVENTFILTER : public wxEventFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
POPUP_EVENTFILTER( wxDialog* aPopup ) :
|
POPUP_EVENTFILTER( wxDialog* aPopup, wxComboCtrl* aCombobox ) :
|
||||||
m_popup( aPopup )
|
m_popup( aPopup ),
|
||||||
|
m_combobox( aCombobox ),
|
||||||
|
m_firstMouseUp( false )
|
||||||
{
|
{
|
||||||
wxEvtHandler::AddFilter( this );
|
wxEvtHandler::AddFilter( this );
|
||||||
}
|
}
|
||||||
|
@ -63,36 +65,58 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int FilterEvent( wxEvent& aEvent ) override
|
int FilterEvent( wxEvent& aEvent ) override
|
||||||
|
{
|
||||||
|
if( aEvent.GetEventType() == wxEVT_LEFT_DOWN )
|
||||||
{
|
{
|
||||||
// Click outside popup cancels
|
// Click outside popup cancels
|
||||||
if( aEvent.GetEventType() == wxEVT_LEFT_DOWN
|
if( !m_popup->GetScreenRect().Contains( wxGetMousePosition() ) )
|
||||||
&& !m_popup->GetScreenRect().Contains( wxGetMousePosition() ) )
|
|
||||||
{
|
{
|
||||||
m_popup->EndModal( wxID_CANCEL );
|
m_popup->EndModal( wxID_CANCEL );
|
||||||
return Event_Processed;
|
return Event_Processed;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if( aEvent.GetEventType() == wxEVT_LEFT_UP )
|
||||||
|
{
|
||||||
|
if( m_firstMouseUp )
|
||||||
|
{
|
||||||
|
// A first mouse-up inside the popup represents a drag-style menu selection
|
||||||
|
if( m_popup->GetScreenRect().Contains( wxGetMousePosition() ) )
|
||||||
|
m_popup->EndModal( wxID_APPLY );
|
||||||
|
|
||||||
|
// Otherwise the first mouse-up is sent back to the combox button
|
||||||
|
else if( m_combobox->GetButton() )
|
||||||
|
m_combobox->GetButton()->GetEventHandler()->ProcessEvent( aEvent );
|
||||||
|
|
||||||
|
m_firstMouseUp = false;
|
||||||
|
return Event_Processed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Event_Skip;
|
return Event_Skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxDialog* m_popup;
|
wxDialog* m_popup;
|
||||||
|
wxComboCtrl* m_combobox;
|
||||||
|
bool m_firstMouseUp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class NET_SELECTOR_POPUP : public wxDialog
|
class NET_SELECTOR_POPUP : public wxDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NET_SELECTOR_POPUP( wxWindow* aParent, const wxPoint& aPos, const wxSize& aSize,
|
NET_SELECTOR_POPUP( wxComboCtrl* aParent, const wxPoint& aPos, const wxSize& aSize,
|
||||||
NETINFO_LIST* aNetInfoList ) :
|
NETINFO_LIST* aNetInfoList ) :
|
||||||
wxDialog( aParent, wxID_ANY, wxEmptyString, aPos, aSize, wxSIMPLE_BORDER|wxWANTS_CHARS ),
|
wxDialog( aParent->GetParent(), wxID_ANY, wxEmptyString, aPos, aSize,
|
||||||
|
wxSIMPLE_BORDER|wxWANTS_CHARS ),
|
||||||
|
m_parentCombobox( aParent ),
|
||||||
m_popupWidth( -1 ),
|
m_popupWidth( -1 ),
|
||||||
m_maxPopupHeight( 1000 ),
|
m_maxPopupHeight( 1000 ),
|
||||||
m_netinfoList( aNetInfoList ),
|
m_netinfoList( aNetInfoList ),
|
||||||
m_filterCtrl( nullptr ),
|
m_filterCtrl( nullptr ),
|
||||||
m_netListBox( nullptr ),
|
m_netListBox( nullptr ),
|
||||||
m_initialized( false ),
|
m_initialized( false ),
|
||||||
m_selectedNet( 0 ),
|
m_selectedNetcode( 0 ),
|
||||||
m_retCode( 0 )
|
m_retCode( 0 )
|
||||||
{
|
{
|
||||||
SetExtraStyle( wxWS_EX_BLOCK_EVENTS|wxWS_EX_PROCESS_IDLE );
|
SetExtraStyle( wxWS_EX_BLOCK_EVENTS|wxWS_EX_PROCESS_IDLE );
|
||||||
|
@ -116,8 +140,10 @@ public:
|
||||||
Layout();
|
Layout();
|
||||||
|
|
||||||
Connect( wxEVT_IDLE, wxIdleEventHandler( NET_SELECTOR_POPUP::onIdle ), NULL, this );
|
Connect( wxEVT_IDLE, wxIdleEventHandler( NET_SELECTOR_POPUP::onIdle ), NULL, this );
|
||||||
|
Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
||||||
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
||||||
m_netListBox->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( NET_SELECTOR_POPUP::onListBoxMouseClick ), NULL, this );
|
m_netListBox->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( NET_SELECTOR_POPUP::onListBoxMouseClick ), NULL, this );
|
||||||
|
m_netListBox->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
||||||
m_filterCtrl->Connect( wxEVT_TEXT, wxCommandEventHandler( NET_SELECTOR_POPUP::onFilterEdit ), NULL, this );
|
m_filterCtrl->Connect( wxEVT_TEXT, wxCommandEventHandler( NET_SELECTOR_POPUP::onFilterEdit ), NULL, this );
|
||||||
|
|
||||||
rebuildList();
|
rebuildList();
|
||||||
|
@ -126,29 +152,32 @@ public:
|
||||||
~NET_SELECTOR_POPUP()
|
~NET_SELECTOR_POPUP()
|
||||||
{
|
{
|
||||||
Disconnect( wxEVT_IDLE, wxIdleEventHandler( NET_SELECTOR_POPUP::onIdle ), NULL, this );
|
Disconnect( wxEVT_IDLE, wxIdleEventHandler( NET_SELECTOR_POPUP::onIdle ), NULL, this );
|
||||||
|
Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
||||||
Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
||||||
m_netListBox->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( NET_SELECTOR_POPUP::onListBoxMouseClick ), NULL, this );
|
m_netListBox->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( NET_SELECTOR_POPUP::onListBoxMouseClick ), NULL, this );
|
||||||
|
m_netListBox->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( NET_SELECTOR_POPUP::onKeyDown ), NULL, this );
|
||||||
m_filterCtrl->Disconnect( wxEVT_TEXT, wxCommandEventHandler( NET_SELECTOR_POPUP::onFilterEdit ), NULL, this );
|
m_filterCtrl->Disconnect( wxEVT_TEXT, wxCommandEventHandler( NET_SELECTOR_POPUP::onFilterEdit ), NULL, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSelectedNetcode( int aNetcode )
|
void SetSelectedNetcode( int aNetcode )
|
||||||
{
|
{
|
||||||
m_selectedNet = aNetcode;
|
m_selectedNetcode = aNetcode;
|
||||||
m_netListBox->SetFocus();
|
m_netListBox->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetSelectedNetcode()
|
int GetSelectedNetcode()
|
||||||
{
|
{
|
||||||
return m_selectedNet;
|
return m_selectedNetcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// While we act like a modal our implementation is not modal. This is done to allow us
|
// While we act like a modal our implementation is not modal. This is done to allow us
|
||||||
// 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 );
|
POPUP_EVENTFILTER filter( this, m_parentCombobox );
|
||||||
|
|
||||||
Show( true );
|
Show( true );
|
||||||
|
doSetFocus( m_netListBox );
|
||||||
|
|
||||||
while( !m_retCode )
|
while( !m_retCode )
|
||||||
wxYield();
|
wxYield();
|
||||||
|
@ -162,8 +191,35 @@ public:
|
||||||
Show( false );
|
Show( false );
|
||||||
|
|
||||||
if( !m_retCode )
|
if( !m_retCode )
|
||||||
|
{
|
||||||
|
if( aReason == wxID_APPLY )
|
||||||
|
{
|
||||||
|
wxString selectedNetName;
|
||||||
|
int selection = m_netListBox->GetSelection();
|
||||||
|
|
||||||
|
if( selection >= 0 )
|
||||||
|
m_netListBox->GetString( (unsigned) selection );
|
||||||
|
|
||||||
|
if( selectedNetName.IsEmpty() )
|
||||||
|
{
|
||||||
|
m_selectedNetcode = -1;
|
||||||
|
m_retCode = wxID_CANCEL;
|
||||||
|
}
|
||||||
|
else if( selectedNetName == NO_NET )
|
||||||
|
{
|
||||||
|
m_selectedNetcode = 0;
|
||||||
|
m_retCode = wxID_OK ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_selectedNetcode = m_netinfoList->GetNetItem( selectedNetName )->GetNet();
|
||||||
|
m_retCode = wxID_OK ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
m_retCode = aReason;
|
m_retCode = aReason;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateSize()
|
void updateSize()
|
||||||
|
@ -227,8 +283,7 @@ protected:
|
||||||
#ifndef __WXGTK__
|
#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). This is possibly an OSX-only issue, but it
|
// never got notified of the click).
|
||||||
// doesn't seem to cause any harm on MSW.
|
|
||||||
// Note: don't try to do this with KillFocus events; the event ordering is too
|
// Note: don't try to do this with KillFocus events; the event ordering is too
|
||||||
// platform-dependant.
|
// platform-dependant.
|
||||||
wxWindow* focus = wxWindow::FindFocus();
|
wxWindow* focus = wxWindow::FindFocus();
|
||||||
|
@ -278,7 +333,7 @@ protected:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WXK_RETURN:
|
case WXK_RETURN:
|
||||||
doSelect( m_netListBox->GetSelection() );
|
EndModal( wxID_APPLY );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WXK_DOWN:
|
case WXK_DOWN:
|
||||||
|
@ -306,7 +361,8 @@ protected:
|
||||||
|
|
||||||
void onListBoxMouseClick( wxMouseEvent& aEvent )
|
void onListBoxMouseClick( wxMouseEvent& aEvent )
|
||||||
{
|
{
|
||||||
doSelect( m_netListBox->HitTest( aEvent.GetPosition()));
|
m_netListBox->SetSelection( m_netListBox->HitTest( aEvent.GetPosition() ) );
|
||||||
|
EndModal( wxID_APPLY );
|
||||||
}
|
}
|
||||||
|
|
||||||
void doSetFocus( wxWindow* aWindow )
|
void doSetFocus( wxWindow* aWindow )
|
||||||
|
@ -318,26 +374,8 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void doSelect( int aItem )
|
|
||||||
{
|
|
||||||
if( aItem >= 0 )
|
|
||||||
{
|
|
||||||
wxString selectedNetName = m_netListBox->GetString( (unsigned) aItem );
|
|
||||||
|
|
||||||
if( selectedNetName.IsEmpty() )
|
|
||||||
m_selectedNet = -1;
|
|
||||||
else if( selectedNetName == NO_NET )
|
|
||||||
m_selectedNet = 0;
|
|
||||||
else
|
|
||||||
m_selectedNet = m_netinfoList->GetNetItem( selectedNetName )->GetNet();
|
|
||||||
|
|
||||||
EndModal( wxID_OK );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
EndModal( wxID_CANCEL );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
wxComboCtrl* m_parentCombobox;
|
||||||
int m_popupWidth;
|
int m_popupWidth;
|
||||||
int m_maxPopupHeight;
|
int m_maxPopupHeight;
|
||||||
NETINFO_LIST* m_netinfoList;
|
NETINFO_LIST* m_netinfoList;
|
||||||
|
@ -347,7 +385,7 @@ protected:
|
||||||
|
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
|
|
||||||
int m_selectedNet;
|
int m_selectedNetcode;
|
||||||
int m_retCode;
|
int m_retCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -379,9 +417,6 @@ void NET_SELECTOR::OnButtonClick()
|
||||||
if( m_netSelectorPopup )
|
if( m_netSelectorPopup )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Allow button to process mouse-up event
|
|
||||||
wxYield();
|
|
||||||
|
|
||||||
wxRect comboRect = GetScreenRect();
|
wxRect comboRect = GetScreenRect();
|
||||||
wxPoint popupPos( comboRect.x + POPUP_PADDING, comboRect.y + comboRect.height );
|
wxPoint popupPos( comboRect.x + POPUP_PADDING, comboRect.y + comboRect.height );
|
||||||
wxDisplay display( (unsigned) wxDisplay::GetFromWindow( this ) );
|
wxDisplay display( (unsigned) wxDisplay::GetFromWindow( this ) );
|
||||||
|
@ -389,7 +424,7 @@ void NET_SELECTOR::OnButtonClick()
|
||||||
wxSize popupSize( comboRect.width - ( POPUP_PADDING * 2 ),
|
wxSize popupSize( comboRect.width - ( POPUP_PADDING * 2 ),
|
||||||
display.GetClientArea().y + display.GetClientArea().height - popupPos.y );
|
display.GetClientArea().y + display.GetClientArea().height - popupPos.y );
|
||||||
|
|
||||||
m_netSelectorPopup = new NET_SELECTOR_POPUP( m_parent, popupPos, popupSize, m_netinfoList );
|
m_netSelectorPopup = new NET_SELECTOR_POPUP( this, popupPos, popupSize, m_netinfoList );
|
||||||
|
|
||||||
m_netSelectorPopup->SetSelectedNetcode( m_netcode );
|
m_netSelectorPopup->SetSelectedNetcode( m_netcode );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue