KiCad PCB EDA Suite
tool_manager.cpp
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-2017 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <map>
27 #include <stack>
28 #include <algorithm>
29 
30 #include <boost/optional.hpp>
31 
32 #include <wx/event.h>
33 #include <wx/clipbrd.h>
34 
35 #include <view/view.h>
36 
37 #include <tool/tool_base.h>
38 #include <tool/tool_interactive.h>
39 #include <tool/tool_manager.h>
40 #include <tool/context_menu.h>
41 #include <tool/coroutine.h>
42 #include <tool/action_manager.h>
43 
44 #include <wxPcbStruct.h>
45 #include <class_draw_panel_gal.h>
46 
47 using boost::optional;
48 
51 {
52  TOOL_STATE( TOOL_BASE* aTool ) :
53  theTool( aTool )
54  {
55  clear();
56  }
57 
58  TOOL_STATE( const TOOL_STATE& aState )
59  {
60  theTool = aState.theTool;
61  idle = aState.idle;
62  pendingWait = aState.pendingWait;
64  contextMenu = aState.contextMenu;
66  cofunc = aState.cofunc;
67  wakeupEvent = aState.wakeupEvent;
68  waitEvents = aState.waitEvents;
69  transitions = aState.transitions;
70  vcSettings = aState.vcSettings;
71  // do not copy stateStack
72  }
73 
75  {
76  assert( stateStack.empty() );
77  }
78 
81 
83  bool idle;
84 
88 
91 
94 
97 
100 
103 
106 
109  std::vector<TRANSITION> transitions;
110 
113 
114  void operator=( const TOOL_STATE& aState )
115  {
116  theTool = aState.theTool;
117  idle = aState.idle;
118  pendingWait = aState.pendingWait;
119  pendingContextMenu = aState.pendingContextMenu;
120  contextMenu = aState.contextMenu;
121  contextMenuTrigger = aState.contextMenuTrigger;
122  cofunc = aState.cofunc;
123  wakeupEvent = aState.wakeupEvent;
124  waitEvents = aState.waitEvents;
125  transitions = aState.transitions;
126  vcSettings = aState.vcSettings;
127  // do not copy stateStack
128  }
129 
130  bool operator==( const TOOL_MANAGER::TOOL_STATE& aRhs ) const
131  {
132  return aRhs.theTool == this->theTool;
133  }
134 
135  bool operator!=( const TOOL_MANAGER::TOOL_STATE& aRhs ) const
136  {
137  return aRhs.theTool != this->theTool;
138  }
139 
145  void Push()
146  {
147  auto state = std::make_unique<TOOL_STATE>( *this );
148  stateStack.push( std::move( state ) );
149  clear();
150  }
151 
158  bool Pop()
159  {
160  delete cofunc;
161 
162  if( !stateStack.empty() )
163  {
164  *this = *stateStack.top().get();
165  stateStack.pop();
166  return true;
167  }
168  else
169  {
170  cofunc = NULL;
171  return false;
172  }
173  }
174 
175 private:
177  std::stack<std::unique_ptr<TOOL_STATE>> stateStack;
178 
180  void clear()
181  {
182  idle = true;
183  pendingWait = false;
184  pendingContextMenu = false;
185  cofunc = NULL;
186  contextMenu = NULL;
187  contextMenuTrigger = CMENU_OFF;
188  vcSettings.Reset();
189  transitions.clear();
190  }
191 };
192 
193 
195  m_model( NULL ),
196  m_view( NULL ),
197  m_viewControls( NULL ),
198  m_editFrame( NULL ),
199  m_passEvent( false ),
200  m_menuActive( false )
201 {
202  m_actionMgr = new ACTION_MANAGER( this );
203 
204  // Keep default VIEW_CONTROLS settings at the bottom of the stack
205  m_vcStack.push( KIGFX::VC_SETTINGS() );
206 }
207 
208 
210 {
211  std::map<TOOL_BASE*, TOOL_STATE*>::iterator it, it_end;
212 
213  for( it = m_toolState.begin(), it_end = m_toolState.end(); it != it_end; ++it )
214  {
215  delete it->second->cofunc; // delete cofunction
216  delete it->second; // delete TOOL_STATE
217  delete it->first; // delete the tool itself
218  }
219 
220  delete m_actionMgr;
221 }
222 
223 
225 {
226  wxASSERT_MSG( m_toolNameIndex.find( aTool->GetName() ) == m_toolNameIndex.end(),
227  wxT( "Adding two tools with the same name may result in unexpected behaviour.") );
228  wxASSERT_MSG( m_toolIdIndex.find( aTool->GetId() ) == m_toolIdIndex.end(),
229  wxT( "Adding two tools with the same ID may result in unexpected behaviour.") );
230  wxASSERT_MSG( m_toolTypes.find( typeid( *aTool ).name() ) == m_toolTypes.end(),
231  wxT( "Adding two tools of the same type may result in unexpected behaviour.") );
232 
233  TOOL_STATE* st = new TOOL_STATE( aTool );
234 
235  m_toolState[aTool] = st;
236  m_toolNameIndex[aTool->GetName()] = st;
237  m_toolIdIndex[aTool->GetId()] = st;
238  m_toolTypes[typeid( *aTool ).name()] = st->theTool;
239 
240  aTool->attachManager( this );
241 }
242 
243 
245 {
246  TOOL_BASE* tool = FindTool( aToolId );
247 
248  if( tool && tool->GetType() == INTERACTIVE )
249  return invokeTool( tool );
250 
251  return false; // there is no tool with the given id
252 }
253 
254 
255 bool TOOL_MANAGER::InvokeTool( const std::string& aToolName )
256 {
257  TOOL_BASE* tool = FindTool( aToolName );
258 
259  if( tool && tool->GetType() == INTERACTIVE )
260  return invokeTool( tool );
261 
262  return false; // there is no tool with the given name
263 }
264 
265 
267 {
268  m_actionMgr->RegisterAction( aAction );
269 }
270 
271 
273 {
274  m_actionMgr->UnregisterAction( aAction );
275 }
276 
277 
278 bool TOOL_MANAGER::RunAction( const std::string& aActionName, bool aNow, void* aParam )
279 {
280  TOOL_ACTION* action = m_actionMgr->FindAction( aActionName );
281 
282  if( !action )
283  {
284  wxASSERT_MSG( false, wxString::Format( wxT( "Could not find action %s." ), aActionName ) );
285  return false;
286  }
287 
288  RunAction( *action, aNow, aParam );
289 
290  return false;
291 }
292 
293 
294 void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction, bool aNow, void* aParam )
295 {
296  TOOL_EVENT event = aAction.MakeEvent();
297 
298  // Allow to override the action parameter
299  if( aParam )
300  event.SetParameter( aParam );
301 
302  if( aNow )
303  processEvent( event );
304  else
305  PostEvent( event );
306 }
307 
308 
310 {
311  return m_actionMgr->GetHotKey( aAction );
312 }
313 
314 
316 {
318 }
319 
320 
322 {
323  wxASSERT( aTool != NULL );
324 
325  TOOL_EVENT evt( TC_COMMAND, TA_ACTIVATE, aTool->GetName() );
326  processEvent( evt );
327 
328  return true;
329 }
330 
331 
333 {
334  TOOL_BASE* tool = FindTool( aToolId );
335 
336  if( tool && tool->GetType() == INTERACTIVE )
337  return runTool( tool );
338 
339  return false; // there is no tool with the given id
340 }
341 
342 
343 bool TOOL_MANAGER::runTool( const std::string& aToolName )
344 {
345  TOOL_BASE* tool = FindTool( aToolName );
346 
347  if( tool && tool->GetType() == INTERACTIVE )
348  return runTool( tool );
349 
350  return false; // there is no tool with the given name
351 }
352 
353 
355 {
356  wxASSERT( aTool != NULL );
357 
358  if( !isRegistered( aTool ) )
359  {
360  wxASSERT_MSG( false, wxT( "You cannot run unregistered tools" ) );
361  return false;
362  }
363 
364  TOOL_ID id = aTool->GetId();
365 
366  // If the tool is already active, bring it to the top of the active tools stack
367  if( isActive( aTool ) )
368  {
369  m_activeTools.erase( std::find( m_activeTools.begin(), m_activeTools.end(), id ) );
370  m_activeTools.push_front( id );
371  return false;
372  }
373 
374  aTool->Reset( TOOL_INTERACTIVE::RUN );
375 
376  if( aTool->GetType() == INTERACTIVE )
377  static_cast<TOOL_INTERACTIVE*>( aTool )->resetTransitions();
378 
379  // Add the tool on the front of the processing queue (it gets events first)
380  m_activeTools.push_front( id );
381 
382  return true;
383 }
384 
385 
387 {
388  std::map<TOOL_ID, TOOL_STATE*>::const_iterator it = m_toolIdIndex.find( aId );
389 
390  if( it != m_toolIdIndex.end() )
391  return it->second->theTool;
392 
393  return NULL;
394 }
395 
396 
397 TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const
398 {
399  std::map<std::string, TOOL_STATE*>::const_iterator it = m_toolNameIndex.find( aName );
400 
401  if( it != m_toolNameIndex.end() )
402  return it->second->theTool;
403 
404  return NULL;
405 }
406 
407 
409 {
410  // Deactivate the active tool, but do not run anything new
412  processEvent( evt );
413 }
414 
415 
417 {
418  DeactivateTool();
419 
420  for( auto& state : m_toolState )
421  {
422  TOOL_BASE* tool = state.first;
423  tool->Reset( aReason );
424 
425  if( tool->GetType() == INTERACTIVE )
426  static_cast<TOOL_INTERACTIVE*>( tool )->resetTransitions();
427  }
428 }
429 
430 
432 {
433  for( auto it = m_toolState.begin(); it != m_toolState.end(); /* iteration in the loop */ )
434  {
435  TOOL_BASE* tool = it->first;
436  TOOL_STATE* state = it->second;
437  ++it; // keep the iterator valid if the element is going to be erased
438 
439  if( !tool->Init() )
440  {
441  wxMessageBox(
442  wxString::Format( "Initialization of tool '%s' failed", tool->GetName() ) );
443 
444  // Unregister the tool
445  m_toolState.erase( tool );
446  m_toolNameIndex.erase( tool->GetName() );
447  m_toolIdIndex.erase( tool->GetId() );
448  m_toolTypes.erase( typeid( *tool ).name() );
449 
450  delete state;
451  delete tool;
452  }
453  }
454 
456 }
457 
458 
459 int TOOL_MANAGER::GetPriority( int aToolId ) const
460 {
461  int priority = 0;
462 
463  for( auto it = m_activeTools.begin(), itEnd = m_activeTools.end(); it != itEnd; ++it )
464  {
465  if( *it == aToolId )
466  return priority;
467 
468  ++priority;
469  }
470 
471  return -1;
472 }
473 
474 
476  const TOOL_EVENT_LIST& aConditions )
477 {
478  TOOL_STATE* st = m_toolState[aTool];
479 
480  st->transitions.push_back( TRANSITION( aConditions, aHandler ) );
481 }
482 
483 
485 {
486  m_toolState[aTool]->transitions.clear();
487 }
488 
489 
490 void TOOL_MANAGER::RunMainStack( TOOL_BASE* aTool, std::function<void()> aFunc )
491 {
492  TOOL_STATE* st = m_toolState[aTool];
493  st->cofunc->RunMainStack( std::move( aFunc ) );
494 }
495 
496 
498  const TOOL_EVENT_LIST& aConditions )
499 {
500  TOOL_STATE* st = m_toolState[aTool];
501 
502  assert( !st->pendingWait ); // everything collapses on two KiYield() in a row
503 
504  // indicate to the manager that we are going to sleep and we shall be
505  // woken up when an event matching aConditions arrive
506  st->pendingWait = true;
507  st->waitEvents = aConditions;
508 
509  // switch context back to event dispatcher loop
510  st->cofunc->KiYield();
511 
512  return st->wakeupEvent;
513 }
514 
515 
517 {
518  // iterate over all registered tools
519  for( auto it = m_activeTools.begin(); it != m_activeTools.end(); ++it )
520  {
521  TOOL_STATE* st = m_toolIdIndex[*it];
522 
523  // the tool state handler is waiting for events (i.e. called Wait() method)
524  if( st->pendingWait )
525  {
526  if( st->waitEvents.Matches( aEvent ) )
527  {
528  // By default, only messages are passed further
529  m_passEvent = ( aEvent.Category() == TC_MESSAGE );
530 
531  // got matching event? clear wait list and wake up the coroutine
532  st->wakeupEvent = aEvent;
533  st->pendingWait = false;
534  st->waitEvents.clear();
535 
536  if( st->cofunc )
537  {
539  applyViewControls( st );
540  bool end = !st->cofunc->Resume();
541  saveViewControls( st );
542  popViewControls();
543 
544  if( end )
545  it = finishTool( st );
546  }
547 
548  // If the tool did not request to propagate
549  // the event to other tools, we should stop it now
550  if( !m_passEvent )
551  break;
552  }
553  }
554  }
555 
556  for( auto& state : m_toolState )
557  {
558  TOOL_STATE* st = state.second;
559  bool finished = false;
560 
561  // no state handler in progress - check if there are any transitions (defined by
562  // Go() method that match the event.
563  if( !st->transitions.empty() )
564  {
565  for( TRANSITION& tr : st->transitions )
566  {
567  if( tr.first.Matches( aEvent ) )
568  {
569  auto func_copy = tr.second;
570 
571  // if there is already a context, then store it
572  if( st->cofunc )
573  st->Push();
574 
575  st->cofunc = new COROUTINE<int, const TOOL_EVENT&>( std::move( func_copy ) );
576 
577  // as the state changes, the transition table has to be set up again
578  st->transitions.clear();
579 
580  // got match? Run the handler.
582  applyViewControls( st );
583  st->idle = false;
584  st->cofunc->Call( aEvent );
585  saveViewControls( st );
586  popViewControls();
587 
588  if( !st->cofunc->Running() )
589  finishTool( st ); // The couroutine has finished immediately?
590 
591  // if it is a message, continue processing
592  finished = !( aEvent.Category() == TC_MESSAGE );
593 
594  // there is no point in further checking, as transitions got cleared
595  break;
596  }
597  }
598  }
599 
600  if( finished )
601  break; // only the first tool gets the event
602  }
603 }
604 
605 
607 {
608  if( aEvent.Action() == TA_KEY_PRESSED )
609  {
610  // Check if there is a hotkey associated
611  if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) )
612  return false; // hotkey event was handled so it does not go any further
613  }
614 
615  return true;
616 }
617 
618 
620 {
621  if( aEvent.IsActivate() )
622  {
623  std::map<std::string, TOOL_STATE*>::iterator tool = m_toolNameIndex.find( *aEvent.GetCommandStr() );
624 
625  if( tool != m_toolNameIndex.end() )
626  {
627  runTool( tool->second->theTool );
628  return true;
629  }
630  }
631 
632  return false;
633 }
634 
635 
637 {
638  // Store the current tool ID to decide whether to restore the cursor position
639  TOOL_ID activeTool = GetCurrentToolId();
640 
641  for( TOOL_ID toolId : m_activeTools )
642  {
643  TOOL_STATE* st = m_toolIdIndex[toolId];
644 
645  // the tool requested a context menu. The menu is activated on RMB click (CMENU_BUTTON mode)
646  // or immediately (CMENU_NOW) mode. The latter is used for clarification lists.
647  if( st->contextMenuTrigger == CMENU_OFF )
648  continue;
649 
650  if( st->contextMenuTrigger == CMENU_BUTTON && !aEvent.IsClick( BUT_RIGHT ) )
651  break;
652 
653  st->pendingWait = true;
655 
656  // Store the menu pointer in case it is changed by the TOOL when handling menu events
657  CONTEXT_MENU* m = st->contextMenu;
658 
659  if( st->contextMenuTrigger == CMENU_NOW )
661 
663 
664  // Temporarily store the cursor position, so the tools could execute actions
665  // using the point where the user has invoked a context menu
667  m_origCursor = cursor;
668 
669  m_viewControls->ForceCursorPosition( true, cursor );
670 
671  // Display a copy of menu
672  std::unique_ptr<CONTEXT_MENU> menu( m->Clone() );
673 
674  // Run update handlers on the created copy
675  menu->UpdateAll();
676  m_menuActive = true;
677  GetEditFrame()->PopupMenu( menu.get() );
678  m_menuActive = false;
679 
680  m_viewControls->WarpCursor( cursor, true, false );
681 
682  // If nothing was chosen from the context menu, we must notify the tool as well
683  if( menu->GetSelected() < 0 )
684  {
686  evt.SetParameter( m );
687  dispatchInternal( evt );
688  }
689 
690  // Notify the tools that menu has been closed
692  evt.SetParameter( m );
693  dispatchInternal( evt );
694 
695  // Restore the cursor settings if the tool is still active
696  if( activeTool == GetCurrentToolId() )
697  {
699  m_origCursor.get_value_or( VECTOR2D( 0, 0 ) ) );
700  }
701 
702  m_origCursor = boost::none;
703  break;
704  }
705 }
706 
707 
708 TOOL_MANAGER::ID_LIST::iterator TOOL_MANAGER::finishTool( TOOL_STATE* aState )
709 {
710  auto it = std::find( m_activeTools.begin(), m_activeTools.end(), aState->theTool->GetId() );
711 
712  if( !aState->Pop() )
713  {
714  // Deactivate the tool if there are no other contexts saved on the stack
715  if( it != m_activeTools.end() )
716  it = m_activeTools.erase( it );
717  }
718 
719  // Set transitions to be ready for future TOOL_EVENTs
720  TOOL_BASE* tool = aState->theTool;
721 
722  if( tool->GetType() == INTERACTIVE )
723  static_cast<TOOL_INTERACTIVE*>( tool )->resetTransitions();
724 
725  aState->idle = true;
726 
727  return it;
728 }
729 
730 
732 {
733  processEvent( aEvent );
734 
735  if( TOOL_STATE* active = GetCurrentToolState() )
736  {
737  applyViewControls( active );
738  }
739 
740  if( m_view->IsDirty() )
741  {
742  EDA_DRAW_FRAME* f = static_cast<EDA_DRAW_FRAME*>( GetEditFrame() );
743  f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
744  }
745 }
746 
747 
749  CONTEXT_MENU_TRIGGER aTrigger )
750 {
751  TOOL_STATE* st = m_toolState[aTool];
752 
753  st->contextMenu = aMenu;
754  st->contextMenuTrigger = aTrigger;
755 }
756 
757 
758 bool TOOL_MANAGER::SaveClipboard( const std::string& aText )
759 {
760  if( wxTheClipboard->Open() )
761  {
762  wxTheClipboard->SetData( new wxTextDataObject( wxString( aText.c_str(), wxConvUTF8 ) ) );
763  wxTheClipboard->Close();
764 
765  return true;
766  }
767 
768  return false;
769 }
770 
771 
772 std::string TOOL_MANAGER::GetClipboard() const
773 {
774  std::string result;
775 
776  if( wxTheClipboard->Open() )
777  {
778  if( wxTheClipboard->IsSupported( wxDF_TEXT ) )
779  {
780  wxTextDataObject data;
781  wxTheClipboard->GetData( data );
782 
783  result = data.GetText().mb_str();
784  }
785 
786  wxTheClipboard->Close();
787  }
788 
789  return result;
790 }
791 
792 
793 TOOL_ID TOOL_MANAGER::MakeToolId( const std::string& aToolName )
794 {
795  static int currentId;
796 
797  return currentId++;
798 }
799 
800 
802  KIGFX::VIEW_CONTROLS* aViewControls, wxWindow* aFrame )
803 {
804  m_model = aModel;
805  m_view = aView;
806  m_viewControls = aViewControls;
807  m_editFrame = aFrame;
809 }
810 
811 
813 {
814  if( !isRegistered( aTool ) )
815  return false;
816 
817  // Just check if the tool is on the active tools stack
818  return std::find( m_activeTools.begin(), m_activeTools.end(), aTool->GetId() ) != m_activeTools.end();
819 }
820 
821 
823 {
825 
826  // If context menu has overridden the cursor position, restore the original position
827  // (see dispatchContextMenu())
828  if( m_menuActive )
829  {
830  if( m_origCursor )
831  {
832  aState->vcSettings.m_forceCursorPosition = true;
834  }
835  else
836  {
837  aState->vcSettings.m_forceCursorPosition = false;
838  }
839  }
840 }
841 
842 
844 {
846 }
847 
848 
850 {
852 }
853 
854 
856 {
858  m_vcStack.pop();
859 }
860 
861 
863 {
864  // Early dispatch of events destined for the TOOL_MANAGER
865  if( !dispatchStandardEvents( aEvent ) )
866  return;
867 
868  dispatchInternal( aEvent );
869  dispatchActivation( aEvent );
870  dispatchContextMenu( aEvent );
871 
872  // Dispatch queue
873  while( !m_eventQueue.empty() )
874  {
875  TOOL_EVENT event = m_eventQueue.front();
876  m_eventQueue.pop_front();
877  processEvent( event );
878  }
879 }
880 
882 {
883  auto it = m_toolIdIndex.find( aId );
884  return !it->second->idle;
885 }
void RunMainStack(std::function< void()> func)
Function RunMainStack()
Definition: coroutine.h:190
bool m_menuActive
Flag indicating whether a context menu is currently displayed.
Definition: tool_manager.h:532
bool operator==(const TOOL_MANAGER::TOOL_STATE &aRhs) const
bool IsToolActive(TOOL_ID aId) const
Function IsToolActive() Returns true if a tool with given id is active (executing) ...
virtual bool Init()
Function Init() Init() is called once upon a registration of the tool.
Definition: tool_base.h:93
TOOL_BASE * FindTool(int aId) const
Function FindTool() Searches for a tool with given ID.
void Reset()
Restores the default settings
TOOL_STATE(TOOL_BASE *aTool)
int GetHotKey(const TOOL_ACTION &aAction)
>
TOOL_BASE * theTool
The tool itself.
ACTION_MANAGER * m_actionMgr
Instance of ACTION_MANAGER that handles TOOL_ACTIONs.
Definition: tool_manager.h:512
int GetCurrentToolId() const
Returns id of the tool that is on the top of the active tools stack (was invoked the most recently)...
Definition: tool_manager.h:276
static TOOL_ID MakeToolId(const std::string &aToolName)
Generates a unique ID from for a tool with given name.
std::vector< TRANSITION > transitions
List of possible transitions (ie.
ID_STATE_MAP m_toolIdIndex
Index of the registered tools current states, associated by tools' ID numbers.
Definition: tool_manager.h:503
void ScheduleNextState(TOOL_BASE *aTool, TOOL_STATE_FUNC &aHandler, const TOOL_EVENT_LIST &aConditions)
Defines a state transition - the events that cause a given handler method in the tool to be called...
void RegisterAction(TOOL_ACTION *aAction)
Function RegisterAction() Registers an action that can be used to control tools (eg.
bool dispatchStandardEvents(const TOOL_EVENT &aEvent)
Function dispatchStandardEvents() Handles specific events, that are intended for TOOL_MANAGER rather ...
bool SaveClipboard(const std::string &aText)
Stores an information to the system clipboard.
bool Call(ArgType aArg)
Function Call()
Definition: coroutine.h:204
void UpdateHotKeys()
Function UpdateHotKeys() Updates TOOL_ACTIONs hot key assignment according to the current frame's Hot...
Class CONTEXT_MENU.
Definition: context_menu.h:44
void ApplySettings(const VC_SETTINGS &aSettings)
Applies VIEW_CONTROLS settings from an object
KIGFX::VC_SETTINGS vcSettings
VIEW_CONTROLS settings to preserve settings when the tools are switched.
wxWindow * GetEditFrame() const
Definition: tool_manager.h:266
Tool is invoked after being inactive.
Definition: tool_base.h:82
ID_LIST::iterator finishTool(TOOL_STATE *aState)
Function finishTool() Deactivates a tool and does the necessary clean up.
bool dispatchActivation(const TOOL_EVENT &aEvent)
Function dispatchActivation() Checks if it is a valid activation event and invokes a proper tool...
VECTOR2D m_forcedPosition
Forced cursor position (world coordinates)
Definition: view_controls.h:58
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
void attachManager(TOOL_MANAGER *aManager)
Function attachManager()
Definition: tool_base.cpp:59
Class ACTION_MANAGER.
void ScheduleContextMenu(TOOL_BASE *aTool, CONTEXT_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger)
Sets behaviour of the tool's context popup menu.
int Modifier(int aMask=MD_MODIFIER_MASK) const
Returns information about key modifiers state (Ctrl, Alt, etc.)
Definition: tool_event.h:311
TOOL_ACTION * FindAction(const std::string &aActionName) const
Function FindAction() Finds an action with a given name (if there is one available).
void applyViewControls(TOOL_STATE *aState)
Function applyViewControls() Applies VIEW_CONTROLS settings stored in a TOOL_STATE object...
Class EDA_DRAW_FRAME is the base class for create windows for drawing purpose.
Definition: draw_frame.h:53
int KeyCode() const
Definition: tool_event.h:316
bool IsDirty() const
Function IsDirty() Returns true if any of the VIEW layers needs to be refreshened.
Definition: view.h:539
void Push()
Function Push() Stores the current state of the tool on stack.
void dispatchContextMenu(const TOOL_EVENT &aEvent)
Function dispatchContextMenu() Handles context menu related events.
bool runTool(TOOL_ID aToolId)
Function runTool() Makes a tool active, so it can receive events and react to them.
void DeactivateTool()
Function DeactivateTool() Deactivates the currently active tool.
bool InvokeTool(TOOL_ID aToolId)
Function InvokeTool() Calls a tool by sending a tool activation event to tool of given ID...
boost::optional< const TOOL_EVENT & > Matches(const TOOL_EVENT &aEvent) const
Definition: tool_event.h:493
boost::optional< std::string > GetCommandStr() const
Definition: tool_event.h:395
bool m_passEvent
Flag saying if the currently processed event should be passed to other tools.
Definition: tool_manager.h:529
EDA_ITEM * m_model
Definition: tool_manager.h:517
bool pendingWait
Flag defining if the tool is waiting for any event (i.e.
void SetParameter(T aParam)
Function SetParameter() Sets a non-standard parameter assigned to the event.
Definition: tool_event.h:385
virtual void Reset(RESET_REASON aReason)=0
Function Reset() Brings the tool to a known, initial state.
bool pendingContextMenu
Is there a context menu being displayed.
NAME_STATE_MAP m_toolNameIndex
Index of the registered tools current states, associated by tools' names.
Definition: tool_manager.h:500
int TOOL_ID
Unique identifier for tools.
Definition: tool_base.h:57
virtual void WarpCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false) const =0
Function WarpCursor() If enabled (.
Class TOOL_EVENT_LIST.
Definition: tool_event.h:468
bool operator!=(const TOOL_MANAGER::TOOL_STATE &aRhs) const
Tool that interacts with the user
Definition: tool_base.h:50
CONTEXT_MENU * Clone() const
Creates a deep, recursive copy of this CONTEXT_MENU.
bool m_forceCursorPosition
Is the forced cursor position enabled
Definition: view_controls.h:61
wxWindow * m_editFrame
Definition: tool_manager.h:520
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, wxWindow *aFrame)
Sets the work environment (model, view, view controls and the parent window).
CONTEXT_MENU_TRIGGER
Defines when a context menu is opened.
Definition: tool_event.h:150
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
void dispatchInternal(const TOOL_EVENT &aEvent)
Function dispatchInternal Passes an event at first to the active tools, then to all others...
Class TOOL_EVENT.
Definition: tool_event.h:162
bool idle
Is the tool active (pending execution) or disabled at the moment.
bool IsActivate() const
Definition: tool_event.h:300
std::stack< std::unique_ptr< TOOL_STATE > > stateStack
Stack preserving previous states of a TOOL.
CONTEXT_MENU * contextMenu
Context menu currently used by the tool.
int GetHotKey(const TOOL_ACTION &aAction) const
Function GetHotKey() Returns the hot key associated with a given action or 0 if there is none...
bool RunHotKey(int aHotKey) const
Function RunHotKey() Runs an action associated with a hotkey (if there is one available).
void pushViewControls()
Function pushViewControls() Stores the current VIEW_CONTROLS settings on the stack.
Structure to keep VIEW_CONTROLS settings for easy store/restore operations
Definition: view_controls.h:44
void ResetTools(TOOL_BASE::RESET_REASON aReason)
Function ResetTools() Resets all tools (i.e.
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
int GetPriority(int aToolId) const
Returns priority of a given tool.
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
TOOL_ID GetId() const
Function GetId() Returns the unique identifier of the tool.
Definition: tool_base.h:122
Struct describing the current execution state of a TOOL.
KIGFX::VIEW_CONTROLS * m_viewControls
Definition: tool_manager.h:519
bool Resume()
Function Resume()
Definition: coroutine.h:238
TOOL_STATE * GetCurrentToolState() const
Returns the TOOL_STATE object representing the state of the active tool.
Definition: tool_manager.h:295
void UnregisterAction(TOOL_ACTION *aAction)
Function UnregisterAction() Removes a tool action from the manager and makes it unavailable for furth...
std::function< int(const TOOL_EVENT &)> TOOL_STATE_FUNC
Definition: tool_base.h:59
TOOL_ACTIONS Action() const
Returns more specific information about the type of an event.
Definition: tool_event.h:234
bool isActive(TOOL_BASE *aTool)
Function isActive() Returns information about a tool activation status.
KIGFX::VIEW * m_view
Definition: tool_manager.h:518
std::string GetClipboard() const
Returns the information currently stored in the system clipboard.
void RunMainStack(TOOL_BASE *aTool, std::function< void()> aFunc)
void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it bu a python script (note: it is automatically called by a...
TOOL_EVENT_CATEGORY Category() const
Returns the category (eg. mouse/keyboard/action) of an event..
Definition: tool_event.h:228
const VC_SETTINGS & GetSettings() const
Returns the current VIEW_CONTROLS settings
TOOL_EVENT wakeupEvent
The event that triggered the execution/wakeup of the tool after Wait() call.
std::stack< KIGFX::VC_SETTINGS > m_vcStack
VIEW_CONTROLS settings stack
Definition: tool_manager.h:526
boost::optional< VECTOR2D > m_origCursor
Original cursor position, if overridden by the context menu handler.
Definition: tool_manager.h:515
void popViewControls()
Function pushViewControls() Restores VIEW_CONTROLS settings from the stack.
void RegisterAction(TOOL_ACTION *aAction)
Function RegisterAction() Adds a tool action to the manager and sets it up.
TOOL_TYPE GetType() const
Function GetType() Returns the type of the tool.
Definition: tool_base.h:111
TOOL_EVENT MakeEvent() const
Function HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
std::list< TOOL_EVENT > m_eventQueue
Queue that stores events to be processed at the end of the event processing cycle.
Definition: tool_manager.h:523
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void operator=(const TOOL_STATE &aState)
boost::optional< TOOL_EVENT > ScheduleWait(TOOL_BASE *aTool, const TOOL_EVENT_LIST &aConditions)
Pauses execution of a given tool until one or more events matching aConditions arrives.
bool Pop()
Function Pop() Restores state of the tool from stack.
COROUTINE< int, const TOOL_EVENT & > * cofunc
Tool execution context.
Class TOOL_BASE.
Definition: tool_base.h:68
Class TOOL_ACTION.
Definition: tool_action.h:46
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
bool isRegistered(TOOL_BASE *aTool) const
Function isRegistered() Returns information about a tool registration status.
Definition: tool_manager.h:454
bool ForcedCursorPosition() const
Function ForcedCursorPosition() Returns true if the current cursor position is forced to a specific l...
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
void processEvent(const TOOL_EVENT &aEvent)
Main function for event processing.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Function GetGalCanvas returns a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:836
CONTEXT_MENU_TRIGGER contextMenuTrigger
Defines when the context menu is opened.
void InitTools()
Function InitTools() Initializes all registered tools.
void ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
Class VIEW.
Definition: view.h:58
void ClearTransitions(TOOL_BASE *aTool)
Clears the state transition map for a tool.
ID_LIST m_activeTools
Stack of the active tools.
Definition: tool_manager.h:509
TOOL_EVENT_LIST waitEvents
List of events the tool is currently waiting for.
const std::string & GetName() const
Function GetName() Returns the name of the tool.
Definition: tool_base.h:133
bool Running() const
Function Running()
Definition: coroutine.h:279
bool IsClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:268
void clear()
Restores the initial state.
void PostEvent(const TOOL_EVENT &aEvent)
Puts an event to the event queue to be processed at the end of event processing cycle.
Definition: tool_manager.h:237
TOOL_STATE_MAP m_toolState
Index of registered tools current states, associated by tools' objects.
Definition: tool_manager.h:497
TOOL_STATE(const TOOL_STATE &aState)
void saveViewControls(TOOL_STATE *aState)
Function saveViewControls() Saves the VIEW_CONTROLS settings to the tool state object.
void UpdateHotKeys()
>
bool invokeTool(TOOL_BASE *aTool)
Function invokeTool() Invokes a tool by sending a proper event (in contrary to runTool, which makes the tool run for real).
void RegisterTool(TOOL_BASE *aTool)
Function RegisterTool() Adds a tool to the manager set and sets it up.
void UnregisterAction(TOOL_ACTION *aAction)
Function UnregisterAction() Unregisters an action, so it is no longer active.
void KiYield()
Function KiYield()
Definition: coroutine.h:155
std::pair< TOOL_EVENT_LIST, TOOL_STATE_FUNC > TRANSITION
Definition: tool_manager.h:369
std::map< const char *, TOOL_BASE * > m_toolTypes
Index of the registered tools to easily lookup by their type.
Definition: tool_manager.h:506