2013-08-02 14:46:53 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 CERN
|
2020-12-27 00:41:04 +00:00
|
|
|
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
|
|
|
*
|
2013-08-02 14:46:53 +00:00
|
|
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __TOOL_EVENT_H
|
|
|
|
#define __TOOL_EVENT_H
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
#include <deque>
|
2016-05-28 16:46:29 +00:00
|
|
|
#include <iterator>
|
2013-08-02 14:46:53 +00:00
|
|
|
|
|
|
|
#include <math/vector2d.h>
|
2017-11-01 11:14:16 +00:00
|
|
|
#include <core/optional.h>
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2018-10-08 22:49:42 +00:00
|
|
|
#ifdef WX_COMPATIBILITY
|
|
|
|
#include <wx/debug.h>
|
|
|
|
#else
|
|
|
|
#include <cassert>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2013-09-27 16:51:21 +00:00
|
|
|
class TOOL_ACTION;
|
2013-08-02 14:46:53 +00:00
|
|
|
class TOOL_MANAGER;
|
2019-07-07 23:01:08 +00:00
|
|
|
class TOOL_BASE;
|
2013-08-02 14:46:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal (GUI-independent) event definitions.
|
|
|
|
*/
|
2013-10-14 18:40:36 +00:00
|
|
|
enum TOOL_EVENT_CATEGORY
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
TC_NONE = 0x00,
|
|
|
|
TC_MOUSE = 0x01,
|
|
|
|
TC_KEYBOARD = 0x02,
|
|
|
|
TC_COMMAND = 0x04,
|
|
|
|
TC_MESSAGE = 0x08,
|
|
|
|
TC_VIEW = 0x10,
|
|
|
|
TC_ANY = 0xffffffff
|
2013-08-02 14:46:53 +00:00
|
|
|
};
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
enum TOOL_ACTIONS
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2013-08-21 15:37:27 +00:00
|
|
|
// UI input events
|
2013-11-28 14:19:50 +00:00
|
|
|
TA_NONE = 0x0000,
|
|
|
|
TA_MOUSE_CLICK = 0x0001,
|
|
|
|
TA_MOUSE_DBLCLICK = 0x0002,
|
|
|
|
TA_MOUSE_UP = 0x0004,
|
|
|
|
TA_MOUSE_DOWN = 0x0008,
|
|
|
|
TA_MOUSE_DRAG = 0x0010,
|
|
|
|
TA_MOUSE_MOTION = 0x0020,
|
|
|
|
TA_MOUSE_WHEEL = 0x0040,
|
|
|
|
TA_MOUSE = 0x007f,
|
|
|
|
|
2014-04-09 15:33:22 +00:00
|
|
|
TA_KEY_PRESSED = 0x0080,
|
|
|
|
TA_KEYBOARD = TA_KEY_PRESSED,
|
2013-08-21 15:37:27 +00:00
|
|
|
|
|
|
|
// View related events
|
2014-04-09 15:33:22 +00:00
|
|
|
TA_VIEW_REFRESH = 0x0100,
|
|
|
|
TA_VIEW_ZOOM = 0x0200,
|
|
|
|
TA_VIEW_PAN = 0x0400,
|
|
|
|
TA_VIEW_DIRTY = 0x0800,
|
|
|
|
TA_VIEW = 0x0f00,
|
2013-11-28 14:19:50 +00:00
|
|
|
|
2014-04-09 15:33:22 +00:00
|
|
|
TA_CHANGE_LAYER = 0x1000,
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2013-10-14 11:43:57 +00:00
|
|
|
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
|
|
|
|
// the context menu.
|
2014-04-09 15:33:22 +00:00
|
|
|
TA_CANCEL_TOOL = 0x2000,
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2013-10-14 11:43:57 +00:00
|
|
|
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
|
2020-12-27 00:41:04 +00:00
|
|
|
// over one of choices. Used in dynamic highlighting in disambiguation menu
|
2019-06-15 00:29:42 +00:00
|
|
|
TA_CHOICE_MENU_UPDATE = 0x4000,
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2013-10-14 11:43:57 +00:00
|
|
|
// Context menu choice. Sent if the user picked something from the context menu or
|
|
|
|
// closed it without selecting anything.
|
2019-06-15 00:29:42 +00:00
|
|
|
TA_CHOICE_MENU_CHOICE = 0x8000,
|
2013-09-19 15:02:57 +00:00
|
|
|
|
2015-04-30 08:46:07 +00:00
|
|
|
// Context menu is closed, no matter whether anything has been chosen or not.
|
2019-06-15 00:29:42 +00:00
|
|
|
TA_CHOICE_MENU_CLOSED = 0x10000,
|
2015-04-30 08:46:07 +00:00
|
|
|
|
2019-06-15 00:29:42 +00:00
|
|
|
TA_CHOICE_MENU = TA_CHOICE_MENU_UPDATE | TA_CHOICE_MENU_CHOICE | TA_CHOICE_MENU_CLOSED,
|
2015-04-30 08:46:07 +00:00
|
|
|
|
2014-01-31 15:08:20 +00:00
|
|
|
// This event is sent *before* undo/redo command is performed.
|
2016-09-23 09:31:36 +00:00
|
|
|
TA_UNDO_REDO_PRE = 0x20000,
|
|
|
|
|
|
|
|
// This event is sent *after* undo/redo command is performed.
|
|
|
|
TA_UNDO_REDO_POST = 0x40000,
|
2014-01-30 10:18:58 +00:00
|
|
|
|
2018-07-08 12:12:38 +00:00
|
|
|
// Tool action (allows one to control tools).
|
2016-09-23 09:31:36 +00:00
|
|
|
TA_ACTION = 0x80000,
|
2013-09-19 15:02:57 +00:00
|
|
|
|
2014-07-09 11:50:27 +00:00
|
|
|
// Tool activation event.
|
2016-09-23 09:31:36 +00:00
|
|
|
TA_ACTIVATE = 0x100000,
|
2014-07-09 11:50:27 +00:00
|
|
|
|
2021-02-24 18:43:12 +00:00
|
|
|
// Tool re-activation event for tools already on the stack
|
|
|
|
TA_REACTIVATE = 0x200000,
|
|
|
|
|
2016-11-28 14:45:37 +00:00
|
|
|
// Model has changed (partial update).
|
2021-02-24 18:43:12 +00:00
|
|
|
TA_MODEL_CHANGE = 0x400000,
|
2016-11-28 14:45:37 +00:00
|
|
|
|
2019-10-03 15:55:05 +00:00
|
|
|
// Tool priming event (a special mouse click)
|
2021-02-24 18:43:12 +00:00
|
|
|
TA_PRIME = 0x800001,
|
2019-10-03 15:55:05 +00:00
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TA_ANY = 0xffffffff
|
2013-08-02 14:46:53 +00:00
|
|
|
};
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
enum TOOL_MOUSE_BUTTONS
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2013-10-15 08:41:00 +00:00
|
|
|
BUT_NONE = 0x0,
|
|
|
|
BUT_LEFT = 0x1,
|
|
|
|
BUT_RIGHT = 0x2,
|
|
|
|
BUT_MIDDLE = 0x4,
|
|
|
|
BUT_BUTTON_MASK = BUT_LEFT | BUT_RIGHT | BUT_MIDDLE,
|
|
|
|
BUT_ANY = 0xffffffff
|
2013-08-02 14:46:53 +00:00
|
|
|
};
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
enum TOOL_MODIFIERS
|
2013-08-21 15:37:27 +00:00
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
MD_SHIFT = 0x1000,
|
|
|
|
MD_CTRL = 0x2000,
|
|
|
|
MD_ALT = 0x4000,
|
|
|
|
MD_MODIFIER_MASK = MD_SHIFT | MD_CTRL | MD_ALT,
|
2013-08-21 15:37:27 +00:00
|
|
|
};
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2013-09-19 15:02:57 +00:00
|
|
|
/// Scope of tool actions
|
2013-10-14 18:40:36 +00:00
|
|
|
enum TOOL_ACTION_SCOPE
|
2013-09-19 15:02:57 +00:00
|
|
|
{
|
2020-12-27 00:41:04 +00:00
|
|
|
AS_CONTEXT = 1, ///< Action belongs to a particular tool (i.e. a part of a pop-up menu)
|
|
|
|
AS_ACTIVE, ///< All active tools
|
|
|
|
AS_GLOBAL ///< Global action (toolbar/main menu event, global shortcut)
|
2013-09-19 15:02:57 +00:00
|
|
|
};
|
|
|
|
|
2014-07-09 11:50:27 +00:00
|
|
|
/// Flags for tool actions
|
|
|
|
enum TOOL_ACTION_FLAGS
|
|
|
|
{
|
|
|
|
AF_NONE = 0,
|
2020-12-27 00:41:04 +00:00
|
|
|
AF_ACTIVATE = 1, ///< Action activates a tool
|
|
|
|
AF_NOTIFY = 2 ///< Action is a notification (it is by default passed to all tools)
|
2014-07-09 11:50:27 +00:00
|
|
|
};
|
|
|
|
|
2013-09-19 15:02:57 +00:00
|
|
|
/// Defines when a context menu is opened.
|
2013-09-02 12:21:12 +00:00
|
|
|
enum CONTEXT_MENU_TRIGGER
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2013-10-14 11:43:57 +00:00
|
|
|
CMENU_BUTTON = 0, // On the right button
|
|
|
|
CMENU_NOW, // Right now (after TOOL_INTERACTIVE::SetContextMenu)
|
|
|
|
CMENU_OFF // Never
|
2013-08-02 14:46:53 +00:00
|
|
|
};
|
|
|
|
|
2013-10-14 11:43:57 +00:00
|
|
|
/**
|
2013-08-02 14:46:53 +00:00
|
|
|
* Generic, UI-independent tool event.
|
|
|
|
*/
|
|
|
|
class TOOL_EVENT
|
|
|
|
{
|
2013-08-07 09:20:12 +00:00
|
|
|
public:
|
2013-09-27 14:23:43 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return information about event in form of a human-readable string.
|
2013-09-27 14:23:43 +00:00
|
|
|
*
|
|
|
|
* @return Event information.
|
|
|
|
*/
|
2013-08-07 09:20:12 +00:00
|
|
|
const std::string Format() const;
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory = TC_NONE, TOOL_ACTIONS aAction = TA_NONE,
|
2019-06-17 22:02:30 +00:00
|
|
|
TOOL_ACTION_SCOPE aScope = AS_GLOBAL, void* aParameter = nullptr ) :
|
2013-08-07 09:20:12 +00:00
|
|
|
m_category( aCategory ),
|
|
|
|
m_actions( aAction ),
|
2013-09-19 15:02:57 +00:00
|
|
|
m_scope( aScope ),
|
2013-08-21 15:37:27 +00:00
|
|
|
m_mouseButtons( 0 ),
|
|
|
|
m_keyCode( 0 ),
|
2014-11-21 10:28:34 +00:00
|
|
|
m_modifiers( 0 ),
|
2019-07-07 23:01:08 +00:00
|
|
|
m_param( aParameter ),
|
|
|
|
m_firstResponder( nullptr )
|
2019-06-15 00:29:42 +00:00
|
|
|
{
|
2019-06-27 11:47:24 +00:00
|
|
|
init();
|
2019-06-15 00:29:42 +00:00
|
|
|
}
|
2013-08-07 09:20:12 +00:00
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, int aExtraParam,
|
2019-06-17 22:02:30 +00:00
|
|
|
TOOL_ACTION_SCOPE aScope = AS_GLOBAL, void* aParameter = nullptr ) :
|
2013-08-07 09:20:12 +00:00
|
|
|
m_category( aCategory ),
|
2013-09-19 15:02:57 +00:00
|
|
|
m_actions( aAction ),
|
2014-08-08 12:34:44 +00:00
|
|
|
m_scope( aScope ),
|
|
|
|
m_mouseButtons( 0 ),
|
|
|
|
m_keyCode( 0 ),
|
2014-11-21 10:28:34 +00:00
|
|
|
m_modifiers( 0 ),
|
2019-07-07 23:01:08 +00:00
|
|
|
m_param( aParameter ),
|
|
|
|
m_firstResponder( nullptr )
|
2013-10-14 14:13:35 +00:00
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
if( aCategory == TC_MOUSE )
|
2013-10-14 14:13:35 +00:00
|
|
|
{
|
2015-07-15 12:08:52 +00:00
|
|
|
setMouseButtons( aExtraParam & BUT_BUTTON_MASK );
|
2013-10-14 14:13:35 +00:00
|
|
|
}
|
2013-10-14 18:40:36 +00:00
|
|
|
else if( aCategory == TC_KEYBOARD )
|
2013-10-14 14:13:35 +00:00
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
m_keyCode = aExtraParam & ~MD_MODIFIER_MASK; // Filter out modifiers
|
2013-10-14 14:13:35 +00:00
|
|
|
}
|
2013-10-14 18:40:36 +00:00
|
|
|
else if( aCategory == TC_COMMAND )
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2013-10-14 14:13:35 +00:00
|
|
|
m_commandId = aExtraParam;
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
if( aCategory & ( TC_MOUSE | TC_KEYBOARD ) )
|
2013-10-14 14:13:35 +00:00
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
m_modifiers = aExtraParam & MD_MODIFIER_MASK;
|
2013-10-14 14:13:35 +00:00
|
|
|
}
|
2019-06-15 00:29:42 +00:00
|
|
|
|
2019-06-27 11:47:24 +00:00
|
|
|
init();
|
2013-10-14 14:13:35 +00:00
|
|
|
}
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction,
|
2015-04-30 08:46:01 +00:00
|
|
|
const std::string& aExtraParam, TOOL_ACTION_SCOPE aScope = AS_GLOBAL,
|
2019-06-15 00:29:42 +00:00
|
|
|
void* aParameter = nullptr ) :
|
2013-08-07 09:20:12 +00:00
|
|
|
m_category( aCategory ),
|
|
|
|
m_actions( aAction ),
|
2013-09-19 15:02:57 +00:00
|
|
|
m_scope( aScope ),
|
2014-08-08 12:34:44 +00:00
|
|
|
m_mouseButtons( 0 ),
|
|
|
|
m_keyCode( 0 ),
|
2014-11-21 10:28:34 +00:00
|
|
|
m_modifiers( 0 ),
|
2019-07-07 23:01:08 +00:00
|
|
|
m_param( aParameter ),
|
|
|
|
m_firstResponder( nullptr )
|
2013-10-14 14:13:35 +00:00
|
|
|
{
|
2014-02-27 15:13:27 +00:00
|
|
|
if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE )
|
2013-10-14 14:13:35 +00:00
|
|
|
m_commandStr = aExtraParam;
|
2019-06-15 00:29:42 +00:00
|
|
|
|
2019-06-27 11:47:24 +00:00
|
|
|
init();
|
2013-10-14 14:13:35 +00:00
|
|
|
}
|
2013-08-07 09:20:12 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns the category (eg. mouse/keyboard/action) of an event..
|
2019-06-15 00:29:42 +00:00
|
|
|
TOOL_EVENT_CATEGORY Category() const { return m_category; }
|
2013-08-07 09:20:12 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns more specific information about the type of an event.
|
2019-06-15 00:29:42 +00:00
|
|
|
TOOL_ACTIONS Action() const { return m_actions; }
|
2013-08-07 09:20:12 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< These give a tool a method of informing the TOOL_MANAGER that a particular event should
|
|
|
|
///< be passed on to subsequent tools on the stack. Defaults to true for TC_MESSAGES; false
|
|
|
|
///< for everything else.
|
2019-06-16 11:06:49 +00:00
|
|
|
bool PassEvent() const { return m_passEvent; }
|
2020-08-25 11:53:39 +00:00
|
|
|
void SetPassEvent( bool aPass = true ) { m_passEvent = aPass; }
|
2019-06-16 11:06:49 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns if it this event has a valid position (true for mouse events and context-menu
|
|
|
|
///< or hotkey-based command events)
|
2019-06-15 00:29:42 +00:00
|
|
|
bool HasPosition() const { return m_hasPosition; }
|
|
|
|
void SetHasPosition( bool aHasPosition ) { m_hasPosition = aHasPosition; }
|
2018-10-08 22:49:42 +00:00
|
|
|
|
2021-02-21 12:45:50 +00:00
|
|
|
///< Returns if the action associated with this event should be treated as immediate regardless
|
|
|
|
///< of the current immediate action settings.
|
|
|
|
bool ForceImmediate() const { return m_forceImmediate; }
|
|
|
|
void SetForceImmediate( bool aForceImmediate = true ) { m_forceImmediate = aForceImmediate; }
|
|
|
|
|
2019-07-07 23:01:08 +00:00
|
|
|
TOOL_BASE* FirstResponder() const { return m_firstResponder; }
|
|
|
|
void SetFirstResponder( TOOL_BASE* aTool ) { m_firstResponder = aTool; }
|
|
|
|
|
2021-02-24 18:43:12 +00:00
|
|
|
///< Controls whether the tool is first being pushed to the stack or being reactivated after a pause
|
|
|
|
bool IsReactivate() const { return m_reactivate; }
|
|
|
|
void SetReactivate( bool aReactivate = true ) { m_reactivate = aReactivate; }
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns information about difference between current mouse cursor position and the place
|
|
|
|
///< where dragging has started.
|
2018-10-08 22:49:42 +00:00
|
|
|
const VECTOR2D Delta() const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2018-10-08 22:49:42 +00:00
|
|
|
return returnCheckedPosition( m_mouseDelta );
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns mouse cursor position in world coordinates.
|
2018-10-08 22:49:42 +00:00
|
|
|
const VECTOR2D Position() const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2018-10-08 22:49:42 +00:00
|
|
|
return returnCheckedPosition( m_mousePos );
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns the point where dragging has started.
|
2018-10-08 22:49:42 +00:00
|
|
|
const VECTOR2D DragOrigin() const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2018-10-08 22:49:42 +00:00
|
|
|
return returnCheckedPosition( m_mouseDragOrigin );
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns information about mouse buttons state.
|
2013-08-07 09:20:12 +00:00
|
|
|
int Buttons() const
|
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
assert( m_category == TC_MOUSE ); // this should be used only with mouse events
|
2013-08-07 09:20:12 +00:00
|
|
|
return m_mouseButtons;
|
|
|
|
}
|
|
|
|
|
2019-05-06 20:37:54 +00:00
|
|
|
bool IsClick( int aButtonMask = BUT_ANY ) const;
|
2013-08-07 09:20:12 +00:00
|
|
|
|
2019-05-06 20:37:54 +00:00
|
|
|
bool IsDblClick( int aButtonMask = BUT_ANY ) const;
|
2013-11-28 14:19:50 +00:00
|
|
|
|
2013-10-15 08:41:00 +00:00
|
|
|
bool IsDrag( int aButtonMask = BUT_ANY ) const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2019-07-06 16:50:02 +00:00
|
|
|
return m_actions == TA_MOUSE_DRAG && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2013-10-15 08:41:00 +00:00
|
|
|
bool IsMouseUp( int aButtonMask = BUT_ANY ) const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2019-07-06 16:50:02 +00:00
|
|
|
return m_actions == TA_MOUSE_UP && ( m_mouseButtons & aButtonMask ) == m_mouseButtons;
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool IsMotion() const
|
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
return m_actions == TA_MOUSE_MOTION;
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2019-07-05 20:22:16 +00:00
|
|
|
bool IsMouseAction() const
|
|
|
|
{
|
2019-07-06 12:48:53 +00:00
|
|
|
return ( m_actions & TA_MOUSE );
|
2019-07-05 20:22:16 +00:00
|
|
|
}
|
|
|
|
|
2013-08-07 09:20:12 +00:00
|
|
|
bool IsCancel() const
|
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
return m_actions == TA_CANCEL_TOOL;
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2014-07-09 11:50:27 +00:00
|
|
|
bool IsActivate() const
|
|
|
|
{
|
|
|
|
return m_actions == TA_ACTIVATE;
|
|
|
|
}
|
|
|
|
|
2016-09-23 11:58:33 +00:00
|
|
|
bool IsUndoRedo() const
|
|
|
|
{
|
|
|
|
return m_actions & ( TA_UNDO_REDO_PRE | TA_UNDO_REDO_POST );
|
|
|
|
}
|
|
|
|
|
2019-06-15 00:29:42 +00:00
|
|
|
bool IsChoiceMenu() const
|
2018-01-26 14:53:28 +00:00
|
|
|
{
|
2019-06-15 00:29:42 +00:00
|
|
|
return m_actions & TA_CHOICE_MENU;
|
2018-01-26 14:53:28 +00:00
|
|
|
}
|
|
|
|
|
2019-10-03 15:55:05 +00:00
|
|
|
bool IsPrime() const
|
|
|
|
{
|
|
|
|
return m_actions == TA_PRIME;
|
|
|
|
}
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Returns information about key modifiers state (Ctrl, Alt, etc.)
|
2013-10-14 18:40:36 +00:00
|
|
|
int Modifier( int aMask = MD_MODIFIER_MASK ) const
|
2013-08-21 15:37:27 +00:00
|
|
|
{
|
2013-10-14 14:13:35 +00:00
|
|
|
return m_modifiers & aMask;
|
2013-08-21 15:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int KeyCode() const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2013-08-21 15:37:27 +00:00
|
|
|
return m_keyCode;
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2014-04-09 15:33:22 +00:00
|
|
|
bool IsKeyPressed() const
|
2013-09-13 13:31:19 +00:00
|
|
|
{
|
2014-04-09 15:33:22 +00:00
|
|
|
return m_actions == TA_KEY_PRESSED;
|
2013-09-13 13:31:19 +00:00
|
|
|
}
|
|
|
|
|
2013-09-27 14:23:43 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Test whether two events match in terms of category & action or command.
|
2013-09-27 14:23:43 +00:00
|
|
|
*
|
|
|
|
* @param aEvent is the event to test against.
|
|
|
|
* @return True if two events match, false otherwise.
|
|
|
|
*/
|
2013-08-07 09:20:12 +00:00
|
|
|
bool Matches( const TOOL_EVENT& aEvent ) const
|
|
|
|
{
|
2013-08-19 07:47:36 +00:00
|
|
|
if( !( m_category & aEvent.m_category ) )
|
2013-08-07 09:20:12 +00:00
|
|
|
return false;
|
|
|
|
|
2014-02-27 15:13:27 +00:00
|
|
|
if( m_category == TC_COMMAND || m_category == TC_MESSAGE )
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2014-07-09 13:10:32 +00:00
|
|
|
if( (bool) m_commandStr && (bool) aEvent.m_commandStr )
|
2013-10-14 14:13:35 +00:00
|
|
|
return *m_commandStr == *aEvent.m_commandStr;
|
|
|
|
|
2014-07-09 13:10:32 +00:00
|
|
|
if( (bool) m_commandId && (bool) aEvent.m_commandId )
|
2013-10-14 14:13:35 +00:00
|
|
|
return *m_commandId == *aEvent.m_commandId;
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2015-07-13 04:52:17 +00:00
|
|
|
// BUGFIX: TA_ANY should match EVERYTHING, even TA_NONE (for TC_MESSAGE)
|
2015-07-13 15:18:29 +00:00
|
|
|
if( m_actions == TA_ANY && aEvent.m_actions == TA_NONE && aEvent.m_category == TC_MESSAGE )
|
2015-07-13 04:52:17 +00:00
|
|
|
return true;
|
2015-07-13 04:57:07 +00:00
|
|
|
|
2015-07-13 04:52:17 +00:00
|
|
|
// BUGFIX: This check must happen after the TC_COMMAND check because otherwise events of
|
|
|
|
// the form { TC_COMMAND, TA_NONE } will be incorrectly skipped
|
|
|
|
if( !( m_actions & aEvent.m_actions ) )
|
|
|
|
return false;
|
2013-08-07 09:20:12 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-09-27 16:51:21 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Test if the event contains an action issued upon activation of the given #TOOL_ACTION.
|
|
|
|
*
|
2013-09-27 16:51:21 +00:00
|
|
|
* @param aAction is the TOOL_ACTION to be checked against.
|
|
|
|
* @return True if it matches the given TOOL_ACTION.
|
|
|
|
*/
|
|
|
|
bool IsAction( const TOOL_ACTION* aAction ) const;
|
|
|
|
|
2019-07-01 21:01:33 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Indicate the event should restart/end an ongoing interactive tool's event loop (eg esc
|
2019-07-01 21:01:33 +00:00
|
|
|
* key, click cancel, start different tool).
|
|
|
|
*/
|
2020-12-20 18:44:13 +00:00
|
|
|
bool IsCancelInteractive() const;
|
2019-07-01 21:01:33 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Indicate an selection-changed notification event.
|
2019-07-01 21:01:33 +00:00
|
|
|
*/
|
2020-12-20 18:44:13 +00:00
|
|
|
bool IsSelectionEvent() const;
|
2019-07-01 21:01:33 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Indicate if the event is from one of the point editors.
|
2019-07-01 21:01:33 +00:00
|
|
|
*
|
2020-12-27 00:41:04 +00:00
|
|
|
* Usually used to allow the point editor to activate itself without de-activating the
|
|
|
|
* current drawing tool.
|
2019-07-01 21:01:33 +00:00
|
|
|
*/
|
2020-12-20 18:44:13 +00:00
|
|
|
bool IsPointEditor() const;
|
2019-07-01 21:01:33 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Indicate if the event is from one of the move tools.
|
2019-07-01 21:01:33 +00:00
|
|
|
*
|
2020-12-27 00:41:04 +00:00
|
|
|
* Usually used to allow move to be done without de-activating the current drawing tool.
|
2019-07-01 21:01:33 +00:00
|
|
|
*/
|
2020-12-20 18:44:13 +00:00
|
|
|
bool IsMoveTool() const;
|
2019-07-01 21:01:33 +00:00
|
|
|
|
2021-02-02 01:05:48 +00:00
|
|
|
/**
|
|
|
|
* Indicate if the event is from the simulator.
|
|
|
|
*/
|
|
|
|
bool IsSimulator() const;
|
|
|
|
|
2014-11-21 10:28:34 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Return a non-standard parameter assigned to the event. Its meaning depends on the
|
2014-11-21 10:28:34 +00:00
|
|
|
* target tool.
|
|
|
|
*/
|
2015-04-30 08:46:01 +00:00
|
|
|
template<typename T>
|
|
|
|
inline T Parameter() const
|
2014-11-21 10:28:34 +00:00
|
|
|
{
|
2019-06-17 22:02:30 +00:00
|
|
|
// Exhibit #798 on why I love to hate C++
|
|
|
|
// - reinterpret_cast needs to be used for pointers
|
|
|
|
// - static_cast must be used for enums
|
|
|
|
// - templates can't usefully distinguish between pointer and non-pointer types
|
|
|
|
// Fortunately good old C's cast can be a reinterpret_cast or a static_cast, and
|
|
|
|
// C99 gave us intptr_t which is guaranteed to be round-trippable with a pointer.
|
|
|
|
return (T) reinterpret_cast<intptr_t>( m_param );
|
2014-11-21 10:28:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Set a non-standard parameter assigned to the event. Its meaning depends on the
|
2014-11-21 10:28:34 +00:00
|
|
|
* target tool.
|
2020-12-27 00:41:04 +00:00
|
|
|
*
|
2014-11-21 10:28:34 +00:00
|
|
|
* @param aParam is the new parameter.
|
|
|
|
*/
|
2015-04-30 08:46:01 +00:00
|
|
|
template<typename T>
|
|
|
|
void SetParameter(T aParam)
|
2014-11-21 10:28:34 +00:00
|
|
|
{
|
2015-04-30 08:46:01 +00:00
|
|
|
m_param = (void*) aParam;
|
2014-11-21 10:28:34 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 11:14:16 +00:00
|
|
|
OPT<int> GetCommandId() const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
|
|
|
return m_commandId;
|
|
|
|
}
|
|
|
|
|
2017-11-01 11:14:16 +00:00
|
|
|
OPT<std::string> GetCommandStr() const
|
2014-07-09 11:50:27 +00:00
|
|
|
{
|
|
|
|
return m_commandStr;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:08:52 +00:00
|
|
|
void SetMousePosition( const VECTOR2D& aP )
|
|
|
|
{
|
|
|
|
m_mousePos = aP;
|
|
|
|
}
|
|
|
|
|
2013-08-07 09:20:12 +00:00
|
|
|
private:
|
2015-07-15 12:08:52 +00:00
|
|
|
friend class TOOL_DISPATCHER;
|
|
|
|
|
2019-06-27 11:47:24 +00:00
|
|
|
void init();
|
|
|
|
|
2015-07-15 12:08:52 +00:00
|
|
|
void setMouseDragOrigin( const VECTOR2D& aP )
|
|
|
|
{
|
|
|
|
m_mouseDragOrigin = aP;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setMouseDelta( const VECTOR2D& aP )
|
|
|
|
{
|
|
|
|
m_mouseDelta = aP;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setMouseButtons( int aButtons )
|
|
|
|
{
|
|
|
|
assert( ( aButtons & ~BUT_BUTTON_MASK ) == 0 );
|
|
|
|
m_mouseButtons = aButtons;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setModifiers( int aMods )
|
|
|
|
{
|
|
|
|
assert( ( aMods & ~MD_MODIFIER_MASK ) == 0 );
|
|
|
|
m_modifiers = aMods;
|
|
|
|
}
|
2013-08-07 09:20:12 +00:00
|
|
|
|
2018-10-08 22:49:42 +00:00
|
|
|
/**
|
|
|
|
* Ensure that the event is a type that has a position before returning a
|
2019-05-13 20:42:40 +00:00
|
|
|
* position, otherwise return a null-constructed position.
|
2020-12-27 00:41:04 +00:00
|
|
|
*
|
2018-10-08 22:49:42 +00:00
|
|
|
* Used to defend the position accessors from runtime access when the event
|
|
|
|
* does not have a valid position.
|
|
|
|
*
|
|
|
|
* @param aPos the position to return if the event is valid
|
|
|
|
* @return the checked position
|
|
|
|
*/
|
|
|
|
VECTOR2D returnCheckedPosition( const VECTOR2D& aPos ) const
|
|
|
|
{
|
|
|
|
#ifdef WX_COMPATIBILITY
|
|
|
|
wxCHECK_MSG( HasPosition(), VECTOR2D(),
|
|
|
|
"Attempted to get position from non-position event" );
|
|
|
|
#else
|
|
|
|
assert( HasPosition() );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return aPos;
|
|
|
|
}
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT_CATEGORY m_category;
|
|
|
|
TOOL_ACTIONS m_actions;
|
|
|
|
TOOL_ACTION_SCOPE m_scope;
|
2019-06-16 11:06:49 +00:00
|
|
|
bool m_passEvent;
|
2019-06-15 00:29:42 +00:00
|
|
|
bool m_hasPosition;
|
2021-02-21 12:45:50 +00:00
|
|
|
bool m_forceImmediate;
|
2013-08-07 09:20:12 +00:00
|
|
|
|
2021-02-24 18:43:12 +00:00
|
|
|
///< True when the tool is being re-activated from the stack
|
|
|
|
bool m_reactivate;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Difference between mouse cursor position and
|
|
|
|
///< the point where dragging event has started
|
2013-08-07 09:20:12 +00:00
|
|
|
VECTOR2D m_mouseDelta;
|
2013-09-27 14:23:43 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Current mouse cursor position
|
2013-08-07 09:20:12 +00:00
|
|
|
VECTOR2D m_mousePos;
|
2013-09-27 14:23:43 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Point where dragging has started
|
2013-08-07 09:20:12 +00:00
|
|
|
VECTOR2D m_mouseDragOrigin;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< State of mouse buttons
|
2013-08-07 09:20:12 +00:00
|
|
|
int m_mouseButtons;
|
2013-09-27 14:23:43 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Stores code of pressed/released key
|
2013-08-21 15:37:27 +00:00
|
|
|
int m_keyCode;
|
2013-09-27 14:23:43 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< State of key modifiers (Ctrl/Alt/etc.)
|
2013-08-21 15:37:27 +00:00
|
|
|
int m_modifiers;
|
2013-09-27 14:23:43 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Generic parameter used for passing non-standard data.
|
2014-11-21 10:28:34 +00:00
|
|
|
void* m_param;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< The first tool to receive the event
|
2019-07-07 23:01:08 +00:00
|
|
|
TOOL_BASE* m_firstResponder;
|
|
|
|
|
2017-11-01 11:14:16 +00:00
|
|
|
OPT<int> m_commandId;
|
|
|
|
OPT<std::string> m_commandStr;
|
2013-08-02 14:46:53 +00:00
|
|
|
};
|
|
|
|
|
2017-11-01 11:14:16 +00:00
|
|
|
typedef OPT<TOOL_EVENT> OPT_TOOL_EVENT;
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2013-10-14 11:43:57 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* A list of TOOL_EVENTs, with overloaded || operators allowing for concatenating TOOL_EVENTs
|
|
|
|
* with little code.
|
2013-08-02 14:46:53 +00:00
|
|
|
*/
|
2013-10-14 14:13:35 +00:00
|
|
|
class TOOL_EVENT_LIST
|
|
|
|
{
|
2013-08-07 09:20:12 +00:00
|
|
|
public:
|
|
|
|
typedef TOOL_EVENT value_type;
|
|
|
|
typedef std::deque<TOOL_EVENT>::iterator iterator;
|
|
|
|
typedef std::deque<TOOL_EVENT>::const_iterator const_iterator;
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Default constructor. Creates an empty list.
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT_LIST()
|
|
|
|
{}
|
2013-09-27 14:23:43 +00:00
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///< Constructor for a list containing only one TOOL_EVENT.
|
2013-08-07 09:20:12 +00:00
|
|
|
TOOL_EVENT_LIST( const TOOL_EVENT& aSingleEvent )
|
|
|
|
{
|
2013-09-19 15:02:57 +00:00
|
|
|
m_events.push_back( aSingleEvent );
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2020-12-27 00:41:04 +00:00
|
|
|
///<y Copy an existing TOOL_EVENT_LIST
|
2020-01-08 01:49:11 +00:00
|
|
|
TOOL_EVENT_LIST( const TOOL_EVENT_LIST& aEventList ) = default;
|
|
|
|
|
2013-09-19 15:02:57 +00:00
|
|
|
/**
|
|
|
|
* Function Format()
|
|
|
|
* Returns information about event in form of a human-readable string.
|
|
|
|
*
|
|
|
|
* @return Event information.
|
|
|
|
*/
|
2013-08-07 09:20:12 +00:00
|
|
|
const std::string Format() const;
|
|
|
|
|
2017-11-01 11:14:16 +00:00
|
|
|
OPT<const TOOL_EVENT&> Matches( const TOOL_EVENT& aEvent ) const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2019-06-15 00:29:42 +00:00
|
|
|
for( const TOOL_EVENT& event : m_events )
|
|
|
|
{
|
|
|
|
if( event.Matches( aEvent ) )
|
|
|
|
return event;
|
|
|
|
}
|
2013-10-14 14:13:35 +00:00
|
|
|
|
2017-11-01 11:14:16 +00:00
|
|
|
return OPT<const TOOL_EVENT&>();
|
2013-08-07 09:20:12 +00:00
|
|
|
}
|
|
|
|
|
2013-09-27 14:23:43 +00:00
|
|
|
/**
|
2020-12-27 00:41:04 +00:00
|
|
|
* Add a tool event to the list.
|
|
|
|
*
|
|
|
|
* @param aEvent is the tool event to be added.
|
2013-09-27 14:23:43 +00:00
|
|
|
*/
|
2013-08-07 09:20:12 +00:00
|
|
|
void Add( const TOOL_EVENT& aEvent )
|
|
|
|
{
|
|
|
|
m_events.push_back( aEvent );
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator begin()
|
|
|
|
{
|
|
|
|
return m_events.begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator end()
|
|
|
|
{
|
|
|
|
return m_events.end();
|
|
|
|
}
|
|
|
|
|
2013-08-21 15:37:27 +00:00
|
|
|
const_iterator cbegin() const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
|
|
|
return m_events.begin();
|
|
|
|
}
|
|
|
|
|
2013-08-21 15:37:27 +00:00
|
|
|
const_iterator cend() const
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
|
|
|
return m_events.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
int size() const
|
|
|
|
{
|
|
|
|
return m_events.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear()
|
|
|
|
{
|
|
|
|
m_events.clear();
|
|
|
|
}
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT_LIST& operator=( const TOOL_EVENT_LIST& aEventList )
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
|
|
|
m_events.clear();
|
|
|
|
|
2019-06-15 00:29:42 +00:00
|
|
|
for( const TOOL_EVENT& event : aEventList.m_events )
|
|
|
|
m_events.push_back( event );
|
2013-08-07 09:20:12 +00:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT_LIST& operator=( const TOOL_EVENT& aEvent )
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
|
|
|
m_events.clear();
|
2013-10-14 18:40:36 +00:00
|
|
|
m_events.push_back( aEvent );
|
2013-08-07 09:20:12 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT_LIST& operator||( const TOOL_EVENT& aEvent )
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
Add( aEvent );
|
2013-08-07 09:20:12 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT_LIST& operator||( const TOOL_EVENT_LIST& aEvent )
|
2013-08-07 09:20:12 +00:00
|
|
|
{
|
2015-06-05 15:49:01 +00:00
|
|
|
std::copy( aEvent.m_events.begin(), aEvent.m_events.end(), std::back_inserter( m_events ) );
|
2013-08-07 09:20:12 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::deque<TOOL_EVENT> m_events;
|
2013-08-02 14:46:53 +00:00
|
|
|
};
|
|
|
|
|
2019-04-29 17:50:46 +00:00
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEventA, const TOOL_EVENT& aEventB )
|
2013-08-02 14:46:53 +00:00
|
|
|
{
|
2013-10-14 11:43:57 +00:00
|
|
|
TOOL_EVENT_LIST l;
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
l.Add( aEventA );
|
|
|
|
l.Add( aEventB );
|
2013-08-02 14:46:53 +00:00
|
|
|
|
2013-10-14 11:43:57 +00:00
|
|
|
return l;
|
2013-08-02 14:46:53 +00:00
|
|
|
}
|
|
|
|
|
2019-04-29 17:50:46 +00:00
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent,
|
|
|
|
const TOOL_EVENT_LIST& aEventList )
|
2013-08-02 14:46:53 +00:00
|
|
|
{
|
2013-10-14 18:40:36 +00:00
|
|
|
TOOL_EVENT_LIST l( aEventList );
|
2013-10-14 11:43:57 +00:00
|
|
|
|
2013-10-14 18:40:36 +00:00
|
|
|
l.Add( aEvent );
|
2013-10-14 11:43:57 +00:00
|
|
|
return l;
|
2013-08-02 14:46:53 +00:00
|
|
|
}
|
|
|
|
|
2019-04-29 17:50:46 +00:00
|
|
|
|
2013-08-02 14:46:53 +00:00
|
|
|
#endif
|