2013-08-02 14:46:53 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 CERN
|
2020-12-27 00:41:04 +00:00
|
|
|
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
|
|
|
*
|
2013-08-02 14:46:53 +00:00
|
|
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
2013-09-27 16:51:21 +00:00
|
|
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
2013-08-02 14:46:53 +00:00
|
|
|
*
|
|
|
|
* 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_MANAGER_H
|
|
|
|
#define __TOOL_MANAGER_H
|
|
|
|
|
2016-05-28 16:46:29 +00:00
|
|
|
#include <list>
|
2023-06-26 23:57:09 +00:00
|
|
|
#include <map>
|
2017-03-06 10:49:52 +00:00
|
|
|
#include <stack>
|
2023-06-26 23:57:09 +00:00
|
|
|
#include <typeinfo>
|
|
|
|
#include <type_traits>
|
2013-08-02 14:46:53 +00:00
|
|
|
|
|
|
|
#include <tool/tool_base.h>
|
2021-06-06 17:26:26 +00:00
|
|
|
#include <tool/tool_event.h>
|
2017-03-07 16:18:58 +00:00
|
|
|
#include <view/view_controls.h>
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
class COMMIT;
|
2020-03-24 01:01:23 +00:00
|
|
|
class TOOLS_HOLDER;
|
2021-06-06 17:26:26 +00:00
|
|
|
class TOOL_ACTION;
|
2013-08-02 14:46:53 +00:00
|
|
|
class TOOL_BASE;
|
2013-09-27 16:51:21 +00:00
|
|
|
class ACTION_MANAGER;
|
2019-05-14 11:14:00 +00:00
|
|
|
class ACTION_MENU;
|
2020-06-12 10:58:56 +00:00
|
|
|
class APP_SETTINGS_BASE;
|
2019-06-09 12:18:11 +00:00
|
|
|
|
2013-08-02 14:46:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Master controller class:
|
|
|
|
* - registers editing tools
|
|
|
|
* - pumps UI events to tools requesting them
|
|
|
|
* - manages tool state machines (transitions and wait requests)
|
|
|
|
*/
|
|
|
|
class TOOL_MANAGER
|
|
|
|
{
|
2017-02-11 20:26:08 +00:00
|
|
|
private:
|
|
|
|
struct TOOL_STATE;
|
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
public:
|
2014-05-14 14:29:53 +00:00
|
|
|
TOOL_MANAGER();
|
2014-03-21 09:40:50 +00:00
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
~TOOL_MANAGER();
|
|
|
|
|
2017-02-11 20:26:08 +00:00
|
|
|
// Helper typedefs
|
|
|
|
typedef std::map<TOOL_BASE*, TOOL_STATE*> TOOL_STATE_MAP;
|
|
|
|
typedef std::map<std::string, TOOL_STATE*> NAME_STATE_MAP;
|
|
|
|
typedef std::map<TOOL_ID, TOOL_STATE*> ID_STATE_MAP;
|
|
|
|
typedef std::list<TOOL_ID> ID_LIST;
|
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
/**
|
2015-04-06 19:50:12 +00:00
|
|
|
* Generates a unique ID from for a tool with given name.
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
|
|
|
static TOOL_ID MakeToolId( const std::string& aToolName );
|
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Add a tool to the manager set and sets it up. Called once for each tool during
|
|
|
|
* application initialization.
|
|
|
|
*
|
2013-08-08 12:59:59 +00:00
|
|
|
* @param aTool: tool to be added. Ownership is transferred.
|
|
|
|
*/
|
|
|
|
void RegisterTool( TOOL_BASE* aTool );
|
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Call a tool by sending a tool activation event to tool of given ID.
|
2013-09-06 14:01:46 +00:00
|
|
|
*
|
2013-09-19 15:02:57 +00:00
|
|
|
* @param aToolId is the ID number of the requested tool.
|
2013-09-06 14:01:46 +00:00
|
|
|
* @return True if the requested tool was invoked successfully.
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
2013-08-30 08:37:26 +00:00
|
|
|
bool InvokeTool( TOOL_ID aToolId );
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2013-09-19 15:02:57 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Call a tool by sending a tool activation event to tool of given name.
|
2013-09-19 15:02:57 +00:00
|
|
|
*
|
|
|
|
* @param aToolName is the name of the requested tool.
|
|
|
|
* @return True if the requested tool was invoked successfully.
|
|
|
|
*/
|
|
|
|
bool InvokeTool( const std::string& aToolName );
|
|
|
|
|
2020-02-03 14:00:48 +00:00
|
|
|
/**
|
|
|
|
* Shutdown all tools with a currently registered event loop in this tool manager
|
|
|
|
* by waking them up with a null event.
|
|
|
|
*/
|
|
|
|
void ShutdownAllTools();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shutdown the specified tool by waking it up with a null event to terminate
|
|
|
|
* the processing loop.
|
|
|
|
*
|
|
|
|
* @param aTool is the tool to shutdown
|
|
|
|
*/
|
|
|
|
void ShutdownTool( TOOL_BASE* aTool );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shutdown the specified tool by waking it up with a null event to terminate
|
|
|
|
* the processing loop.
|
|
|
|
*
|
|
|
|
* @param aToolId is the ID of the tool to shutdown
|
|
|
|
*/
|
|
|
|
void ShutdownTool( TOOL_ID aToolId );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shutdown the specified tool by waking it up with a null event to terminate
|
|
|
|
* the processing loop.
|
|
|
|
*
|
|
|
|
* @param aToolName is name of the tool to shutdown
|
|
|
|
*/
|
|
|
|
void ShutdownTool( const std::string& aToolName );
|
|
|
|
|
2013-12-03 14:41:41 +00:00
|
|
|
/**
|
2023-06-26 22:16:51 +00:00
|
|
|
* Run the specified action immediately, pausing the current action to run the new one.
|
2020-12-27 00:41:04 +00:00
|
|
|
*
|
|
|
|
* The common format for action names is "application.ToolName.Action".
|
2013-12-03 14:41:41 +00:00
|
|
|
*
|
2022-09-29 23:43:39 +00:00
|
|
|
* Note: The type of the optional parameter must match exactly with the type the consuming
|
|
|
|
* action is expecting, otherwise an assert will occur when reading the paramter.
|
|
|
|
*
|
2013-12-03 14:41:41 +00:00
|
|
|
* @param aActionName is the name of action to be invoked.
|
2014-11-21 10:28:34 +00:00
|
|
|
* @param aParam is an optional parameter that might be used by the invoked action. Its meaning
|
2020-12-27 00:41:04 +00:00
|
|
|
* depends on the action.
|
2014-07-09 14:25:50 +00:00
|
|
|
* @return False if the action was not found.
|
2013-12-03 14:41:41 +00:00
|
|
|
*/
|
2023-06-26 23:57:09 +00:00
|
|
|
template<typename T,
|
|
|
|
std::enable_if_t<!std::is_convertible_v<T*, COMMIT*>>* = nullptr>
|
2023-06-26 22:16:51 +00:00
|
|
|
bool RunAction( const std::string& aActionName, T aParam )
|
2022-09-29 23:43:39 +00:00
|
|
|
{
|
|
|
|
// Use a cast to ensure the proper type is stored inside the parameter
|
|
|
|
std::any a( static_cast<T>( aParam ) );
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
return doRunAction( aActionName, true, a, nullptr );
|
2022-09-29 23:43:39 +00:00
|
|
|
}
|
2015-04-30 08:46:02 +00:00
|
|
|
|
2023-06-26 22:16:51 +00:00
|
|
|
bool RunAction( const std::string& aActionName )
|
2015-04-30 08:46:02 +00:00
|
|
|
{
|
2022-09-28 22:13:32 +00:00
|
|
|
// Default initialize the parameter argument to an empty std::any
|
|
|
|
std::any a;
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
return doRunAction( aActionName, true, a, nullptr );
|
2015-04-30 08:46:02 +00:00
|
|
|
}
|
2013-12-03 14:41:41 +00:00
|
|
|
|
2014-02-28 14:46:05 +00:00
|
|
|
/**
|
2023-06-26 22:16:51 +00:00
|
|
|
* Run the specified action immediately, pausing the current action to run the new one.
|
2019-08-05 12:19:44 +00:00
|
|
|
*
|
2022-09-29 23:43:39 +00:00
|
|
|
* Note: The type of the optional parameter must match exactly with the type the consuming
|
|
|
|
* action is expecting, otherwise an assert will occur when reading the paramter.
|
|
|
|
*
|
2014-02-28 14:46:05 +00:00
|
|
|
* @param aAction is the action to be invoked.
|
2014-11-21 10:28:34 +00:00
|
|
|
* @param aParam is an optional parameter that might be used by the invoked action. Its meaning
|
2020-12-27 00:41:04 +00:00
|
|
|
* depends on the action.
|
2019-08-05 12:19:44 +00:00
|
|
|
* @return True if the action was handled immediately
|
2014-02-28 14:46:05 +00:00
|
|
|
*/
|
2023-06-26 23:57:09 +00:00
|
|
|
template<typename T,
|
2023-06-27 16:59:04 +00:00
|
|
|
std::enable_if_t<!std::is_convertible_v<T, COMMIT*>>* = nullptr>
|
2023-06-26 22:16:51 +00:00
|
|
|
bool RunAction( const TOOL_ACTION& aAction, T aParam )
|
|
|
|
{
|
|
|
|
// Use a cast to ensure the proper type is stored inside the parameter
|
|
|
|
std::any a( static_cast<T>( aParam ) );
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
return doRunAction( aAction, true, a, nullptr );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run the specified action immediately, pausing the current action to run the new one.
|
|
|
|
*
|
|
|
|
* Note: The type of the optional parameter must match exactly with the type the consuming
|
|
|
|
* action is expecting, otherwise an assert will occur when reading the paramter.
|
|
|
|
*
|
|
|
|
* @param aAction is the action to be invoked.
|
|
|
|
* @param aCommit is the commit object the tool handling the action should add the new edits to
|
|
|
|
* @return True if the action was handled immediately
|
|
|
|
*/
|
|
|
|
bool RunAction( const TOOL_ACTION& aAction, COMMIT* aCommit )
|
|
|
|
{
|
|
|
|
// Default initialize the parameter argument to an empty std::any
|
|
|
|
std::any a;
|
|
|
|
|
|
|
|
return doRunAction( aAction, true, a, aCommit );
|
2023-06-26 22:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool RunAction( const TOOL_ACTION& aAction )
|
|
|
|
{
|
|
|
|
// Default initialize the parameter argument to an empty std::any
|
|
|
|
std::any a;
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
return doRunAction( aAction, true, a, nullptr );
|
2023-06-26 22:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run the specified action after the current action (coroutine) ends.
|
|
|
|
*
|
|
|
|
* The common format for action names is "application.ToolName.Action".
|
|
|
|
*
|
|
|
|
* Note: The type of the optional parameter must match exactly with the type the consuming
|
|
|
|
* action is expecting, otherwise an assert will occur when reading the paramter.
|
|
|
|
*
|
|
|
|
* @param aActionName is the name of action to be invoked.
|
|
|
|
* @param aParam is an optional parameter that might be used by the invoked action. Its meaning
|
|
|
|
* depends on the action.
|
|
|
|
* @return False if the action was not found.
|
|
|
|
*/
|
|
|
|
template<typename T>
|
|
|
|
bool PostAction( const std::string& aActionName, T aParam )
|
|
|
|
{
|
|
|
|
// Use a cast to ensure the proper type is stored inside the parameter
|
|
|
|
std::any a( static_cast<T>( aParam ) );
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
return doRunAction( aActionName, false, a, nullptr );
|
2023-06-26 22:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool PostAction( const std::string& aActionName )
|
|
|
|
{
|
|
|
|
// Default initialize the parameter argument to an empty std::any
|
|
|
|
std::any a;
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
return doRunAction( aActionName, false, a, nullptr );
|
2023-06-26 22:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run the specified action after the current action (coroutine) ends.
|
|
|
|
*
|
|
|
|
* Note: The type of the optional parameter must match exactly with the type the consuming
|
|
|
|
* action is expecting, otherwise an assert will occur when reading the paramter.
|
|
|
|
*
|
|
|
|
* @param aAction is the action to be invoked.
|
|
|
|
* @param aParam is an optional parameter that might be used by the invoked action. Its meaning
|
|
|
|
* depends on the action.
|
|
|
|
*/
|
|
|
|
template<typename T>
|
|
|
|
bool PostAction( const TOOL_ACTION& aAction, T aParam )
|
2022-09-29 23:43:39 +00:00
|
|
|
{
|
|
|
|
// Use a cast to ensure the proper type is stored inside the parameter
|
|
|
|
std::any a( static_cast<T>( aParam ) );
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
return doRunAction( aAction, false, a, nullptr );
|
2022-09-29 23:43:39 +00:00
|
|
|
}
|
2015-04-30 08:46:02 +00:00
|
|
|
|
2023-06-26 22:16:51 +00:00
|
|
|
void PostAction( const TOOL_ACTION& aAction )
|
2015-04-30 08:46:02 +00:00
|
|
|
{
|
2022-09-28 22:13:32 +00:00
|
|
|
// Default initialize the parameter argument to an empty std::any
|
|
|
|
std::any a;
|
|
|
|
|
2023-06-26 23:57:09 +00:00
|
|
|
doRunAction( aAction, false, a, nullptr );
|
2015-04-30 08:46:02 +00:00
|
|
|
}
|
2014-02-28 14:46:05 +00:00
|
|
|
|
2020-09-05 00:48:22 +00:00
|
|
|
/**
|
|
|
|
* Send a cancel event to the tool currently at the top of the tool stack.
|
|
|
|
*/
|
|
|
|
void CancelTool();
|
|
|
|
|
2019-10-03 15:55:05 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* "Prime" a tool by sending a cursor left-click event with the mouse position set
|
2019-10-03 15:55:05 +00:00
|
|
|
* to the passed in position.
|
|
|
|
*
|
|
|
|
* @param aPosition is the mouse position to use in the event
|
|
|
|
*/
|
|
|
|
void PrimeTool( const VECTOR2D& aPosition );
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< @copydoc ACTION_MANAGER::GetHotKey()
|
2021-03-06 09:27:41 +00:00
|
|
|
int GetHotKey( const TOOL_ACTION& aAction ) const;
|
2019-08-05 12:19:44 +00:00
|
|
|
|
2021-03-06 09:27:41 +00:00
|
|
|
ACTION_MANAGER* GetActionManager() const { return m_actionMgr; }
|
2015-05-05 18:39:42 +00:00
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Search for a tool with given ID.
|
2013-09-06 14:01:46 +00:00
|
|
|
*
|
2013-09-19 15:02:57 +00:00
|
|
|
* @param aId is the ID number of the requested tool.
|
|
|
|
* @return Pointer to the requested tool or NULL in case of failure.
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
2013-08-19 07:47:36 +00:00
|
|
|
TOOL_BASE* FindTool( int aId ) const;
|
2013-09-19 15:02:57 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Search for a tool with given name.
|
2013-09-19 15:02:57 +00:00
|
|
|
*
|
|
|
|
* @param aName is the name of the requested tool.
|
|
|
|
* @return Pointer to the requested tool or NULL in case of failure.
|
|
|
|
*/
|
2013-08-19 07:47:36 +00:00
|
|
|
TOOL_BASE* FindTool( const std::string& aName ) const;
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2014-07-09 09:59:24 +00:00
|
|
|
/*
|
2021-03-06 09:27:41 +00:00
|
|
|
* Return the tool of given type or nullptr if there is no such tool registered.
|
2014-07-09 09:59:24 +00:00
|
|
|
*/
|
|
|
|
template<typename T>
|
|
|
|
T* GetTool()
|
|
|
|
{
|
2014-07-09 11:50:27 +00:00
|
|
|
std::map<const char*, TOOL_BASE*>::iterator tool = m_toolTypes.find( typeid( T ).name() );
|
2014-07-09 09:59:24 +00:00
|
|
|
|
|
|
|
if( tool != m_toolTypes.end() )
|
|
|
|
return static_cast<T*>( tool->second );
|
|
|
|
|
2021-03-06 09:27:41 +00:00
|
|
|
return nullptr;
|
2014-07-09 09:59:24 +00:00
|
|
|
}
|
|
|
|
|
2022-02-24 09:59:54 +00:00
|
|
|
/*
|
|
|
|
* Return all registered tools.
|
|
|
|
*/
|
|
|
|
std::vector<TOOL_BASE*> Tools() { return m_toolOrder; }
|
|
|
|
|
2016-08-05 17:45:14 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Deactivate the currently active tool.
|
2016-08-05 17:45:14 +00:00
|
|
|
*/
|
|
|
|
void DeactivateTool();
|
|
|
|
|
2017-08-29 23:15:23 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return true if a tool with given id is active (executing)
|
2017-08-29 23:15:23 +00:00
|
|
|
*/
|
|
|
|
bool IsToolActive( TOOL_ID aId ) const;
|
|
|
|
|
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Reset all tools (i.e. calls their Reset() method).
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
2013-12-09 09:42:38 +00:00
|
|
|
void ResetTools( TOOL_BASE::RESET_REASON aReason );
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2017-01-30 10:38:02 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Initializes all registered tools.
|
|
|
|
*
|
|
|
|
* If a tool fails during the initialization, it is deactivated and becomes unavailable
|
|
|
|
* for further use. Initialization should be done only once.
|
2017-01-30 10:38:02 +00:00
|
|
|
*/
|
|
|
|
void InitTools();
|
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Propagate an event to tools that requested events of matching type(s).
|
|
|
|
*
|
2014-07-09 14:25:50 +00:00
|
|
|
* @param aEvent is the event to be processed.
|
2017-10-06 07:23:13 +00:00
|
|
|
* @return true if the event is a managed hotkey
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
2020-05-03 19:55:58 +00:00
|
|
|
bool ProcessEvent( const TOOL_EVENT& aEvent );
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2014-07-09 14:25:50 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Put an event to the event queue to be processed at the end of event processing cycle.
|
|
|
|
*
|
2014-07-09 14:25:50 +00:00
|
|
|
* @param aEvent is the event to be put into the queue.
|
|
|
|
*/
|
2021-06-06 17:26:26 +00:00
|
|
|
void PostEvent( const TOOL_EVENT& aEvent );
|
2014-07-09 14:25:50 +00:00
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Set the work environment (model, view, view controls and the parent window).
|
|
|
|
*
|
2019-06-09 12:18:11 +00:00
|
|
|
* These are made available to the tool. Called by the parent frame when it is set up.
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
2013-10-14 14:13:35 +00:00
|
|
|
void SetEnvironment( EDA_ITEM* aModel, KIGFX::VIEW* aView,
|
2020-06-12 10:58:56 +00:00
|
|
|
KIGFX::VIEW_CONTROLS* aViewControls, APP_SETTINGS_BASE* aSettings,
|
|
|
|
TOOLS_HOLDER* aFrame );
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2020-06-12 10:58:56 +00:00
|
|
|
/*
|
|
|
|
* Accessors for the environment objects (view, model, etc.)
|
2020-12-27 00:41:04 +00:00
|
|
|
*/
|
2020-06-12 10:58:56 +00:00
|
|
|
KIGFX::VIEW* GetView() const { return m_view; }
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2020-06-12 10:58:56 +00:00
|
|
|
KIGFX::VIEW_CONTROLS* GetViewControls() const { return m_viewControls; }
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2021-03-06 09:27:41 +00:00
|
|
|
VECTOR2D GetMousePosition() const;
|
|
|
|
VECTOR2D GetCursorPosition() const;
|
2019-10-03 20:36:11 +00:00
|
|
|
|
2020-06-12 10:58:56 +00:00
|
|
|
EDA_ITEM* GetModel() const { return m_model; }
|
|
|
|
|
|
|
|
APP_SETTINGS_BASE* GetSettings() const { return m_settings; }
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2020-06-12 10:58:56 +00:00
|
|
|
TOOLS_HOLDER* GetToolHolder() const { return m_frame; }
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2014-04-04 09:50:15 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return id of the tool that is on the top of the active tools stack (was invoked the
|
|
|
|
* most recently).
|
|
|
|
*
|
2014-04-04 09:50:15 +00:00
|
|
|
* @return Id of the currently used tool.
|
|
|
|
*/
|
2014-07-09 14:25:50 +00:00
|
|
|
inline int GetCurrentToolId() const
|
2014-04-04 09:50:15 +00:00
|
|
|
{
|
2017-02-11 20:26:08 +00:00
|
|
|
return m_activeTools.empty() ? -1 : m_activeTools.front();
|
2014-04-04 09:50:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return the tool that is on the top of the active tools stack (was invoked the most
|
|
|
|
* recently).
|
|
|
|
*
|
2014-04-04 09:50:15 +00:00
|
|
|
* @return Pointer to the currently used tool.
|
|
|
|
*/
|
2014-07-09 14:25:50 +00:00
|
|
|
inline TOOL_BASE* GetCurrentTool() const
|
2014-04-04 09:50:15 +00:00
|
|
|
{
|
|
|
|
return FindTool( GetCurrentToolId() );
|
|
|
|
}
|
|
|
|
|
2017-02-11 20:26:08 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return the #TOOL_STATE object representing the state of the active tool. If there are no
|
2017-02-11 20:26:08 +00:00
|
|
|
* tools active, it returns nullptr.
|
|
|
|
*/
|
|
|
|
TOOL_STATE* GetCurrentToolState() const
|
|
|
|
{
|
|
|
|
auto it = m_toolIdIndex.find( GetCurrentToolId() );
|
|
|
|
return ( it != m_toolIdIndex.end() ) ? it->second : nullptr;
|
|
|
|
}
|
|
|
|
|
2014-04-09 15:05:05 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return priority of a given tool.
|
|
|
|
*
|
|
|
|
* Higher number means that the tool is closer to the beginning of the active tools
|
|
|
|
* queue (i.e. receives events earlier, tools with lower priority receive events later).
|
|
|
|
*
|
2014-04-09 15:05:05 +00:00
|
|
|
* @param aToolId is the id of queried tool.
|
|
|
|
* @return The priority of a given tool. If returned number is negative, then it means that
|
2020-12-27 00:41:04 +00:00
|
|
|
* the tool id is invalid or the tool is not active.
|
2014-04-09 15:05:05 +00:00
|
|
|
*/
|
|
|
|
int GetPriority( int aToolId ) const;
|
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Define a state transition.
|
|
|
|
*
|
|
|
|
* The events that cause a given handler method in the tool to be called. Called by
|
|
|
|
* TOOL_INTERACTIVE::Go(). May be called from a coroutine context.
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
|
|
|
void ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler,
|
2020-12-27 00:41:04 +00:00
|
|
|
const TOOL_EVENT_LIST& aConditions );
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2017-07-31 12:30:51 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Clear the state transition map for a tool.
|
|
|
|
*
|
2017-07-31 12:30:51 +00:00
|
|
|
* @param aTool is the tool that should have the transition map cleared.
|
|
|
|
*/
|
|
|
|
void ClearTransitions( TOOL_BASE* aTool );
|
|
|
|
|
2016-09-21 09:54:58 +00:00
|
|
|
void RunMainStack( TOOL_BASE* aTool, std::function<void()> aFunc );
|
|
|
|
|
2019-05-13 20:42:40 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Update the status bar and synchronizes toolbars.
|
2019-05-13 20:42:40 +00:00
|
|
|
*/
|
2019-06-11 08:47:47 +00:00
|
|
|
void UpdateUI( const TOOL_EVENT& aEvent );
|
2019-05-13 20:42:40 +00:00
|
|
|
|
2013-08-08 12:59:59 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Pause execution of a given tool until one or more events matching aConditions arrives.
|
|
|
|
*
|
|
|
|
* The pause/resume operation is done through #COROUTINE object. Called only from coroutines.
|
2013-08-08 12:59:59 +00:00
|
|
|
*/
|
2019-06-17 13:43:22 +00:00
|
|
|
TOOL_EVENT* ScheduleWait( TOOL_BASE* aTool, const TOOL_EVENT_LIST& aConditions );
|
2013-08-08 12:59:59 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Set behavior of the tool's context popup menu.
|
|
|
|
*
|
|
|
|
* @param aTool is the parent tool.
|
|
|
|
* @param aMenu is the menu structure, defined by the tool.
|
|
|
|
* @param aTrigger determines when the menu is activated:
|
2014-11-02 16:25:04 +00:00
|
|
|
* CMENU_NOW: opens the menu right now
|
|
|
|
* CMENU_BUTTON: opens the menu when RMB is pressed
|
|
|
|
* CMENU_OFF: menu is disabled.
|
2013-08-08 12:59:59 +00:00
|
|
|
* May be called from a coroutine context.
|
|
|
|
*/
|
2019-06-17 13:43:22 +00:00
|
|
|
void ScheduleContextMenu( TOOL_BASE* aTool, ACTION_MENU* aMenu, CONTEXT_MENU_TRIGGER aTrigger );
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2014-07-09 12:01:07 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Store information to the system clipboard.
|
|
|
|
*
|
|
|
|
* @param aText is the information to be stored, expected UTF8 encoding. The text will be
|
|
|
|
* stored as Unicode string (not stored as UTF8 string).
|
2018-02-25 12:17:25 +00:00
|
|
|
* @return False if error occurred.
|
2014-07-09 12:01:07 +00:00
|
|
|
*/
|
2020-11-21 09:59:25 +00:00
|
|
|
bool SaveClipboard( const std::string& aTextUTF8 );
|
2014-07-09 12:01:07 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return the information currently stored in the system clipboard.
|
|
|
|
*
|
|
|
|
* If data stored in the clipboard is in non-text format, empty string is returned.
|
|
|
|
*
|
|
|
|
* @note The clipboard is expected containing Unicode chars, not only ASCII7 chars.
|
|
|
|
* The returned string is UTF8 encoded
|
2014-07-09 12:01:07 +00:00
|
|
|
*/
|
2020-11-21 09:59:25 +00:00
|
|
|
std::string GetClipboardUTF8() const;
|
2014-07-09 12:01:07 +00:00
|
|
|
|
2018-04-24 10:55:33 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return the view controls settings for the current tool or the general settings if there is
|
2018-04-24 10:55:33 +00:00
|
|
|
* no active tool.
|
|
|
|
*/
|
2018-04-24 13:20:35 +00:00
|
|
|
const KIGFX::VC_SETTINGS& GetCurrentToolVC() const;
|
2018-04-24 10:55:33 +00:00
|
|
|
|
2019-06-19 20:04:34 +00:00
|
|
|
/**
|
|
|
|
* True while processing a context menu.
|
|
|
|
*/
|
2021-03-06 09:27:41 +00:00
|
|
|
bool IsContextMenuActive() const
|
2019-06-19 20:04:34 +00:00
|
|
|
{
|
|
|
|
return m_menuActive;
|
|
|
|
}
|
|
|
|
|
2019-04-13 15:22:48 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Disable mouse warping after the current context menu is closed.
|
|
|
|
*
|
|
|
|
* This must be called before invoking each context menu. It's a good idea to call this
|
|
|
|
* from non-modal dialogs (e.g. DRC window).
|
2019-04-13 15:22:48 +00:00
|
|
|
*/
|
2019-04-08 18:59:23 +00:00
|
|
|
void VetoContextMenuMouseWarp()
|
|
|
|
{
|
|
|
|
m_warpMouseAfterContextMenu = false;
|
|
|
|
}
|
|
|
|
|
2019-06-05 19:15:57 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Handle context menu related events.
|
2019-06-05 19:15:57 +00:00
|
|
|
*/
|
|
|
|
void DispatchContextMenu( const TOOL_EVENT& aEvent );
|
2019-04-08 18:59:23 +00:00
|
|
|
|
2020-05-03 19:55:58 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Handle specific events, that are intended for TOOL_MANAGER rather than tools.
|
|
|
|
*
|
2020-05-03 19:55:58 +00:00
|
|
|
* @param aEvent is the event to be processed.
|
|
|
|
* @return true if the event was processed and should not go any further.
|
|
|
|
*/
|
2020-06-23 10:21:16 +00:00
|
|
|
bool DispatchHotKey( const TOOL_EVENT& aEvent );
|
2020-05-03 19:55:58 +00:00
|
|
|
|
2021-03-06 09:27:41 +00:00
|
|
|
VECTOR2D GetMenuCursorPos() const
|
2020-09-26 06:44:14 +00:00
|
|
|
{
|
|
|
|
return m_menuCursor;
|
|
|
|
}
|
|
|
|
|
2014-05-14 14:29:53 +00:00
|
|
|
private:
|
2013-09-02 12:21:12 +00:00
|
|
|
typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> TRANSITION;
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2022-09-29 23:43:39 +00:00
|
|
|
/**
|
|
|
|
* Helper function to actually run an action.
|
|
|
|
*/
|
2023-06-26 23:57:09 +00:00
|
|
|
bool doRunAction( const TOOL_ACTION& aAction, bool aNow, std::any aParam, COMMIT* aCommit );
|
|
|
|
bool doRunAction( const std::string& aActionName, bool aNow, std::any aParam, COMMIT* aCommit );
|
2022-09-29 23:43:39 +00:00
|
|
|
|
2014-07-09 11:50:27 +00:00
|
|
|
/**
|
2021-03-06 09:27:41 +00:00
|
|
|
* Pass an event at first to the active tools, then to all others.
|
2014-07-09 11:50:27 +00:00
|
|
|
*/
|
2021-03-06 09:27:41 +00:00
|
|
|
bool dispatchInternal( TOOL_EVENT& aEvent );
|
2013-09-19 15:02:57 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Check if it is a valid activation event and invokes a proper tool.
|
|
|
|
*
|
2013-09-19 15:02:57 +00:00
|
|
|
* @param aEvent is an event to be tested.
|
|
|
|
* @return True if a tool was invoked, false otherwise.
|
|
|
|
*/
|
2015-02-14 20:28:47 +00:00
|
|
|
bool dispatchActivation( const TOOL_EVENT& aEvent );
|
2013-09-19 15:02:57 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Invoke a tool by sending a proper event (in contrary to runTool, which makes the tool run
|
2013-09-27 16:51:21 +00:00
|
|
|
* for real).
|
2020-12-27 00:41:04 +00:00
|
|
|
*
|
2013-09-19 15:02:57 +00:00
|
|
|
* @param aTool is the tool to be invoked.
|
|
|
|
*/
|
|
|
|
bool invokeTool( TOOL_BASE* aTool );
|
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Make a tool active, so it can receive events and react to them.
|
|
|
|
*
|
|
|
|
* The activated tool is pushed on the active tools stack, so the last activated tool
|
|
|
|
* receives events first.
|
2013-09-19 15:02:57 +00:00
|
|
|
*
|
2014-11-02 16:25:04 +00:00
|
|
|
* @param aTool is the tool to be run.
|
2013-09-19 15:02:57 +00:00
|
|
|
*/
|
|
|
|
bool runTool( TOOL_BASE* aTool );
|
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Deactivate a tool and does the necessary clean up.
|
2013-09-19 15:02:57 +00:00
|
|
|
*
|
|
|
|
* @param aState is the state variable of the tool to be stopped.
|
2017-02-11 20:26:08 +00:00
|
|
|
* @return m_activeTools iterator. If the tool has been completely deactivated, it points
|
2020-12-27 00:41:04 +00:00
|
|
|
* to the next active tool on the list. Otherwise it is an iterator pointing to
|
|
|
|
* \a aState.
|
2013-09-19 15:02:57 +00:00
|
|
|
*/
|
2017-02-11 20:26:08 +00:00
|
|
|
ID_LIST::iterator finishTool( TOOL_STATE* aState );
|
2013-08-30 08:37:26 +00:00
|
|
|
|
2013-09-19 15:02:57 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return information about a tool registration status.
|
2013-09-19 15:02:57 +00:00
|
|
|
*
|
|
|
|
* @param aTool is the tool to be checked.
|
2014-11-02 16:25:04 +00:00
|
|
|
* @return true if the tool is in the registered tools list, false otherwise.
|
2013-09-19 15:02:57 +00:00
|
|
|
*/
|
|
|
|
bool isRegistered( TOOL_BASE* aTool ) const
|
|
|
|
{
|
2013-10-14 14:13:35 +00:00
|
|
|
return m_toolState.count( aTool ) > 0;
|
2013-09-19 15:02:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return information about a tool activation status.
|
2013-09-19 15:02:57 +00:00
|
|
|
*
|
|
|
|
* @param aTool is the tool to be checked.
|
|
|
|
* @return True if the tool is on the active tools stack, false otherwise.
|
|
|
|
*/
|
2021-03-06 09:27:41 +00:00
|
|
|
bool isActive( TOOL_BASE* aTool ) const;
|
2013-09-19 15:02:57 +00:00
|
|
|
|
2017-03-02 11:02:10 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Save the #VIEW_CONTROLS settings to the tool state object.
|
|
|
|
*
|
|
|
|
* If #VIEW_CONTROLS settings are affected by #TOOL_MANAGER, the original settings are saved.
|
2017-03-02 11:02:10 +00:00
|
|
|
*/
|
|
|
|
void saveViewControls( TOOL_STATE* aState );
|
|
|
|
|
2017-03-06 10:49:52 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Apply #VIEW_CONTROLS settings stored in a #TOOL_STATE object.
|
2017-03-06 10:49:52 +00:00
|
|
|
*/
|
2021-03-06 09:27:41 +00:00
|
|
|
void applyViewControls( const TOOL_STATE* aState );
|
2017-03-06 10:49:52 +00:00
|
|
|
|
2020-05-02 13:36:29 +00:00
|
|
|
/**
|
|
|
|
* Main function for event processing.
|
2020-12-27 00:41:04 +00:00
|
|
|
*
|
|
|
|
* @return true if a hotkey was handled.
|
2020-05-02 13:36:29 +00:00
|
|
|
*/
|
2020-05-03 19:55:58 +00:00
|
|
|
bool processEvent( const TOOL_EVENT& aEvent );
|
2017-03-06 10:49:52 +00:00
|
|
|
|
2018-02-14 14:09:10 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Save the previous active state and sets a new one.
|
|
|
|
*
|
2018-02-14 14:09:10 +00:00
|
|
|
* @param aState is the new active state. Might be null to indicate there is no new
|
2020-12-27 00:41:04 +00:00
|
|
|
* active state.
|
2018-02-14 14:09:10 +00:00
|
|
|
*/
|
|
|
|
void setActiveState( TOOL_STATE* aState );
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< List of tools in the order they were registered
|
2022-02-24 09:59:54 +00:00
|
|
|
std::vector<TOOL_BASE*> m_toolOrder;
|
2020-10-02 20:09:15 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Index of registered tools current states, associated by tools' objects.
|
2017-02-11 20:26:08 +00:00
|
|
|
TOOL_STATE_MAP m_toolState;
|
2013-09-19 15:02:57 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Index of the registered tools current states, associated by tools' names.
|
2017-02-11 20:26:08 +00:00
|
|
|
NAME_STATE_MAP m_toolNameIndex;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Index of the registered tools current states, associated by tools' ID numbers.
|
2017-02-11 20:26:08 +00:00
|
|
|
ID_STATE_MAP m_toolIdIndex;
|
2014-07-09 09:59:24 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Index of the registered tools to easily lookup by their type.
|
2014-07-09 11:50:27 +00:00
|
|
|
std::map<const char*, TOOL_BASE*> m_toolTypes;
|
2013-09-19 15:02:57 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Stack of the active tools
|
2017-02-11 20:26:08 +00:00
|
|
|
ID_LIST m_activeTools;
|
2013-08-08 12:59:59 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Instance of ACTION_MANAGER that handles TOOL_ACTIONs
|
2013-09-27 16:51:21 +00:00
|
|
|
ACTION_MANAGER* m_actionMgr;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Original cursor position, if overridden by the context menu handler
|
2022-08-25 22:50:47 +00:00
|
|
|
std::map<TOOL_ID, std::optional<VECTOR2D>> m_cursorSettings;
|
2017-02-24 15:39:52 +00:00
|
|
|
|
2020-03-24 01:01:23 +00:00
|
|
|
EDA_ITEM* m_model;
|
|
|
|
KIGFX::VIEW* m_view;
|
2013-10-14 14:13:35 +00:00
|
|
|
KIGFX::VIEW_CONTROLS* m_viewControls;
|
2020-03-24 01:01:23 +00:00
|
|
|
TOOLS_HOLDER* m_frame;
|
2020-06-12 10:58:56 +00:00
|
|
|
APP_SETTINGS_BASE* m_settings;
|
2013-09-19 15:02:57 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Queue that stores events to be processed at the end of the event processing cycle.
|
2014-07-09 14:25:50 +00:00
|
|
|
std::list<TOOL_EVENT> m_eventQueue;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Right click context menu position.
|
2018-02-02 15:20:14 +00:00
|
|
|
VECTOR2D m_menuCursor;
|
|
|
|
|
2019-04-08 18:59:23 +00:00
|
|
|
bool m_warpMouseAfterContextMenu;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Flag indicating whether a context menu is currently displayed.
|
2017-03-06 10:49:52 +00:00
|
|
|
bool m_menuActive;
|
2018-01-26 14:53:28 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Tool currently displaying a popup menu. It is negative when there is no menu displayed.
|
2018-01-26 14:53:28 +00:00
|
|
|
TOOL_ID m_menuOwner;
|
2018-02-02 15:20:14 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Pointer to the state object corresponding to the currently executed tool.
|
2018-02-02 15:20:14 +00:00
|
|
|
TOOL_STATE* m_activeState;
|
2022-07-15 23:37:33 +00:00
|
|
|
|
|
|
|
///< True if the tool manager is shutting down (don't process additional events)
|
|
|
|
bool m_shuttingDown;
|
2013-08-02 14:46:53 +00:00
|
|
|
};
|
|
|
|
|
2021-03-06 09:27:41 +00:00
|
|
|
#endif // __TOOL_MANAGER_H
|