142 lines
3.0 KiB
C++
142 lines
3.0 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 "GestureProcessor.hpp"
|
|
#include "Touch.hpp"
|
|
#include "Gesture.hpp"
|
|
#include "Base/Logger.hpp"
|
|
|
|
namespace OpenVulkano::Input
|
|
{
|
|
bool Gesture::ResolveConflicts()
|
|
{
|
|
if (m_processor) return m_processor->ResolveConflicts(this);
|
|
return false;
|
|
}
|
|
|
|
void Gesture::RemoveFromProcessor()
|
|
{
|
|
if (m_processor) m_processor->RemoveGesture(this);
|
|
}
|
|
|
|
GestureProcessor::GestureProcessor()
|
|
: m_gesturePan(1), m_gesturePanTwoFingers(2)
|
|
{}
|
|
|
|
GestureProcessor::~GestureProcessor()
|
|
{
|
|
if (!m_gestures.empty()) Close();
|
|
}
|
|
|
|
void GestureProcessor::Init()
|
|
{
|
|
AddGesture(&m_gesturePan);
|
|
AddGesture(&m_gesturePanTwoFingers);
|
|
AddGesture(&m_gesturePinch);
|
|
AddGesture(&m_gestureTap);
|
|
m_conflictResolutionDelegate = [this](const Gesture* existing, const Gesture* newGesture) {
|
|
if(existing == &m_gesturePan && newGesture != &m_gestureTap)
|
|
{
|
|
Logger::INPUT->debug("Replacing pan with multitouch gesture");
|
|
return ConflictResult::NewGesture;
|
|
}
|
|
return ConflictResult::BothGestures;
|
|
};
|
|
}
|
|
|
|
void GestureProcessor::Close()
|
|
{
|
|
for(const auto& gesture : m_gestures)
|
|
{
|
|
gesture->m_processor = nullptr;
|
|
}
|
|
m_gestures.clear();
|
|
m_conflictResolutionDelegate = nullptr;
|
|
}
|
|
|
|
void GestureProcessor::AddGesture(Gesture* gesture)
|
|
{
|
|
gesture->m_processor = this;
|
|
m_gestures.push_back(gesture);
|
|
}
|
|
|
|
void GestureProcessor::RemoveGesture(OpenVulkano::Input::Gesture* gesture)
|
|
{
|
|
for (auto it = m_gestures.begin(); it != m_gestures.end(); it++)
|
|
{
|
|
if (*it == gesture)
|
|
{
|
|
(*it)->m_processor = nullptr;
|
|
m_gestures.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//region forward events
|
|
void GestureProcessor::Reset()
|
|
{
|
|
for (const auto& gesture : m_gestures)
|
|
{
|
|
gesture->Reset();
|
|
}
|
|
}
|
|
|
|
void GestureProcessor::TouchDown(const OpenVulkano::Input::Touch& touch)
|
|
{
|
|
for (const auto& gesture : m_gestures)
|
|
{
|
|
gesture->TouchDown(touch);
|
|
}
|
|
}
|
|
|
|
void GestureProcessor::TouchUp(const OpenVulkano::Input::Touch& touch)
|
|
{
|
|
for (const auto& gesture : m_gestures)
|
|
{
|
|
gesture->TouchUp(touch);
|
|
}
|
|
}
|
|
|
|
void GestureProcessor::TouchMoved(const OpenVulkano::Input::Touch& touch)
|
|
{
|
|
for (const auto& gesture : m_gestures)
|
|
{
|
|
gesture->TouchMoved(touch);
|
|
}
|
|
}
|
|
//endregion
|
|
|
|
bool GestureProcessor::ResolveConflicts(Gesture* gesture)
|
|
{
|
|
if (!m_conflictResolutionDelegate) return true;
|
|
bool canActivate = true;
|
|
for (const auto& g : m_gestures)
|
|
{
|
|
if (g != gesture && g->IsActive())
|
|
{
|
|
ConflictResult conflictResult = m_conflictResolutionDelegate(g, gesture);
|
|
|
|
switch (conflictResult)
|
|
{
|
|
case ConflictResult::NeitherGesture:
|
|
g->Reset();
|
|
canActivate = false;
|
|
break;
|
|
case ConflictResult::ExistingGesture:
|
|
canActivate = false;
|
|
break;
|
|
case ConflictResult::NewGesture:
|
|
g->Reset();
|
|
break;
|
|
case ConflictResult::BothGestures:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return canActivate;
|
|
}
|
|
} |