Removed TA_ActivateTool (now tools are invoked by sending TA_Action event, with the tool name as string parameter).
Developed TOOL_Action class & added ActionManager. Hot keys registered by tools are processed. Selection & move tool can be invoked by a hot key.
This commit is contained in:
parent
eb784536af
commit
2c03bf4109
|
@ -162,6 +162,7 @@ set(COMMON_SRCS
|
|||
tool/tool_dispatcher.cpp
|
||||
tool/tool_event.cpp
|
||||
tool/tool_interactive.cpp
|
||||
tool/action_manager.cpp
|
||||
tool/context_menu.cpp
|
||||
|
||||
geometry/seg.cpp
|
||||
|
|
|
@ -83,9 +83,9 @@ const std::string TOOL_EVENT::Format() const
|
|||
{ TA_ViewDirty, "view-dirty" },
|
||||
{ TA_ChangeLayer, "change-layer" },
|
||||
{ TA_CancelTool, "cancel-tool" },
|
||||
{ TA_ActivateTool, "activate-tool" },
|
||||
{ TA_ContextMenuUpdate, "context-menu-update" },
|
||||
{ TA_ContextMenuChoice, "context-menu-choice" },
|
||||
{ TA_Action, "action" },
|
||||
{ 0, "" }
|
||||
};
|
||||
|
||||
|
|
|
@ -82,9 +82,8 @@ struct TOOL_MANAGER::TOOL_STATE
|
|||
|
||||
|
||||
TOOL_MANAGER::TOOL_MANAGER() :
|
||||
m_model( NULL ), m_view( NULL )
|
||||
m_actionMgr( this ), m_model( NULL ), m_view( NULL )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,38 +127,79 @@ bool TOOL_MANAGER::InvokeTool( TOOL_ID aToolId )
|
|||
TOOL_BASE* tool = FindTool( aToolId );
|
||||
|
||||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
{
|
||||
// If the tool is already active, do not invoke it again
|
||||
if( m_toolIdIndex[aToolId]->idle == false )
|
||||
return false;
|
||||
|
||||
m_toolIdIndex[aToolId]->idle = false;
|
||||
static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
|
||||
|
||||
TOOL_EVENT evt( TC_Command, TA_ActivateTool, tool->GetName() );
|
||||
ProcessEvent( evt );
|
||||
|
||||
// Save the tool on the front of the processing queue
|
||||
m_activeTools.push_front( aToolId );
|
||||
|
||||
return true;
|
||||
}
|
||||
return invokeTool( tool );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::InvokeTool( const std::string& aName )
|
||||
bool TOOL_MANAGER::InvokeTool( const std::string& aToolName )
|
||||
{
|
||||
TOOL_BASE* tool = FindTool( aName );
|
||||
TOOL_BASE* tool = FindTool( aToolName );
|
||||
|
||||
if( tool )
|
||||
return InvokeTool( tool->GetId() );
|
||||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
return invokeTool( tool );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool )
|
||||
{
|
||||
wxASSERT( aTool != NULL );
|
||||
|
||||
TOOL_EVENT evt( TC_Command, TA_Action, aTool->GetName() );
|
||||
ProcessEvent( evt );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::runTool( TOOL_ID aToolId )
|
||||
{
|
||||
TOOL_BASE* tool = FindTool( aToolId );
|
||||
|
||||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
return runTool( tool );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::runTool( const std::string& aToolName )
|
||||
{
|
||||
TOOL_BASE* tool = FindTool( aToolName );
|
||||
|
||||
if( tool && tool->GetType() == TOOL_Interactive )
|
||||
return runTool( tool );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::runTool( TOOL_BASE* aTool )
|
||||
{
|
||||
wxASSERT( aTool != NULL );
|
||||
|
||||
if( !isRegistered( aTool ) )
|
||||
return false;
|
||||
|
||||
TOOL_STATE* state = m_toolState[aTool];
|
||||
|
||||
// If the tool is already active, do not invoke it again
|
||||
if( state->idle == false )
|
||||
return false;
|
||||
state->idle = false;
|
||||
|
||||
static_cast<TOOL_INTERACTIVE*>( aTool )->Reset();
|
||||
|
||||
// Add the tool on the front of the processing queue (it gets events first)
|
||||
m_activeTools.push_front( aTool->GetId() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TOOL_BASE* TOOL_MANAGER::FindTool( int aId ) const
|
||||
{
|
||||
std::map<TOOL_ID, TOOL_STATE*>::const_iterator it = m_toolIdIndex.find( aId );
|
||||
|
@ -228,7 +268,8 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
|||
finishTool( st );
|
||||
}
|
||||
|
||||
// The tool requested to stop propagating event to other tools
|
||||
// If the tool did not request to propagate
|
||||
// the event to other tools, we should stop it now
|
||||
if( !m_passEvent )
|
||||
break;
|
||||
}
|
||||
|
@ -269,6 +310,21 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent )
|
||||
{
|
||||
BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values )
|
||||
{
|
||||
if( st->theTool->GetName() == aEvent.m_commandStr )
|
||||
{
|
||||
runTool( st->theTool );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
|
||||
{
|
||||
wxASSERT( m_activeTools.front() == aState->theTool->GetId() );
|
||||
|
@ -286,8 +342,18 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
|
|||
{
|
||||
// wxLogDebug( "event: %s", aEvent.Format().c_str() );
|
||||
|
||||
if( aEvent.Action() == TA_KeyUp )
|
||||
{
|
||||
// Check if there is a hotkey associated
|
||||
if( m_actionMgr.RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) )
|
||||
return false; // hotkey event was handled so it does not go any further
|
||||
} else if( aEvent.Category() == TC_Command ) // it may be a tool activation event
|
||||
{
|
||||
dispatchActivation( aEvent );
|
||||
}
|
||||
|
||||
dispatchInternal( aEvent );
|
||||
|
||||
|
||||
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
|
||||
{
|
||||
TOOL_STATE* st = m_toolIdIndex[toolId];
|
||||
|
@ -359,3 +425,12 @@ void TOOL_MANAGER::SetEnvironment( EDA_ITEM* aModel, KiGfx::VIEW* aView,
|
|||
static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_MANAGER::isActive( TOOL_BASE* aTool )
|
||||
{
|
||||
if( !isRegistered( aTool ) )
|
||||
return false;
|
||||
|
||||
return !m_toolState[aTool]->idle;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __TOOL_ACTION_H
|
||||
#define __TOOL_ACTION_H
|
||||
|
||||
|
@ -5,82 +29,157 @@
|
|||
#include <wx/wx.h>
|
||||
|
||||
#include <tool/tool_base.h>
|
||||
|
||||
///> Scope of tool actions
|
||||
enum TOOL_ActionScope {
|
||||
SCOPE_CONTEXT = 1, ///> Action belongs to a particular tool (i.e. a part of a pop-up menu)
|
||||
SCOPE_GLOBAL ///> Global action (toolbar/main menu event, global shortcut)
|
||||
};
|
||||
#include <tool/action_manager.h>
|
||||
|
||||
// TOOL_ACTION - represents a single action. For instance:
|
||||
// - changing layer to top by pressing PgUp
|
||||
// - running the DRC from the menu
|
||||
// and so on, and so forth....
|
||||
class TOOL_ACTION
|
||||
class TOOL_ACTION
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
TOOL_ACTION( const std::string& aName, TOOL_ActionScope aScope = AS_CONTEXT, int aDefaultHotKey = 0,
|
||||
const wxString& aMenuItem = wxT( "" ), const wxString& aMenuDesc = wxT( "" ) ) :
|
||||
m_name( aName ), m_scope( aScope ), m_defaultHotKey( aDefaultHotKey ),
|
||||
m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ),
|
||||
m_menuDescription( aMenuDesc ), m_id( -1 ), m_actionMgr( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
TOOL_ACTION
|
||||
(
|
||||
const std::string& name,
|
||||
TOOL_ActionScope scope = SCOPE_GLOBAL,
|
||||
int aDefaultHotKey = 0,
|
||||
const wxString& menuItem = wxT(""),
|
||||
const wxString& menuDesc = wxT("")
|
||||
) :
|
||||
m_name(name),
|
||||
m_scope(scope),
|
||||
m_defaultHotKey(aDefaultHotKey),
|
||||
m_currentHotKey(aDefaultHotKey),
|
||||
m_menuItem(menuItem),
|
||||
m_menuDescription(menuDesc) {}
|
||||
~TOOL_ACTION()
|
||||
{
|
||||
if( m_actionMgr )
|
||||
m_actionMgr->UnregisterAction( this );
|
||||
}
|
||||
|
||||
bool operator == ( const TOOL_ACTION& rhs ) const
|
||||
{
|
||||
return m_id == rhs.m_id;
|
||||
}
|
||||
bool operator==( const TOOL_ACTION& aRhs ) const
|
||||
{
|
||||
return m_id == aRhs.m_id;
|
||||
}
|
||||
|
||||
bool operator != ( const TOOL_ACTION& rhs ) const
|
||||
{
|
||||
return m_id != rhs.m_id;
|
||||
}
|
||||
bool operator!=( const TOOL_ACTION& aRhs ) const
|
||||
{
|
||||
return m_id != aRhs.m_id;
|
||||
}
|
||||
|
||||
bool hasHotKey() const
|
||||
{
|
||||
return m_currentHotKey > 0;
|
||||
}
|
||||
/**
|
||||
* Function GetName()
|
||||
* Returns name of the action. It is the same one that is contained in TOOL_EVENT that is
|
||||
* sent by activating the TOOL_ACTION.
|
||||
*
|
||||
* @return Name of the action.
|
||||
*/
|
||||
const std::string& GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class TOOL_MANAGER;
|
||||
/**
|
||||
* Function GetId()
|
||||
* Returns the unique id of the TOOL_ACTION object. It is valid only after registering the
|
||||
* TOOL_ACTION by ACTION_MANAGER.
|
||||
*
|
||||
* @return The unique identification number. If the number is negative, then it is not valid.
|
||||
*/
|
||||
int GetId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void setId ( int aId )
|
||||
{
|
||||
m_id = aId;
|
||||
}
|
||||
/**
|
||||
* Function ChangeHotKey()
|
||||
* Assigns a new hot key.
|
||||
*
|
||||
* @param aNewHotKey is the new hot key.
|
||||
*/
|
||||
void ChangeHotKey( int aNewHotKey )
|
||||
{
|
||||
wxASSERT_MSG( false, wxT( "It is not fully implemented yet") );
|
||||
// I mean it has to be changed in the ACTION_MANAGER, or change the implementation
|
||||
m_currentHotKey = aNewHotKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function RestoreHotKey()
|
||||
* Changes the assigned hot key to the default one.
|
||||
*/
|
||||
void RestoreHotKey()
|
||||
{
|
||||
wxASSERT_MSG( false, wxT( "It is not fully implemented yet") );
|
||||
// I mean it has to be changed in the ACTION_MANAGER, or change the implementation
|
||||
m_currentHotKey = m_defaultHotKey;
|
||||
}
|
||||
|
||||
// name of the action (convention is: app.[tool.]action.name)
|
||||
std::string m_name;
|
||||
TOOL_ActionScope m_scope;
|
||||
int m_defaultHotKey;
|
||||
int m_currentHotKey;
|
||||
|
||||
// Menu item text
|
||||
wxString m_menuItem;
|
||||
// Pop-up help
|
||||
wxString m_menuDescription;
|
||||
|
||||
//KiBitmap m_bitmap;
|
||||
/**
|
||||
* Function HasHotKey()
|
||||
* Checks if the action has a hot key assigned.
|
||||
*
|
||||
* @return True if there is a hot key assigned, false otherwise.
|
||||
*
|
||||
*/
|
||||
bool HasHotKey() const
|
||||
{
|
||||
return m_currentHotKey > 0;
|
||||
}
|
||||
|
||||
// Unique ID for fast matching. Assigned by TOOL_MANAGER
|
||||
int m_id;
|
||||
/**
|
||||
* Function GetEvent()
|
||||
* Returns the event associated with the action (ie. the event that will be sent after
|
||||
* activating the action).
|
||||
*
|
||||
* @return The event associated with the action.
|
||||
*/
|
||||
TOOL_EVENT GetEvent() const
|
||||
{
|
||||
return TOOL_EVENT( TC_Command, TA_Action, m_name, m_scope );
|
||||
}
|
||||
|
||||
// Origin of the action
|
||||
TOOL_BASE *m_origin;
|
||||
private:
|
||||
friend class ACTION_MANAGER;
|
||||
|
||||
// Originating UI object
|
||||
wxWindow *m_uiOrigin;
|
||||
/// Assigns an unique identifier. It is given by an instance of ACTION_MANAGER.
|
||||
void setId( int 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)
|
||||
std::string m_name;
|
||||
|
||||
/// Scope of the action (ie. the event that is issued after activation).
|
||||
TOOL_ActionScope m_scope;
|
||||
|
||||
/// Default hot key that activates the action.
|
||||
const int m_defaultHotKey;
|
||||
|
||||
/// Custom assigned hot key that activates the action.
|
||||
int m_currentHotKey;
|
||||
|
||||
/// Menu entry text
|
||||
wxString m_menuItem;
|
||||
|
||||
/// Pop-up help
|
||||
wxString m_menuDescription;
|
||||
|
||||
// Icon for menu entry
|
||||
//KiBitmap m_bitmap;
|
||||
|
||||
/// Unique ID for fast matching. Assigned by ACTION_MANAGER.
|
||||
int m_id;
|
||||
|
||||
/// Action manager that handles this TOOL_ACTION.
|
||||
ACTION_MANAGER* m_actionMgr;
|
||||
|
||||
/// Origin of the action
|
||||
// const TOOL_BASE* m_origin;
|
||||
|
||||
/// Originating UI object
|
||||
// wxWindow* m_uiOrigin;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -74,15 +74,16 @@ enum TOOL_Actions
|
|||