1, restrict mouse in window. 2, fix mouse move bugs

This commit is contained in:
Tian Zhou 2019-12-08 00:36:14 -05:00
commit 90079e83d9
2 changed files with 78 additions and 88 deletions

View file

@ -1,15 +1,14 @@
#include <QDebug> #include <QDebug>
#include <QCursor> #include <QCursor>
#include <QGuiApplication> #include <QGuiApplication>
#include "inputconvertgame.h" #include "inputconvertgame.h"
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
#include <windef.h> #include <windef.h>
// restrict mouse into a window // restrict mouse into a window
static void restrictMouse(const int left, const int right, static void restrictMouse(const int left, const int right,
const int top, const int bottom) const int top, const int bottom)
@ -26,14 +25,13 @@ static void freeMouse()
ClipCursor(nullptr); ClipCursor(nullptr);
} }
#else #else // linux and macos
// dummy
static void restrictMouse(const int left, const int right, static void restrictMouse(const int left, const int right,
const int top, const int bottom) const int top, const int bottom)
{} {}
static void freeMouse() static void freeMouse()
{} {}
#endif // _WINDOWS_ #endif
#define CURSOR_POS_CHECK 50 #define CURSOR_POS_CHECK 50
@ -191,20 +189,25 @@ QPointF InputConvertGame::calcFrameAbsolutePos(QPointF relativePos)
int InputConvertGame::attachTouchID(int key) int InputConvertGame::attachTouchID(int key)
{ {
//QMetaEnum map = QMetaEnum::fromType<Qt::Key>();
for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) { for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) {
if (0 == multiTouchID[i]) { if (0 == multiTouchID[i]) {
multiTouchID[i] = key; multiTouchID[i] = key;
//qDebug() << "attach "<<key<<" ("<<map.valueToKey(key)<<") as "<<i;
return i; return i;
} }
} }
//qDebug() << "attach "<<key<<" ("<<map.valueToKey(key)<<") failed ";
return -1; return -1;
} }
void InputConvertGame::detachTouchID(int key) void InputConvertGame::detachTouchID(int key)
{ {
//QMetaEnum map = QMetaEnum::fromType<Qt::Key>();
for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) { for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) {
if (key == multiTouchID[i]) { if (key == multiTouchID[i]) {
multiTouchID[i] = 0; multiTouchID[i] = 0;
//qDebug() << "detach "<<key<<" ("<<map.valueToKey(key)<<") from "<<i;
return; return;
} }
} }
@ -220,6 +223,8 @@ int InputConvertGame::getTouchID(int key)
return -1; return -1;
} }
// -------- steer wheel event --------
void InputConvertGame::processSteerWheel(KeyMap::KeyMapNode &node, const QKeyEvent *from) void InputConvertGame::processSteerWheel(KeyMap::KeyMapNode &node, const QKeyEvent *from)
{ {
int keyPress1 = Qt::Key_unknown; int keyPress1 = Qt::Key_unknown;
@ -317,8 +322,16 @@ void InputConvertGame::steerWheelMove(KeyMap::KeyMapNode &node, int keysNum, int
return; return;
} }
QPointF movePos = node.steerWheel.centerPos; QPointF movePos = node.steerWheel.centerPos;
switch (keysNum) { if (keyPress1 == node.steerWheel.up.key) {
case 2: movePos.setY(movePos.y() - node.steerWheel.up.offset);
} else if (keyPress1 == node.steerWheel.right.key) {
movePos.setX(movePos.x() + node.steerWheel.right.offset);
} else if (keyPress1 == node.steerWheel.down.key) {
movePos.setY(movePos.y() + node.steerWheel.down.offset);
} else if (keyPress1 == node.steerWheel.left.key) {
movePos.setX(movePos.x() - node.steerWheel.left.offset);
}
if(keysNum > 1) {
if (keyPress2 == node.steerWheel.up.key) { if (keyPress2 == node.steerWheel.up.key) {
movePos.setY(movePos.y() - node.steerWheel.up.offset); movePos.setY(movePos.y() - node.steerWheel.up.offset);
} else if (keyPress2 == node.steerWheel.right.key) { } else if (keyPress2 == node.steerWheel.right.key) {
@ -328,21 +341,12 @@ void InputConvertGame::steerWheelMove(KeyMap::KeyMapNode &node, int keysNum, int
} else if (keyPress2 == node.steerWheel.left.key) { } else if (keyPress2 == node.steerWheel.left.key) {
movePos.setX(movePos.x() - node.steerWheel.left.offset); movePos.setX(movePos.x() - node.steerWheel.left.offset);
} }
case 1:
if (keyPress1 == node.steerWheel.up.key) {
movePos.setY(movePos.y() - node.steerWheel.up.offset);
} else if (keyPress1 == node.steerWheel.right.key) {
movePos.setX(movePos.x() + node.steerWheel.right.offset);
} else if (keyPress1 == node.steerWheel.down.key) {
movePos.setY(movePos.y() + node.steerWheel.down.offset);
} else if (keyPress1 == node.steerWheel.left.key) {
movePos.setX(movePos.x() - node.steerWheel.left.offset);
}
break;
} }
sendTouchMoveEvent(getTouchID(node.steerWheel.firstPressKey), movePos); sendTouchMoveEvent(getTouchID(node.steerWheel.firstPressKey), movePos);
} }
// -------- key event --------
void InputConvertGame::processKeyClick(QPointF clickPos, bool clickTwice, bool switchMap, const QKeyEvent *from) void InputConvertGame::processKeyClick(QPointF clickPos, bool clickTwice, bool switchMap, const QKeyEvent *from)
{ {
if (switchMap && QEvent::KeyRelease == from->type()) { if (switchMap && QEvent::KeyRelease == from->type()) {
@ -378,6 +382,8 @@ void InputConvertGame::processKeyDrag(QPointF startPos, QPointF endPos, const QK
} }
} }
// -------- mouse event --------
bool InputConvertGame::processMouseClick(const QMouseEvent *from) bool InputConvertGame::processMouseClick(const QMouseEvent *from)
{ {
KeyMap::KeyMapNode& node = m_keyMap.getKeyMapNodeMouse(from->button()); KeyMap::KeyMapNode& node = m_keyMap.getKeyMapNodeMouse(from->button());
@ -402,56 +408,51 @@ bool InputConvertGame::processMouseMove(const QMouseEvent *from)
if (QEvent::MouseMove != from->type()) { if (QEvent::MouseMove != from->type()) {
return false; return false;
} }
QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().startPos;
//qreal xbound = qMin(mmsp.x()-0.05, 0.95-mmsp.x());//m_keyMap.getMouseMoveMap().speedRatio;
//qreal ybound = qMin(mmsp.y()-0.05, 0.95-mmsp.y());//m_keyMap.getMouseMoveMap().speedRatio;
//qWarning() << from->localPos() << " - " << from->globalPos(); if(m_mouseMoving){
if (checkCursorPos(from)) { QPointF mousePos = from->localPos();
m_mouseMoveLastPos = QPointF(0.0, 0.0); mousePos.rx() /= m_showSize.width();
return true; mousePos.ry() /= m_showSize.height();
} QPointF offset = mousePos - mouseMoveStartPos;
//qDebug()<<from->localPos()<<" - "<<m_mouseMoveLastConverPos<<" - "<<offset<<" - "<<offset.manhattanLength();
if (!m_mouseMoveLastPos.isNull()) { //if (qAbs(offset.x()) > xbound || qAbs(offset.y()) > ybound)
QPointF distance = from->localPos() - m_mouseMoveLastPos; if(mousePos.x()<0.05 || mousePos.x()>0.95 || mousePos.y()<0.05 || mousePos.y()>0.95)
distance /= m_keyMap.getMouseMoveMap().speedRatio; {
//qDebug()<<"reset";
mouseMoveStartTouch(from);
//startMouseMoveTimer();
m_mouseMoveLastConverPos.setX(m_mouseMoveLastConverPos.x() + distance.x() / m_showSize.width());
m_mouseMoveLastConverPos.setY(m_mouseMoveLastConverPos.y() + distance.y() / m_showSize.height());
if (m_mouseMoveLastConverPos.x() < 0.1
|| m_mouseMoveLastConverPos.x() > 0.9
|| m_mouseMoveLastConverPos.y() < 0.1
|| m_mouseMoveLastConverPos.y() > 0.9) {
mouseMoveStopTouch(); mouseMoveStopTouch();
mouseMoveStartTouch(from); mouseMoveStartTouch(from);
} }
//qWarning() << "move: "<<m_mouseMoveLastConverPos; offset /= m_keyMap.getMouseMoveMap().speedRatio;
sendTouchMoveEvent(getTouchID(Qt::ExtraButton24), m_mouseMoveLastConverPos); m_mouseMoveLastConverPos = mouseMoveStartPos + offset;
mouseMoveMovingTouch(m_mouseMoveLastConverPos);
}else{
mouseMoveStartTouch(from);
int left = from->globalX() - from->x();
int top = from->globalY() - from->y();
restrictMouse(left, left + m_showSize.width(), top, top+m_showSize.height());
} }
m_mouseMoveLastPos = from->localPos();
return true; return true;
} }
void InputConvertGame::moveCursorToStart(const QMouseEvent *from) void InputConvertGame::moveCursorToStart(const QMouseEvent *from)
{ {
QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().startPos; QPointF mouseMoveStartPosF = m_keyMap.getMouseMoveMap().startPos;
QPoint localPos = QPoint(static_cast<int>(m_showSize.width()*mouseMoveStartPos.x()), QPointF mmspLocal = QPointF(
static_cast<int>(m_showSize.height()*mouseMoveStartPos.y())); m_showSize.width()*mouseMoveStartPosF.x(),
QPoint posOffset = from->localPos().toPoint() - localPos; m_showSize.height()*mouseMoveStartPosF.y());
QPoint globalPos = from->globalPos(); moveCursorTo(from, mmspLocal.toPoint());
globalPos -= posOffset;
QCursor::setPos(globalPos);
} }
void InputConvertGame::moveCursorTo(const QMouseEvent *from, const QPoint &pos) void InputConvertGame::moveCursorTo(const QMouseEvent *from, const QPoint &localPos)
{ {
QPoint posOffset = from->localPos().toPoint() - pos; QPoint posOffset = from->pos() - localPos;
QPoint globalPos = from->globalPos(); QPoint globalPos = from->globalPos();
globalPos -= posOffset; globalPos -= posOffset;
//qWarning() <<"move to: "<<globalPos; //qDebug()<<"move cursor to "<<globalPos<<" offset "<<posOffset;
QCursor::setPos(globalPos); QCursor::setPos(globalPos);
} }
@ -471,23 +472,30 @@ void InputConvertGame::stopMouseMoveTimer()
void InputConvertGame::mouseMoveStartTouch(const QMouseEvent* from) void InputConvertGame::mouseMoveStartTouch(const QMouseEvent* from)
{ {
Q_UNUSED(from) if (!m_mouseMoving) {
if (!m_mouseMovePress) {
QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().startPos; QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().startPos;
moveCursorToStart(from); moveCursorToStart(from);
int id = attachTouchID(Qt::ExtraButton24); int id = attachTouchID(Qt::ExtraButton24);
sendTouchDownEvent(id, mouseMoveStartPos); sendTouchDownEvent(id, mouseMoveStartPos);
m_mouseMoveLastConverPos = mouseMoveStartPos; m_mouseMoveLastConverPos = mouseMoveStartPos;
m_mouseMovePress = true; m_mouseMoving = true;
}
}
void InputConvertGame::mouseMoveMovingTouch(const QPointF& target)
{
if (m_mouseMoving) {
sendTouchMoveEvent(getTouchID(Qt::ExtraButton24), target);
} }
} }
void InputConvertGame::mouseMoveStopTouch() void InputConvertGame::mouseMoveStopTouch()
{ {
if (m_mouseMovePress) { if (m_mouseMoving) {
sendTouchUpEvent(getTouchID(Qt::ExtraButton24), m_mouseMoveLastConverPos); int id = getTouchID(Qt::ExtraButton24);
sendTouchUpEvent(id, m_mouseMoveLastConverPos);
detachTouchID(Qt::ExtraButton24); detachTouchID(Qt::ExtraButton24);
m_mouseMovePress = false; m_mouseMoving = false;
} }
} }
@ -496,37 +504,20 @@ bool InputConvertGame::switchGameMap()
m_gameMap = !m_gameMap; m_gameMap = !m_gameMap;
emit grabCursor(m_gameMap); emit grabCursor(m_gameMap);
if (m_gameMap) { if (m_gameMap) {
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor)); #ifdef QT_NO_DEBUG
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
#else
QGuiApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
#endif
//restrictMouse(); // called at the first run of processMouseMove()
} else { } else {
mouseMoveStopTouch(); mouseMoveStopTouch();
QGuiApplication::restoreOverrideCursor(); QGuiApplication::restoreOverrideCursor();
freeMouse();
} }
return m_gameMap; return m_gameMap;
} }
bool InputConvertGame::checkCursorPos(const QMouseEvent *from)
{
bool moveCursor = true;
QPoint pos = from->pos();
if (pos.x() < CURSOR_POS_CHECK) {
pos.setX(m_showSize.width() - CURSOR_POS_CHECK);
} else if (pos.x() > m_showSize.width() - CURSOR_POS_CHECK) {
pos.setX(CURSOR_POS_CHECK);
} else if (pos.y() < CURSOR_POS_CHECK) {
pos.setY(m_showSize.height() - CURSOR_POS_CHECK);
} else if (pos.y() > m_showSize.height() - CURSOR_POS_CHECK) {
pos.setY(CURSOR_POS_CHECK);
}else{
moveCursor = false;
}
if (moveCursor) {
moveCursorTo(from, pos);
}
return moveCursor;
}
void InputConvertGame::timerEvent(QTimerEvent *event) void InputConvertGame::timerEvent(QTimerEvent *event)
{ {
if (m_mouseMoveTimer == event->timerId()) { if (m_mouseMoveTimer == event->timerId()) {

View file

@ -48,14 +48,14 @@ protected:
bool processMouseClick(const QMouseEvent* from); bool processMouseClick(const QMouseEvent* from);
bool processMouseMove(const QMouseEvent* from); bool processMouseMove(const QMouseEvent* from);
void moveCursorToStart(const QMouseEvent* from); void moveCursorToStart(const QMouseEvent* from);
void moveCursorTo(const QMouseEvent* from, const QPoint& pos); void moveCursorTo(const QMouseEvent* from, const QPoint& localPos);
void startMouseMoveTimer(); void startMouseMoveTimer();
void stopMouseMoveTimer(); void stopMouseMoveTimer();
void mouseMoveStartTouch(const QMouseEvent* from); void mouseMoveStartTouch(const QMouseEvent* from);
void mouseMoveMovingTouch(const QPointF& target);
void mouseMoveStopTouch(); void mouseMoveStopTouch();
bool switchGameMap(); bool switchGameMap();
bool checkCursorPos(const QMouseEvent* from);
protected: protected:
void timerEvent(QTimerEvent *event); void timerEvent(QTimerEvent *event);
@ -75,10 +75,9 @@ private:
int multiTouchID[MULTI_TOUCH_MAX_NUM] = { 0 }; int multiTouchID[MULTI_TOUCH_MAX_NUM] = { 0 };
// mouse move // mouse move
QPointF m_mouseMoveLastConverPos; QPointF m_mouseMoveLastConverPos;
QPointF m_mouseMoveLastPos = {0.0, 0.0}; bool m_mouseMoving = false;
bool m_mouseMovePress = false;
int m_mouseMoveTimer = 0; int m_mouseMoveTimer = 0;
bool m_needSwitchGameAgain = false; bool m_needSwitchGameAgain = false;