219 lines
6.1 KiB
C++
219 lines
6.1 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "InputDeviceTouch.hpp"
|
|
#include "Base/Logger.hpp"
|
|
#include <algorithm>
|
|
|
|
namespace OpenVulkano::Input
|
|
{
|
|
void InputDeviceTouch::Init()
|
|
{
|
|
InputDevice::Init(InputDeviceType::TOUCH, 0, "Touch");
|
|
|
|
m_gestureProcessor.Init();
|
|
m_gestureProcessor.m_gestureTap.OnTap += EventHandler(this, &InputDeviceTouch::UpdateTap);
|
|
m_gestureProcessor.m_gesturePan.OnPanStarted += EventHandler(this, &InputDeviceTouch::UpdatePanStarted);
|
|
m_gestureProcessor.m_gesturePan.OnPanMoved += EventHandler(this, &InputDeviceTouch::UpdatePanMoved);
|
|
m_gestureProcessor.m_gesturePan.OnPanEnded += EventHandler(this, &InputDeviceTouch::UpdatePanStarted);
|
|
m_gestureProcessor.m_gesturePanTwoFingers.OnPanStarted += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersStarted);
|
|
m_gestureProcessor.m_gesturePanTwoFingers.OnPanMoved += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersMoved);
|
|
m_gestureProcessor.m_gesturePanTwoFingers.OnPanEnded += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersStarted);
|
|
m_gestureProcessor.m_gesturePinch.OnPinchStarted += EventHandler(this, &InputDeviceTouch::UpdatePinchStarted);
|
|
m_gestureProcessor.m_gesturePinch.OnPinchMoved += EventHandler(this, &InputDeviceTouch::UpdatePinchMoved);
|
|
m_gestureProcessor.m_gesturePinch.OnPinchEnded += EventHandler(this, &InputDeviceTouch::UpdatePinchStarted);
|
|
}
|
|
|
|
decltype(InputDeviceTouch::m_touches)::iterator InputDeviceTouch::FindTouch(TouchId id)
|
|
{
|
|
return std::find_if(m_touches.begin(), m_touches.end(), [id](const Touch& touch)
|
|
{
|
|
return (id == touch.GetId());
|
|
});
|
|
}
|
|
|
|
TouchId InputDeviceTouch::AddTouch(const Math::Vector2f& position)
|
|
{
|
|
m_touches.emplace_back(m_nextId, position);
|
|
OnTouchAdded(m_touches.back());
|
|
return m_nextId++;
|
|
}
|
|
|
|
void InputDeviceTouch::TouchDown(TouchId id)
|
|
{
|
|
auto touchIter = FindTouch(id);
|
|
|
|
if (touchIter != m_touches.end())
|
|
{
|
|
touchIter->m_down = true;
|
|
if (!m_multiTouch && m_touches.size() > 1)
|
|
{
|
|
int count = 0;
|
|
for (const auto &touch : m_touches)
|
|
{
|
|
if(touch.IsDown()) count++;
|
|
if (count > 1)
|
|
{
|
|
Logger::INPUT->debug("Begin multitouch");
|
|
m_multiTouch = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
OnTouchDown.NotifyAll(*touchIter);
|
|
m_gestureProcessor.TouchDown(*touchIter);
|
|
}
|
|
else
|
|
{
|
|
Logger::INPUT->warn("Received touch down event for unknown touch id.");
|
|
}
|
|
}
|
|
|
|
void InputDeviceTouch::TouchUp(TouchId id)
|
|
{
|
|
auto touchIter = FindTouch(id);
|
|
|
|
if (touchIter != m_touches.end())
|
|
{
|
|
touchIter->m_down = false;
|
|
|
|
if (m_multiTouch)
|
|
{
|
|
bool hasDown = false;
|
|
for (const auto &touch : m_touches)
|
|
{
|
|
if (touch.IsDown())
|
|
{
|
|
hasDown = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!hasDown)
|
|
{
|
|
Logger::INPUT->debug("End multitouch");
|
|
m_multiTouch = false;
|
|
}
|
|
}
|
|
|
|
OnTouchUp.NotifyAll(*touchIter);
|
|
m_gestureProcessor.TouchUp(*touchIter);
|
|
}
|
|
else
|
|
{
|
|
Logger::INPUT->warn("Received touch up for unknown touch id.");
|
|
}
|
|
}
|
|
|
|
void InputDeviceTouch::TouchMoved(TouchId id, const Math::Vector2f& position)
|
|
{
|
|
auto touchIter = FindTouch(id);
|
|
|
|
if (touchIter != m_touches.end())
|
|
{
|
|
touchIter->m_lastPosition = touchIter->m_position;
|
|
touchIter->m_position = position;
|
|
|
|
OnTouchMoved.NotifyAll(*touchIter);
|
|
m_gestureProcessor.TouchMoved(*touchIter);
|
|
}
|
|
else
|
|
{
|
|
Logger::INPUT->warn("Received touch moved for unknown touch id");
|
|
}
|
|
}
|
|
|
|
void InputDeviceTouch::RemoveTouch(TouchId id)
|
|
{
|
|
auto touchIter = FindTouch(id);
|
|
if (touchIter != m_touches.end())
|
|
{
|
|
auto removedTouch = *touchIter;
|
|
m_touches.erase(touchIter);
|
|
|
|
if (m_touches.empty())
|
|
{
|
|
m_multiTouch = false;
|
|
}
|
|
|
|
OnTouchRemoved.NotifyAll(removedTouch);
|
|
}
|
|
else
|
|
{
|
|
Logger::INPUT->warn("Received remove request for unknown touch id");
|
|
}
|
|
}
|
|
|
|
void InputDeviceTouch::UpdatePinchStarted(const Gesture* pinch, const PinchInfo& info)
|
|
{
|
|
m_lastPinchInfo = m_nextPinchInfo = info;
|
|
}
|
|
|
|
void InputDeviceTouch::UpdatePanStarted(const Gesture* pan, const PanInfo& info)
|
|
{
|
|
m_lastPanInfo = m_nextPanInfo = info;
|
|
}
|
|
|
|
void InputDeviceTouch::UpdatePanTwoFingersStarted(const Gesture* pan, const PanInfo& info)
|
|
{
|
|
m_last2FPanInfo = m_next2FPanInfo = info;
|
|
}
|
|
|
|
void InputDeviceTouch::UpdatePinchMoved(const Gesture* pinch, const PinchInfo& info)
|
|
{
|
|
m_nextPinchInfo = info;
|
|
}
|
|
|
|
void InputDeviceTouch::UpdatePanMoved(const Gesture* pan, const PanInfo& info)
|
|
{
|
|
m_nextPanInfo = info;
|
|
}
|
|
|
|
void InputDeviceTouch::UpdatePanTwoFingersMoved(const Gesture* pan, const PanInfo& info)
|
|
{
|
|
m_next2FPanInfo = info;
|
|
}
|
|
|
|
void InputDeviceTouch::UpdateTap(const Gesture* tap, const TapInfo& info)
|
|
{
|
|
m_toBePressedButtons = 1;
|
|
m_nextTap = info.position;
|
|
m_axes[InputKey::Touch::Axis::AXIS_TAP_DURATION] = info.duration.count();
|
|
}
|
|
|
|
void InputDeviceTouch::Tick()
|
|
{
|
|
m_lastPressedButtons = m_pressedButtons;
|
|
m_pressedButtons = m_toBePressedButtons;
|
|
m_toBePressedButtons = 0;
|
|
|
|
// Tap
|
|
auto diff = m_nextTap - m_lastTap;
|
|
m_axes[InputKey::Touch::Axis::AXIS_TAP_X] = diff.x;
|
|
m_axes[InputKey::Touch::Axis::AXIS_TAP_Y] = diff.y;
|
|
m_axes[InputKey::Touch::Axis::AXIS_TAP_X_ABS] = m_nextTap.x;
|
|
m_axes[InputKey::Touch::Axis::AXIS_TAP_Y_ABS] = m_nextTap.y;
|
|
m_lastTap = m_nextTap;
|
|
|
|
// Pan
|
|
diff = m_nextPanInfo.position - m_lastPanInfo.position;
|
|
m_axes[InputKey::Touch::Axis::AXIS_PAN_X] = diff.x;
|
|
m_axes[InputKey::Touch::Axis::AXIS_PAN_Y] = diff.y;
|
|
m_lastPanInfo = m_nextPanInfo;
|
|
diff = m_next2FPanInfo.position - m_last2FPanInfo.position;
|
|
m_axes[InputKey::Touch::Axis::AXIS_PAN_TWO_FINGERS_X] = diff.x;
|
|
m_axes[InputKey::Touch::Axis::AXIS_PAN_TWO_FINGERS_Y] = diff.y;
|
|
m_last2FPanInfo = m_next2FPanInfo;
|
|
|
|
// Pinch
|
|
m_axes[InputKey::Touch::Axis::AXIS_PINCH] = m_nextPinchInfo.scale - m_lastPinchInfo.scale;
|
|
diff = m_nextPinchInfo.position - m_lastPinchInfo.position;
|
|
m_axes[InputKey::Touch::Axis::AXIS_PINCH_CENTER_X] = diff.x;
|
|
m_axes[InputKey::Touch::Axis::AXIS_PINCH_CENTER_Y] = diff.y;
|
|
m_lastPinchInfo = m_nextPinchInfo;
|
|
}
|
|
}
|