From 2683af26c01d50c26bd4e07bdf159503aa52873e Mon Sep 17 00:00:00 2001 From: Chris Pavlina Date: Thu, 23 Feb 2017 20:29:03 -0500 Subject: [PATCH] Fix DIALOG_CHOOSE_COMPONENT enter and double-click events --- eeschema/dialogs/dialog_choose_component.cpp | 39 ++++++++++++++----- eeschema/dialogs/dialog_choose_component.h | 8 +++- .../dialogs/dialog_choose_component_base.cpp | 8 ++-- .../dialogs/dialog_choose_component_base.fbp | 8 ++-- .../dialogs/dialog_choose_component_base.h | 4 +- 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp index 858043448f..6c608357e2 100644 --- a/eeschema/dialogs/dialog_choose_component.cpp +++ b/eeschema/dialogs/dialog_choose_component.cpp @@ -35,6 +35,7 @@ #include #include #include +#include // Tree navigation helpers. static wxTreeListItem GetPrevItem( const wxTreeListCtrl& tree, const wxTreeListItem& item ); @@ -53,6 +54,7 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const m_received_doubleclick_in_tree = false; m_search_container->SetTree( m_libraryComponentTree ); m_componentView->SetLayoutDirection( wxLayout_LeftToRight ); + m_dbl_click_timer = std::make_unique( this ); // Initialize footprint preview through Kiway m_footprintPreviewPanel = @@ -69,6 +71,7 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const m_chooseFootprint->Hide(); #endif + Bind( wxEVT_TIMER, &DIALOG_CHOOSE_COMPONENT::OnCloseTimer, this ); Layout(); Centre(); @@ -166,10 +169,6 @@ void DIALOG_CHOOSE_COMPONENT::OnTreeSelect( wxTreeListEvent& aEvent ) } -// Test strategy for OnDoubleClickTreeActivation()/OnTreeMouseUp() work around wxWidgets bug: -// - search for an item. -// - use the mouse to double-click on an item in the tree. -// -> The dialog should close, and the component should _not_ be immediately placed void DIALOG_CHOOSE_COMPONENT::OnDoubleClickTreeActivation( wxTreeListEvent& aEvent ) { if( !updateSelection() ) @@ -179,16 +178,38 @@ void DIALOG_CHOOSE_COMPONENT::OnDoubleClickTreeActivation( wxTreeListEvent& aEve // wait for the MouseUp event to occur. Otherwise something (broken?) // happens: the dialog will close and will deliver the 'MouseUp' event // to the eeschema canvas, that will immediately place the component. + // + // NOW, here's where it gets really fun. wxTreeListCtrl eats MouseUp. + // This isn't really feasible to bypass without a fully custom + // wxDataViewCtrl implementation, and even then might not be fully + // possible (docs are vague). To get around this, we use a one-shot + // timer to schedule the dialog close. + // + // See DIALOG_CHOOSE_COMPONENT::OnCloseTimer for the other end of this + // spaghetti noodle. m_received_doubleclick_in_tree = true; + m_dbl_click_timer->StartOnce( DIALOG_CHOOSE_COMPONENT::DblClickDelay ); } -void DIALOG_CHOOSE_COMPONENT::OnTreeMouseUp( wxMouseEvent& aMouseEvent ) +void DIALOG_CHOOSE_COMPONENT::OnCloseTimer( wxTimerEvent& aEvent ) { - if( m_received_doubleclick_in_tree ) - EndModal( wxID_OK ); // We are done (see OnDoubleClickTreeSelect) - else - aMouseEvent.Skip(); // Let upstream handle it. + // Hack handler because of eaten MouseUp event. See + // DIALOG_CHOOSE_COMPONENT::OnDoubleClickTreeActivation for the beginning + // of this spaghetti noodle. + + auto state = wxGetMouseState(); + + if( state.LeftIsDown() ) + { + // Mouse hasn't been raised yet, so fire the timer again. Otherwise the + // purpose of this timer is defeated. + m_dbl_click_timer->StartOnce( DIALOG_CHOOSE_COMPONENT::DblClickDelay ); + } + else if( m_received_doubleclick_in_tree ) + { + EndModal( wxID_OK ); + } } // Test strategy to see if OnInterceptTreeEnter() works: diff --git a/eeschema/dialogs/dialog_choose_component.h b/eeschema/dialogs/dialog_choose_component.h index 9b5ab95221..77c3b1b2f4 100644 --- a/eeschema/dialogs/dialog_choose_component.h +++ b/eeschema/dialogs/dialog_choose_component.h @@ -25,6 +25,8 @@ #define DIALOG_CHOOSE_COMPONENT_H #include +#include +#include class FOOTPRINT_PREVIEW_PANEL; class COMPONENT_TREE_SEARCH_CONTAINER; @@ -80,12 +82,13 @@ protected: virtual void OnTreeSelect( wxTreeListEvent& aEvent ) override; virtual void OnDoubleClickTreeActivation( wxTreeListEvent& aEvent ) override; virtual void OnInterceptTreeEnter( wxKeyEvent& aEvent ) override; - virtual void OnTreeMouseUp( wxMouseEvent& aMouseEvent ) override; virtual void OnStartComponentBrowser( wxMouseEvent& aEvent ) override; virtual void OnHandlePreviewRepaint( wxPaintEvent& aRepaintEvent ) override; virtual void OnDatasheetClick( wxHtmlLinkEvent& aEvent ) override; + virtual void OnCloseTimer( wxTimerEvent& aEvent ); + private: bool updateSelection(); void selectIfValid( const wxTreeListItem& aTreeId ); @@ -93,7 +96,10 @@ private: void updateFootprint(); + std::unique_ptr m_dbl_click_timer; FOOTPRINT_PREVIEW_PANEL* m_footprintPreviewPanel; + + static constexpr int DblClickDelay = 100; // milliseconds }; #endif /* DIALOG_CHOOSE_COMPONENT_H */ diff --git a/eeschema/dialogs/dialog_choose_component_base.cpp b/eeschema/dialogs/dialog_choose_component_base.cpp index 12ce4b9003..60b4b818a9 100644 --- a/eeschema/dialogs/dialog_choose_component_base.cpp +++ b/eeschema/dialogs/dialog_choose_component_base.cpp @@ -27,7 +27,7 @@ DIALOG_CHOOSE_COMPONENT_BASE::DIALOG_CHOOSE_COMPONENT_BASE( wxWindow* parent, wx wxBoxSizer* bSizer10; bSizer10 = new wxBoxSizer( wxVERTICAL ); - m_searchBox = new wxSearchCtrl( m_panel3, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_searchBox = new wxSearchCtrl( m_panel3, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); #ifndef __WXMAC__ m_searchBox->ShowSearchButton( true ); #endif @@ -101,12 +101,13 @@ DIALOG_CHOOSE_COMPONENT_BASE::DIALOG_CHOOSE_COMPONENT_BASE( wxWindow* parent, wx this->Centre( wxBOTH ); // Connect Events + this->Connect( wxEVT_IDLE, wxIdleEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnIdle ) ); this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInitDialog ) ); m_searchBox->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptSearchBoxKey ), NULL, this ); + m_searchBox->Connect( wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxEnter ), NULL, this ); m_searchBox->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxChange ), NULL, this ); m_searchBox->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxEnter ), NULL, this ); m_libraryComponentTree->Connect( wxEVT_KEY_UP, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptTreeEnter ), NULL, this ); - m_libraryComponentTree->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeMouseUp ), NULL, this ); m_libraryComponentTree->Connect( wxEVT_TREELIST_ITEM_ACTIVATED, wxTreeListEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnDoubleClickTreeActivation ), NULL, this ); m_libraryComponentTree->Connect( wxEVT_TREELIST_SELECTION_CHANGED, wxTreeListEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeSelect ), NULL, this ); m_componentDetails->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnDatasheetClick ), NULL, this ); @@ -117,12 +118,13 @@ DIALOG_CHOOSE_COMPONENT_BASE::DIALOG_CHOOSE_COMPONENT_BASE( wxWindow* parent, wx DIALOG_CHOOSE_COMPONENT_BASE::~DIALOG_CHOOSE_COMPONENT_BASE() { // Disconnect Events + this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnIdle ) ); this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInitDialog ) ); m_searchBox->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptSearchBoxKey ), NULL, this ); + m_searchBox->Disconnect( wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxEnter ), NULL, this ); m_searchBox->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxChange ), NULL, this ); m_searchBox->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxEnter ), NULL, this ); m_libraryComponentTree->Disconnect( wxEVT_KEY_UP, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptTreeEnter ), NULL, this ); - m_libraryComponentTree->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeMouseUp ), NULL, this ); m_libraryComponentTree->Disconnect( wxEVT_TREELIST_ITEM_ACTIVATED, wxTreeListEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnDoubleClickTreeActivation ), NULL, this ); m_libraryComponentTree->Disconnect( wxEVT_TREELIST_SELECTION_CHANGED, wxTreeListEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeSelect ), NULL, this ); m_componentDetails->Disconnect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnDatasheetClick ), NULL, this ); diff --git a/eeschema/dialogs/dialog_choose_component_base.fbp b/eeschema/dialogs/dialog_choose_component_base.fbp index 88a3443ef3..53a3f6ee0e 100644 --- a/eeschema/dialogs/dialog_choose_component_base.fbp +++ b/eeschema/dialogs/dialog_choose_component_base.fbp @@ -66,7 +66,7 @@ - + OnIdle OnInitDialog @@ -312,7 +312,7 @@ 1 1 - + wxTE_PROCESS_ENTER 0 @@ -345,7 +345,7 @@ - + OnSearchBoxEnter OnSearchBoxChange @@ -418,7 +418,7 @@ - OnTreeMouseUp + diff --git a/eeschema/dialogs/dialog_choose_component_base.h b/eeschema/dialogs/dialog_choose_component_base.h index bcf9209d7a..b67b1d8845 100644 --- a/eeschema/dialogs/dialog_choose_component_base.h +++ b/eeschema/dialogs/dialog_choose_component_base.h @@ -55,12 +55,12 @@ class DIALOG_CHOOSE_COMPONENT_BASE : public DIALOG_SHIM wxButton* m_stdButtonsCancel; // Virtual event handlers, overide them in your derived class + virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); } virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); } virtual void OnInterceptSearchBoxKey( wxKeyEvent& event ) { event.Skip(); } - virtual void OnSearchBoxChange( wxCommandEvent& event ) { event.Skip(); } virtual void OnSearchBoxEnter( wxCommandEvent& event ) { event.Skip(); } + virtual void OnSearchBoxChange( wxCommandEvent& event ) { event.Skip(); } virtual void OnInterceptTreeEnter( wxKeyEvent& event ) { event.Skip(); } - virtual void OnTreeMouseUp( wxMouseEvent& event ) { event.Skip(); } virtual void OnDoubleClickTreeActivation( wxTreeListEvent& event ) { event.Skip(); } virtual void OnTreeSelect( wxTreeListEvent& event ) { event.Skip(); } virtual void OnDatasheetClick( wxHtmlLinkEvent& event ) { event.Skip(); }