495 lines
19 KiB
C++
495 lines
19 KiB
C++
/**
|
|
* @author Edouard DUPIN
|
|
*
|
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
|
*
|
|
* @license APACHE v2.0 (see license file)
|
|
*/
|
|
|
|
#include <etk/types.h>
|
|
#include <etk/types.h>
|
|
|
|
#include <ewol/debug.h>
|
|
|
|
#include <ewol/ewol.h>
|
|
|
|
#include <ewol/object/Object.h>
|
|
#include <ewol/object/Manager.h>
|
|
#include <ewol/context/Context.h>
|
|
#include <ewol/context/InputManager.h>
|
|
#include <ewol/resource/Texture.h>
|
|
|
|
#include <ewol/widget/Widget.h>
|
|
#include <ewol/widget/Windows.h>
|
|
#include <ewol/widget/Manager.h>
|
|
|
|
|
|
|
|
#define EVENT_DEBUG EWOL_VERBOSE
|
|
//#define EVENT_DEBUG EWOL_DEBUG
|
|
|
|
void ewol::context::InputManager::calculateLimit() {
|
|
m_eventInputLimit.sepatateTime = 300000; // µs
|
|
m_eventInputLimit.DpiOffset = m_dpi*100;
|
|
m_eventMouseLimit.sepatateTime = 300000; // µs
|
|
m_eventMouseLimit.DpiOffset = (float)m_dpi*(float)0.1;
|
|
}
|
|
|
|
void ewol::context::InputManager::setDpi(int32_t newDPI) {
|
|
m_dpi = newDPI;
|
|
// recalculate the DPI system ...
|
|
calculateLimit();
|
|
}
|
|
|
|
bool ewol::context::InputManager::localEventInput(enum gale::key::type _type,
|
|
std::shared_ptr<ewol::Widget> _destWidget,
|
|
int32_t _IdInput,
|
|
enum gale::key::status _status,
|
|
vec2 _pos) {
|
|
if (nullptr != _destWidget) {
|
|
if (_type == gale::key::type_mouse || _type == gale::key::type_finger) {
|
|
// create the system Event :
|
|
ewol::event::InputSystem tmpEventSystem(_type, _status, _IdInput, _pos, _destWidget, 0, m_specialKey); // TODO : set the real ID ...
|
|
// generate the event :
|
|
return _destWidget->systemEventInput(tmpEventSystem);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ewol::context::InputManager::abortElement(InputPoperty *_eventTable,
|
|
int32_t _idInput,
|
|
enum gale::key::type _type) {
|
|
if (nullptr == _eventTable) {
|
|
return;
|
|
}
|
|
if (_eventTable[_idInput].isUsed == true) {
|
|
localEventInput(_type,
|
|
_eventTable[_idInput].curentWidgetEvent.lock(),
|
|
_eventTable[_idInput].destinationInputId,
|
|
gale::key::status_abort,
|
|
_eventTable[_idInput].posEvent);
|
|
}
|
|
}
|
|
|
|
void ewol::context::InputManager::cleanElement(InputPoperty *_eventTable,
|
|
int32_t _idInput) {
|
|
if (nullptr == _eventTable) {
|
|
return;
|
|
}
|
|
//EWOL_INFO("CleanElement[" << idInput << "] = @" << (int64_t)eventTable);
|
|
_eventTable[_idInput].isUsed = false;
|
|
_eventTable[_idInput].destinationInputId = 0;
|
|
_eventTable[_idInput].lastTimeEvent = 0;
|
|
_eventTable[_idInput].curentWidgetEvent.reset();
|
|
_eventTable[_idInput].origin.setValue(0,0);
|
|
_eventTable[_idInput].size.setValue(99999999,99999999);
|
|
_eventTable[_idInput].downStart.setValue(0,0);
|
|
_eventTable[_idInput].isDown = false;
|
|
_eventTable[_idInput].isInside = false;
|
|
_eventTable[_idInput].nbClickEvent = 0;
|
|
_eventTable[_idInput].posEvent.setValue(0,0);
|
|
}
|
|
|
|
void ewol::context::InputManager::transfertEvent(std::shared_ptr<ewol::Widget> _source, std::shared_ptr<ewol::Widget> _destination) {
|
|
if( _source == nullptr
|
|
|| _destination == nullptr) {
|
|
// prevent errors ...
|
|
return;
|
|
}
|
|
for(int32_t iii=0; iii<MAX_MANAGE_INPUT; iii++) {
|
|
std::shared_ptr<ewol::Widget> tmpWidget = m_eventInputSaved[iii].curentWidgetEvent.lock();
|
|
if (tmpWidget == _source) {
|
|
// inform the widget that it does not receive the event now
|
|
EVENT_DEBUG("GUI : Input ID=" << iii << " == >" << m_eventInputSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_ABORT] " << m_eventInputSaved[iii].posEvent);
|
|
localEventInput(gale::key::type_finger, tmpWidget, m_eventInputSaved[iii].destinationInputId, gale::key::status_abort, m_eventInputSaved[iii].posEvent);
|
|
// set the new widget ...
|
|
m_eventInputSaved[iii].curentWidgetEvent = _destination;
|
|
// inform the widget that he receive the event property now...
|
|
EVENT_DEBUG("GUI : Input ID=" << iii << " == >" << m_eventInputSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_TRANSFERT] " << m_eventInputSaved[iii].posEvent);
|
|
localEventInput(gale::key::type_finger, _destination, m_eventInputSaved[iii].destinationInputId, gale::key::status_transfert, m_eventInputSaved[iii].posEvent);
|
|
}
|
|
tmpWidget = m_eventMouseSaved[iii].curentWidgetEvent.lock();
|
|
if (tmpWidget == _source) {
|
|
// inform the widget that it does not receive the event now
|
|
EVENT_DEBUG("GUI : Input ID=" << iii << " == >" << m_eventMouseSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_ABORT] " << m_eventMouseSaved[iii].posEvent);
|
|
localEventInput(gale::key::type_mouse, tmpWidget, m_eventMouseSaved[iii].destinationInputId, gale::key::status_abort, m_eventMouseSaved[iii].posEvent);
|
|
// set the new widget ...
|
|
m_eventMouseSaved[iii].curentWidgetEvent = _destination;
|
|
// inform the widget that he receive the event property now...
|
|
EVENT_DEBUG("GUI : Input ID=" << iii << " == >" << m_eventMouseSaved[iii].destinationInputId << " [EVENT_INPUT_TYPE_TRANSFERT] " << m_eventMouseSaved[iii].posEvent);
|
|
localEventInput(gale::key::type_mouse, _destination, m_eventMouseSaved[iii].destinationInputId, gale::key::status_transfert, m_eventMouseSaved[iii].posEvent);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ewol::context::InputManager::grabPointer(std::shared_ptr<ewol::Widget> _widget) {
|
|
if(_widget == nullptr) {
|
|
return;
|
|
}
|
|
m_grabWidget = _widget;
|
|
/* TODO :
|
|
m_context.grabPointerEvents(true, _widget->getOrigin()
|
|
+ ivec2(_widget->getSize().x()/2.0f,
|
|
_widget->getSize().y()/2.0f) );
|
|
*/
|
|
}
|
|
|
|
void ewol::context::InputManager::unGrabPointer() {
|
|
m_grabWidget.reset();
|
|
// TODO: m_context.grabPointerEvents(false, vec2(0,0));
|
|
}
|
|
|
|
void ewol::context::InputManager::newLayerSet() {
|
|
for(int32_t iii=0; iii<MAX_MANAGE_INPUT; iii++) {
|
|
// remove the property of this input ...
|
|
abortElement(m_eventInputSaved, iii, gale::key::type_finger);
|
|
cleanElement(m_eventInputSaved, iii);
|
|
abortElement(m_eventMouseSaved, iii, gale::key::type_mouse);
|
|
cleanElement(m_eventMouseSaved, iii);
|
|
}
|
|
}
|
|
|
|
ewol::context::InputManager::InputManager(ewol::Context& _context) :
|
|
m_grabWidget(),
|
|
m_context(_context) {
|
|
setDpi(200);
|
|
EWOL_INFO("Init (start)");
|
|
for(int32_t iii=0; iii<MAX_MANAGE_INPUT; iii++) {
|
|
// remove the property of this input ...
|
|
cleanElement(m_eventInputSaved, iii);
|
|
cleanElement(m_eventMouseSaved, iii);
|
|
}
|
|
EWOL_INFO("Init (end)");
|
|
}
|
|
|
|
ewol::context::InputManager::~InputManager() {
|
|
EWOL_INFO("Un-Init (start)");
|
|
EWOL_INFO("Un-Init (end)");
|
|
}
|
|
|
|
int32_t ewol::context::InputManager::localGetDestinationId(enum gale::key::type _type,
|
|
std::shared_ptr<ewol::Widget> _destWidget,
|
|
int32_t _realInputId) {
|
|
if (_type == gale::key::type_finger) {
|
|
int32_t lastMinimum = 0;
|
|
for(int32_t iii=0; iii<MAX_MANAGE_INPUT; iii++) {
|
|
if (true == m_eventInputSaved[iii].isUsed) {
|
|
std::shared_ptr<ewol::Widget> tmpWidget = m_eventInputSaved[iii].curentWidgetEvent.lock();
|
|
if (tmpWidget == _destWidget) {
|
|
if (iii != _realInputId) {
|
|
lastMinimum = std::max(lastMinimum, m_eventInputSaved[iii].destinationInputId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return lastMinimum+1;
|
|
}
|
|
return _realInputId;
|
|
}
|
|
|
|
// note if id<0 == > the it was finger event ...
|
|
void ewol::context::InputManager::motion(enum gale::key::type _type,
|
|
int _pointerID,
|
|
vec2 _pos) {
|
|
EVENT_DEBUG("motion event : " << _type << " " << _pointerID << " " << _pos);
|
|
if (MAX_MANAGE_INPUT <= _pointerID) {
|
|
// reject pointer == > out of IDs...
|
|
return;
|
|
}
|
|
InputPoperty *eventTable = nullptr;
|
|
if (_type == gale::key::type_mouse) {
|
|
eventTable = m_eventMouseSaved;
|
|
} else if (_type == gale::key::type_finger) {
|
|
eventTable = m_eventInputSaved;
|
|
} else {
|
|
EWOL_ERROR("Unknown type of event");
|
|
return;
|
|
}
|
|
if( _pointerID > MAX_MANAGE_INPUT
|
|
|| _pointerID < 0) {
|
|
// not manage input
|
|
return;
|
|
}
|
|
std::shared_ptr<ewol::widget::Windows> tmpWindows = m_context.getWindows();
|
|
// special case for the mouse event 0 that represent the hover event of the system :
|
|
if (_type == gale::key::type_mouse && _pointerID == 0) {
|
|
// this event is all time on the good widget ... and manage the enter and leave ...
|
|
// NOTE : the "layer widget" force us to get the widget at the specific position all the time :
|
|
std::shared_ptr<ewol::Widget> tmpWidget;
|
|
if (m_grabWidget.lock() != nullptr) {
|
|
// grab all events ...
|
|
tmpWidget = m_grabWidget.lock();
|
|
} else {
|
|
if (nullptr != tmpWindows) {
|
|
tmpWidget = tmpWindows->getWidgetAtPos(_pos);
|
|
}
|
|
}
|
|
if( tmpWidget != eventTable[_pointerID].curentWidgetEvent.lock()
|
|
|| ( true == eventTable[_pointerID].isInside
|
|
&& ( eventTable[_pointerID].origin.x() > _pos.x()
|
|
|| eventTable[_pointerID].origin.y() > _pos.y()
|
|
|| (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x()
|
|
|| (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()) ) ) {
|
|
eventTable[_pointerID].isInside = false;
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID << " == >" << eventTable[_pointerID].destinationInputId << " [LEAVE] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
eventTable[_pointerID].curentWidgetEvent.lock(),
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_leave,
|
|
_pos);
|
|
}
|
|
if (eventTable[_pointerID].isInside == false) {
|
|
// set the element inside ...
|
|
eventTable[_pointerID].isInside = true;
|
|
// get destination widget :
|
|
eventTable[_pointerID].curentWidgetEvent = tmpWidget;
|
|
if (tmpWidget == nullptr) {
|
|
eventTable[_pointerID].isInside = false;
|
|
} else {
|
|
eventTable[_pointerID].origin = tmpWidget->getOrigin();
|
|
eventTable[_pointerID].size = tmpWidget->getSize();
|
|
}
|
|
eventTable[_pointerID].destinationInputId = 0;
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [ENTER] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
tmpWidget,
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_enter,
|
|
_pos);
|
|
}
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [MOVE] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
tmpWidget,
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_move,
|
|
_pos);
|
|
} else if (true == eventTable[_pointerID].isUsed) {
|
|
if (true == eventTable[_pointerID].isInside) {
|
|
if( eventTable[_pointerID].origin.x() > _pos.x()
|
|
|| eventTable[_pointerID].origin.y() > _pos.y()
|
|
|| (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x()
|
|
|| (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()) {
|
|
eventTable[_pointerID].isInside = false;
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [LEAVE] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
eventTable[_pointerID].curentWidgetEvent.lock(),
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_leave,
|
|
_pos);
|
|
}
|
|
} else {
|
|
if( ( eventTable[_pointerID].origin.x() <= _pos.x()
|
|
&& (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) >= _pos.x() )
|
|
&& ( eventTable[_pointerID].origin.y() <= _pos.y()
|
|
&& (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) >= _pos.y() ) ) {
|
|
eventTable[_pointerID].isInside = true;
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [ENTER] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
eventTable[_pointerID].curentWidgetEvent.lock(),
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_enter,
|
|
_pos);
|
|
}
|
|
}
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [MOVE] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
eventTable[_pointerID].curentWidgetEvent.lock(),
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_move,
|
|
_pos);
|
|
}
|
|
}
|
|
|
|
void ewol::context::InputManager::state(enum gale::key::type _type,
|
|
int _pointerID,
|
|
bool _isDown,
|
|
vec2 _pos)
|
|
{
|
|
if (MAX_MANAGE_INPUT <= _pointerID) {
|
|
// reject pointer == > out of IDs...
|
|
return;
|
|
}
|
|
EVENT_DEBUG("event pointerId=" << _pointerID);
|
|
// convert position in open-GL coordonates ...
|
|
InputPoperty *eventTable = nullptr;
|
|
InputLimit localLimit;
|
|
if (_type == gale::key::type_mouse) {
|
|
eventTable = m_eventMouseSaved;
|
|
localLimit = m_eventMouseLimit;
|
|
} else if (_type == gale::key::type_finger) {
|
|
eventTable = m_eventInputSaved;
|
|
localLimit = m_eventInputLimit;
|
|
} else {
|
|
EWOL_ERROR("Unknown type of event");
|
|
return;
|
|
}
|
|
if( _pointerID > MAX_MANAGE_INPUT
|
|
|| _pointerID <= 0) {
|
|
// not manage input
|
|
return;
|
|
}
|
|
// get the curent time ...
|
|
int64_t currentTime = ewol::getTime();
|
|
std::shared_ptr<ewol::widget::Windows> tmpWindows = m_context.getWindows();
|
|
|
|
if (true == _isDown) {
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [DOWN] " << _pos);
|
|
if(true == eventTable[_pointerID].isUsed) {
|
|
// we have an event previously ... check delay between click and offset position
|
|
if (currentTime - eventTable[_pointerID].lastTimeEvent > localLimit.sepatateTime) {
|
|
cleanElement(eventTable, _pointerID);
|
|
} else if( abs(eventTable[_pointerID].downStart.x() - _pos.x()) >= localLimit.DpiOffset
|
|
|| abs(eventTable[_pointerID].downStart.y() - _pos.y()) >= localLimit.DpiOffset ){
|
|
cleanElement(eventTable, _pointerID);
|
|
}
|
|
}
|
|
if(true == eventTable[_pointerID].isUsed) {
|
|
// save start time
|
|
eventTable[_pointerID].lastTimeEvent = currentTime;
|
|
// generate DOWN Event
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [DOWN] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
eventTable[_pointerID].curentWidgetEvent.lock(),
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_down,
|
|
_pos);
|
|
} else {
|
|
// Mark it used :
|
|
eventTable[_pointerID].isUsed = true;
|
|
// Save current position :
|
|
eventTable[_pointerID].downStart = _pos;
|
|
// save start time
|
|
eventTable[_pointerID].lastTimeEvent = currentTime;
|
|
// set the element inside ...
|
|
eventTable[_pointerID].isInside = true;
|
|
std::shared_ptr<ewol::Widget> tmpWidget = m_grabWidget.lock();
|
|
// get destination widget :
|
|
if(nullptr != tmpWindows) {
|
|
if ( tmpWidget != nullptr
|
|
&& _type == gale::key::type_mouse) {
|
|
eventTable[_pointerID].curentWidgetEvent = tmpWidget;
|
|
} else {
|
|
eventTable[_pointerID].curentWidgetEvent = tmpWindows->getWidgetAtPos(_pos);
|
|
}
|
|
} else {
|
|
eventTable[_pointerID].curentWidgetEvent.reset();
|
|
}
|
|
tmpWidget = eventTable[_pointerID].curentWidgetEvent.lock();
|
|
if (tmpWidget != nullptr) {
|
|
eventTable[_pointerID].origin = tmpWidget->getOrigin();
|
|
eventTable[_pointerID].size = tmpWidget->getSize();
|
|
eventTable[_pointerID].destinationInputId = localGetDestinationId(_type, tmpWidget, _pointerID);
|
|
} else {
|
|
eventTable[_pointerID].destinationInputId = -1;
|
|
}
|
|
// generate DOWN Event
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [DOWN] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
tmpWidget,
|
|
eventTable[_pointerID].destinationInputId,
|
|
gale::key::status_down,
|
|
_pos);
|
|
}
|
|
} else {
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [UP] " << _pos);
|
|
if(false == eventTable[_pointerID].isUsed) {
|
|
// bad case ... ???
|
|
EWOL_DEBUG("Up event without previous down ... ");
|
|
// Mark it un-used :
|
|
eventTable[_pointerID].isUsed = false;
|
|
// revove the widget ...
|
|
eventTable[_pointerID].curentWidgetEvent.reset();
|
|
} else {
|
|
std::shared_ptr<ewol::Widget> tmpWidget = eventTable[_pointerID].curentWidgetEvent.lock();
|
|
// generate UP Event
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [UP] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
// send up event after the single event to prevent multiple widget getting elements
|
|
localEventInput(_type,
|
|
tmpWidget,
|
|
_pointerID,
|
|
gale::key::status_up,
|
|
_pos);
|
|
// generate event (single)
|
|
if( abs(eventTable[_pointerID].downStart.x() - _pos.x()) < localLimit.DpiOffset
|
|
&& abs(eventTable[_pointerID].downStart.y() - _pos.y()) < localLimit.DpiOffset ){
|
|
// Save current position :
|
|
eventTable[_pointerID].downStart = _pos;
|
|
// save start time
|
|
eventTable[_pointerID].lastTimeEvent = currentTime;
|
|
int32_t nbClickMax = 0;
|
|
if(tmpWidget != nullptr) {
|
|
nbClickMax = tmpWidget->getMouseLimit();
|
|
if (nbClickMax>5) {
|
|
nbClickMax = 5;
|
|
}
|
|
}
|
|
// in grab mode the single to quinte event are not generated ....
|
|
if( ( m_grabWidget.lock() == nullptr
|
|
|| _type != gale::key::type_mouse )
|
|
&& eventTable[_pointerID].nbClickEvent < nbClickMax) {
|
|
// generate event SINGLE :
|
|
eventTable[_pointerID].nbClickEvent++;
|
|
EVENT_DEBUG("GUI : Input ID=" << _pointerID
|
|
<< " == >" << eventTable[_pointerID].destinationInputId
|
|
<< " [" << eventTable[_pointerID].nbClickEvent << "] " << _pos);
|
|
eventTable[_pointerID].posEvent = _pos;
|
|
localEventInput(_type,
|
|
tmpWidget,
|
|
eventTable[_pointerID].destinationInputId,
|
|
(enum gale::key::status)(gale::key::status_single + eventTable[_pointerID].nbClickEvent-1),
|
|
_pos);
|
|
if( eventTable[_pointerID].nbClickEvent >= nbClickMax) {
|
|
eventTable[_pointerID].nbClickEvent = 0;
|
|
}
|
|
} else {
|
|
eventTable[_pointerID].nbClickEvent = 0;
|
|
}
|
|
}
|
|
// send up event after the single event to prevent multiple widget getting elements
|
|
localEventInput(_type,
|
|
tmpWidget,
|
|
_pointerID,
|
|
gale::key::status_upAfter,
|
|
_pos);
|
|
// specific for tuch event
|
|
if (_type == gale::key::type_finger) {
|
|
cleanElement(eventTable, _pointerID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|