mirror of https://github.com/axmolengine/axmol.git
754 lines
20 KiB
C++
754 lines
20 KiB
C++
#include "InputProcessor.h"
|
|
#include "GComponent.h"
|
|
#include "InputEvent.h"
|
|
#include "GRoot.h"
|
|
#include "GRichTextField.h"
|
|
#include "GTextInput.h"
|
|
#include "utils/WeakPtr.h"
|
|
|
|
NS_FGUI_BEGIN
|
|
USING_NS_AX;
|
|
|
|
InputProcessor* InputProcessor::_activeProcessor = nullptr;
|
|
bool InputProcessor::_touchOnUI = false;
|
|
unsigned int InputProcessor::_touchOnUIFlagFrameId = 0;
|
|
|
|
class TouchInfo
|
|
{
|
|
public:
|
|
TouchInfo();
|
|
~TouchInfo();
|
|
|
|
void reset();
|
|
|
|
axis::Touch* touch;
|
|
axis::Vec2 pos;
|
|
int touchId;
|
|
int clickCount;
|
|
int mouseWheelDelta;
|
|
axis::EventMouse::MouseButton button;
|
|
axis::Vec2 downPos;
|
|
bool began;
|
|
bool clickCancelled;
|
|
clock_t lastClickTime;
|
|
WeakPtr lastRollOver;
|
|
std::vector<WeakPtr> downTargets;
|
|
std::vector<WeakPtr> touchMonitors;
|
|
};
|
|
|
|
InputProcessor::InputProcessor(GComponent* owner) :
|
|
_keyModifiers(0),
|
|
_mouseListener(nullptr),
|
|
_touchListener(nullptr),
|
|
_keyboardListener(nullptr)
|
|
{
|
|
_owner = owner;
|
|
_recentInput._inputProcessor = this;
|
|
|
|
#ifdef AX_PLATFORM_PC
|
|
_mouseListener = EventListenerMouse::create();
|
|
AX_SAFE_RETAIN(_mouseListener);
|
|
_mouseListener->onMouseDown = AX_CALLBACK_1(InputProcessor::onMouseDown, this);
|
|
_mouseListener->onMouseUp = AX_CALLBACK_1(InputProcessor::onMouseUp, this);
|
|
_mouseListener->onMouseMove = AX_CALLBACK_1(InputProcessor::onMouseMove, this);
|
|
_mouseListener->onMouseScroll = AX_CALLBACK_1(InputProcessor::onMouseScroll, this);
|
|
_owner->displayObject()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(_mouseListener, _owner->displayObject());
|
|
#endif
|
|
|
|
_touchListener = EventListenerTouchOneByOne::create();
|
|
AX_SAFE_RETAIN(_touchListener);
|
|
_touchListener->setSwallowTouches(false);
|
|
_touchListener->onTouchBegan = AX_CALLBACK_2(InputProcessor::onTouchBegan, this);
|
|
_touchListener->onTouchMoved = AX_CALLBACK_2(InputProcessor::onTouchMoved, this);
|
|
_touchListener->onTouchEnded = AX_CALLBACK_2(InputProcessor::onTouchEnded, this);
|
|
_touchListener->onTouchCancelled = AX_CALLBACK_2(InputProcessor::onTouchCancelled, this);
|
|
_owner->displayObject()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(_touchListener, _owner->displayObject());
|
|
|
|
_keyboardListener = EventListenerKeyboard::create();
|
|
AX_SAFE_RETAIN(_keyboardListener);
|
|
_keyboardListener->onKeyPressed = AX_CALLBACK_2(InputProcessor::onKeyDown, this);
|
|
_keyboardListener->onKeyReleased = AX_CALLBACK_2(InputProcessor::onKeyUp, this);
|
|
_owner->displayObject()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(_keyboardListener, _owner->displayObject());
|
|
}
|
|
|
|
InputProcessor::~InputProcessor()
|
|
{
|
|
#ifdef AX_PLATFORM_PC
|
|
_owner->displayObject()->getEventDispatcher()->removeEventListener(_mouseListener);
|
|
#endif
|
|
_owner->displayObject()->getEventDispatcher()->removeEventListener(_touchListener);
|
|
_owner->displayObject()->getEventDispatcher()->removeEventListener(_keyboardListener);
|
|
AX_SAFE_RELEASE_NULL(_touchListener);
|
|
AX_SAFE_RELEASE_NULL(_mouseListener);
|
|
AX_SAFE_RELEASE_NULL(_keyboardListener);
|
|
|
|
for (auto &ti : _touches)
|
|
delete ti;
|
|
}
|
|
|
|
axis::Vec2 InputProcessor::getTouchPosition(int touchId)
|
|
{
|
|
for (auto &ti : _touches)
|
|
{
|
|
if (ti->touchId == touchId)
|
|
return ti->pos;
|
|
}
|
|
return _recentInput.getPosition();
|
|
}
|
|
|
|
TouchInfo* InputProcessor::getTouch(int touchId, bool createIfNotExisits)
|
|
{
|
|
TouchInfo* ret = nullptr;
|
|
for (auto &ti : _touches)
|
|
{
|
|
if (ti->touchId == touchId)
|
|
return ti;
|
|
else if (ti->touchId == -1)
|
|
ret = ti;
|
|
}
|
|
|
|
if (!ret)
|
|
{
|
|
if (!createIfNotExisits)
|
|
return nullptr;
|
|
|
|
ret = new TouchInfo();
|
|
_touches.push_back(ret);
|
|
}
|
|
ret->touchId = touchId;
|
|
return ret;
|
|
}
|
|
|
|
void InputProcessor::updateRecentInput(TouchInfo* ti, GObject* target)
|
|
{
|
|
_recentInput._pos.x = (int)ti->pos.x;
|
|
_recentInput._pos.y = (int)ti->pos.y;
|
|
_recentInput._target = target;
|
|
_recentInput._clickCount = ti->clickCount;
|
|
_recentInput._button = ti->button;
|
|
_recentInput._mouseWheelDelta = ti->mouseWheelDelta;
|
|
_recentInput._touch = ti->touch;
|
|
_recentInput._touchId = ti->touch ? ti->touchId : -1;
|
|
|
|
int curFrame = Director::getInstance()->getTotalFrames();
|
|
bool flag = target != _owner;
|
|
if (curFrame != _touchOnUIFlagFrameId)
|
|
_touchOnUI = flag;
|
|
else if (flag)
|
|
_touchOnUI = true;
|
|
_touchOnUIFlagFrameId = curFrame;
|
|
}
|
|
|
|
void InputProcessor::handleRollOver(TouchInfo* touch, GObject* target)
|
|
{
|
|
if (touch->lastRollOver == target)
|
|
return;
|
|
|
|
std::vector<WeakPtr> rollOutChain;
|
|
std::vector<WeakPtr> rollOverChain;
|
|
GObject* element = touch->lastRollOver.ptr();
|
|
while (element != nullptr)
|
|
{
|
|
rollOutChain.push_back(WeakPtr(element));
|
|
element = element->findParent();
|
|
}
|
|
|
|
element = target;
|
|
while (element != nullptr)
|
|
{
|
|
auto iter = std::find(rollOutChain.cbegin(), rollOutChain.cend(), element);
|
|
if (iter != rollOutChain.cend())
|
|
{
|
|
rollOutChain.resize(iter - rollOutChain.cbegin());
|
|
break;
|
|
}
|
|
rollOverChain.push_back(WeakPtr(element));
|
|
|
|
element = element->findParent();
|
|
}
|
|
|
|
touch->lastRollOver = target;
|
|
|
|
for (auto &wptr : rollOutChain)
|
|
{
|
|
element = wptr.ptr();
|
|
if (element && element->onStage())
|
|
element->dispatchEvent(UIEventType::RollOut);
|
|
}
|
|
|
|
for (auto &wptr : rollOverChain)
|
|
{
|
|
element = wptr.ptr();
|
|
if (element && element->onStage())
|
|
element->dispatchEvent(UIEventType::RollOver);
|
|
}
|
|
}
|
|
|
|
void InputProcessor::addTouchMonitor(int touchId, GObject * target)
|
|
{
|
|
TouchInfo* ti = getTouch(touchId, false);
|
|
if (!ti)
|
|
return;
|
|
|
|
auto it = std::find(ti->touchMonitors.cbegin(), ti->touchMonitors.cend(), target);
|
|
if (it == ti->touchMonitors.cend())
|
|
ti->touchMonitors.push_back(WeakPtr(target));
|
|
}
|
|
|
|
void InputProcessor::removeTouchMonitor(GObject * target)
|
|
{
|
|
for (auto it = _touches.cbegin(); it != _touches.cend(); ++it)
|
|
{
|
|
auto it2 = std::find((*it)->touchMonitors.begin(), (*it)->touchMonitors.end(), target);
|
|
if (it2 != (*it)->touchMonitors.end())
|
|
*it2 = nullptr;
|
|
}
|
|
}
|
|
|
|
void InputProcessor::cancelClick(int touchId)
|
|
{
|
|
TouchInfo* ti = getTouch(touchId, false);
|
|
if (ti)
|
|
ti->clickCancelled = true;
|
|
}
|
|
|
|
void InputProcessor::simulateClick(GObject* target, int touchId)
|
|
{
|
|
_activeProcessor = this;
|
|
|
|
Vec2 pt = target->localToGlobal(Vec2::ZERO);
|
|
_recentInput._pos.x = pt.x;
|
|
_recentInput._pos.y = pt.y;
|
|
_recentInput._target = target;
|
|
_recentInput._clickCount = 1;
|
|
_recentInput._button = EventMouse::MouseButton::BUTTON_LEFT;
|
|
_recentInput._touch = nullptr;
|
|
_recentInput._touchId = touchId;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchBegin);
|
|
|
|
WeakPtr wptr(target);
|
|
target->bubbleEvent(UIEventType::TouchBegin);
|
|
|
|
target = wptr.ptr();
|
|
if (target)
|
|
{
|
|
target->bubbleEvent(UIEventType::TouchEnd);
|
|
|
|
target = wptr.ptr();
|
|
if (target)
|
|
target->bubbleEvent(UIEventType::Click);
|
|
}
|
|
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::setBegin(TouchInfo* touch, GObject* target)
|
|
{
|
|
touch->began = true;
|
|
touch->clickCancelled = false;
|
|
touch->downPos = touch->pos;
|
|
|
|
touch->downTargets.clear();
|
|
GObject* obj = target;
|
|
while (obj != nullptr)
|
|
{
|
|
touch->downTargets.push_back(WeakPtr(obj));
|
|
obj = obj->findParent();
|
|
}
|
|
}
|
|
|
|
void InputProcessor::setEnd(TouchInfo* touch, GObject* target)
|
|
{
|
|
touch->began = false;
|
|
|
|
auto now = clock();
|
|
float elapsed = (now - touch->lastClickTime) / (double)CLOCKS_PER_SEC;
|
|
|
|
if (elapsed < 0.45f)
|
|
{
|
|
if (touch->clickCount == 2)
|
|
touch->clickCount = 1;
|
|
else
|
|
touch->clickCount++;
|
|
}
|
|
else
|
|
touch->clickCount = 1;
|
|
touch->lastClickTime = now;
|
|
}
|
|
|
|
GObject* InputProcessor::clickTest(TouchInfo* touch, GObject* target)
|
|
{
|
|
if (touch->downTargets.empty()
|
|
|| touch->clickCancelled
|
|
|| std::abs(touch->pos.x - touch->downPos.x) > 50 || std::abs(touch->pos.y - touch->downPos.y) > 50)
|
|
return nullptr;
|
|
|
|
GObject* obj = touch->downTargets[0].ptr();
|
|
if (obj && obj->onStage())
|
|
return obj;
|
|
|
|
obj = target;
|
|
while (obj != nullptr)
|
|
{
|
|
auto it = std::find(touch->downTargets.cbegin(), touch->downTargets.cend(), obj);
|
|
if (it != touch->downTargets.cend() && it->onStage())
|
|
{
|
|
obj = it->ptr();
|
|
break;
|
|
}
|
|
|
|
obj = obj->findParent();
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
|
|
bool InputProcessor::isTouchOnUI()
|
|
{
|
|
return _touchOnUI;
|
|
}
|
|
|
|
void InputProcessor::disableDefaultTouchEvent()
|
|
{
|
|
_owner->displayObject()->getEventDispatcher()->removeEventListener(_touchListener);
|
|
}
|
|
|
|
bool InputProcessor::touchDown(axis::Touch *touch, axis::Event *event)
|
|
{
|
|
return onTouchBegan(touch, event);
|
|
}
|
|
|
|
void InputProcessor::touchMove(axis::Touch *touch, axis::Event *event)
|
|
{
|
|
onTouchMoved(touch, event);
|
|
}
|
|
|
|
void InputProcessor::touchUp(axis::Touch *touch, axis::Event *event)
|
|
{
|
|
onTouchEnded(touch, event);
|
|
}
|
|
|
|
bool InputProcessor::onTouchBegan(Touch *touch, Event* /*unusedEvent*/)
|
|
{
|
|
if (!(_owner->isTouchable() && _owner->isVisible())) {
|
|
return false;
|
|
}
|
|
|
|
auto camera = Camera::getVisitingCamera();
|
|
Vec2 pt = touch->getLocation();
|
|
GObject* target = _owner->hitTest(pt, camera);
|
|
if (!target)
|
|
target = _owner;
|
|
_touchListener->setSwallowTouches(target != _owner);
|
|
|
|
TouchInfo* ti = getTouch(touch->getID());
|
|
ti->pos = UIRoot->worldToRoot(pt);
|
|
ti->button = EventMouse::MouseButton::BUTTON_LEFT;
|
|
ti->touch = touch;
|
|
setBegin(ti, target);
|
|
|
|
updateRecentInput(ti, target);
|
|
_activeProcessor = this;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchBegin);
|
|
|
|
WeakPtr wptr(target);
|
|
target->bubbleEvent(UIEventType::TouchBegin);
|
|
target = wptr.ptr();
|
|
|
|
handleRollOver(ti, target);
|
|
|
|
_activeProcessor = nullptr;
|
|
|
|
return true;
|
|
}
|
|
|
|
void InputProcessor::onTouchMoved(Touch *touch, Event* /*unusedEvent*/)
|
|
{
|
|
auto camera = Camera::getVisitingCamera();
|
|
Vec2 pt = touch->getLocation();
|
|
GObject* target = _owner->hitTest(pt, camera);
|
|
if (!target)
|
|
target = _owner;
|
|
|
|
TouchInfo* ti = getTouch(touch->getID());
|
|
ti->pos = UIRoot->worldToRoot(pt);
|
|
ti->button = EventMouse::MouseButton::BUTTON_LEFT;
|
|
ti->touch = touch;
|
|
|
|
updateRecentInput(ti, target);
|
|
_activeProcessor = this;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchMove);
|
|
|
|
handleRollOver(ti, target);
|
|
|
|
if (ti->began)
|
|
{
|
|
bool done = false;
|
|
size_t cnt = ti->touchMonitors.size();
|
|
if (cnt > 0)
|
|
{
|
|
for (size_t i = 0; i < cnt; i++)
|
|
{
|
|
GObject* mm = ti->touchMonitors[i].ptr();
|
|
if (!mm)
|
|
continue;
|
|
|
|
mm->dispatchEvent(UIEventType::TouchMove);
|
|
if (mm == _owner)
|
|
done = true;
|
|
}
|
|
}
|
|
if (!done)
|
|
_owner->dispatchEvent(UIEventType::TouchMove);
|
|
}
|
|
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::onTouchEnded(Touch *touch, Event* /*unusedEvent*/)
|
|
{
|
|
auto camera = Camera::getVisitingCamera();
|
|
Vec2 pt = touch->getLocation();
|
|
GObject* target = _owner->hitTest(pt, camera);
|
|
if (!target)
|
|
target = _owner;
|
|
|
|
TouchInfo* ti = getTouch(touch->getID());
|
|
ti->pos = UIRoot->worldToRoot(pt);
|
|
ti->button = EventMouse::MouseButton::BUTTON_LEFT;
|
|
ti->touch = touch;
|
|
setEnd(ti, target);
|
|
|
|
updateRecentInput(ti, target);
|
|
_activeProcessor = this;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchEnd);
|
|
|
|
WeakPtr wptr(target);
|
|
size_t cnt = ti->touchMonitors.size();
|
|
if (cnt > 0)
|
|
{
|
|
for (size_t i = 0; i < cnt; i++)
|
|
{
|
|
GObject* mm = ti->touchMonitors[i].ptr();
|
|
if (!mm)
|
|
continue;
|
|
|
|
if (mm != target
|
|
&& (!dynamic_cast<GComponent*>(mm) || !((GComponent*)mm)->isAncestorOf(target)))
|
|
mm->dispatchEvent(UIEventType::TouchEnd);
|
|
}
|
|
ti->touchMonitors.clear();
|
|
target = wptr.ptr();
|
|
}
|
|
if (target)
|
|
{
|
|
target->bubbleEvent(UIEventType::TouchEnd);
|
|
target = wptr.ptr();
|
|
}
|
|
|
|
target = clickTest(ti, target);
|
|
if (target)
|
|
{
|
|
wptr = target;
|
|
updateRecentInput(ti, target);
|
|
|
|
GRichTextField* tf = dynamic_cast<GRichTextField*>(target);
|
|
if (tf)
|
|
{
|
|
const char* linkHref = dynamic_cast<FUIRichText*>(tf->displayObject())->hitTestLink(pt);
|
|
if (linkHref)
|
|
{
|
|
tf->bubbleEvent(UIEventType::ClickLink, nullptr, Value(linkHref));
|
|
target = wptr.ptr();
|
|
}
|
|
}
|
|
|
|
target->bubbleEvent(UIEventType::Click);
|
|
target = wptr.ptr();
|
|
}
|
|
|
|
#ifndef AX_PLATFORM_PC
|
|
//on mobile platform, trigger RollOut on up event, but not on PC
|
|
handleRollOver(ti, nullptr);
|
|
#else
|
|
handleRollOver(ti, target);
|
|
#endif
|
|
ti->touchId = -1;
|
|
ti->button = EventMouse::MouseButton::BUTTON_UNSET;
|
|
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::onTouchCancelled(Touch* touch, Event* /*unusedEvent*/)
|
|
{
|
|
TouchInfo* ti = getTouch(touch->getID());
|
|
if (ti == nullptr)
|
|
return;
|
|
|
|
ti->touch = touch;
|
|
updateRecentInput(ti, _owner);
|
|
_activeProcessor = this;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchEnd);
|
|
|
|
size_t cnt = ti->touchMonitors.size();
|
|
if (cnt > 0)
|
|
{
|
|
for (size_t i = 0; i < cnt; i++)
|
|
{
|
|
GObject* mm = ti->touchMonitors[i].ptr();
|
|
if (!mm)
|
|
continue;
|
|
|
|
if (mm != _owner)
|
|
mm->dispatchEvent(UIEventType::TouchEnd);
|
|
}
|
|
ti->touchMonitors.clear();
|
|
}
|
|
_owner->dispatchEvent(UIEventType::TouchEnd);
|
|
|
|
handleRollOver(ti, nullptr);
|
|
|
|
ti->touchId = -1;
|
|
ti->button = EventMouse::MouseButton::BUTTON_UNSET;
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::onMouseDown(axis::EventMouse * event)
|
|
{
|
|
if (event->getMouseButton() == EventMouse::MouseButton::BUTTON_LEFT)
|
|
return;
|
|
|
|
auto camera = Camera::getVisitingCamera();
|
|
Vec2 pt(event->getCursorX(), event->getCursorY());
|
|
GObject* target = _owner->hitTest(pt, camera);
|
|
if (!target)
|
|
target = _owner;
|
|
_touchListener->setSwallowTouches(target != _owner);
|
|
|
|
TouchInfo* ti = getTouch(0);
|
|
ti->pos = UIRoot->worldToRoot(pt);
|
|
ti->button = event->getMouseButton();
|
|
ti->touch = nullptr;
|
|
setBegin(ti, target);
|
|
|
|
updateRecentInput(ti, target);
|
|
_activeProcessor = this;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchBegin);
|
|
|
|
WeakPtr wptr(target);
|
|
target->bubbleEvent(UIEventType::TouchBegin);
|
|
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::onMouseUp(axis::EventMouse * event)
|
|
{
|
|
if (event->getMouseButton() == EventMouse::MouseButton::BUTTON_LEFT)
|
|
return;
|
|
|
|
auto camera = Camera::getVisitingCamera();
|
|
Vec2 pt(event->getCursorX(), event->getCursorY());
|
|
GObject* target = _owner->hitTest(pt, camera);
|
|
if (!target)
|
|
target = _owner;
|
|
|
|
TouchInfo* ti = getTouch(0);
|
|
ti->pos = UIRoot->worldToRoot(pt);
|
|
ti->button = event->getMouseButton();
|
|
ti->touch = nullptr;
|
|
setEnd(ti, target);
|
|
|
|
updateRecentInput(ti, target);
|
|
_activeProcessor = this;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchEnd);
|
|
|
|
WeakPtr wptr(target);
|
|
size_t cnt = ti->touchMonitors.size();
|
|
if (cnt > 0)
|
|
{
|
|
for (size_t i = 0; i < cnt; i++)
|
|
{
|
|
GObject* mm = ti->touchMonitors[i].ptr();
|
|
if (!mm)
|
|
continue;
|
|
|
|
if (mm != target
|
|
&& (!dynamic_cast<GComponent*>(mm) || !((GComponent*)mm)->isAncestorOf(target)))
|
|
mm->dispatchEvent(UIEventType::TouchEnd);
|
|
}
|
|
ti->touchMonitors.clear();
|
|
target = wptr.ptr();
|
|
}
|
|
if (target)
|
|
{
|
|
target->bubbleEvent(UIEventType::TouchEnd);
|
|
target = wptr.ptr();
|
|
}
|
|
|
|
target = clickTest(ti, target);
|
|
if (target)
|
|
{
|
|
wptr = target;
|
|
updateRecentInput(ti, target);
|
|
|
|
if (ti->button == EventMouse::MouseButton::BUTTON_MIDDLE)
|
|
target->bubbleEvent(UIEventType::MiddleClick);
|
|
else
|
|
target->bubbleEvent(UIEventType::RightClick);
|
|
}
|
|
|
|
ti->touchId = -1;
|
|
ti->button = EventMouse::MouseButton::BUTTON_UNSET;
|
|
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::onMouseMove(axis::EventMouse * event)
|
|
{
|
|
TouchInfo* ti = getTouch(0);
|
|
Vec2 npos = UIRoot->worldToRoot(Vec2(event->getCursorX(), event->getCursorY()));
|
|
if (std::abs(ti->pos.x - npos.x) < 1
|
|
&& std::abs(ti->pos.y - npos.y) < 1)
|
|
return;
|
|
|
|
auto camera = Camera::getVisitingCamera();
|
|
Vec2 pt(event->getCursorX(), event->getCursorY());
|
|
GObject* target = _owner->hitTest(pt, camera);
|
|
if (!target)
|
|
target = _owner;
|
|
|
|
ti->pos = UIRoot->worldToRoot(pt);
|
|
ti->touch = nullptr;
|
|
|
|
updateRecentInput(ti, target);
|
|
_activeProcessor = this;
|
|
|
|
if (_captureCallback)
|
|
_captureCallback(UIEventType::TouchMove);
|
|
|
|
handleRollOver(ti, target);
|
|
|
|
if (ti->began)
|
|
{
|
|
bool done = false;
|
|
size_t cnt = ti->touchMonitors.size();
|
|
if (cnt > 0)
|
|
{
|
|
for (size_t i = 0; i < cnt; i++)
|
|
{
|
|
GObject* mm = ti->touchMonitors[i].ptr();
|
|
if (!mm)
|
|
continue;
|
|
|
|
mm->dispatchEvent(UIEventType::TouchMove);
|
|
if (mm == _owner)
|
|
done = true;
|
|
}
|
|
}
|
|
if (!done)
|
|
_owner->dispatchEvent(UIEventType::TouchMove);
|
|
}
|
|
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::onMouseScroll(axis::EventMouse * event)
|
|
{
|
|
auto camera = Camera::getVisitingCamera();
|
|
Vec2 pt(event->getCursorX(), event->getCursorY());
|
|
GObject* target = _owner->hitTest(pt, camera);
|
|
if (!target)
|
|
target = _owner;
|
|
|
|
TouchInfo* ti = getTouch(0);
|
|
ti->pos = UIRoot->worldToRoot(pt);
|
|
ti->touch = nullptr;
|
|
ti->mouseWheelDelta = MAX(event->getScrollX(), event->getScrollY());
|
|
|
|
updateRecentInput(ti, target);
|
|
_activeProcessor = this;
|
|
|
|
target->bubbleEvent(UIEventType::MouseWheel);
|
|
ti->mouseWheelDelta = 0;
|
|
|
|
_activeProcessor = nullptr;
|
|
}
|
|
|
|
void InputProcessor::onKeyDown(axis::EventKeyboard::KeyCode keyCode, axis::Event * event)
|
|
{
|
|
if (keyCode == EventKeyboard::KeyCode::KEY_LEFT_CTRL || keyCode == EventKeyboard::KeyCode::KEY_RIGHT_CTRL)
|
|
_keyModifiers |= 1;
|
|
else if (keyCode == EventKeyboard::KeyCode::KEY_LEFT_ALT || keyCode == EventKeyboard::KeyCode::KEY_RIGHT_ALT)
|
|
_keyModifiers |= 2;
|
|
else if (keyCode == EventKeyboard::KeyCode::KEY_LEFT_SHIFT || keyCode == EventKeyboard::KeyCode::KEY_RIGHT_SHIFT)
|
|
_keyModifiers |= 4;
|
|
|
|
_recentInput._keyCode = keyCode;
|
|
_recentInput._target = _owner;
|
|
_recentInput._target->dispatchEvent(UIEventType::KeyDown);
|
|
}
|
|
|
|
void InputProcessor::onKeyUp(axis::EventKeyboard::KeyCode keyCode, axis::Event *)
|
|
{
|
|
if (keyCode == EventKeyboard::KeyCode::KEY_LEFT_CTRL || keyCode == EventKeyboard::KeyCode::KEY_RIGHT_CTRL)
|
|
_keyModifiers &= ~1;
|
|
else if (keyCode == EventKeyboard::KeyCode::KEY_LEFT_ALT || keyCode == EventKeyboard::KeyCode::KEY_RIGHT_ALT)
|
|
_keyModifiers &= ~2;
|
|
else if (keyCode == EventKeyboard::KeyCode::KEY_LEFT_SHIFT || keyCode == EventKeyboard::KeyCode::KEY_RIGHT_SHIFT)
|
|
_keyModifiers &= ~4;
|
|
|
|
_recentInput._keyCode = keyCode;
|
|
_recentInput._target = _owner;
|
|
_recentInput._target->dispatchEvent(UIEventType::KeyUp);
|
|
}
|
|
|
|
TouchInfo::TouchInfo() :
|
|
touch(nullptr),
|
|
touchId(-1),
|
|
clickCount(0),
|
|
mouseWheelDelta(0),
|
|
button(EventMouse::MouseButton::BUTTON_UNSET),
|
|
began(false),
|
|
lastClickTime(0),
|
|
clickCancelled(false)
|
|
{
|
|
}
|
|
|
|
TouchInfo::~TouchInfo()
|
|
{
|
|
downTargets.clear();
|
|
touchMonitors.clear();
|
|
}
|
|
|
|
void TouchInfo::reset()
|
|
{
|
|
touchId = -1;
|
|
mouseWheelDelta = 0;
|
|
button = EventMouse::MouseButton::BUTTON_UNSET;
|
|
touch = nullptr;
|
|
pos.setZero();
|
|
downPos.setZero();
|
|
clickCount = 0;
|
|
lastClickTime = 0;
|
|
began = false;
|
|
downTargets.clear();
|
|
lastRollOver = nullptr;
|
|
clickCancelled = false;
|
|
touchMonitors.clear();
|
|
}
|
|
|
|
NS_FGUI_END |