/* * This file is part of openauto project. * Copyright (C) 2018 f1x.studio (Michal Szwaj) * * openauto is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * openauto is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with openauto. If not, see . */ #include #include #include namespace f1x { namespace openauto { namespace autoapp { namespace projection { InputDevice::InputDevice(QObject& parent, configuration::IConfiguration::Pointer configuration, const QRect& touchscreenGeometry, const QRect& displayGeometry) : parent_(parent) , configuration_(std::move(configuration)) , touchscreenGeometry_(touchscreenGeometry) , displayGeometry_(displayGeometry) , eventHandler_(nullptr) { this->moveToThread(parent.thread()); } void InputDevice::start(IInputDeviceEventHandler& eventHandler) { std::lock_guard lock(mutex_); OPENAUTO_LOG(info) << "[InputDevice] start."; eventHandler_ = &eventHandler; parent_.installEventFilter(this); } void InputDevice::stop() { std::lock_guard lock(mutex_); OPENAUTO_LOG(info) << "[InputDevice] stop."; parent_.removeEventFilter(this); eventHandler_ = nullptr; } bool InputDevice::eventFilter(QObject* obj, QEvent* event) { std::lock_guard lock(mutex_); if(eventHandler_ != nullptr) { if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { QKeyEvent* key = static_cast(event); if(!key->isAutoRepeat()) { return this->handleKeyEvent(event, key); } } else if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) { return this->handleTouchEvent(event); } } return QObject::eventFilter(obj, event); } bool InputDevice::handleKeyEvent(QEvent* event, QKeyEvent* key) { auto eventType = event->type() == QEvent::KeyPress ? ButtonEventType::PRESS : ButtonEventType::RELEASE; aasdk::proto::enums::ButtonCode::Enum buttonCode; WheelDirection wheelDirection = WheelDirection::NONE; switch(key->key()) { case Qt::Key_Return: case Qt::Key_Enter: buttonCode = aasdk::proto::enums::ButtonCode::ENTER; break; case Qt::Key_Left: buttonCode = aasdk::proto::enums::ButtonCode::LEFT; break; case Qt::Key_Right: buttonCode = aasdk::proto::enums::ButtonCode::RIGHT; break; case Qt::Key_Up: buttonCode = aasdk::proto::enums::ButtonCode::UP; break; case Qt::Key_Down: buttonCode = aasdk::proto::enums::ButtonCode::DOWN; break; case Qt::Key_Escape: buttonCode = aasdk::proto::enums::ButtonCode::BACK; break; case Qt::Key_H: buttonCode = aasdk::proto::enums::ButtonCode::HOME; break; case Qt::Key_P: buttonCode = aasdk::proto::enums::ButtonCode::PHONE; break; case Qt::Key_O: buttonCode = aasdk::proto::enums::ButtonCode::CALL_END; break; case Qt::Key_X: buttonCode = aasdk::proto::enums::ButtonCode::PLAY; break; case Qt::Key_C: buttonCode = aasdk::proto::enums::ButtonCode::PAUSE; break; case Qt::Key_MediaPrevious: case Qt::Key_V: buttonCode = aasdk::proto::enums::ButtonCode::PREV; break; case Qt::Key_MediaPlay: case Qt::Key_B: buttonCode = aasdk::proto::enums::ButtonCode::TOGGLE_PLAY; break; case Qt::Key_MediaNext: case Qt::Key_N: buttonCode = aasdk::proto::enums::ButtonCode::NEXT; break; case Qt::Key_M: buttonCode = aasdk::proto::enums::ButtonCode::MICROPHONE_1; break; case Qt::Key_1: wheelDirection = WheelDirection::LEFT; eventType = ButtonEventType::NONE; buttonCode = aasdk::proto::enums::ButtonCode::SCROLL_WHEEL; break; case Qt::Key_2: wheelDirection = WheelDirection::RIGHT; eventType = ButtonEventType::NONE; buttonCode = aasdk::proto::enums::ButtonCode::SCROLL_WHEEL; break; default: return true; } const auto& buttonCodes = this->getSupportedButtonCodes(); if(std::find(buttonCodes.begin(), buttonCodes.end(), buttonCode) != buttonCodes.end()) { if(buttonCode != aasdk::proto::enums::ButtonCode::SCROLL_WHEEL || event->type() == QEvent::KeyRelease) { eventHandler_->onButtonEvent({eventType, wheelDirection, buttonCode}); } } return true; } bool InputDevice::handleTouchEvent(QEvent* event) { if(!configuration_->getTouchscreenEnabled()) { return true; } aasdk::proto::enums::TouchAction::Enum type; switch(event->type()) { case QEvent::MouseButtonPress: type = aasdk::proto::enums::TouchAction::PRESS; break; case QEvent::MouseButtonRelease: type = aasdk::proto::enums::TouchAction::RELEASE; break; case QEvent::MouseMove: type = aasdk::proto::enums::TouchAction::DRAG; break; default: return true; }; QMouseEvent* mouse = static_cast(event); if(event->type() == QEvent::MouseButtonRelease || mouse->buttons().testFlag(Qt::LeftButton)) { const uint32_t x = (static_cast(mouse->pos().x()) / touchscreenGeometry_.width()) * displayGeometry_.width(); const uint32_t y = (static_cast(mouse->pos().y()) / touchscreenGeometry_.height()) * displayGeometry_.height(); eventHandler_->onTouchEvent({type, x, y, 0}); } return true; } bool InputDevice::hasTouchscreen() const { return configuration_->getTouchscreenEnabled(); } QRect InputDevice::getTouchscreenGeometry() const { return touchscreenGeometry_; } void InputDevice::setTouchscreenGeometry(QRect& touchscreenGeometry) { touchscreenGeometry_ = touchscreenGeometry; } IInputDevice::ButtonCodes InputDevice::getSupportedButtonCodes() const { return configuration_->getButtonCodes(); } } } } }