TOOL_MANAGER is no longer static. Reworked autoregistration of TOOL_ACTIONs.

This commit is contained in:
Maciej Suminski 2014-05-14 16:29:53 +02:00
parent ae4f41c328
commit def53707d5
11 changed files with 71 additions and 61 deletions

View File

@ -50,6 +50,7 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
// action name without specifying at least toolName is not valid // action name without specifying at least toolName is not valid
assert( aAction->GetName().find( '.', 0 ) != std::string::npos ); assert( aAction->GetName().find( '.', 0 ) != std::string::npos );
// TOOL_ACTIONs must have unique names & ids
assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() ); assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() );
assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() ); assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() );
@ -60,6 +61,8 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
if( aAction->HasHotKey() ) if( aAction->HasHotKey() )
m_actionHotKeys[aAction->m_currentHotKey].push_back( aAction ); m_actionHotKeys[aAction->m_currentHotKey].push_back( aAction );
aAction->setActionMgr( this );
} }
@ -69,6 +72,7 @@ void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
m_actionIdIndex.erase( aAction->m_id ); m_actionIdIndex.erase( aAction->m_id );
// Indicate that the ACTION_MANAGER no longer care about the object // Indicate that the ACTION_MANAGER no longer care about the object
aAction->setActionMgr( NULL );
aAction->setId( -1 ); aAction->setId( -1 );
if( aAction->HasHotKey() ) if( aAction->HasHotKey() )

View File

@ -73,14 +73,8 @@ CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
void CONTEXT_MENU::setupEvents() void CONTEXT_MENU::setupEvents()
{ {
Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CONTEXT_MENU::onMenuEvent ), Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CONTEXT_MENU::onMenuEvent ), NULL, this );
NULL, this ); Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CONTEXT_MENU::onMenuEvent ), NULL, this );
Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CONTEXT_MENU::onMenuEvent ),
NULL, this );
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
wxMenuEvent menuEvent( wxEVT_MENU_HIGHLIGHT, -1, this );
AddPendingEvent( menuEvent );
} }
@ -191,8 +185,11 @@ void CONTEXT_MENU::onMenuEvent( wxEvent& aEvent )
} }
} }
assert( m_tool ); // without tool & tool manager we cannot handle events
// forward the action/update event to the TOOL_MANAGER // forward the action/update event to the TOOL_MANAGER
TOOL_MANAGER::Instance().ProcessEvent( *evt ); if( evt && m_tool )
m_tool->GetManager()->ProcessEvent( *evt );
} }

View File

@ -103,14 +103,6 @@ TOOL_MANAGER::TOOL_MANAGER() :
TOOL_MANAGER::~TOOL_MANAGER() TOOL_MANAGER::~TOOL_MANAGER()
{
DeleteAll();
delete m_actionMgr;
}
void TOOL_MANAGER::DeleteAll()
{ {
std::map<TOOL_BASE*, TOOL_STATE*>::iterator it, it_end; std::map<TOOL_BASE*, TOOL_STATE*>::iterator it, it_end;
@ -122,6 +114,7 @@ void TOOL_MANAGER::DeleteAll()
} }
m_toolState.clear(); m_toolState.clear();
delete m_actionMgr;
} }

View File

