KiCad PCB EDA Suite
Loading...
Searching...
No Matches
tool_manager.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2013-2023 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
8 * @author Maciej Suminski <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#ifndef TOOL_MANAGER_H
25#define TOOL_MANAGER_H
26
27#include <list>
28#include <map>
29#include <stack>
30#include <vector>
31#include <typeinfo>
32#include <type_traits>
33
34#include <tool/tool_base.h>
35#include <tool/tool_event.h>
36
37namespace KIGFX
38{
39class VIEW_CONTROLS;
40struct VC_SETTINGS;
41}
42
43class COMMIT;
44class TOOLS_HOLDER;
45class TOOL_ACTION;
46class ACTION_MANAGER;
47class ACTION_MENU;
49
50
58{
59private:
60 struct TOOL_STATE;
61
62public:
64
66
67 // Helper typedefs
68 typedef std::map<TOOL_BASE*, TOOL_STATE*> TOOL_STATE_MAP;
69 typedef std::map<std::string, TOOL_STATE*> NAME_STATE_MAP;
70 typedef std::map<TOOL_ID, TOOL_STATE*> ID_STATE_MAP;
71 typedef std::list<TOOL_ID> ID_LIST;
72
76 static TOOL_ID MakeToolId( const std::string& aToolName );
77
84 void RegisterTool( TOOL_BASE* aTool );
85
92 bool InvokeTool( TOOL_ID aToolId );
93
100 bool InvokeTool( const std::string& aToolName );
101
106 void ShutdownAllTools();
107
114 void ShutdownTool( TOOL_BASE* aTool );
115
122 void ShutdownTool( TOOL_ID aToolId );
123
130 void ShutdownTool( const std::string& aToolName );
131
145 template<typename T, std::enable_if_t<!std::is_convertible_v<T*, COMMIT*>>* = nullptr>
146 bool RunAction( const std::string& aActionName, T aParam )
147 {
148 // Use a cast to ensure the proper type is stored inside the parameter
149 ki::any a( static_cast<T>( aParam ) );
150
151 return doRunAction( aActionName, true, a, nullptr );
152 }
153
154 bool RunAction( const std::string& aActionName )
155 {
156 // Default initialize the parameter argument to an empty ki_any
157 ki::any a;
158
159 return doRunAction( aActionName, true, a, nullptr );
160 }
161
173 template<typename T, std::enable_if_t<!std::is_convertible_v<T, COMMIT*>>* = nullptr>
174 bool RunAction( const TOOL_ACTION& aAction, T aParam )
175 {
176 // Use a cast to ensure the proper type is stored inside the parameter
177 ki::any a( static_cast<T>( aParam ) );
178
179 return doRunAction( aAction, true, a, nullptr );
180 }
181
192 template<typename T>
193 bool RunSynchronousAction( const TOOL_ACTION& aAction, COMMIT* aCommit, T aParam )
194 {
195 // Use a cast to ensure the proper type is stored inside the parameter
196 ki::any a( static_cast<T>( aParam ) );
197
198 return doRunAction( aAction, true, a, aCommit );
199 }
200
201 bool RunSynchronousAction( const TOOL_ACTION& aAction, COMMIT* aCommit )
202 {
203 // Default initialize the parameter argument to an empty ki_any
204 ki::any a;
205
206 return doRunAction( aAction, true, a, aCommit );
207 }
208
209 bool RunAction( const TOOL_ACTION& aAction )
210 {
211 // Default initialize the parameter argument to an empty ki_any
212 ki::any a;
213
214 return doRunAction( aAction, true, a, nullptr );
215 }
216
230 template<typename T>
231 bool PostAction( const std::string& aActionName, T aParam )
232 {
233 // Use a cast to ensure the proper type is stored inside the parameter
234 ki::any a( static_cast<T>( aParam ) );
235
236 return doRunAction( aActionName, false, a, nullptr );
237 }
238
239 bool PostAction( const std::string& aActionName )
240 {
241 // Default initialize the parameter argument to an empty ki_any
242 ki::any a;
243
244 return doRunAction( aActionName, false, a, nullptr );
245 }
246
258 template<typename T, std::enable_if_t<!std::is_convertible_v<T, COMMIT*>>* = nullptr>
259 bool PostAction( const TOOL_ACTION& aAction, T aParam )
260 {
261 // Use a cast to ensure the proper type is stored inside the parameter
262 ki::any a( static_cast<T>( aParam ) );
263
264 return doRunAction( aAction, false, a, nullptr );
265 }
266
267 void PostAction( const TOOL_ACTION& aAction )
268 {
269 // Default initialize the parameter argument to an empty ki_any
270 ki::any a;
271
272 doRunAction( aAction, false, a, nullptr );
273 }
274
275 // TODO: we need a way to guarantee that user events can't be processed in
276 // between API actions. Otherwise the COMMITs will get tangled up and we'll
277 // crash on bad pointers.
278 bool PostAPIAction( const TOOL_ACTION& aAction, COMMIT* aCommit )
279 {
280 // Default initialize the parameter argument to an empty ki_any
281 ki::any a;
282
283 return doRunAction( aAction, false, a, aCommit, true );
284 }
285
289 void CancelTool();
290
297 void PrimeTool( const VECTOR2D& aPosition );
298
300 int GetHotKey( const TOOL_ACTION& aAction ) const;
301
303
310 TOOL_BASE* FindTool( int aId ) const;
311
318 TOOL_BASE* FindTool( const std::string& aName ) const;
319
320 /*
321 * Return the tool of given type or nullptr if there is no such tool registered.
322 */
323 template<typename T>
325 {
326 std::map<const char*, TOOL_BASE*>::iterator tool = m_toolTypes.find( typeid( T ).name() );
327
328 if( tool != m_toolTypes.end() )
329 return static_cast<T*>( tool->second );
330
331 return nullptr;
332 }
333
334 /*
335 * Return all registered tools.
336 */
337 std::vector<TOOL_BASE*> Tools() { return m_toolOrder; }
338
342 void DeactivateTool();
343
344
348 bool IsToolActive( TOOL_ID aId ) const;
349
350
354 void ResetTools( TOOL_BASE::RESET_REASON aReason );
355
362 void InitTools();
363
370 bool ProcessEvent( const TOOL_EVENT& aEvent );
371
377 void PostEvent( const TOOL_EVENT& aEvent );
378
384 void SetEnvironment( EDA_ITEM* aModel, KIGFX::VIEW* aView,
385 KIGFX::VIEW_CONTROLS* aViewControls, APP_SETTINGS_BASE* aSettings,
386 TOOLS_HOLDER* aFrame );
387
388 /*
389 * Accessors for the environment objects (view, model, etc.)
390 */
391 KIGFX::VIEW* GetView() const { return m_view; }
392
394
397
398 EDA_ITEM* GetModel() const { return m_model; }
399 void ClearModel() { m_model = nullptr; }
400
402
403 TOOLS_HOLDER* GetToolHolder() const { return m_frame; }
404
411 inline int GetCurrentToolId() const
412 {
413 return m_activeTools.empty() ? -1 : m_activeTools.front();
414 }
415
422 inline TOOL_BASE* GetCurrentTool() const
423 {
424 return FindTool( GetCurrentToolId() );
425 }
426
432 {
433 auto it = m_toolIdIndex.find( GetCurrentToolId() );
434 return ( it != m_toolIdIndex.end() ) ? it->second : nullptr;
435 }
436
447 int GetPriority( int aToolId ) const;
448
455 void ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler,
456 const TOOL_EVENT_LIST& aConditions );
457
463 void ClearTransitions( TOOL_BASE* aTool );
464
465 void RunMainStack( TOOL_BASE* aTool, std::function<void()> aFunc );
466
470 void UpdateUI( const TOOL_EVENT& aEvent );
471
477 TOOL_EVENT* ScheduleWait( TOOL_BASE* aTool, const TOOL_EVENT_LIST& aConditions );
478
490 void ScheduleContextMenu( TOOL_BASE* aTool, ACTION_MENU* aMenu, CONTEXT_MENU_TRIGGER aTrigger );
491
497
502 {
503 return m_menuActive;
504 }
505
516
525
529 void DispatchContextMenu( const TOOL_EVENT& aEvent );
530
537 bool DispatchHotKey( const TOOL_EVENT& aEvent );
538
540 {
541 return m_menuCursor;
542 }
543
544private:
545 typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> TRANSITION;
546
550 bool doRunAction( const TOOL_ACTION& aAction, bool aNow, const ki::any& aParam,
551 COMMIT* aCommit, bool aFromAPI = false );
552 bool doRunAction( const std::string& aActionName, bool aNow, const ki::any& aParam,
553 COMMIT* aCommit );
554
558 bool dispatchInternal( TOOL_EVENT& aEvent );
559
566 bool dispatchActivation( const TOOL_EVENT& aEvent );
567
574 bool invokeTool( TOOL_BASE* aTool );
575
584 bool runTool( TOOL_BASE* aTool );
585
594 ID_LIST::iterator finishTool( TOOL_STATE* aState );
595
602 bool isRegistered( TOOL_BASE* aTool ) const
603 {
604 return m_toolState.count( aTool ) > 0;
605 }
606
613 bool isActive( TOOL_BASE* aTool ) const;
614
620 void saveViewControls( TOOL_STATE* aState );
621
625 void applyViewControls( const TOOL_STATE* aState );
626
632 bool processEvent( const TOOL_EVENT& aEvent );
633
640 void setActiveState( TOOL_STATE* aState );
641
642private:
644 std::vector<TOOL_BASE*> m_toolOrder;
645
648
651
654
656 std::map<const char*, TOOL_BASE*> m_toolTypes;
657
660
663
665 std::map<TOOL_ID, std::optional<VECTOR2D>> m_cursorSettings;
666
672
674 std::list<TOOL_EVENT> m_eventQueue;
675
678
681 std::optional<VECTOR2D> m_hotKeyPos;
682
684
687
690
693
696};
697
698#endif // TOOL_MANAGER_H
const char * name
Manage TOOL_ACTION objects.
Define the structure of a menu based on ACTIONs.
Definition action_menu.h:43
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition commit.h:68
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
An interface for classes handling user events controlling the view behavior such as zooming,...
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
Represent a single user action.
Base abstract interface for all kinds of tools.
Definition tool_base.h:62
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
A list of TOOL_EVENTs, with overloaded || operators allowing for concatenating TOOL_EVENTs with littl...
Definition tool_event.h:644
Generic, UI-independent tool event.
Definition tool_event.h:167
void applyViewControls(const TOOL_STATE *aState)
Apply #VIEW_CONTROLS settings stored in a TOOL_STATE object.
int GetPriority(int aToolId) const
Return priority of a given tool.
bool PostAction(const TOOL_ACTION &aAction, T aParam)
Run the specified action after the current action (coroutine) ends.
std::map< std::string, TOOL_STATE * > NAME_STATE_MAP
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void ClearModel()
TOOL_STATE * m_activeState
Pointer to the state object corresponding to the currently executed tool.
void UpdateUI(const TOOL_EVENT &aEvent)
Update the status bar and synchronizes toolbars.
std::map< TOOL_ID, std::optional< VECTOR2D > > m_cursorSettings
Original cursor position, if overridden by the context menu handler.
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
void ScheduleNextState(TOOL_BASE *aTool, TOOL_STATE_FUNC &aHandler, const TOOL_EVENT_LIST &aConditions)
Define a state transition.
std::map< const char *, TOOL_BASE * > m_toolTypes
Index of the registered tools to easily lookup by their type.
bool isRegistered(TOOL_BASE *aTool) const
Return information about a tool registration status.
APP_SETTINGS_BASE * m_settings
TOOL_STATE * GetCurrentToolState() const
Return the TOOL_STATE object representing the state of the active tool.
VECTOR2D GetMenuCursorPos() const
VECTOR2D GetCursorPosition() const
std::list< TOOL_EVENT > m_eventQueue
Queue that stores events to be processed at the end of the event processing cycle.
bool RunAction(const std::string &aActionName)
std::pair< TOOL_EVENT_LIST, TOOL_STATE_FUNC > TRANSITION
void setActiveState(TOOL_STATE *aState)
Save the previous active state and sets a new one.
void DeactivateTool()
Deactivate the currently active tool.
bool RunAction(const TOOL_ACTION &aAction, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
std::optional< VECTOR2D > m_hotKeyPos
Mouse position captured at hotkey time, used to avoid the delay between keypress and action dispatch ...
bool dispatchInternal(TOOL_EVENT &aEvent)
Pass an event at first to the active tools, then to all others.
void PrimeTool(const VECTOR2D &aPosition)
"Prime" a tool by sending a cursor left-click event with the mouse position set to the passed in posi...
bool runTool(TOOL_BASE *aTool)
Make a tool active, so it can receive events and react to them.
bool InvokeTool(TOOL_ID aToolId)
Call a tool by sending a tool activation event to tool of given ID.
NAME_STATE_MAP m_toolNameIndex
Index of the registered tools current states, associated by tools' names.
bool RunAction(const TOOL_ACTION &aAction)
TOOLS_HOLDER * m_frame
void CancelTool()
Send a cancel event to the tool currently at the top of the tool stack.
bool m_warpMouseAfterContextMenu
KIGFX::VIEW_CONTROLS * m_viewControls
void WarpAfterContextMenu()
Normally we warp the mouse after the context menu action runs.
ACTION_MANAGER * m_actionMgr
Instance of ACTION_MANAGER that handles TOOL_ACTIONs.
int GetCurrentToolId() const
Return id of the tool that is on the top of the active tools stack (was invoked the most recently).
const KIGFX::VC_SETTINGS & GetCurrentToolVC() const
Return the view controls settings for the current tool or the general settings if there is no active ...
void RunMainStack(TOOL_BASE *aTool, std::function< void()> aFunc)
TOOLS_HOLDER * GetToolHolder() const
ACTION_MANAGER * GetActionManager() const
VECTOR2D GetMousePosition() const
TOOL_BASE * GetCurrentTool() const
Return the tool that is on the top of the active tools stack (was invoked the most recently).
bool processEvent(const TOOL_EVENT &aEvent)
Main function for event processing.
std::list< TOOL_ID > ID_LIST
KIGFX::VIEW_CONTROLS * GetViewControls() const
ID_LIST::iterator finishTool(TOOL_STATE *aState)
Deactivate a tool and does the necessary clean up.
bool doRunAction(const TOOL_ACTION &aAction, bool aNow, const ki::any &aParam, COMMIT *aCommit, bool aFromAPI=false)
Helper function to actually run an action.
APP_SETTINGS_BASE * GetSettings() const
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
bool dispatchActivation(const TOOL_EVENT &aEvent)
Check if it is a valid activation event and invokes a proper tool.
ID_STATE_MAP m_toolIdIndex
Index of the registered tools current states, associated by tools' ID numbers.
TOOL_ID m_menuOwner
Tool currently displaying a popup menu. It is negative when there is no menu displayed.
KIGFX::VIEW * m_view
void ClearTransitions(TOOL_BASE *aTool)
Clear the state transition map for a tool.
bool PostAPIAction(const TOOL_ACTION &aAction, COMMIT *aCommit)
bool m_shuttingDown
True if the tool manager is shutting down (don't process additional events)
void saveViewControls(TOOL_STATE *aState)
Save the #VIEW_CONTROLS settings to the tool state object.
int GetHotKey(const TOOL_ACTION &aAction) const
Return the hot key associated with a given action or 0 if there is none.
bool m_menuActive
Flag indicating whether a context menu is currently displayed.
bool IsContextMenuActive() const
True while processing a context menu.
bool RunSynchronousAction(const TOOL_ACTION &aAction, COMMIT *aCommit, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
TOOL_STATE_MAP m_toolState
Index of registered tools current states, associated by tools' objects.
void ShutdownTool(TOOL_BASE *aTool)
Shutdown the specified tool by waking it up with a null event to terminate the processing loop.
std::map< TOOL_BASE *, TOOL_STATE * > TOOL_STATE_MAP
EDA_ITEM * GetModel() const
void VetoContextMenuMouseWarp()
Disable mouse warping after the current context menu is closed.
ID_LIST m_activeTools
Stack of the active tools.
void ResetTools(TOOL_BASE::RESET_REASON aReason)
Reset all tools (i.e.
EDA_ITEM * m_model
std::map< TOOL_ID, TOOL_STATE * > ID_STATE_MAP
KIGFX::VIEW * GetView() const
bool DispatchHotKey(const TOOL_EVENT &aEvent)
Handle specific events, that are intended for TOOL_MANAGER rather than tools.
static TOOL_ID MakeToolId(const std::string &aToolName)
Generate a unique ID from for a tool with given name.
bool invokeTool(TOOL_BASE *aTool)
Invoke a tool by sending a proper event (in contrary to runTool, which makes the tool run for real).
void DispatchContextMenu(const TOOL_EVENT &aEvent)
Handle context menu related events.
std::vector< TOOL_BASE * > m_toolOrder
List of tools in the order they were registered.
void PostAction(const TOOL_ACTION &aAction)
TOOL_BASE * FindTool(int aId) const
Search for a tool with given ID.
std::vector< TOOL_BASE * > Tools()
void ScheduleContextMenu(TOOL_BASE *aTool, ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger)
Set behavior of the tool's context popup menu.
TOOL_EVENT * ScheduleWait(TOOL_BASE *aTool, const TOOL_EVENT_LIST &aConditions)
Pause execution of a given tool until one or more events matching aConditions arrives.
bool IsToolActive(TOOL_ID aId) const
Return true if a tool with given id is active (executing)
bool PostAction(const std::string &aActionName)
bool RunSynchronousAction(const TOOL_ACTION &aAction, COMMIT *aCommit)
bool isActive(TOOL_BASE *aTool) const
Return information about a tool activation status.
void RegisterTool(TOOL_BASE *aTool)
Add a tool to the manager set and sets it up.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
void InitTools()
Initialize all registered tools.
VECTOR2D m_menuCursor
Right click context menu position.
void ShutdownAllTools()
Shutdown all tools with a currently registered event loop in this tool manager by waking them up with...
A type-safe container of any type.
Definition ki_any.h:92
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:29
Structure to keep VIEW_CONTROLS settings for easy store/restore operations.
Struct describing the current execution state of a TOOL.
std::function< int(const TOOL_EVENT &)> TOOL_STATE_FUNC
Definition tool_base.h:54
int TOOL_ID
Unique identifier for tools.
Definition tool_base.h:52
CONTEXT_MENU_TRIGGER
Defines when a context menu is opened.
Definition tool_event.h:150
VECTOR2< double > VECTOR2D
Definition vector2d.h:682