feat: optimize keymap

This commit is contained in:
rankun 2020-01-30 19:03:25 +08:00
commit b4b7b0dc25
3 changed files with 219 additions and 199 deletions

View file

@ -73,10 +73,10 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize& frameSize, c
// 处理特殊按键:可以在按键映射和普通映射间切换的按键 // 处理特殊按键:可以在按键映射和普通映射间切换的按键
if (m_needSwitchGameAgain if (m_needSwitchGameAgain
&& KeyMap::KMT_CLICK == node.type && KeyMap::KMT_CLICK == node.type
&& node.click.switchMap) { && node.data.click.switchMap) {
updateSize(frameSize, showSize); updateSize(frameSize, showSize);
// Qt::Key_Tab Qt::Key_M for PUBG mobile // Qt::Key_Tab Qt::Key_M for PUBG mobile
processKeyClick(node.click.keyNode.pos, false, node.click.switchMap, from); processKeyClick(node.data.click.keyNode.pos, false, node.data.click.switchMap, from);
return; return;
} }
@ -93,13 +93,13 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize& frameSize, c
return; return;
// 处理普通按键 // 处理普通按键
case KeyMap::KMT_CLICK: case KeyMap::KMT_CLICK:
processKeyClick(node.click.keyNode.pos, false, node.click.switchMap, from); processKeyClick(node.data.click.keyNode.pos, false, node.data.click.switchMap, from);
return; return;
case KeyMap::KMT_CLICK_TWICE: case KeyMap::KMT_CLICK_TWICE:
processKeyClick(node.clickTwice.keyNode.pos, true, false, from); processKeyClick(node.data.clickTwice.keyNode.pos, true, false, from);
return; return;
case KeyMap::KMT_DRAG: case KeyMap::KMT_DRAG:
processKeyDrag(node.drag.startPos, node.drag.endPos, from); processKeyDrag(node.data.drag.keyNode.pos, node.data.drag.keyNode.extendPos, from);
return; return;
default: default:
break; break;
@ -115,7 +115,7 @@ void InputConvertGame::loadKeyMap(const QString &json)
if (m_keyMap.isValidMouseMoveMap()) { if (m_keyMap.isValidMouseMoveMap()) {
m_ctrlMouseMove.valid = true; m_ctrlMouseMove.valid = true;
m_ctrlMouseMove.touching = false; m_ctrlMouseMove.touching = false;
m_ctrlMouseMove.startPosRel = m_keyMap.getMouseMoveMap().startPos; m_ctrlMouseMove.startPosRel = m_keyMap.getMouseMoveMap().data.mouseMove.startPos;
m_ctrlMouseMove.startPosPixel = calcFrameAbsolutePos(m_ctrlMouseMove.startPosRel); m_ctrlMouseMove.startPosPixel = calcFrameAbsolutePos(m_ctrlMouseMove.startPosRel);
} }
if(m_keyMap.isValidSteerWheelMap()){ if(m_keyMap.isValidSteerWheelMap()){
@ -222,11 +222,11 @@ void InputConvertGame::processSteerWheel(const KeyMap::KeyMapNode &node, const Q
int key = from->key(); int key = from->key();
bool flag = from->type() == QEvent::KeyPress; bool flag = from->type() == QEvent::KeyPress;
// identify keys // identify keys
if(key == node.steerWheel.up.key){ if(key == node.data.steerWheel.up.key){
m_ctrlSteerWheel.pressedUp = flag; m_ctrlSteerWheel.pressedUp = flag;
}else if(key == node.steerWheel.right.key){ }else if(key == node.data.steerWheel.right.key){
m_ctrlSteerWheel.pressedRight = flag; m_ctrlSteerWheel.pressedRight = flag;
}else if(key == node.steerWheel.down.key){ }else if(key == node.data.steerWheel.down.key){
m_ctrlSteerWheel.pressedDown = flag; m_ctrlSteerWheel.pressedDown = flag;
}else{ // left }else{ // left
m_ctrlSteerWheel.pressedLeft = flag; m_ctrlSteerWheel.pressedLeft = flag;
@ -235,36 +235,36 @@ void InputConvertGame::processSteerWheel(const KeyMap::KeyMapNode &node, const Q
int nPressed = 0; int nPressed = 0;
if(m_ctrlSteerWheel.pressedUp){ if(m_ctrlSteerWheel.pressedUp){
++nPressed; ++nPressed;
offset.ry() -= node.steerWheel.up.offset; offset.ry() -= node.data.steerWheel.up.extendOffset;
} }
if(m_ctrlSteerWheel.pressedRight){ if(m_ctrlSteerWheel.pressedRight){
++nPressed; ++nPressed;
offset.rx() += node.steerWheel.right.offset; offset.rx() += node.data.steerWheel.right.extendOffset;
} }
if(m_ctrlSteerWheel.pressedDown){ if(m_ctrlSteerWheel.pressedDown){
++nPressed; ++nPressed;
offset.ry() += node.steerWheel.down.offset; offset.ry() += node.data.steerWheel.down.extendOffset;
} }
if(m_ctrlSteerWheel.pressedLeft){ if(m_ctrlSteerWheel.pressedLeft){
++nPressed; ++nPressed;
offset.rx() -= node.steerWheel.left.offset; offset.rx() -= node.data.steerWheel.left.extendOffset;
} }
// action // action
//qDebug()<<nPressed<<"-"<<char(from->key())<<"-"<<from->type()<<"-"<<offset; //qDebug()<<nPressed<<"-"<<char(from->key())<<"-"<<from->type()<<"-"<<offset;
if(nPressed == 0){ // release all if(nPressed == 0){ // release all
int id = getTouchID(m_ctrlSteerWheel.touchKey); int id = getTouchID(m_ctrlSteerWheel.touchKey);
sendTouchUpEvent(id, node.steerWheel.centerPos + m_ctrlSteerWheel.lastOffset); sendTouchUpEvent(id, node.data.steerWheel.centerPos + m_ctrlSteerWheel.lastOffset);
detachTouchID(m_ctrlSteerWheel.touchKey); detachTouchID(m_ctrlSteerWheel.touchKey);
}else{ }else{
int id; int id;
if(nPressed == 1 && flag){ // first press if(nPressed == 1 && flag){ // first press
m_ctrlSteerWheel.touchKey = from->key(); m_ctrlSteerWheel.touchKey = from->key();
id = attachTouchID(m_ctrlSteerWheel.touchKey); id = attachTouchID(m_ctrlSteerWheel.touchKey);
sendTouchDownEvent(id, node.steerWheel.centerPos); sendTouchDownEvent(id, node.data.steerWheel.centerPos);
}else{ }else{
id = getTouchID(m_ctrlSteerWheel.touchKey); id = getTouchID(m_ctrlSteerWheel.touchKey);
} }
sendTouchMoveEvent(id, node.steerWheel.centerPos + offset); sendTouchMoveEvent(id, node.data.steerWheel.centerPos + offset);
} }
m_ctrlSteerWheel.lastOffset = offset; m_ctrlSteerWheel.lastOffset = offset;
return; return;
@ -319,9 +319,9 @@ bool InputConvertGame::processMouseClick(const QMouseEvent *from)
if (QEvent::MouseButtonPress == from->type() || QEvent::MouseButtonDblClick == from->type()) { if (QEvent::MouseButtonPress == from->type() || QEvent::MouseButtonDblClick == from->type()) {
int id = attachTouchID(from->button()); int id = attachTouchID(from->button());
sendTouchDownEvent(id, node.click.keyNode.pos); sendTouchDownEvent(id, node.data.click.keyNode.pos);
} else if (QEvent::MouseButtonRelease == from->type()) { } else if (QEvent::MouseButtonRelease == from->type()) {
sendTouchUpEvent(getTouchID(from->button()), node.click.keyNode.pos); sendTouchUpEvent(getTouchID(from->button()), node.data.click.keyNode.pos);
detachTouchID(from->button()); detachTouchID(from->button());
} else { } else {
return false; return false;
@ -346,7 +346,7 @@ bool InputConvertGame::processMouseMove(const QMouseEvent *from)
mouseMoveStopTouch(); mouseMoveStopTouch();
mouseMoveStartTouch(from); mouseMoveStartTouch(from);
} }
offset /= m_keyMap.getMouseMoveMap().speedRatio; offset /= m_keyMap.getMouseMoveMap().data.mouseMove.speedRatio;
m_ctrlMouseMove.lastPosRel = m_ctrlMouseMove.startPosRel + offset; m_ctrlMouseMove.lastPosRel = m_ctrlMouseMove.startPosRel + offset;
mouseMoveMovingTouch(m_ctrlMouseMove.lastPosRel); mouseMoveMovingTouch(m_ctrlMouseMove.lastPosRel);
} else { } else {

View file

@ -1,6 +1,5 @@
#include <QFile> #include <QFile>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include <QMetaEnum> #include <QMetaEnum>
#include <QFileInfo> #include <QFileInfo>
@ -40,51 +39,57 @@ void KeyMap::loadKeyMap(const QString &json)
QJsonParseError jsonError; QJsonParseError jsonError;
QJsonDocument jsonDoc; QJsonDocument jsonDoc;
QJsonObject rootObj; QJsonObject rootObj;
QPair<ActionType, int> switchKey;
jsonDoc = QJsonDocument::fromJson(json.toUtf8(), &jsonError); jsonDoc = QJsonDocument::fromJson(json.toUtf8(), &jsonError);
if(jsonError.error != QJsonParseError::NoError) if(jsonError.error != QJsonParseError::NoError) {
{
errorString = QString("json error: %1").arg(jsonError.errorString()); errorString = QString("json error: %1").arg(jsonError.errorString());
goto parseError; goto parseError;
} }
// switchKey // switchKey
rootObj = jsonDoc.object(); rootObj = jsonDoc.object();
if (rootObj.contains("switchKey") && rootObj.value("switchKey").isString()) {
QPair<ActionType, int> p = getItemKey(rootObj, "switchKey"); if (!checkItemString(rootObj, "switchKey")) {
if(p.first == AT_INVALID){
errorString = QString("json error: switchKey invalid");
goto parseError;
}
m_switchType = p.first;
m_switchKey = p.second;
} else {
errorString = QString("json error: no find switchKey"); errorString = QString("json error: no find switchKey");
goto parseError; goto parseError;
} }
switchKey = getItemKey(rootObj, "switchKey");
if(switchKey.first == AT_INVALID) {
errorString = QString("json error: switchKey invalid");
goto parseError;
}
m_switchKey.type = switchKey.first;
m_switchKey.key= switchKey.second;
// mouseMoveMap // mouseMoveMap
if (rootObj.contains("mouseMoveMap") && rootObj.value("mouseMoveMap").isObject()) { if (checkItemObject(rootObj, "mouseMoveMap")) {
QJsonObject mouseMoveMap = rootObj.value("mouseMoveMap").toObject(); QJsonObject mouseMoveMap = getItemObject(rootObj, "mouseMoveMap");
if (mouseMoveMap.contains("speedRatio") && mouseMoveMap.value("speedRatio").isDouble()) { KeyMapNode keyMapNode;
m_mouseMoveMap.speedRatio = mouseMoveMap.value("speedRatio").toInt(); keyMapNode.type = KMT_MOUSE_MOVE;
} else {
if (!checkItemDouble(mouseMoveMap, "speedRatio")) {
errorString = QString("json error: mouseMoveMap on find speedRatio"); errorString = QString("json error: mouseMoveMap on find speedRatio");
goto parseError; goto parseError;
} }
if (mouseMoveMap.contains("startPos") && mouseMoveMap.value("startPos").isObject()) { keyMapNode.data.mouseMove.speedRatio = static_cast<int>(getItemDouble(mouseMoveMap, "speedRatio"));
QJsonObject startPos = mouseMoveMap.value("startPos").toObject();
if (startPos.contains("x") && startPos.value("x").isDouble()) { if (!checkItemObject(mouseMoveMap, "startPos")) {
m_mouseMoveMap.startPos.setX(startPos.value("x").toDouble());
}
if (startPos.contains("y") && startPos.value("y").isDouble()) {
m_mouseMoveMap.startPos.setY(startPos.value("y").toDouble());
}
} else {
errorString = QString("json error: mouseMoveMap on find startPos"); errorString = QString("json error: mouseMoveMap on find startPos");
goto parseError; goto parseError;
} }
QJsonObject startPos = mouseMoveMap.value("startPos").toObject();
if (checkItemDouble(startPos, "x")) {
keyMapNode.data.mouseMove.startPos.setX(getItemDouble(startPos, "x"));
}
if (checkItemDouble(startPos, "y")) {
keyMapNode.data.mouseMove.startPos.setY(getItemDouble(startPos, "y"));
}
m_idxMouseMove = m_keyMapNodes.size();
m_keyMapNodes.push_back(keyMapNode);
} }
// keyMapNodes // keyMapNodes
@ -103,7 +108,7 @@ void KeyMap::loadKeyMap(const QString &json)
goto parseError; goto parseError;
} }
KeyMap::KeyMapType type = getItemType(node, "type"); KeyMap::KeyMapType type = getItemKeyMapType(node, "type");
switch (type) { switch (type) {
case KeyMap::KMT_CLICK: case KeyMap::KMT_CLICK:
{ {
@ -113,16 +118,16 @@ void KeyMap::loadKeyMap(const QString &json)
break; break;
} }
QPair<ActionType, int> key = getItemKey(node, "key"); QPair<ActionType, int> key = getItemKey(node, "key");
if(key.first == AT_INVALID){ if (key.first == AT_INVALID) {
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString(); qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString();
break; break;
} }
KeyMapNode keyMapNode; KeyMapNode keyMapNode;
keyMapNode.type = type; keyMapNode.type = type;
keyMapNode.click.keyNode.type = key.first; keyMapNode.data.click.keyNode.type = key.first;
keyMapNode.click.keyNode.key = key.second; keyMapNode.data.click.keyNode.key = key.second;
keyMapNode.click.keyNode.pos = getItemPos(node, "pos"); keyMapNode.data.click.keyNode.pos = getItemPos(node, "pos");
keyMapNode.click.switchMap = getItemSwitchMap(node, "switchMap"); keyMapNode.data.click.switchMap = getItemBool(node, "switchMap");
m_keyMapNodes.push_back(keyMapNode); m_keyMapNodes.push_back(keyMapNode);
} }
break; break;
@ -135,23 +140,23 @@ void KeyMap::loadKeyMap(const QString &json)
} }
QPair<ActionType, int> key = getItemKey(node, "key"); QPair<ActionType, int> key = getItemKey(node, "key");
if(key.first == AT_INVALID){ if (key.first == AT_INVALID) {
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString(); qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString();
break; break;
} }
KeyMapNode keyMapNode; KeyMapNode keyMapNode;
keyMapNode.type = type; keyMapNode.type = type;
keyMapNode.click.keyNode.type = key.first; keyMapNode.data.click.keyNode.type = key.first;
keyMapNode.click.keyNode.key = key.second; keyMapNode.data.click.keyNode.key = key.second;
keyMapNode.click.keyNode.pos = getItemPos(node, "pos"); keyMapNode.data.click.keyNode.pos = getItemPos(node, "pos");
keyMapNode.click.switchMap = getItemSwitchMap(node, "switchMap"); keyMapNode.data.click.switchMap = getItemBool(node, "switchMap");
m_keyMapNodes.push_back(keyMapNode); m_keyMapNodes.push_back(keyMapNode);
} }
break; break;
case KeyMap::KMT_STEER_WHEEL: case KeyMap::KMT_STEER_WHEEL:
{ {
// safe check // safe check
if(!checkForSteerWhell(node)){ if (!checkForSteerWhell(node)) {
qWarning() << "json error: keyMapNodes node format error"; qWarning() << "json error: keyMapNodes node format error";
break; break;
} }
@ -159,33 +164,40 @@ void KeyMap::loadKeyMap(const QString &json)
QPair<ActionType, int> rightKey = getItemKey(node, "rightKey"); QPair<ActionType, int> rightKey = getItemKey(node, "rightKey");
QPair<ActionType, int> upKey = getItemKey(node, "upKey"); QPair<ActionType, int> upKey = getItemKey(node, "upKey");
QPair<ActionType, int> downKey = getItemKey(node, "downKey"); QPair<ActionType, int> downKey = getItemKey(node, "downKey");
if(leftKey.first == AT_INVALID || rightKey.first == AT_INVALID if (leftKey.first == AT_INVALID || rightKey.first == AT_INVALID
|| upKey.first == AT_INVALID || downKey.first == AT_INVALID) || upKey.first == AT_INVALID || downKey.first == AT_INVALID) {
{ if (leftKey.first == AT_INVALID) {
if(leftKey.first == AT_INVALID)
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("leftKey").toString(); qWarning() << "json error: keyMapNodes node invalid key: " << node.value("leftKey").toString();
if(rightKey.first == AT_INVALID) }
if (rightKey.first == AT_INVALID) {
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("rightKey").toString(); qWarning() << "json error: keyMapNodes node invalid key: " << node.value("rightKey").toString();
if(upKey.first == AT_INVALID) }
if (upKey.first == AT_INVALID) {
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("upKey").toString(); qWarning() << "json error: keyMapNodes node invalid key: " << node.value("upKey").toString();
if(downKey.first == AT_INVALID) }
if (downKey.first == AT_INVALID) {
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("downKey").toString(); qWarning() << "json error: keyMapNodes node invalid key: " << node.value("downKey").toString();
}
break; break;
} }
KeyMapNode keyMapNode; KeyMapNode keyMapNode;
keyMapNode.type = type; keyMapNode.type = type;
keyMapNode.steerWheel.left = { leftKey.first, leftKey.second, keyMapNode.data.steerWheel.left = { leftKey.first, leftKey.second,
getItemNumber(node, "leftOffset") }; QPointF(0, 0), QPointF(0, 0),
keyMapNode.steerWheel.right = { rightKey.first, rightKey.second, getItemDouble(node, "leftOffset") };
getItemNumber(node, "rightOffset") }; keyMapNode.data.steerWheel.right = { rightKey.first, rightKey.second,
keyMapNode.steerWheel.up = { upKey.first, upKey.second, QPointF(0, 0), QPointF(0, 0),
getItemNumber(node, "upOffset") }; getItemDouble(node, "rightOffset") };
keyMapNode.steerWheel.down = { downKey.first, downKey.second, keyMapNode.data.steerWheel.up = { upKey.first, upKey.second,
getItemNumber(node, "downOffset") }; QPointF(0, 0), QPointF(0, 0),
getItemDouble(node, "upOffset") };
keyMapNode.data.steerWheel.down = { downKey.first, downKey.second,
QPointF(0, 0), QPointF(0, 0),
getItemDouble(node, "downOffset") };
keyMapNode.steerWheel.centerPos = getItemPos(node, "centerPos"); keyMapNode.data.steerWheel.centerPos = getItemPos(node, "centerPos");
m_idxSteerWheel = m_keyMapNodes.size(); m_idxSteerWheel = m_keyMapNodes.size();
m_keyMapNodes.push_back(keyMapNode); m_keyMapNodes.push_back(keyMapNode);
} }
@ -193,22 +205,22 @@ void KeyMap::loadKeyMap(const QString &json)
case KeyMap::KMT_DRAG: case KeyMap::KMT_DRAG:
{ {
// safe check // safe check
if(!checkForDrag(node)){ if (!checkForDrag(node)) {
qWarning() << "json error: keyMapNodes node format error"; qWarning() << "json error: keyMapNodes node format error";
break; break;
} }
QPair<ActionType, int> key = getItemKey(node, "key"); QPair<ActionType, int> key = getItemKey(node, "key");
if(key.first == AT_INVALID){ if (key.first == AT_INVALID) {
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString(); qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString();
break; break;
} }
KeyMapNode keyMapNode; KeyMapNode keyMapNode;
keyMapNode.type = type; keyMapNode.type = type;
keyMapNode.drag.type = key.first; keyMapNode.data.drag.keyNode.type = key.first;
keyMapNode.drag.key = key.second; keyMapNode.data.drag.keyNode.key = key.second;
keyMapNode.drag.startPos = getItemPos(node, "startPos"); keyMapNode.data.drag.keyNode.pos = getItemPos(node, "startPos");
keyMapNode.drag.endPos = getItemPos(node, "endPos"); keyMapNode.data.drag.keyNode.extendPos = getItemPos(node, "endPos");
m_keyMapNodes.push_back(keyMapNode); m_keyMapNodes.push_back(keyMapNode);
break; break;
} }
@ -220,7 +232,7 @@ void KeyMap::loadKeyMap(const QString &json)
} }
// this must be called after m_keyMapNodes is stable // this must be called after m_keyMapNodes is stable
makeReverseMap(); makeReverseMap();
qWarning() << "Script updated."; qInfo() << "Script updated.";
parseError: parseError:
if (!errorString.isEmpty()) { if (!errorString.isEmpty()) {
@ -231,45 +243,41 @@ parseError:
const KeyMap::KeyMapNode& KeyMap::getKeyMapNode(int key) const KeyMap::KeyMapNode& KeyMap::getKeyMapNode(int key)
{ {
auto p = rmapKey.value(key, &m_invalidNode); auto p = m_rmapKey.value(key, &m_invalidNode);
if(p == &m_invalidNode) if (p == &m_invalidNode) {
return *rmapMouse.value(key, &m_invalidNode); return *m_rmapMouse.value(key, &m_invalidNode);
}
return *p; return *p;
} }
const KeyMap::KeyMapNode& KeyMap::getKeyMapNodeKey(int key) const KeyMap::KeyMapNode& KeyMap::getKeyMapNodeKey(int key)
{ {
return *rmapKey.value(key, &m_invalidNode); return *m_rmapKey.value(key, &m_invalidNode);
} }
const KeyMap::KeyMapNode& KeyMap::getKeyMapNodeMouse(int key) const KeyMap::KeyMapNode& KeyMap::getKeyMapNodeMouse(int key)
{ {
return *rmapMouse.value(key, &m_invalidNode); return *m_rmapMouse.value(key, &m_invalidNode);
} }
bool KeyMap::isSwitchOnKeyboard() bool KeyMap::isSwitchOnKeyboard()
{ {
return m_switchType == AT_KEY; return m_switchKey.type == AT_KEY;
} }
int KeyMap::getSwitchKey() int KeyMap::getSwitchKey()
{ {
return m_switchKey; return m_switchKey.key;
} }
const KeyMap::MouseMoveMap& KeyMap::getMouseMoveMap() const KeyMap::KeyMapNode& KeyMap::getMouseMoveMap()
{ {
return m_mouseMoveMap; return m_keyMapNodes[m_idxMouseMove];
}
const KeyMap::KeyMapNode& KeyMap::getSteerWheelMap()
{
return m_keyMapNodes[m_idxSteerWheel];
} }
bool KeyMap::isValidMouseMoveMap() bool KeyMap::isValidMouseMoveMap()
{ {
return !m_mouseMoveMap.startPos.isNull(); return m_idxMouseMove != -1;
} }
bool KeyMap::isValidSteerWheelMap() bool KeyMap::isValidSteerWheelMap()
@ -279,39 +287,39 @@ bool KeyMap::isValidSteerWheelMap()
void KeyMap::makeReverseMap() void KeyMap::makeReverseMap()
{ {
rmapKey.clear(); m_rmapKey.clear();
rmapMouse.clear(); m_rmapMouse.clear();
for(int i = 0 ;i < m_keyMapNodes.size(); ++i) { for (int i = 0 ; i < m_keyMapNodes.size(); ++i) {
auto& node = m_keyMapNodes[i]; auto& node = m_keyMapNodes[i];
switch (node.type) { switch (node.type) {
case KMT_CLICK: case KMT_CLICK:
{ {
QMultiHash<int, KeyMapNode*>& m = node.click.keyNode.type == AT_KEY ? rmapKey : rmapMouse; QMultiHash<int, KeyMapNode*>& m = node.data.click.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
m.insert(node.click.keyNode.key, &node); m.insert(node.data.click.keyNode.key, &node);
} }
break; break;
case KMT_CLICK_TWICE: case KMT_CLICK_TWICE:
{ {
QMultiHash<int, KeyMapNode*>& m = node.clickTwice.keyNode.type == AT_KEY ? rmapKey : rmapMouse; QMultiHash<int, KeyMapNode*>& m = node.data.clickTwice.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
m.insert(node.clickTwice.keyNode.key, &node); m.insert(node.data.clickTwice.keyNode.key, &node);
} }
break; break;
case KMT_STEER_WHEEL: case KMT_STEER_WHEEL:
{ {
QMultiHash<int, KeyMapNode*>& ml = node.steerWheel.left.type == AT_KEY ? rmapKey : rmapMouse; QMultiHash<int, KeyMapNode*>& ml = node.data.steerWheel.left.type == AT_KEY ? m_rmapKey : m_rmapMouse;
ml.insert(node.steerWheel.left.key, &node); ml.insert(node.data.steerWheel.left.key, &node);
QMultiHash<int, KeyMapNode*>& mr = node.steerWheel.right.type == AT_KEY ? rmapKey : rmapMouse; QMultiHash<int, KeyMapNode*>& mr = node.data.steerWheel.right.type == AT_KEY ? m_rmapKey : m_rmapMouse;
mr.insert(node.steerWheel.right.key, &node); mr.insert(node.data.steerWheel.right.key, &node);
QMultiHash<int, KeyMapNode*>& mu = node.steerWheel.up.type == AT_KEY ? rmapKey : rmapMouse; QMultiHash<int, KeyMapNode*>& mu = node.data.steerWheel.up.type == AT_KEY ? m_rmapKey : m_rmapMouse;
mu.insert(node.steerWheel.up.key, &node); mu.insert(node.data.steerWheel.up.key, &node);
QMultiHash<int, KeyMapNode*>& md = node.steerWheel.down.type == AT_KEY ? rmapKey : rmapMouse; QMultiHash<int, KeyMapNode*>& md = node.data.steerWheel.down.type == AT_KEY ? m_rmapKey : m_rmapMouse;
md.insert(node.steerWheel.down.key, &node); md.insert(node.data.steerWheel.down.key, &node);
} }
break; break;
case KMT_DRAG: case KMT_DRAG:
{ {
QMultiHash<int, KeyMapNode*>& m = node.drag.type == AT_KEY ? rmapKey : rmapMouse; QMultiHash<int, KeyMapNode*>& m = node.data.drag.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
m.insert(node.drag.key, &node); m.insert(node.data.drag.keyNode.key, &node);
} }
break; break;
default: default:
@ -320,51 +328,24 @@ void KeyMap::makeReverseMap()
} }
} }
// ---- check and get of json item ---- QString KeyMap::getItemString(const QJsonObject &node, const QString &name)
bool KeyMap::checkItemKey(const QJsonObject& node, const QString& name)
{ {
return node.contains(name) && node.value(name).isString(); return node.value(name).toString();
} }
bool KeyMap::checkItemPos(const QJsonObject& node, const QString& name) double KeyMap::getItemDouble(const QJsonObject& node, const QString& name)
{ {
if(node.contains(name) && node.value(name).isObject()){ return node.value(name).toDouble();
QJsonObject pos = node.value(name).toObject();
return pos.contains("x") && pos.value("x").isDouble()
&& pos.contains("y") && pos.value("y").isDouble();
}
return false;
} }
bool KeyMap::checkItemDouble(const QJsonObject& node, const QString& name) bool KeyMap::getItemBool(const QJsonObject& node, const QString& name)
{ {
return node.contains(name) && node.value(name).isDouble(); return node.value(name).toBool(false);
} }
bool KeyMap::checkItemSwitchMap(const QJsonObject& node, const QString& name) QJsonObject KeyMap::getItemObject(const QJsonObject &node, const QString &name)
{ {
return !node.contains(name) || node.value(name).isBool(); return node.value(name).toObject();
}
KeyMap::KeyMapType KeyMap::getItemType(const QJsonObject& node, const QString& name)
{
QString value = node.value(name).toString();
return static_cast<KeyMap::KeyMapType>(m_metaEnumKeyMapType.keyToValue(value.toStdString().c_str()));
}
QPair<KeyMap::ActionType, int> KeyMap::getItemKey(const QJsonObject& node, const QString& name)
{
QString value = node.value(name).toString();
int key = m_metaEnumKey.keyToValue(value.toStdString().c_str());
int btn = m_metaEnumMouseButtons.keyToValue(value.toStdString().c_str());
if(key == -1 && btn == -1){
return {AT_INVALID, -1};
}else if(key != -1){
return {AT_KEY, key};
}else{
return {AT_MOUSE, btn};
}
} }
QPointF KeyMap::getItemPos(const QJsonObject& node, const QString& name) QPointF KeyMap::getItemPos(const QJsonObject& node, const QString& name)
@ -373,23 +354,60 @@ QPointF KeyMap::getItemPos(const QJsonObject& node, const QString& name)
return QPointF(pos.value("x").toDouble(), pos.value("y").toDouble()); return QPointF(pos.value("x").toDouble(), pos.value("y").toDouble());
} }
double KeyMap::getItemNumber(const QJsonObject& node, const QString& name) QPair<KeyMap::ActionType, int> KeyMap::getItemKey(const QJsonObject& node, const QString& name)
{ {
return node.value(name).toDouble(); QString value = getItemString(node, name);
int key = m_metaEnumKey.keyToValue(value.toStdString().c_str());
int btn = m_metaEnumMouseButtons.keyToValue(value.toStdString().c_str());
if (key == -1 && btn == -1) {
return {AT_INVALID, -1};
} else if (key != -1) {
return {AT_KEY, key};
} else {
return {AT_MOUSE, btn};
}
} }
bool KeyMap::getItemSwitchMap(const QJsonObject& node, const QString& name) KeyMap::KeyMapType KeyMap::getItemKeyMapType(const QJsonObject& node, const QString& name)
{ {
return node.value(name).toBool(false); QString value = getItemString(node, name);
return static_cast<KeyMap::KeyMapType>(m_metaEnumKeyMapType.keyToValue(value.toStdString().c_str()));
} }
bool KeyMap::checkItemString(const QJsonObject& node, const QString& name)
{
return node.contains(name) && node.value(name).isString();
}
// ---- check for key-map node ---- bool KeyMap::checkItemDouble(const QJsonObject& node, const QString& name)
{
return node.contains(name) && node.value(name).isDouble();
}
bool KeyMap::checkItemBool(const QJsonObject& node, const QString& name)
{
return !node.contains(name) || node.value(name).isBool();
}
bool KeyMap::checkItemObject(const QJsonObject &node, const QString &name)
{
return !node.contains(name) || node.value(name).isObject();
}
bool KeyMap::checkItemPos(const QJsonObject& node, const QString& name)
{
if (node.contains(name) && node.value(name).isObject()) {
QJsonObject pos = node.value(name).toObject();
return pos.contains("x") && pos.value("x").isDouble()
&& pos.contains("y") && pos.value("y").isDouble();
}
return false;
}
bool KeyMap::checkForClick(const QJsonObject& node) bool KeyMap::checkForClick(const QJsonObject& node)
{ {
return checkItemKey(node, "key") && checkItemPos(node, "pos") return checkItemString(node, "key") && checkItemPos(node, "pos")
&& checkItemSwitchMap(node, "switchMap"); && checkItemBool(node, "switchMap");
} }
bool KeyMap::checkForClickDouble(const QJsonObject& node) bool KeyMap::checkForClickDouble(const QJsonObject& node)
@ -399,8 +417,8 @@ bool KeyMap::checkForClickDouble(const QJsonObject& node)
bool KeyMap::checkForSteerWhell(const QJsonObject& node) bool KeyMap::checkForSteerWhell(const QJsonObject& node)
{ {
return checkItemKey(node, "leftKey") && checkItemKey(node, "rightKey") return checkItemString(node, "leftKey") && checkItemString(node, "rightKey")
&& checkItemKey(node, "upKey") && checkItemKey(node, "downKey") && checkItemString(node, "upKey") && checkItemString(node, "downKey")
&& checkItemDouble(node, "leftOffset") && checkItemDouble(node, "rightOffset") && checkItemDouble(node, "leftOffset") && checkItemDouble(node, "rightOffset")
&& checkItemDouble(node, "upOffset") && checkItemDouble(node, "downOffset") && checkItemDouble(node, "upOffset") && checkItemDouble(node, "downOffset")
&& checkItemPos(node, "centerPos"); && checkItemPos(node, "centerPos");
@ -408,8 +426,7 @@ bool KeyMap::checkForSteerWhell(const QJsonObject& node)
bool KeyMap::checkForDrag(const QJsonObject& node) bool KeyMap::checkForDrag(const QJsonObject& node)
{ {
return checkItemKey(node, "key") return checkItemString(node, "key")
&& checkItemPos(node, "startPos") && checkItemPos(node, "endPos") && checkItemPos(node, "startPos") && checkItemPos(node, "endPos");
&& checkItemSwitchMap(node, "switchMap");
} }

View file

@ -7,8 +7,7 @@
#include <QPair> #include <QPair>
#include <QMetaEnum> #include <QMetaEnum>
#include <QMultiHash> #include <QMultiHash>
#include <QJsonObject>
class QJsonObject;
class KeyMap : public QObject class KeyMap : public QObject
{ {
@ -20,6 +19,7 @@ public:
KMT_CLICK_TWICE, KMT_CLICK_TWICE,
KMT_STEER_WHEEL, KMT_STEER_WHEEL,
KMT_DRAG, KMT_DRAG,
KMT_MOUSE_MOVE
}; };
Q_ENUM(KeyMapType) Q_ENUM(KeyMapType)
@ -33,12 +33,14 @@ public:
struct KeyNode { struct KeyNode {
ActionType type = AT_INVALID; ActionType type = AT_INVALID;
int key = Qt::Key_unknown; int key = Qt::Key_unknown;
QPointF pos = QPointF(0, 0); QPointF pos = QPointF(0, 0); // normal key
QPointF extendPos = QPointF(0, 0); // for drag
double extendOffset = 0.0; // for steerWheel
}; };
struct KeyMapNode { struct KeyMapNode {
KeyMapType type = KMT_INVALID; KeyMapType type = KMT_INVALID;
union { union DATA {
struct { struct {
KeyNode keyNode; KeyNode keyNode;
bool switchMap = false; bool switchMap = false;
@ -48,27 +50,20 @@ public:
} clickTwice; } clickTwice;
struct { struct {
QPointF centerPos = {0.0, 0.0}; QPointF centerPos = {0.0, 0.0};
struct DirInfo{ KeyNode left, right, up, down;
ActionType type = AT_KEY; // keyboard/mouse
int key = Qt::Key_unknown; // key/button
double offset = 0.0;
};
DirInfo left, right, up, down;
} steerWheel; } steerWheel;
struct { struct {
ActionType type = AT_KEY; KeyNode keyNode;
int key = Qt::Key_unknown;
QPointF startPos = QPointF(0, 0);
QPointF endPos = QPointF(0, 0);
} drag; } drag;
}; struct {
KeyMapNode() {}
~KeyMapNode() {}
};
struct MouseMoveMap {
QPointF startPos = {0.0, 0.0}; QPointF startPos = {0.0, 0.0};
int speedRatio = 1; int speedRatio = 1;
} mouseMove;
DATA() {}
~DATA() {}
} data;
KeyMapNode() {}
~KeyMapNode() {}
}; };
KeyMap(QObject *parent = Q_NULLPTR); KeyMap(QObject *parent = Q_NULLPTR);
@ -83,8 +78,7 @@ public:
bool isValidMouseMoveMap(); bool isValidMouseMoveMap();
bool isValidSteerWheelMap(); bool isValidSteerWheelMap();
const MouseMoveMap& getMouseMoveMap(); const KeyMap::KeyMapNode& getMouseMoveMap();
const KeyMapNode& getSteerWheelMap();
static const QString& getKeyMapPath(); static const QString& getKeyMapPath();
@ -92,41 +86,50 @@ private:
// set up the reverse map from key/event event to keyMapNode // set up the reverse map from key/event event to keyMapNode
void makeReverseMap(); void makeReverseMap();
// parse json of the mapping script // safe check for base
bool checkItemKey(const QJsonObject& node, const QString& name="key"); bool checkItemString(const QJsonObject& node, const QString& name);
bool checkItemPos(const QJsonObject& node, const QString& name="pos");
bool checkItemDouble(const QJsonObject& node, const QString& name); bool checkItemDouble(const QJsonObject& node, const QString& name);
bool checkItemSwitchMap(const QJsonObject& node, const QString& name="switchMap"); bool checkItemBool(const QJsonObject& node, const QString& name);
bool checkItemObject(const QJsonObject& node, const QString& name);
bool checkItemPos(const QJsonObject& node, const QString& name);
KeyMapType getItemType(const QJsonObject& node, const QString& name="type"); // safe check for KeyMapNode
QPair<ActionType, int> getItemKey(const QJsonObject& node, const QString& name="key");
QPointF getItemPos(const QJsonObject& node, const QString& name="pos");
double getItemNumber(const QJsonObject& node, const QString& name);
bool getItemSwitchMap(const QJsonObject& node, const QString& name="switchMap");
private:
bool checkForClick(const QJsonObject& node); bool checkForClick(const QJsonObject& node);
bool checkForClickDouble(const QJsonObject& node); bool checkForClickDouble(const QJsonObject& node);
bool checkForSteerWhell(const QJsonObject& node); bool checkForSteerWhell(const QJsonObject& node);
bool checkForDrag(const QJsonObject& node); bool checkForDrag(const QJsonObject& node);
// get keymap from json object
QString getItemString(const QJsonObject& node, const QString& name);
double getItemDouble(const QJsonObject& node, const QString& name);
bool getItemBool(const QJsonObject& node, const QString& name);
QJsonObject getItemObject(const QJsonObject& node, const QString& name);
QPointF getItemPos(const QJsonObject& node, const QString& name);
QPair<ActionType, int> getItemKey(const QJsonObject& node, const QString& name);
KeyMapType getItemKeyMapType(const QJsonObject& node, const QString& name);
private: private:
QVector<KeyMapNode> m_keyMapNodes;
KeyMapNode m_invalidNode;
ActionType m_switchType = AT_KEY;
int m_switchKey = Qt::Key_QuoteLeft;
MouseMoveMap m_mouseMoveMap;
static QString s_keyMapPath; static QString s_keyMapPath;
QVector<KeyMapNode> m_keyMapNodes;
KeyNode m_switchKey = { AT_KEY, Qt::Key_QuoteLeft };
// just for return
KeyMapNode m_invalidNode;
// steer wheel index
int m_idxSteerWheel = -1; int m_idxSteerWheel = -1;
// mouse move index
int m_idxMouseMove = -1;
// mapping of key/mouse event name to index // mapping of key/mouse event name to index
QMetaEnum m_metaEnumKey = QMetaEnum::fromType<Qt::Key>(); QMetaEnum m_metaEnumKey = QMetaEnum::fromType<Qt::Key>();
QMetaEnum m_metaEnumMouseButtons = QMetaEnum::fromType<Qt::MouseButtons>(); QMetaEnum m_metaEnumMouseButtons = QMetaEnum::fromType<Qt::MouseButtons>();
QMetaEnum m_metaEnumKeyMapType = QMetaEnum::fromType<KeyMap::KeyMapType>(); QMetaEnum m_metaEnumKeyMapType = QMetaEnum::fromType<KeyMap::KeyMapType>();
// reverse map of key/mouse event // reverse map of key/mouse event
QMultiHash<int, KeyMapNode*> rmapKey; QMultiHash<int, KeyMapNode*> m_rmapKey;
QMultiHash<int, KeyMapNode*> rmapMouse; QMultiHash<int, KeyMapNode*> m_rmapMouse;
}; };
#endif // KEYMAP_H #endif // KEYMAP_H