Fix DIALOG_CHOOSE_COMPONENT enter and double-click events

This commit is contained in:
Chris Pavlina 2017-02-23 20:29:03 -05:00
parent 986c92f880
commit 2683af26c0
5 changed files with 48 additions and 19 deletions

View File

@ -35,6 +35,7 @@
#include <widgets/two_column_tree_list.h>
#include <template_fieldnames.h>
#include <generate_alias_info.h>
#include <make_unique.h>
// 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<wxTimer>( 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:

View File

@ -25,6 +25,8 @@
#define DIALOG_CHOOSE_COMPONENT_H
#include <dialog_choose_component_base.h>
#include <wx/timer.h>
#include <memory>
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<wxTimer> m_dbl_click_timer;
FOOTPRINT_PREVIEW_PANEL* m_footprintPreviewPanel;
static constexpr int DblClickDelay = 100; // milliseconds
};
#endif /* DIALOG_CHOOSE_COMPONENT_H */

View File

@ -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 );

View File

@ -66,7 +66,7 @@
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnIdle">OnIdle</event>
<event name="OnInitDialog">OnInitDialog</event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
@ -312,7 +312,7 @@
<property name="search_button">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="style">wxTE_PROCESS_ENTER</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
@ -345,7 +345,7 @@
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSearchButton"></event>
<event name="OnSearchButton">OnSearchBoxEnter</event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText">OnSearchBoxChange</event>
@ -418,7 +418,7 @@
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp">OnTreeMouseUp</event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>

View File

@ -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(); }