Files
OpenVulkano/openVulkanoCpp/Input/Touch/GestureProcessor.cpp
2023-10-15 13:39:22 +02:00

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;
}
}