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