@ -52,12 +52,12 @@ public:
m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ), m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ),
m_menuDescription( aMenuDesc ), m_id( -1 ) m_menuDescription( aMenuDesc ), m_id( -1 )
{ {
TOOL_MANAGER::Instance().RegisterAction( this ); TOOL_MANAGER::GetActionList().push_back( this );
} }
~TOOL_ACTION() ~TOOL_ACTION()
{ {
TOOL_MANAGER::Instance().UnregisterAction( this ); TOOL_MANAGER::GetActionList().remove( this );
} }
bool operator==( const TOOL_ACTION& aRhs ) const bool operator==( const TOOL_ACTION& aRhs ) const
@ -195,6 +195,12 @@ private:
m_id = aId; m_id = aId;
} }
/// Assigns ACTION_MANAGER object that handles the TOOL_ACTION.
void setActionMgr( ACTION_MANAGER* aManager )
{
m_actionMgr = aManager;
}
/// Name of the action (convention is: app.[tool.]action.name) /// Name of the action (convention is: app.[tool.]action.name)
std::string m_name; std::string m_name;
@ -219,11 +225,14 @@ private:
/// Unique ID for fast matching. Assigned by ACTION_MANAGER. /// Unique ID for fast matching. Assigned by ACTION_MANAGER.
int m_id; int m_id;
/// Action manager that handles this TOOL_ACTION.
ACTION_MANAGER* m_actionMgr;
/// Origin of the action /// Origin of the action
// const TOOL_BASE* m_origin; // const TOOL_BASE* m_origin;
/// Originating UI object /// Originating UI object
// wxWindow* m_uiOrigin; // wxWindow* m_uiOrigin;
}; };
#endif #endif

View File

@ -48,20 +48,10 @@ class wxWindow;
class TOOL_MANAGER class TOOL_MANAGER
{ {
public: public:
static TOOL_MANAGER& Instance() TOOL_MANAGER();
{
static TOOL_MANAGER manager;
return manager;
}
~TOOL_MANAGER(); ~TOOL_MANAGER();
/**
* Deletes all the tools that were registered in the TOOL_MANAGER.
*/
void DeleteAll();
/** /**
* Generates an unique ID from for a tool with given name. * Generates an unique ID from for a tool with given name.
*/ */
@ -251,9 +241,20 @@ public:
m_passEvent = true; m_passEvent = true;
} }
private: /**
TOOL_MANAGER(); * Returns list of TOOL_ACTIONs. TOOL_ACTIONs add themselves to the list upon their
* creation.
* @return List of TOOL_ACTIONs.
*/
static std::list<TOOL_ACTION*>& GetActionList()
{
// TODO I am afraid this approach won't work when we reach multitab version of kicad.
static std::list<TOOL_ACTION*> actionList;
return actionList;
}
private:
struct TOOL_STATE; struct TOOL_STATE;
typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> TRANSITION; typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> TRANSITION;

View File

@ -90,7 +90,7 @@ protected:
/// main window. /// main window.
wxAuiToolBar* m_auxiliaryToolBar; wxAuiToolBar* m_auxiliaryToolBar;
TOOL_MANAGER& m_toolManager; TOOL_MANAGER* m_toolManager;
TOOL_DISPATCHER* m_toolDispatcher; TOOL_DISPATCHER* m_toolDispatcher;
void updateGridSelectBox(); void updateGridSelectBox();

View File

