You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

772 lines
21 KiB

12 years ago
6 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2013 CERN
  5. * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #ifndef __TOOL_EVENT_H
  27. #define __TOOL_EVENT_H
  28. #include <any>
  29. #include <cstdio>
  30. #include <deque>
  31. #include <iterator>
  32. #include <math/vector2d.h>
  33. #include <optional>
  34. #include <atomic>
  35. #include <tool/tool_action.h>
  36. #include <wx/debug.h>
  37. class COMMIT;
  38. class TOOL_ACTION;
  39. class TOOL_MANAGER;
  40. class TOOL_BASE;
  41. class TOOLS_HOLDER;
  42. /**
  43. * Internal (GUI-independent) event definitions.
  44. */
  45. enum TOOL_EVENT_CATEGORY
  46. {
  47. TC_NONE = 0x00,
  48. TC_MOUSE = 0x01,
  49. TC_KEYBOARD = 0x02,
  50. TC_COMMAND = 0x04,
  51. TC_MESSAGE = 0x08,
  52. TC_VIEW = 0x10,
  53. TC_ANY = 0xffffffff
  54. };
  55. enum TOOL_ACTIONS
  56. {
  57. // UI input events
  58. TA_NONE = 0x0000,
  59. TA_MOUSE_CLICK = 0x0001,
  60. TA_MOUSE_DBLCLICK = 0x0002,
  61. TA_MOUSE_UP = 0x0004,
  62. TA_MOUSE_DOWN = 0x0008,
  63. TA_MOUSE_DRAG = 0x0010,
  64. TA_MOUSE_MOTION = 0x0020,
  65. TA_MOUSE_WHEEL = 0x0040,
  66. TA_MOUSE = 0x007f,
  67. TA_KEY_PRESSED = 0x0080,
  68. TA_KEYBOARD = TA_KEY_PRESSED,
  69. // View related events
  70. TA_VIEW_REFRESH = 0x0100,
  71. TA_VIEW_ZOOM = 0x0200,
  72. TA_VIEW_PAN = 0x0400,
  73. TA_VIEW_DIRTY = 0x0800,
  74. TA_VIEW = 0x0f00,
  75. TA_CHANGE_LAYER = 0x1000,
  76. // Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
  77. // the context menu.
  78. TA_CANCEL_TOOL = 0x2000,
  79. // Context menu update. Issued whenever context menu is open and the user hovers the mouse
  80. // over one of choices. Used in dynamic highlighting in disambiguation menu
  81. TA_CHOICE_MENU_UPDATE = 0x4000,
  82. // Context menu choice. Sent if the user picked something from the context menu or
  83. // closed it without selecting anything.
  84. TA_CHOICE_MENU_CHOICE = 0x8000,
  85. // Context menu is closed, no matter whether anything has been chosen or not.
  86. TA_CHOICE_MENU_CLOSED = 0x10000,
  87. TA_CHOICE_MENU = TA_CHOICE_MENU_UPDATE | TA_CHOICE_MENU_CHOICE | TA_CHOICE_MENU_CLOSED,
  88. // This event is sent *before* undo/redo command is performed.
  89. TA_UNDO_REDO_PRE = 0x20000,
  90. // This event is sent *after* undo/redo command is performed.
  91. TA_UNDO_REDO_POST = 0x40000,
  92. // Tool action (allows one to control tools).
  93. TA_ACTION = 0x80000,
  94. // Tool activation event.
  95. TA_ACTIVATE = 0x100000,
  96. // Tool re-activation event for tools already on the stack
  97. TA_REACTIVATE = 0x200000,
  98. // Model has changed (partial update).
  99. TA_MODEL_CHANGE = 0x400000,
  100. // Tool priming event (a special mouse click)
  101. TA_PRIME = 0x800001,
  102. TA_ANY = 0xffffffff
  103. };
  104. enum TOOL_MOUSE_BUTTONS
  105. {
  106. BUT_NONE = 0x0,
  107. BUT_LEFT = 0x1,
  108. BUT_RIGHT = 0x2,
  109. BUT_MIDDLE = 0x4,
  110. BUT_AUX1 = 0x8,
  111. BUT_AUX2 = 0x10,
  112. BUT_BUTTON_MASK = BUT_LEFT | BUT_RIGHT | BUT_MIDDLE | BUT_AUX1 | BUT_AUX2,
  113. BUT_ANY = 0xffffffff
  114. };
  115. enum TOOL_MODIFIERS
  116. {
  117. MD_SHIFT = 0x1000,
  118. MD_CTRL = 0x2000,
  119. MD_ALT = 0x4000,
  120. MD_MODIFIER_MASK = MD_SHIFT | MD_CTRL | MD_ALT,
  121. };
  122. /// Defines when a context menu is opened.
  123. enum CONTEXT_MENU_TRIGGER
  124. {
  125. CMENU_BUTTON = 0, // On the right button
  126. CMENU_NOW, // Right now (after TOOL_INTERACTIVE::SetContextMenu)
  127. CMENU_OFF // Never
  128. };
  129. enum SYNCRONOUS_TOOL_STATE
  130. {
  131. STS_RUNNING,
  132. STS_FINISHED,
  133. STS_CANCELLED
  134. };
  135. /**
  136. * Generic, UI-independent tool event.
  137. */
  138. class TOOL_EVENT
  139. {
  140. public:
  141. /**
  142. * Return information about event in form of a human-readable string.
  143. *
  144. * @return Event information.
  145. */
  146. const std::string Format() const;
  147. TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory = TC_NONE, TOOL_ACTIONS aAction = TA_NONE,
  148. TOOL_ACTION_SCOPE aScope = AS_GLOBAL ) :
  149. m_category( aCategory ),
  150. m_actions( aAction ),
  151. m_scope( aScope ),
  152. m_mouseButtons( 0 ),
  153. m_keyCode( 0 ),
  154. m_modifiers( 0 ),
  155. m_synchronousState( nullptr ),
  156. m_commit( nullptr ),
  157. m_firstResponder( nullptr )
  158. {
  159. init();
  160. }
  161. TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, int aExtraParam,
  162. TOOL_ACTION_SCOPE aScope = AS_GLOBAL ) :
  163. m_category( aCategory ),
  164. m_actions( aAction ),
  165. m_scope( aScope ),
  166. m_mouseButtons( 0 ),
  167. m_keyCode( 0 ),
  168. m_modifiers( 0 ),
  169. m_synchronousState( nullptr ),
  170. m_commit( nullptr ),
  171. m_firstResponder( nullptr )
  172. {
  173. if( aCategory == TC_MOUSE )
  174. {
  175. setMouseButtons( aExtraParam & BUT_BUTTON_MASK );
  176. }
  177. else if( aCategory == TC_KEYBOARD )
  178. {
  179. m_keyCode = aExtraParam & ~MD_MODIFIER_MASK; // Filter out modifiers
  180. }
  181. else if( aCategory == TC_COMMAND )
  182. {
  183. m_commandId = aExtraParam;
  184. }
  185. if( aCategory & ( TC_MOUSE | TC_KEYBOARD ) )
  186. {
  187. m_modifiers = aExtraParam & MD_MODIFIER_MASK;
  188. }
  189. init();
  190. }
  191. TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction,
  192. const std::string& aExtraParam, TOOL_ACTION_SCOPE aScope = AS_GLOBAL ) :
  193. m_category( aCategory ),
  194. m_actions( aAction ),
  195. m_scope( aScope ),
  196. m_mouseButtons( 0 ),
  197. m_keyCode( 0 ),
  198. m_modifiers( 0 ),
  199. m_synchronousState( nullptr ),
  200. m_commit( nullptr ),
  201. m_firstResponder( nullptr )
  202. {
  203. if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE )
  204. m_commandStr = aExtraParam;
  205. init();
  206. }
  207. ///< Returns the category (eg. mouse/keyboard/action) of an event..
  208. TOOL_EVENT_CATEGORY Category() const { return m_category; }
  209. ///< Returns more specific information about the type of an event.
  210. TOOL_ACTIONS Action() const { return m_actions; }
  211. ///< These give a tool a method of informing the TOOL_MANAGER that a particular event should
  212. ///< be passed on to subsequent tools on the stack. Defaults to true for TC_MESSAGES; false
  213. ///< for everything else.
  214. bool PassEvent() const { return m_passEvent; }
  215. void SetPassEvent( bool aPass = true ) { m_passEvent = aPass; }
  216. ///< Returns if it this event has a valid position (true for mouse events and context-menu
  217. ///< or hotkey-based command events)
  218. bool HasPosition() const { return m_hasPosition; }
  219. void SetHasPosition( bool aHasPosition ) { m_hasPosition = aHasPosition; }
  220. ///< Returns if the action associated with this event should be treated as immediate regardless
  221. ///< of the current immediate action settings.
  222. bool ForceImmediate() const { return m_forceImmediate; }
  223. void SetForceImmediate( bool aForceImmediate = true ) { m_forceImmediate = aForceImmediate; }
  224. TOOL_BASE* FirstResponder() const { return m_firstResponder; }
  225. void SetFirstResponder( TOOL_BASE* aTool ) { m_firstResponder = aTool; }
  226. ///< Controls whether the tool is first being pushed to the stack or being reactivated after a pause
  227. bool IsReactivate() const { return m_reactivate; }
  228. void SetReactivate( bool aReactivate = true ) { m_reactivate = aReactivate; }
  229. void SetSynchronous( std::atomic<SYNCRONOUS_TOOL_STATE>* aState ) { m_synchronousState = aState; }
  230. std::atomic<SYNCRONOUS_TOOL_STATE>* SynchronousState() const { return m_synchronousState; }
  231. void SetCommit( COMMIT* aCommit ) { m_commit = aCommit; }
  232. COMMIT* Commit() const { return m_commit; }
  233. ///< Returns information about difference between current mouse cursor position and the place
  234. ///< where dragging has started.
  235. const VECTOR2D Delta() const
  236. {
  237. return returnCheckedPosition( m_mouseDelta );
  238. }
  239. ///< Returns mouse cursor position in world coordinates.
  240. const VECTOR2D Position() const
  241. {
  242. return returnCheckedPosition( m_mousePos );
  243. }
  244. ///< Returns the point where dragging has started.
  245. const VECTOR2D DragOrigin() const
  246. {
  247. return returnCheckedPosition( m_mouseDragOrigin );
  248. }
  249. ///< Returns information about mouse buttons state.
  250. int Buttons() const
  251. {
  252. assert( m_category == TC_MOUSE ); // this should be used only with mouse events
  253. return m_mouseButtons;
  254. }
  255. bool IsClick( int aButtonMask = BUT_ANY ) const;
  256. bool IsDblClick( int aButtonMask = BUT_ANY ) const;
  257. bool IsDrag( int aButtonMask = BUT_ANY ) const
  258. {
  259. return m_actions == TA_MOUSE_DRAG && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
  260. }
  261. bool IsMouseDown( int aButtonMask = BUT_ANY ) const
  262. {
  263. return m_actions == TA_MOUSE_DOWN && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
  264. }
  265. bool IsMouseUp( int aButtonMask = BUT_ANY ) const
  266. {
  267. return m_actions == TA_MOUSE_UP && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
  268. }
  269. bool IsMotion() const
  270. {
  271. return m_actions == TA_MOUSE_MOTION;
  272. }
  273. bool IsMouseAction() const
  274. {
  275. return ( m_actions & TA_MOUSE );
  276. }
  277. bool IsCancel() const
  278. {
  279. return m_actions == TA_CANCEL_TOOL;
  280. }
  281. bool IsActivate() const
  282. {
  283. return m_actions == TA_ACTIVATE;
  284. }
  285. bool IsUndoRedo() const
  286. {
  287. return m_actions & ( TA_UNDO_REDO_PRE | TA_UNDO_REDO_POST );
  288. }
  289. bool IsChoiceMenu() const
  290. {
  291. return m_actions & TA_CHOICE_MENU;
  292. }
  293. bool IsPrime() const
  294. {
  295. return m_actions == TA_PRIME;
  296. }
  297. ///< Returns information about key modifiers state (Ctrl, Alt, etc.)
  298. int Modifier( int aMask = MD_MODIFIER_MASK ) const
  299. {
  300. return m_modifiers & aMask;
  301. }
  302. bool DisableGridSnapping() const
  303. {
  304. return Modifier( MD_CTRL );
  305. }
  306. int KeyCode() const
  307. {
  308. return m_keyCode;
  309. }
  310. bool IsKeyPressed() const
  311. {
  312. return m_actions == TA_KEY_PRESSED;
  313. }
  314. /**
  315. * Test whether two events match in terms of category & action or command.
  316. *
  317. * @param aEvent is the event to test against.
  318. * @return True if two events match, false otherwise.
  319. */
  320. bool Matches( const TOOL_EVENT& aEvent ) const
  321. {
  322. if( !( m_category & aEvent.m_category ) )
  323. return false;
  324. if( m_category == TC_COMMAND || m_category == TC_MESSAGE )
  325. {
  326. if( !m_commandStr.empty() && !aEvent.getCommandStr().empty() )
  327. return m_commandStr == aEvent.m_commandStr;
  328. if( (bool) m_commandId && (bool) aEvent.m_commandId )
  329. return *m_commandId == *aEvent.m_commandId;
  330. }
  331. // BUGFIX: TA_ANY should match EVERYTHING, even TA_NONE (for TC_MESSAGE)
  332. if( m_actions == TA_ANY && aEvent.m_actions == TA_NONE && aEvent.m_category == TC_MESSAGE )
  333. return true;
  334. // BUGFIX: This check must happen after the TC_COMMAND check because otherwise events of
  335. // the form { TC_COMMAND, TA_NONE } will be incorrectly skipped
  336. if( !( m_actions & aEvent.m_actions ) )
  337. return false;
  338. return true;
  339. }
  340. /**
  341. * Test if the event contains an action issued upon activation of the given #TOOL_ACTION.
  342. *
  343. * @param aAction is the TOOL_ACTION to be checked against.
  344. * @return True if it matches the given TOOL_ACTION.
  345. */
  346. bool IsAction( const TOOL_ACTION* aAction ) const;
  347. /**
  348. * Indicate the event should restart/end an ongoing interactive tool's event loop (eg esc
  349. * key, click cancel, start different tool).
  350. */
  351. bool IsCancelInteractive() const;
  352. /**
  353. * Indicate an selection-changed notification event.
  354. */
  355. bool IsSelectionEvent() const;
  356. /**
  357. * Indicate if the event is from one of the point editors.
  358. *
  359. * Usually used to allow the point editor to activate itself without de-activating the
  360. * current drawing tool.
  361. */
  362. bool IsPointEditor() const;
  363. /**
  364. * Indicate if the event is from one of the move tools.
  365. *
  366. * Usually used to allow move to be done without de-activating the current drawing tool.
  367. */
  368. bool IsMoveTool() const;
  369. /**
  370. * Indicate if the event is asking for an editor tool.
  371. *
  372. * Used to allow deleting an element without de-activating the current tool.
  373. */
  374. bool IsEditorTool() const;
  375. /**
  376. * Indicate if the event is from the simulator.
  377. */
  378. bool IsSimulator() const;
  379. /**
  380. * Return a parameter assigned to the event. Its meaning depends on the target tool.
  381. */
  382. template<typename T,
  383. std::enable_if_t<!std::is_pointer<T>::value>* = nullptr >
  384. T Parameter() const
  385. {
  386. T param;
  387. wxCHECK_MSG( m_param.has_value(), T(), "Attempted to get a parameter from an event with no parameter." );
  388. try
  389. {
  390. param = std::any_cast<T>( m_param );
  391. }
  392. catch( const std::bad_any_cast& )
  393. {
  394. wxCHECK_MSG( false, T(),
  395. wxString::Format( "Requested parameter type %s from event with parameter type %s.",
  396. typeid(T).name(), m_param.type().name() ) );
  397. }
  398. return param;
  399. }
  400. /**
  401. * Return pointer parameter assigned to the event. Its meaning depends on the target tool.
  402. */
  403. template<typename T,
  404. std::enable_if_t<std::is_pointer<T>::value>* = nullptr>
  405. T Parameter() const
  406. {
  407. T param = nullptr;
  408. wxCHECK_MSG( m_param.has_value(), param, "Attempted to get a parameter from an event with no parameter." );
  409. try
  410. {
  411. param = std::any_cast<T>( m_param );
  412. }
  413. catch( const std::bad_any_cast& )
  414. {
  415. wxCHECK_MSG( false, param,
  416. wxString::Format( "Requested parameter type %s from event with parameter type %s.",
  417. typeid(T).name(), m_param.type().name() ) );
  418. }
  419. return param;
  420. }
  421. /**
  422. * Set a non-standard parameter assigned to the event. Its meaning depends on the
  423. * target tool.
  424. *
  425. * @param aParam is the new parameter.
  426. */
  427. template<typename T>
  428. void SetParameter(T aParam)
  429. {
  430. m_param = aParam;
  431. }
  432. std::optional<int> GetCommandId() const
  433. {
  434. return m_commandId;
  435. }
  436. void SetMousePosition( const VECTOR2D& aP )
  437. {
  438. m_mousePos = aP;
  439. }
  440. void SetActionGroup( const TOOL_ACTION_GROUP& aGroup )
  441. {
  442. m_actionGroup = aGroup;
  443. }
  444. bool IsActionInGroup( const TOOL_ACTION_GROUP& aGroup ) const;
  445. private:
  446. friend class TOOL_DISPATCHER;
  447. friend class TOOL_MANAGER;
  448. friend class TOOLS_HOLDER;
  449. void init();
  450. const std::string& getCommandStr() const { return m_commandStr; }
  451. void setMouseDragOrigin( const VECTOR2D& aP )
  452. {
  453. m_mouseDragOrigin = aP;
  454. }
  455. void setMouseDelta( const VECTOR2D& aP )
  456. {
  457. m_mouseDelta = aP;
  458. }
  459. void setMouseButtons( int aButtons )
  460. {
  461. assert( ( aButtons & ~BUT_BUTTON_MASK ) == 0 );
  462. m_mouseButtons = aButtons;
  463. }
  464. void setModifiers( int aMods )
  465. {
  466. assert( ( aMods & ~MD_MODIFIER_MASK ) == 0 );
  467. m_modifiers = aMods;
  468. }
  469. /**
  470. * Ensure that the event is a type that has a position before returning a
  471. * position, otherwise return a null-constructed position.
  472. *
  473. * Used to defend the position accessors from runtime access when the event
  474. * does not have a valid position.
  475. *
  476. * @param aPos the position to return if the event is valid
  477. * @return the checked position
  478. */
  479. VECTOR2D returnCheckedPosition( const VECTOR2D& aPos ) const;
  480. TOOL_EVENT_CATEGORY m_category;
  481. TOOL_ACTIONS m_actions;
  482. TOOL_ACTION_SCOPE m_scope;
  483. bool m_passEvent;
  484. bool m_hasPosition;
  485. bool m_forceImmediate;
  486. ///< Optional group that the parent action for the event belongs to
  487. std::optional<TOOL_ACTION_GROUP> m_actionGroup;
  488. ///< True when the tool is being re-activated from the stack
  489. bool m_reactivate;
  490. ///< Difference between mouse cursor position and
  491. ///< the point where dragging event has started
  492. VECTOR2D m_mouseDelta;
  493. ///< Current mouse cursor position
  494. VECTOR2D m_mousePos;
  495. ///< Point where dragging has started
  496. VECTOR2D m_mouseDragOrigin;
  497. ///< State of mouse buttons
  498. int m_mouseButtons;
  499. ///< Stores code of pressed/released key
  500. int m_keyCode;
  501. ///< State of key modifiers (Ctrl/Alt/etc.)
  502. int m_modifiers;
  503. std::atomic<SYNCRONOUS_TOOL_STATE>* m_synchronousState;
  504. /// Commit the tool handling the event should add to
  505. COMMIT* m_commit;
  506. ///< Generic parameter used for passing non-standard data.
  507. std::any m_param;
  508. ///< The first tool to receive the event
  509. TOOL_BASE* m_firstResponder;
  510. std::optional<int> m_commandId;
  511. std::string m_commandStr;
  512. };
  513. typedef std::optional<TOOL_EVENT> OPT_TOOL_EVENT;
  514. /**
  515. * A list of TOOL_EVENTs, with overloaded || operators allowing for concatenating TOOL_EVENTs
  516. * with little code.
  517. */
  518. class TOOL_EVENT_LIST
  519. {
  520. public:
  521. typedef TOOL_EVENT value_type;
  522. typedef std::deque<TOOL_EVENT>::iterator iterator;
  523. typedef std::deque<TOOL_EVENT>::const_iterator const_iterator;
  524. ///< Default constructor. Creates an empty list.
  525. TOOL_EVENT_LIST()
  526. {}
  527. ///< Constructor for a list containing only one TOOL_EVENT.
  528. TOOL_EVENT_LIST( const TOOL_EVENT& aSingleEvent )
  529. {
  530. m_events.push_back( aSingleEvent );
  531. }
  532. ///< Copy an existing TOOL_EVENT_LIST
  533. TOOL_EVENT_LIST( const TOOL_EVENT_LIST& aEventList )
  534. {
  535. m_events.clear();
  536. for( const TOOL_EVENT& event : aEventList.m_events )
  537. m_events.push_back( event );
  538. }
  539. /**
  540. * Function Format()
  541. * Returns information about event in form of a human-readable string.
  542. *
  543. * @return Event information.
  544. */
  545. const std::string Format() const;
  546. OPT_TOOL_EVENT Matches( const TOOL_EVENT& aEvent ) const
  547. {
  548. for( const TOOL_EVENT& event : m_events )
  549. {
  550. if( event.Matches( aEvent ) )
  551. return event;
  552. }
  553. return OPT_TOOL_EVENT();
  554. }
  555. /**
  556. * Add a tool event to the list.
  557. *
  558. * @param aEvent is the tool event to be added.
  559. */
  560. void Add( const TOOL_EVENT& aEvent )
  561. {
  562. m_events.push_back( aEvent );
  563. }
  564. iterator begin()
  565. {
  566. return m_events.begin();
  567. }
  568. iterator end()
  569. {
  570. return m_events.end();
  571. }
  572. const_iterator cbegin() const
  573. {
  574. return m_events.begin();
  575. }
  576. const_iterator cend() const
  577. {
  578. return m_events.end();
  579. }
  580. int size() const
  581. {
  582. return m_events.size();
  583. }
  584. void clear()
  585. {
  586. m_events.clear();
  587. }
  588. TOOL_EVENT_LIST& operator=( const TOOL_EVENT_LIST& aEventList )
  589. {
  590. m_events.clear();
  591. for( const TOOL_EVENT& event : aEventList.m_events )
  592. m_events.push_back( event );
  593. return *this;
  594. }
  595. TOOL_EVENT_LIST& operator=( const TOOL_EVENT& aEvent )
  596. {
  597. m_events.clear();
  598. m_events.push_back( aEvent );
  599. return *this;
  600. }
  601. TOOL_EVENT_LIST& operator||( const TOOL_EVENT& aEvent )
  602. {
  603. Add( aEvent );
  604. return *this;
  605. }
  606. TOOL_EVENT_LIST& operator||( const TOOL_EVENT_LIST& aEvent )
  607. {
  608. std::copy( aEvent.m_events.begin(), aEvent.m_events.end(), std::back_inserter( m_events ) );
  609. return *this;
  610. }
  611. private:
  612. std::deque<TOOL_EVENT> m_events;
  613. };
  614. inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEventA, const TOOL_EVENT& aEventB )
  615. {
  616. TOOL_EVENT_LIST l;
  617. l.Add( aEventA );
  618. l.Add( aEventB );
  619. return l;
  620. }
  621. inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent,
  622. const TOOL_EVENT_LIST& aEventList )
  623. {
  624. TOOL_EVENT_LIST l( aEventList );
  625. l.Add( aEvent );
  626. return l;
  627. }
  628. #endif