From d3b2e50200de2ab394a784e9be5c3ef62304c356 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH] Alternative approach to handling events and commands by TOOL_DISPATCHER. Event handlers are (dis)connected depending on the active view. TOOL_DISPATCHER inherits from wxEvtHandler, so now it receives events directly instead of being fed by external handlers. --- common/draw_panel_gal.cpp | 85 ++++++++++++++++++++------------- common/tool/tool_dispatcher.cpp | 2 + include/class_draw_panel_gal.h | 13 ++--- include/tool/tool_dispatcher.h | 4 +- include/wxPcbStruct.h | 2 +- pcbnew/pcbframe.cpp | 6 +++ pcbnew/tools/pcb_tools.cpp | 31 ++---------- 7 files changed, 73 insertions(+), 70 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 3b96ef58cf..e960accb9b 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -41,6 +41,8 @@ #include #include +#include + #ifdef __WXDEBUG__ #include #endif /* __WXDEBUG__ */ @@ -50,6 +52,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin GalType aGalType ) : wxWindow( aParentWindow, aWindowId, aPosition, aSize ) { + m_parent = aParentWindow; m_gal = NULL; m_backend = GAL_TYPE_NONE; m_view = NULL; @@ -67,24 +70,8 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this ); - Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); - - /* Generic events for the Tool Dispatcher */ - Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_CHAR, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); - Connect( KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE, - wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); + Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); // Set up timer that prevents too frequent redraw commands m_refreshTimer.SetOwner( this ); @@ -180,6 +167,53 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool aEraseBackground, const wxRect* aRect ) } +void EDA_DRAW_PANEL_GAL::SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher ) +{ + m_eventDispatcher = aEventDispatcher; + + const wxEventType events[] = + { + wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK, + wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK, + wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK, + wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE + }; + + const wxEventType commands[] = + { +#if wxCHECK_VERSION( 3, 0, 0 ) + wxEVT_TOOL +#else + wxEVT_COMMAND_MENU_SELECTED, wxEVT_COMMAND_TOOL_CLICKED +#endif + }; + + if( m_eventDispatcher ) + { + BOOST_FOREACH( wxEventType eventType, events ) + Connect( eventType, wxEventHandler( TOOL_DISPATCHER::DispatchWxEvent ), + NULL, m_eventDispatcher ); + + BOOST_FOREACH( wxEventType eventType, commands ) + m_parent->Connect( eventType, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ); + } + else + { + // While loops are used to be sure, that we are removing all event handlers + BOOST_FOREACH( wxEventType eventType, events ) + while( Disconnect( eventType, wxEventHandler( TOOL_DISPATCHER::DispatchWxEvent ), + NULL, m_eventDispatcher ) ); + + BOOST_FOREACH( wxEventType eventType, commands ) + while( m_parent->Disconnect( eventType, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ) ); + } +} + + void EDA_DRAW_PANEL_GAL::StartDrawing() { m_pendingRefresh = false; @@ -258,21 +292,6 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) } -void EDA_DRAW_PANEL_GAL::onEvent( wxEvent& aEvent ) -{ - if( !m_eventDispatcher ) - { - aEvent.Skip(); - } - else - { - m_eventDispatcher->DispatchWxEvent( aEvent ); - } - - Refresh(); -} - - void EDA_DRAW_PANEL_GAL::onEnter( wxEvent& aEvent ) { // Getting focus is necessary in order to receive key events properly diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 89c09a16ec..7a3320460b 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -281,6 +281,8 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( evt ) m_toolMgr->ProcessEvent( *evt ); + static_cast( m_toolMgr->GetEditFrame() )->GetGalCanvas()->Refresh(); + // pass the event to the GUI, it might still be interested in it aEvent.Skip(); } diff --git a/include/class_draw_panel_gal.h b/include/class_draw_panel_gal.h index bed6af0890..66793adf04 100644 --- a/include/class_draw_panel_gal.h +++ b/include/class_draw_panel_gal.h @@ -114,11 +114,10 @@ public: * Function SetEventDispatcher() * Sets a dispatcher that processes events and forwards them to tools. * @param aEventDispatcher is the object that will be used for dispatching events. + * DRAW_PANEL_GAL does not take over the ownership. Passing NULL disconnects all event + * handlers from the DRAW_PANEL_GAL and parent frame. */ - void SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher ) - { - m_eventDispatcher = aEventDispatcher; - } + void SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher ); /** * Function StartDrawing() @@ -148,12 +147,14 @@ public: protected: void onPaint( wxPaintEvent& WXUNUSED( aEvent ) ); void onSize( wxSizeEvent& aEvent ); - void onEvent( wxEvent& aEvent ); void onEnter( wxEvent& aEvent ); - void onRefreshTimer ( wxTimerEvent& aEvent ); + void onRefreshTimer( wxTimerEvent& aEvent ); static const int MinRefreshPeriod = 17; ///< 60 FPS. + /// Pointer to the parent window + wxWindow* m_parent; + /// Last timestamp when the panel was refreshed wxLongLong m_lastRefresh; diff --git a/include/tool/tool_dispatcher.h b/include/tool/tool_dispatcher.h index bea510bc0b..8a7289e56c 100644 --- a/include/tool/tool_dispatcher.h +++ b/include/tool/tool_dispatcher.h @@ -26,7 +26,7 @@ #define __TOOL_DISPATCHER_H #include - +#include #include class TOOL_MANAGER; @@ -47,7 +47,7 @@ class VIEW; * - issues TOOL_EVENTS to the tool manager */ -class TOOL_DISPATCHER +class TOOL_DISPATCHER : public wxEvtHandler { public: /** diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 3cba461273..4620fc2767 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -120,9 +120,9 @@ protected: bool m_useCmpFileForFpNames; ///< is true, use the .cmp file from CvPcb, else use the netlist // to know the footprint name of components. + // Functions that handle the Tool Framework (de)initalization void setupTools(); void destroyTools(); - void onGenericCommand( wxCommandEvent& aEvent ); // we'll use lower case function names for private member functions. void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 4b61ec562a..66f939663d 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -636,8 +636,14 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) { SetBoard( m_Pcb ); GetGalCanvas()->GetView()->RecacheAllItems( true ); + GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); GetGalCanvas()->StartDrawing(); } + else + { + // Redirect all events to the legacy canvas + GetGalCanvas()->SetEventDispatcher( NULL ); + } } diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index df0fc1a4ab..83fda666db 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -22,10 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include -#include - #include #include @@ -33,7 +29,7 @@ #include #include -#include +//#include #include "selection_tool.h" #include "edit_tool.h" @@ -47,18 +43,9 @@ void PCB_EDIT_FRAME::setupTools() { // Create the manager and dispatcher & route draw panel events to the dispatcher m_toolManager = new TOOL_MANAGER; + m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); - GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); - - // Connect handlers to toolbar buttons -#if wxCHECK_VERSION( 3, 0, 0 ) - Connect( wxEVT_TOOL, wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); -#else - Connect( wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); - Connect( wxEVT_COMMAND_TOOL_CLICKED, - wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); -#endif // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); @@ -67,9 +54,6 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); - - m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); m_toolManager->ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active @@ -82,12 +66,3 @@ void PCB_EDIT_FRAME::destroyTools() delete m_toolManager; delete m_toolDispatcher; } - - -void PCB_EDIT_FRAME::onGenericCommand( wxCommandEvent& aEvent ) -{ - if( IsGalCanvasActive() ) - m_toolDispatcher->DispatchWxCommand( aEvent ); - else - aEvent.Skip(); -}