@ -133,10 +133,10 @@ END_EVENT_TABLE()
PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString & aFrameName ) : long aStyle, const wxString & aFrameName ) :
EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ), EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName )
m_toolManager( TOOL_MANAGER::Instance() )
{ {
m_Pcb = NULL; m_Pcb = NULL;
m_toolManager = NULL;
m_toolDispatcher = NULL; m_toolDispatcher = NULL;
m_DisplayPadFill = true; // How to draw pads m_DisplayPadFill = true; // How to draw pads

View File

@ -637,7 +637,7 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent )
// Inform tools that undo command was issued // Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager.ProcessEvent( event ); m_toolManager->ProcessEvent( event );
/* Get the old list */ /* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
@ -660,7 +660,7 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent )
// Inform tools that redo command was issued // Inform tools that redo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager.ProcessEvent( event ); m_toolManager->ProcessEvent( event );
/* Get the old list */ /* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();

View File

@ -1391,15 +1391,15 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
// Cancel the current tool // Cancel the current tool
// TODO while sending a lot of cancel events works for sure, it is not the most // TODO while sending a lot of cancel events works for sure, it is not the most
// elegant way to cancel a tool, this should be probably done another way // elegant way to cancel a tool, this should be probably done another way
while( m_toolManager.GetCurrentTool()->GetName() != "pcbnew.InteractiveSelection" && while( m_toolManager->GetCurrentTool()->GetName() != "pcbnew.InteractiveSelection" &&
trials++ < MAX_TRIALS ) trials++ < MAX_TRIALS )
{ {
TOOL_EVENT cancel( TC_ANY, TA_CANCEL_TOOL ); TOOL_EVENT cancel( TC_ANY, TA_CANCEL_TOOL );
m_toolManager.ProcessEvent( cancel ); m_toolManager->ProcessEvent( cancel );
} }
if( !actionName.empty() ) if( !actionName.empty() )
m_toolManager.RunAction( actionName ); m_toolManager->RunAction( actionName );
} }
} }
else else

View File

@ -495,9 +495,9 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
ViewReloadBoard( aBoard ); ViewReloadBoard( aBoard );
// update the tool manager with the new board and its view. // update the tool manager with the new board and its view.
m_toolManager.SetEnvironment( aBoard, GetGalCanvas()->GetView(), m_toolManager->SetEnvironment( aBoard, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this ); GetGalCanvas()->GetViewControls(), this );
m_toolManager.ResetTools( TOOL_BASE::MODEL_RELOAD ); m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
} }
} }
@ -677,9 +677,9 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable )
ViewReloadBoard( m_Pcb ); ViewReloadBoard( m_Pcb );
GetGalCanvas()->GetView()->RecacheAllItems(); GetGalCanvas()->GetView()->RecacheAllItems();
m_toolManager.SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this ); GetGalCanvas()->GetViewControls(), this );
m_toolManager.ResetTools( TOOL_BASE::MODEL_RELOAD ); m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
GetGalCanvas()->StartDrawing(); GetGalCanvas()->StartDrawing();
} }

View File

@ -24,6 +24,7 @@
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/event.h> #include <wx/event.h>
#include <boost/foreach.hpp>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <wxBasePcbFrame.h> #include <wxBasePcbFrame.h>
@ -45,8 +46,8 @@
void PCB_EDIT_FRAME::setupTools() void PCB_EDIT_FRAME::setupTools()
{ {
// Create the manager and dispatcher & route draw panel events to the dispatcher // Create the manager and dispatcher & route draw panel events to the dispatcher
m_toolManager = TOOL_MANAGER::Instance(); m_toolManager = new TOOL_MANAGER;
m_toolDispatcher = new TOOL_DISPATCHER( &m_toolManager, this ); m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, this );
GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); GetGalCanvas()->SetEventDispatcher( m_toolDispatcher );
// Connect handlers to toolbar buttons // Connect handlers to toolbar buttons
@ -59,26 +60,31 @@ void PCB_EDIT_FRAME::setupTools()
wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this );
#endif #endif
// Register tools // Register actions
m_toolManager.RegisterTool( new SELECTION_TOOL ); std::list<TOOL_ACTION*>& actionList = m_toolManager->GetActionList();
m_toolManager.RegisterTool( new ROUTER_TOOL ); BOOST_FOREACH( TOOL_ACTION* action, actionList )
m_toolManager.RegisterTool( new EDIT_TOOL ); m_toolManager->RegisterAction( action );
m_toolManager.RegisterTool( new DRAWING_TOOL );
m_toolManager.RegisterTool( new POINT_EDITOR );
m_toolManager.RegisterTool( new PCBNEW_CONTROL );
m_toolManager.SetEnvironment( NULL, GetGalCanvas()->GetView(), // Register tools
GetGalCanvas()->GetViewControls(), this ); m_toolManager->RegisterTool( new SELECTION_TOOL );
m_toolManager.ResetTools( TOOL_BASE::RUN ); m_toolManager->RegisterTool( new ROUTER_TOOL );
m_toolManager->RegisterTool( new EDIT_TOOL );
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 // Run the selection tool, it is supposed to be always active
m_toolManager.InvokeTool( "pcbnew.InteractiveSelection" ); m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" );
} }
void PCB_EDIT_FRAME::destroyTools() void PCB_EDIT_FRAME::destroyTools()
{ {
m_toolManager.DeleteAll(); delete m_toolManager;
delete m_toolDispatcher; delete m_toolDispatcher;
} }