KiCad PCB EDA Suite
tool_event.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 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #ifndef __TOOL_EVENT_H
26 #define __TOOL_EVENT_H
27 
28 #include <cstdio>
29 #include <deque>
30 #include <iterator>
31 
32 #include <math/vector2d.h>
33 #include <core/optional.h>
34 
35 #ifdef WX_COMPATIBILITY
36 #include <wx/debug.h>
37 #else
38 #include <cassert>
39 #endif
40 
41 
42 class TOOL_ACTION;
43 class TOOL_MANAGER;
44 class TOOL_BASE;
45 
51 {
52  TC_NONE = 0x00,
53  TC_MOUSE = 0x01,
54  TC_KEYBOARD = 0x02,
55  TC_COMMAND = 0x04,
56  TC_MESSAGE = 0x08,
57  TC_VIEW = 0x10,
58  TC_ANY = 0xffffffff
59 };
60 
62 {
63  // UI input events
64  TA_NONE = 0x0000,
65  TA_MOUSE_CLICK = 0x0001,
67  TA_MOUSE_UP = 0x0004,
68  TA_MOUSE_DOWN = 0x0008,
69  TA_MOUSE_DRAG = 0x0010,
70  TA_MOUSE_MOTION = 0x0020,
71  TA_MOUSE_WHEEL = 0x0040,
72  TA_MOUSE = 0x007f,
73 
74  TA_KEY_PRESSED = 0x0080,
76 
77  // View related events
78  TA_VIEW_REFRESH = 0x0100,
79  TA_VIEW_ZOOM = 0x0200,
80  TA_VIEW_PAN = 0x0400,
81  TA_VIEW_DIRTY = 0x0800,
82  TA_VIEW = 0x0f00,
83 
84  TA_CHANGE_LAYER = 0x1000,
85 
86  // Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
87  // the context menu.
88  TA_CANCEL_TOOL = 0x2000,
89 
90  // Context menu update. Issued whenever context menu is open and the user hovers the mouse
91  // over one of choices. Used in dynamic highligting in disambiguation menu
93 
94  // Context menu choice. Sent if the user picked something from the context menu or
95  // closed it without selecting anything.
97 
98  // Context menu is closed, no matter whether anything has been chosen or not.
100 
102 
103  // This event is sent *before* undo/redo command is performed.
104  TA_UNDO_REDO_PRE = 0x20000,
105 
106  // This event is sent *after* undo/redo command is performed.
107  TA_UNDO_REDO_POST = 0x40000,
108 
109  // Tool action (allows one to control tools).
110  TA_ACTION = 0x80000,
111 
112  // Tool activation event.
113  TA_ACTIVATE = 0x100000,
114 
115  // Model has changed (partial update).
116  TA_MODEL_CHANGE = 0x200000,
117 
118  // Tool priming event (a special mouse click)
119  TA_PRIME = 0x400001,
120 
121  TA_ANY = 0xffffffff
122 };
123 
125 {
126  BUT_NONE = 0x0,
127  BUT_LEFT = 0x1,
128  BUT_RIGHT = 0x2,
129  BUT_MIDDLE = 0x4,
131  BUT_ANY = 0xffffffff
132 };
133 
135 {
136  MD_SHIFT = 0x1000,
137  MD_CTRL = 0x2000,
138  MD_ALT = 0x4000,
140 };
141 
144 {
148 };
149 
152 {
153  AF_NONE = 0,
156 };
157 
160 {
161  CMENU_BUTTON = 0, // On the right button
162  CMENU_NOW, // Right now (after TOOL_INTERACTIVE::SetContextMenu)
163  CMENU_OFF // Never
164 };
165 
172 {
173 public:
180  const std::string Format() const;
181 
183  TOOL_ACTION_SCOPE aScope = AS_GLOBAL, void* aParameter = nullptr ) :
184  m_category( aCategory ),
185  m_actions( aAction ),
186  m_scope( aScope ),
187  m_mouseButtons( 0 ),
188  m_keyCode( 0 ),
189  m_modifiers( 0 ),
190  m_param( aParameter ),
191  m_firstResponder( nullptr )
192  {
193  init();
194  }
195 
196  TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, int aExtraParam,
197  TOOL_ACTION_SCOPE aScope = AS_GLOBAL, void* aParameter = nullptr ) :
198  m_category( aCategory ),
199  m_actions( aAction ),
200  m_scope( aScope ),
201  m_mouseButtons( 0 ),
202  m_keyCode( 0 ),
203  m_modifiers( 0 ),
204  m_param( aParameter ),
205  m_firstResponder( nullptr )
206  {
207  if( aCategory == TC_MOUSE )
208  {
209  setMouseButtons( aExtraParam & BUT_BUTTON_MASK );
210  }
211  else if( aCategory == TC_KEYBOARD )
212  {
213  m_keyCode = aExtraParam & ~MD_MODIFIER_MASK; // Filter out modifiers
214  }
215  else if( aCategory == TC_COMMAND )
216  {
217  m_commandId = aExtraParam;
218  }
219 
220  if( aCategory & ( TC_MOUSE | TC_KEYBOARD ) )
221  {
222  m_modifiers = aExtraParam & MD_MODIFIER_MASK;
223  }
224 
225  init();
226  }
227 
229  const std::string& aExtraParam, TOOL_ACTION_SCOPE aScope = AS_GLOBAL,
230  void* aParameter = nullptr ) :
231  m_category( aCategory ),
232  m_actions( aAction ),
233  m_scope( aScope ),
234  m_mouseButtons( 0 ),
235  m_keyCode( 0 ),
236  m_modifiers( 0 ),
237  m_param( aParameter ),
238  m_firstResponder( nullptr )
239  {
240  if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE )
241  m_commandStr = aExtraParam;
242 
243  init();
244  }
245 
248 
250  TOOL_ACTIONS Action() const { return m_actions; }
251 
255  bool PassEvent() const { return m_passEvent; }
256  void SetPassEvent() { m_passEvent = true; }
257 
260  bool HasPosition() const { return m_hasPosition; }
261  void SetHasPosition( bool aHasPosition ) { m_hasPosition = aHasPosition; }
262 
264  void SetFirstResponder( TOOL_BASE* aTool ) { m_firstResponder = aTool; }
265 
268  const VECTOR2D Delta() const
269  {
271  }
272 
274  const VECTOR2D Position() const
275  {
277  }
278 
280  const VECTOR2D DragOrigin() const
281  {
283  }
284 
286  int Buttons() const
287  {
288  assert( m_category == TC_MOUSE ); // this should be used only with mouse events
289  return m_mouseButtons;
290  }
291 
292  bool IsClick( int aButtonMask = BUT_ANY ) const;
293 
294  bool IsDblClick( int aButtonMask = BUT_ANY ) const;
295 
296  bool IsDrag( int aButtonMask = BUT_ANY ) const
297  {
298  return m_actions == TA_MOUSE_DRAG && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
299  }
300 
301  bool IsMouseUp( int aButtonMask = BUT_ANY ) const
302  {
303  return m_actions == TA_MOUSE_UP && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
304  }
305 
306  bool IsMotion() const
307  {
308  return m_actions == TA_MOUSE_MOTION;
309  }
310 
311  bool IsMouseAction() const
312  {
313  return ( m_actions & TA_MOUSE );
314  }
315 
316  bool IsCancel() const
317  {
318  return m_actions == TA_CANCEL_TOOL;
319  }
320 
321  bool IsActivate() const
322  {
323  return m_actions == TA_ACTIVATE;
324  }
325 
326  bool IsUndoRedo() const
327  {
329  }
330 
331  bool IsChoiceMenu() const
332  {
333  return m_actions & TA_CHOICE_MENU;
334  }
335 
336  bool IsPrime() const
337  {
338  return m_actions == TA_PRIME;
339  }
340 
342  int Modifier( int aMask = MD_MODIFIER_MASK ) const
343  {
344  return m_modifiers & aMask;
345  }
346 
347  int KeyCode() const
348  {
349  return m_keyCode;
350  }
351 
352  bool IsKeyPressed() const
353  {
354  return m_actions == TA_KEY_PRESSED;
355  }
356 
364  bool Matches( const TOOL_EVENT& aEvent ) const
365  {
366  if( !( m_category & aEvent.m_category ) )
367  return false;
368 
370  {
371  if( (bool) m_commandStr && (bool) aEvent.m_commandStr )
372  return *m_commandStr == *aEvent.m_commandStr;
373 
374  if( (bool) m_commandId && (bool) aEvent.m_commandId )
375  return *m_commandId == *aEvent.m_commandId;
376  }
377 
378  // BUGFIX: TA_ANY should match EVERYTHING, even TA_NONE (for TC_MESSAGE)
379  if( m_actions == TA_ANY && aEvent.m_actions == TA_NONE && aEvent.m_category == TC_MESSAGE )
380  return true;
381 
382  // BUGFIX: This check must happen after the TC_COMMAND check because otherwise events of
383  // the form { TC_COMMAND, TA_NONE } will be incorrectly skipped
384  if( !( m_actions & aEvent.m_actions ) )
385  return false;
386 
387  return true;
388  }
389 
396  bool IsAction( const TOOL_ACTION* aAction ) const;
397 
404  bool IsCancelInteractive();
405 
411  bool IsSelectionEvent();
412 
419  bool IsPointEditor();
420 
427  bool IsMoveTool();
428 
434  template<typename T>
435  inline T Parameter() const
436  {
437  // Exhibit #798 on why I love to hate C++
438  // - reinterpret_cast needs to be used for pointers
439  // - static_cast must be used for enums
440  // - templates can't usefully distinguish between pointer and non-pointer types
441  // Fortunately good old C's cast can be a reinterpret_cast or a static_cast, and
442  // C99 gave us intptr_t which is guaranteed to be round-trippable with a pointer.
443  return (T) reinterpret_cast<intptr_t>( m_param );
444  }
445 
452  template<typename T>
453  void SetParameter(T aParam)
454  {
455  m_param = (void*) aParam;
456  }
457 
459  {
460  return m_commandId;
461  }
462 
464  {
465  return m_commandStr;
466  }
467 
468  void SetMousePosition( const VECTOR2D& aP )
469  {
470  m_mousePos = aP;
471  }
472 
473 private:
474  friend class TOOL_DISPATCHER;
475 
476  void init();
477 
478  void setMouseDragOrigin( const VECTOR2D& aP )
479  {
480  m_mouseDragOrigin = aP;
481  }
482 
483  void setMouseDelta( const VECTOR2D& aP )
484  {
485  m_mouseDelta = aP;
486  }
487 
488  void setMouseButtons( int aButtons )
489  {
490  assert( ( aButtons & ~BUT_BUTTON_MASK ) == 0 );
491  m_mouseButtons = aButtons;
492  }
493 
494  void setModifiers( int aMods )
495  {
496  assert( ( aMods & ~MD_MODIFIER_MASK ) == 0 );
497  m_modifiers = aMods;
498  }
499 
510  {
511  #ifdef WX_COMPATIBILITY
512  wxCHECK_MSG( HasPosition(), VECTOR2D(),
513  "Attempted to get position from non-position event" );
514  #else
515  assert( HasPosition() );
516  #endif
517 
518  return aPos;
519  }
520 
526 
530 
533 
536 
539 
542 
545 
547  void* m_param;
548 
551 
554 };
555 
557 
565 {
566 public:
568  typedef std::deque<TOOL_EVENT>::iterator iterator;
569  typedef std::deque<TOOL_EVENT>::const_iterator const_iterator;
570 
573  {}
574 
576  TOOL_EVENT_LIST( const TOOL_EVENT& aSingleEvent )
577  {
578  m_events.push_back( aSingleEvent );
579  }
580 
587  const std::string Format() const;
588 
590  {
591  for( const TOOL_EVENT& event : m_events )
592  {
593  if( event.Matches( aEvent ) )
594  return event;
595  }
596 
597  return OPT<const TOOL_EVENT&>();
598  }
599 
605  void Add( const TOOL_EVENT& aEvent )
606  {
607  m_events.push_back( aEvent );
608  }
609 
611  {
612  return m_events.begin();
613  }
614 
616  {
617  return m_events.end();
618  }
619 
621  {
622  return m_events.begin();
623  }
624 
626  {
627  return m_events.end();
628  }
629 
630  int size() const
631  {
632  return m_events.size();
633  }
634 
635  void clear()
636  {
637  m_events.clear();
638  }
639 
641  {
642  m_events.clear();
643 
644  for( const TOOL_EVENT& event : aEventList.m_events )
645  m_events.push_back( event );
646 
647  return *this;
648  }
649 
651  {
652  m_events.clear();
653  m_events.push_back( aEvent );
654  return *this;
655  }
656 
658  {
659  Add( aEvent );
660  return *this;
661  }
662 
664  {
665  std::copy( aEvent.m_events.begin(), aEvent.m_events.end(), std::back_inserter( m_events ) );
666  return *this;
667  }
668 
669 private:
670  std::deque<TOOL_EVENT> m_events;
671 };
672 
673 
674 inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEventA, const TOOL_EVENT& aEventB )
675 {
676  TOOL_EVENT_LIST l;
677 
678  l.Add( aEventA );
679  l.Add( aEventB );
680 
681  return l;
682 }
683 
684 
685 inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent,
686  const TOOL_EVENT_LIST& aEventList )
687 {
688  TOOL_EVENT_LIST l( aEventList );
689 
690  l.Add( aEvent );
691  return l;
692 }
693 
694 
695 #endif
int Buttons() const
Returns information about mouse buttons state.
Definition: tool_event.h:286
bool IsCancel() const
Definition: tool_event.h:316
void setMouseButtons(int aButtons)
Definition: tool_event.h:488
bool m_hasPosition
Definition: tool_event.h:525
OPT< int > GetCommandId() const
Definition: tool_event.h:458
void setModifiers(int aMods)
Definition: tool_event.h:494
TOOL_EVENT(TOOL_EVENT_CATEGORY aCategory=TC_NONE, TOOL_ACTIONS aAction=TA_NONE, TOOL_ACTION_SCOPE aScope=AS_GLOBAL, void *aParameter=nullptr)
Definition: tool_event.h:182
void setMouseDelta(const VECTOR2D &aP)
Definition: tool_event.h:483
TOOL_EVENT value_type
Definition: tool_event.h:567
const std::string Format() const
Function Format() Returns information about event in form of a human-readable string.
Definition: tool_event.cpp:73
iterator begin()
Definition: tool_event.h:610
void init()
Definition: tool_event.cpp:54
TOOL_EVENT(TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, int aExtraParam, TOOL_ACTION_SCOPE aScope=AS_GLOBAL, void *aParameter=nullptr)
Definition: tool_event.h:196
OPT< const TOOL_EVENT & > Matches(const TOOL_EVENT &aEvent) const
Definition: tool_event.h:589
TOOL_ACTIONS Action() const
Returns more specific information about the type of an event.
Definition: tool_event.h:250
int m_modifiers
State of key modifierts (Ctrl/Alt/etc.)
Definition: tool_event.h:544
bool IsClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:178
bool IsMouseAction() const
Definition: tool_event.h:311
TOOL_ACTIONS m_actions
Definition: tool_event.h:522
TOOL_ACTIONS
Definition: tool_event.h:61
bool IsPointEditor()
Function IsPointEditor.
Definition: tool_event.cpp:208
int m_mouseButtons
State of mouse buttons
Definition: tool_event.h:538
Action activates a tool
Definition: tool_event.h:155
bool IsMotion() const
Definition: tool_event.h:306
bool IsKeyPressed() const
Definition: tool_event.h:352
TOOL_EVENT_CATEGORY Category() const
Returns the category (eg. mouse/keyboard/action) of an event..
Definition: tool_event.h:247
VECTOR2D returnCheckedPosition(const VECTOR2D &aPos) const
Ensure that the event is a type that has a position before returning a position, otherwise return a n...
Definition: tool_event.h:509
OPT< std::string > m_commandStr
Definition: tool_event.h:553
VECTOR2D m_mouseDelta
Difference between mouse cursor position and the point where dragging event has started
Definition: tool_event.h:529
TOOL_EVENT_CATEGORY
Internal (GUI-independent) event definitions.
Definition: tool_event.h:50
TOOL_ACTION_SCOPE
Scope of tool actions.
Definition: tool_event.h:143
int m_keyCode
Stores code of pressed/released key
Definition: tool_event.h:541
TOOL_EVENT_LIST & operator=(const TOOL_EVENT &aEvent)
Definition: tool_event.h:650
VECTOR2D m_mouseDragOrigin
Point where dragging has started
Definition: tool_event.h:535
TOOL_EVENT_LIST & operator||(const TOOL_EVENT_LIST &aEvent)
Definition: tool_event.h:663
OPT< int > m_commandId
Definition: tool_event.h:552
TOOL_ACTION_FLAGS
Flags for tool actions.
Definition: tool_event.h:151
void SetMousePosition(const VECTOR2D &aP)
Definition: tool_event.h:468
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:67
std::deque< TOOL_EVENT > m_events
Definition: tool_event.h:670
TOOL_EVENT_LIST()
Default constructor. Creates an empty list.
Definition: tool_event.h:572
TOOL_EVENT(TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, const std::string &aExtraParam, TOOL_ACTION_SCOPE aScope=AS_GLOBAL, void *aParameter=nullptr)
Definition: tool_event.h:228
Class TOOL_MANAGER.
Definition: tool_manager.h:50
void SetParameter(T aParam)
Function SetParameter() Sets a non-standard parameter assigned to the event.
Definition: tool_event.h:453
bool m_passEvent
Definition: tool_event.h:524
Class TOOL_EVENT_LIST.
Definition: tool_event.h:564
bool IsMoveTool()
Function IsMoveTool.
Definition: tool_event.cpp:217
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:296
Action belongs to a particular tool (i.e. a part of a pop-up menu)
Definition: tool_event.h:146
const VECTOR2D Delta() const
Returns information about difference between current mouse cursor position and the place where draggi...
Definition: tool_event.h:268
VECTOR2< double > VECTOR2D
Definition: vector2d.h:586
TOOL_ACTION_SCOPE m_scope
Definition: tool_event.h:523
bool IsDblClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:184
TOOL_EVENT_LIST & operator||(const TOOL_EVENT &aEvent)
Definition: tool_event.h:657
CONTEXT_MENU_TRIGGER
Defines when a context menu is opened.
Definition: tool_event.h:159
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
Class TOOL_EVENT.
Definition: tool_event.h:171
TOOL_EVENT_LIST(const TOOL_EVENT &aSingleEvent)
Constructor for a list containing only one TOOL_EVENT.
Definition: tool_event.h:576
void SetPassEvent()
Definition: tool_event.h:256
const VECTOR2D DragOrigin() const
Returns the point where dragging has started.
Definition: tool_event.h:280
bool Matches(const TOOL_EVENT &aEvent) const
Function Matches() Tests whether two events match in terms of category & action or command.
Definition: tool_event.h:364
std::deque< TOOL_EVENT >::const_iterator const_iterator
Definition: tool_event.h:569
All active tools
Definition: tool_event.h:147
bool IsMouseUp(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:301
const std::string Format() const
Function Format() Returns information about event in form of a human-readable string.
Definition: tool_event.cpp:167
bool IsCancelInteractive()
Function IsCancelInteractive()
Definition: tool_event.cpp:190
bool IsSelectionEvent()
Function IsSelectionEvent()
Definition: tool_event.cpp:200
Class TOOL_DISPATCHER.
int Modifier(int aMask=MD_MODIFIER_MASK) const
Returns information about key modifiers state (Ctrl, Alt, etc.)
Definition: tool_event.h:342
bool IsPrime() const
Definition: tool_event.h:336
TOOL_MOUSE_BUTTONS
Definition: tool_event.h:124
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:463
const_iterator cend() const
Definition: tool_event.h:625
bool IsActivate() const
Definition: tool_event.h:321
bool IsUndoRedo() const
Definition: tool_event.h:326
bool PassEvent() const
These give a tool a method of informing the TOOL_MANAGER that a particular event should be passed on ...
Definition: tool_event.h:255
void Add(const TOOL_EVENT &aEvent)
Function Add() Adds a tool event to the list.
Definition: tool_event.h:605
TOOL_BASE * m_firstResponder
The first tool to receive the event
Definition: tool_event.h:550
const_iterator cbegin() const
Definition: tool_event.h:620
int size() const
Definition: tool_event.h:630
void SetFirstResponder(TOOL_BASE *aTool)
Definition: tool_event.h:264
Class TOOL_BASE.
Definition: tool_base.h:67
Class TOOL_ACTION.
Definition: tool_action.h:46
TOOL_EVENT_LIST & operator=(const TOOL_EVENT_LIST &aEventList)
Definition: tool_event.h:640
bool IsChoiceMenu() const
Definition: tool_event.h:331
void * m_param
Generic parameter used for passing non-standard data.
Definition: tool_event.h:547
boost::optional< T > OPT
Definition: optional.h:7
TOOL_MODIFIERS
Definition: tool_event.h:134
TOOL_BASE * FirstResponder() const
Definition: tool_event.h:263
bool HasPosition() const
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition: tool_event.h:260
std::deque< TOOL_EVENT >::iterator iterator
Definition: tool_event.h:568
void setMouseDragOrigin(const VECTOR2D &aP)
Definition: tool_event.h:478
int KeyCode() const
Definition: tool_event.h:347
iterator end()
Definition: tool_event.h:615
VECTOR2D m_mousePos
Current mouse cursor position
Definition: tool_event.h:532
const TOOL_EVENT_LIST operator||(const TOOL_EVENT &aEventA, const TOOL_EVENT &aEventB)
Definition: tool_event.h:674
TOOL_EVENT_CATEGORY m_category
Definition: tool_event.h:521
const VECTOR2D Position() const
Returns mouse cursor position in world coordinates.
Definition: tool_event.h:274
void SetHasPosition(bool aHasPosition)
Definition: tool_event.h:261
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:556