blob: a7a4a172e1238b91932e52bd39d970efeb840d34 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Gamepad module
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qgamepadmouseitem.h"
#include <cmath>
#include <QtGamepad/QGamepad>
#include <QtGui/QWindow>
#include <QtQuick/QQuickWindow>
#include <QtGui/QGuiApplication>
QT_BEGIN_NAMESPACE
QGamepadMouseItem::QGamepadMouseItem(QQuickItem *parent)
: QQuickItem(parent)
, m_active(false)
, m_gamepad(nullptr)
, m_joystick(QGamepadMouseItem::LeftStick)
, m_deadZoneSize(0.1)
{
m_updateTimer.setInterval(16);
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateMousePostion()));
}
bool QGamepadMouseItem::active() const
{
return m_active;
}
QGamepad *QGamepadMouseItem::gamepad() const
{
return m_gamepad;
}
QGamepadMouseItem::GamepadJoystick QGamepadMouseItem::joystick() const
{
return m_joystick;
}
double QGamepadMouseItem::deadZoneSize() const
{
return m_deadZoneSize;
}
QPointF QGamepadMouseItem::mousePosition() const
{
return m_mousePosition;
}
void QGamepadMouseItem::setActive(bool arg)
{
if (m_active != arg) {
m_active = arg;
if (m_active) {
m_deltaTimer.start();
m_updateTimer.start();
} else {
m_updateTimer.stop();
m_deltaTimer.invalidate();
}
emit activeChanged(arg);
}
}
void QGamepadMouseItem::setGamepad(QGamepad *gamepad)
{
if (m_gamepad != gamepad) {
m_gamepad = gamepad;
emit gamepadChanged(gamepad);
}
}
void QGamepadMouseItem::setJoystick(QGamepadMouseItem::GamepadJoystick joystick)
{
if (m_joystick != joystick) {
m_joystick = joystick;
emit joystickChanged(joystick);
}
}
void QGamepadMouseItem::setDeadZoneSize(double size)
{
if (m_deadZoneSize != size) {
m_deadZoneSize = size;
emit deadZoneSizeChanged(size);
}
}
void QGamepadMouseItem::mouseButtonPressed(int button)
{
processMouseButtonEvent(true, (Qt::MouseButton)button);
}
void QGamepadMouseItem::mouseButtonReleased(int button)
{
processMouseButtonEvent(false, (Qt::MouseButton)button);
}
void QGamepadMouseItem::updateMousePostion()
{
//Get the delta from the last call
qint64 delta = m_deltaTimer.restart();
//Don't bother when there is not gamepad to read from
if (!m_gamepad || !m_gamepad->isConnected())
return;
double xVelocity = 0.0;
double yVelocity = 0.0;
if (m_joystick == QGamepadMouseItem::LeftStick) {
xVelocity = m_gamepad->axisLeftX();
yVelocity = m_gamepad->axisLeftY();
} else if (m_joystick == QGamepadMouseItem::RightStick) {
xVelocity = m_gamepad->axisRightX();
yVelocity = m_gamepad->axisRightY();
} else { //The greatest of both
if (std::abs(m_gamepad->axisLeftX()) > std::abs(m_gamepad->axisRightX()))
xVelocity = m_gamepad->axisLeftX();
else
xVelocity = m_gamepad->axisRightX();
if (std::abs(m_gamepad->axisLeftY()) > std::abs(m_gamepad->axisRightY()))
yVelocity = m_gamepad->axisLeftY();
else
yVelocity = m_gamepad->axisRightY();
}
//Check for deadzone limits]
if (std::abs(xVelocity) < m_deadZoneSize)
xVelocity = 0.0;
if (std::abs(yVelocity) < m_deadZoneSize)
yVelocity = 0.0;
if (xVelocity == 0.0 && yVelocity == 0.0)
return;
double newXPosition = m_mousePosition.x() + xVelocity * delta;
double newYPosition = m_mousePosition.y() + yVelocity * delta;
//Check bounds
if (newXPosition < 0)
newXPosition = 0;
else if (newXPosition > width())
newXPosition = width();
if (newYPosition < 0)
newYPosition = 0;
else if (newYPosition > height())
newYPosition = height();
m_mousePosition = QPointF(newXPosition, newYPosition);
emit mousePositionChanged(m_mousePosition);
}
void QGamepadMouseItem::processMouseMoveEvent(QPointF position)
{
QMouseEvent *mouseEvent = new QMouseEvent(QEvent::MouseMove, mapToScene(position), Qt::NoButton, m_mouseButtons, Qt::NoModifier);
sendGeneratedMouseEvent(mouseEvent);
}
void QGamepadMouseItem::processMouseButtonEvent(bool isPressed, Qt::MouseButton button)
{
QMouseEvent *event;
if (isPressed) {
m_mouseButtons |= button;
event = new QMouseEvent(QEvent::MouseButtonPress, mapToScene(m_mousePosition), button, m_mouseButtons, Qt::NoModifier);
} else {
m_mouseButtons ^= button;
event = new QMouseEvent(QEvent::MouseButtonRelease, mapToScene(m_mousePosition), button, m_mouseButtons, Qt::NoModifier);
}
sendGeneratedMouseEvent(event);
}
void QGamepadMouseItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickItem::geometryChanged(newGeometry, oldGeometry);
m_mousePosition = newGeometry.center();
}
void QGamepadMouseItem::sendGeneratedMouseEvent(QMouseEvent *event)
{
if (!m_active || !this->window()) {
delete event;
return;
}
QWindow *window = qobject_cast<QWindow*>(this->window());
if (window)
QGuiApplication::sendEvent(window, event);
}
QT_END_NAMESPACE