Skip to content

Commit e499cf9

Browse files
authored
Merge pull request #263 from barry-ran/dev
Dev
2 parents b2d947f + 9290348 commit e499cf9

File tree

13 files changed

+231
-14
lines changed

13 files changed

+231
-14
lines changed

QtScrcpy/device/controller/controller.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ void Controller::updateScript(QString gameScript)
5656
connect(m_inputConvert, &InputConvertBase::grabCursor, this, &Controller::grabCursor);
5757
}
5858

59+
bool Controller::isCurrentCustomKeymap()
60+
{
61+
if (!m_inputConvert) {
62+
return false;
63+
}
64+
65+
return m_inputConvert->isCurrentCustomKeymap();
66+
}
67+
5968
void Controller::onPostBackOrScreenOn()
6069
{
6170
ControlMsg *controlMsg = new ControlMsg(ControlMsg::CMT_BACK_OR_SCREEN_ON);

QtScrcpy/device/controller/controller.h

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class Controller : public QObject
2121
void test(QRect rc);
2222

2323
void updateScript(QString gameScript = "");
24+
bool isCurrentCustomKeymap();
2425

2526
public slots:
2627
void onPostGoBack();

QtScrcpy/device/controller/inputconvert/inputconvertbase.h

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ class InputConvertBase : public QObject
2121
virtual void mouseEvent(const QMouseEvent *from, const QSize &frameSize, const QSize &showSize) = 0;
2222
virtual void wheelEvent(const QWheelEvent *from, const QSize &frameSize, const QSize &showSize) = 0;
2323
virtual void keyEvent(const QKeyEvent *from, const QSize &frameSize, const QSize &showSize) = 0;
24+
virtual bool isCurrentCustomKeymap()
25+
{
26+
return false;
27+
};
2428

2529
signals:
2630
void grabCursor(bool grab);

QtScrcpy/device/controller/inputconvert/inputconvertgame.cpp

+50-6
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize &frameSize, c
7878
}
7979

8080
// small eyes
81-
if (from->key() == m_keyMap.getMouseMoveMap().data.mouseMove.smallEyes.key) {
81+
if (m_keyMap.isValidMouseMoveMap() && from->key() == m_keyMap.getMouseMoveMap().data.mouseMove.smallEyes.key) {
8282
m_ctrlMouseMove.smallEyes = (QEvent::KeyPress == from->type());
8383

8484
if (QEvent::KeyPress == from->type()) {
@@ -110,6 +110,9 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize &frameSize, c
110110
case KeyMap::KMT_CLICK_TWICE:
111111
processKeyClick(node.data.clickTwice.keyNode.pos, true, false, from);
112112
return;
113+
case KeyMap::KMT_CLICK_MULTI:
114+
processKeyClickMulti(node.data.clickMulti.keyNode.delayClickNodes, node.data.clickMulti.keyNode.delayClickNodesCount, from);
115+
return;
113116
case KeyMap::KMT_DRAG:
114117
processKeyDrag(node.data.drag.keyNode.pos, node.data.drag.keyNode.extendPos, from);
115118
return;
@@ -121,6 +124,11 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize &frameSize, c
121124
}
122125
}
123126

127+
bool InputConvertGame::isCurrentCustomKeymap()
128+
{
129+
return m_gameMap;
130+
}
131+
124132
void InputConvertGame::loadKeyMap(const QString &json)
125133
{
126134
m_keyMap.loadKeyMap(json);
@@ -164,8 +172,15 @@ void InputConvertGame::sendTouchEvent(int id, QPointF pos, AndroidMotioneventAct
164172
if (!controlMsg) {
165173
return;
166174
}
167-
controlMsg->setInjectTouchMsgData(
168-
static_cast<quint64>(id), action, static_cast<AndroidMotioneventButtons>(0), QRect(calcFrameAbsolutePos(pos).toPoint(), m_frameSize), 1.0f);
175+
176+
QPoint absolutePos = calcFrameAbsolutePos(pos).toPoint();
177+
static QPoint lastAbsolutePos = absolutePos;
178+
if (AMOTION_EVENT_ACTION_MOVE == action && lastAbsolutePos == absolutePos) {
179+
return;
180+
}
181+
lastAbsolutePos = absolutePos;
182+
183+
controlMsg->setInjectTouchMsgData(static_cast<quint64>(id), action, static_cast<AndroidMotioneventButtons>(0), QRect(absolutePos, m_frameSize), 1.0f);
169184
sendControlMsg(controlMsg);
170185
}
171186

@@ -302,6 +317,34 @@ void InputConvertGame::processKeyClick(const QPointF &clickPos, bool clickTwice,
302317
}
303318
}
304319

320+
void InputConvertGame::processKeyClickMulti(const KeyMap::DelayClickNode *nodes, const int count, const QKeyEvent *from)
321+
{
322+
if (QEvent::KeyPress != from->type()) {
323+
return;
324+
}
325+
326+
int key = from->key();
327+
int delay = 0;
328+
QPointF clickPos;
329+
330+
for (int i = 0; i < count; i++) {
331+
delay += nodes[i].delay;
332+
clickPos = nodes[i].pos;
333+
QTimer::singleShot(delay, this, [this, key, clickPos]() {
334+
int id = attachTouchID(key);
335+
sendTouchDownEvent(id, clickPos);
336+
});
337+
338+
// Don't up it too fast
339+
delay += 20;
340+
QTimer::singleShot(delay, this, [this, key, clickPos]() {
341+
int id = getTouchID(key);
342+
sendTouchUpEvent(id, clickPos);
343+
detachTouchID(key);
344+
});
345+
}
346+
}
347+
305348
void InputConvertGame::processKeyDrag(const QPointF &startPos, QPointF endPos, const QKeyEvent *from)
306349
{
307350
if (QEvent::KeyPress == from->type()) {
@@ -361,8 +404,8 @@ bool InputConvertGame::processMouseMove(const QMouseEvent *from)
361404
m_ctrlMouseMove.lastConverPos.setX(m_ctrlMouseMove.lastConverPos.x() + distance.x() / m_showSize.width());
362405
m_ctrlMouseMove.lastConverPos.setY(m_ctrlMouseMove.lastConverPos.y() + distance.y() / m_showSize.height());
363406

364-
if (m_ctrlMouseMove.lastConverPos.x() < 0.1 || m_ctrlMouseMove.lastConverPos.x() > 0.8 || m_ctrlMouseMove.lastConverPos.y() < 0.1
365-
|| m_ctrlMouseMove.lastConverPos.y() > 0.8) {
407+
if (m_ctrlMouseMove.lastConverPos.x() < 0.05 || m_ctrlMouseMove.lastConverPos.x() > 0.95 || m_ctrlMouseMove.lastConverPos.y() < 0.05
408+
|| m_ctrlMouseMove.lastConverPos.y() > 0.95) {
366409
if (m_ctrlMouseMove.smallEyes) {
367410
m_processMouseMove = false;
368411
int delay = 30;
@@ -442,7 +485,7 @@ void InputConvertGame::mouseMoveStopTouch()
442485
void InputConvertGame::startMouseMoveTimer()
443486
{
444487
stopMouseMoveTimer();
445-
m_ctrlMouseMove.timer = startTimer(1000);
488+
m_ctrlMouseMove.timer = startTimer(500);
446489
}
447490

448491
void InputConvertGame::stopMouseMoveTimer()
@@ -456,6 +499,7 @@ void InputConvertGame::stopMouseMoveTimer()
456499
bool InputConvertGame::switchGameMap()
457500
{
458501
m_gameMap = !m_gameMap;
502+
qInfo() << tr("current keymap mode: %1").arg(m_gameMap ? tr("custom") : tr("normal"));
459503

460504
if (!m_keyMap.isValidMouseMoveMap()) {
461505
return m_gameMap;

QtScrcpy/device/controller/inputconvert/inputconvertgame.h

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class InputConvertGame : public InputConvertNormal
1717
virtual void mouseEvent(const QMouseEvent *from, const QSize &frameSize, const QSize &showSize);
1818
virtual void wheelEvent(const QWheelEvent *from, const QSize &frameSize, const QSize &showSize);
1919
virtual void keyEvent(const QKeyEvent *from, const QSize &frameSize, const QSize &showSize);
20+
virtual bool isCurrentCustomKeymap();
2021

2122
void loadKeyMap(const QString &json);
2223

@@ -40,6 +41,9 @@ class InputConvertGame : public InputConvertNormal
4041
// click
4142
void processKeyClick(const QPointF &clickPos, bool clickTwice, bool switchMap, const QKeyEvent *from);
4243

44+
// click mutil
45+
void processKeyClickMulti(const KeyMap::DelayClickNode *nodes, const int count, const QKeyEvent *from);
46+
4347
// drag
4448
void processKeyDrag(const QPointF &startPos, QPointF endPos, const QKeyEvent *from);
4549

QtScrcpy/device/controller/inputconvert/keymap/keymap.cpp

+79-1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,41 @@ void KeyMap::loadKeyMap(const QString &json)
175175
keyMapNode.data.click.switchMap = getItemBool(node, "switchMap");
176176
m_keyMapNodes.push_back(keyMapNode);
177177
} break;
178+
case KeyMap::KMT_CLICK_MULTI: {
179+
// safe check
180+
if (!checkForClickMulti(node)) {
181+
qWarning() << "json error: keyMapNodes node format error";
182+
break;
183+
}
184+
QPair<ActionType, int> key = getItemKey(node, "key");
185+
if (key.first == AT_INVALID) {
186+
qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString();
187+
break;
188+
}
189+
KeyMapNode keyMapNode;
190+
keyMapNode.type = type;
191+
keyMapNode.data.clickMulti.keyNode.type = key.first;
192+
keyMapNode.data.clickMulti.keyNode.key = key.second;
193+
194+
QJsonArray clickNodes = node.value("clickNodes").toArray();
195+
QJsonObject clickNode;
196+
keyMapNode.data.clickMulti.keyNode.delayClickNodesCount = 0;
197+
198+
for (int i = 0; i < clickNodes.size(); i++) {
199+
if (i >= MAX_DELAY_CLICK_NODES) {
200+
qInfo() << "clickNodes too much, up to " << MAX_DELAY_CLICK_NODES;
201+
break;
202+
}
203+
clickNode = clickNodes.at(i).toObject();
204+
DelayClickNode delayClickNode;
205+
delayClickNode.delay = getItemDouble(clickNode, "delay");
206+
delayClickNode.pos = getItemPos(clickNode, "pos");
207+
keyMapNode.data.clickMulti.keyNode.delayClickNodes[i] = delayClickNode;
208+
keyMapNode.data.clickMulti.keyNode.delayClickNodesCount++;
209+
}
210+
211+
m_keyMapNodes.push_back(keyMapNode);
212+
} break;
178213
case KeyMap::KMT_STEER_WHEEL: {
179214
// safe check
180215
if (!checkForSteerWhell(node)) {
@@ -242,7 +277,7 @@ void KeyMap::loadKeyMap(const QString &json)
242277
}
243278
// this must be called after m_keyMapNodes is stable
244279
makeReverseMap();
245-
qInfo() << "Script updated.";
280+
qInfo() << tr("Script updated, current keymap mode:normal, Press ~ key to switch keymap mode");
246281

247282
parseError:
248283
if (!errorString.isEmpty()) {
@@ -310,6 +345,10 @@ void KeyMap::makeReverseMap()
310345
QMultiHash<int, KeyMapNode *> &m = node.data.clickTwice.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
311346
m.insert(node.data.clickTwice.keyNode.key, &node);
312347
} break;
348+
case KMT_CLICK_MULTI: {
349+
QMultiHash<int, KeyMapNode *> &m = node.data.clickMulti.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
350+
m.insert(node.data.clickMulti.keyNode.key, &node);
351+
} break;
313352
case KMT_STEER_WHEEL: {
314353
QMultiHash<int, KeyMapNode *> &ml = node.data.steerWheel.left.type == AT_KEY ? m_rmapKey : m_rmapMouse;
315354
ml.insert(node.data.steerWheel.left.key, &node);
@@ -410,6 +449,45 @@ bool KeyMap::checkForClick(const QJsonObject &node)
410449
return checkForClickTwice(node) && checkItemBool(node, "switchMap");
411450
}
412451

452+
bool KeyMap::checkForClickMulti(const QJsonObject &node)
453+
{
454+
bool ret = true;
455+
456+
if (!node.contains("clickNodes") || !node.value("clickNodes").isArray()) {
457+
qWarning("json error: no find clickNodes");
458+
return false;
459+
}
460+
461+
QJsonArray clickNodes = node.value("clickNodes").toArray();
462+
QJsonObject clickNode;
463+
int size = clickNodes.size();
464+
if (0 == size) {
465+
qWarning("json error: clickNodes is empty");
466+
return false;
467+
}
468+
469+
for (int i = 0; i < size; i++) {
470+
if (!clickNodes.at(i).isObject()) {
471+
qWarning("json error: clickNodes node must be json object");
472+
ret = false;
473+
break;
474+
}
475+
476+
clickNode = clickNodes.at(i).toObject();
477+
if (!checkForDelayClickNode(clickNode)) {
478+
ret = false;
479+
break;
480+
}
481+
}
482+
483+
return ret;
484+
}
485+
486+
bool KeyMap::checkForDelayClickNode(const QJsonObject &node)
487+
{
488+
return checkItemPos(node, "pos") && checkItemDouble(node, "delay");
489+
}
490+
413491
bool KeyMap::checkForClickTwice(const QJsonObject &node)
414492
{
415493
return checkItemString(node, "key") && checkItemPos(node, "pos");

QtScrcpy/device/controller/inputconvert/keymap/keymap.h

+21-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <QRectF>
1010
#include <QVector>
1111

12+
#define MAX_DELAY_CLICK_NODES 50
13+
1214
class KeyMap : public QObject
1315
{
1416
Q_OBJECT
@@ -18,6 +20,7 @@ class KeyMap : public QObject
1820
KMT_INVALID = -1,
1921
KMT_CLICK = 0,
2022
KMT_CLICK_TWICE,
23+
KMT_CLICK_MULTI,
2124
KMT_STEER_WHEEL,
2225
KMT_DRAG,
2326
KMT_MOUSE_MOVE
@@ -32,13 +35,21 @@ class KeyMap : public QObject
3235
};
3336
Q_ENUM(ActionType)
3437

38+
struct DelayClickNode
39+
{
40+
int delay = 0;
41+
QPointF pos = QPointF(0, 0);
42+
};
43+
3544
struct KeyNode
3645
{
3746
ActionType type = AT_INVALID;
3847
int key = Qt::Key_unknown;
39-
QPointF pos = QPointF(0, 0); // normal key
40-
QPointF extendPos = QPointF(0, 0); // for drag
41-
double extendOffset = 0.0; // for steerWheel
48+
QPointF pos = QPointF(0, 0); // normal key
49+
QPointF extendPos = QPointF(0, 0); // for drag
50+
double extendOffset = 0.0; // for steerWheel
51+
DelayClickNode delayClickNodes[MAX_DELAY_CLICK_NODES]; // for multi clicks
52+
int delayClickNodesCount = 0;
4253

4354
KeyNode(
4455
ActionType type = AT_INVALID,
@@ -66,6 +77,10 @@ class KeyMap : public QObject
6677
KeyNode keyNode;
6778
} clickTwice;
6879
struct
80+
{
81+
KeyNode keyNode;
82+
} clickMulti;
83+
struct
6984
{
7085
QPointF centerPos = { 0.0, 0.0 };
7186
KeyNode left, right, up, down;
@@ -83,6 +98,7 @@ class KeyMap : public QObject
8398
DATA() {}
8499
~DATA() {}
85100
} data;
101+
86102
KeyMapNode() {}
87103
~KeyMapNode() {}
88104
};
@@ -116,6 +132,8 @@ class KeyMap : public QObject
116132

117133
// safe check for KeyMapNode
118134
bool checkForClick(const QJsonObject &node);
135+
bool checkForClickMulti(const QJsonObject &node);
136+
bool checkForDelayClickNode(const QJsonObject &node);
119137
bool checkForClickTwice(const QJsonObject &node);
120138
bool checkForSteerWhell(const QJsonObject &node);
121139
bool checkForDrag(const QJsonObject &node);

QtScrcpy/device/device.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,14 @@ Device::GroupControlState Device::controlState()
339339
return m_controlState;
340340
}
341341

342+
bool Device::isCurrentCustomKeymap()
343+
{
344+
if (!m_controller) {
345+
return false;
346+
}
347+
return m_controller->isCurrentCustomKeymap();
348+
}
349+
342350
bool Device::saveFrame(const AVFrame *frame)
343351
{
344352
if (!frame) {

QtScrcpy/device/device.h

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class Device : public QObject
5656
void updateScript(QString script);
5757
Device::GroupControlState controlState();
5858

59+
bool isCurrentCustomKeymap();
60+
5961
signals:
6062
void deviceDisconnect(QString serial);
6163

QtScrcpy/device/ui/videoform.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ void VideoForm::setDevice(Device *device)
501501
void VideoForm::mousePressEvent(QMouseEvent *event)
502502
{
503503
if (event->button() == Qt::MiddleButton) {
504-
if (m_device) {
504+
if (m_device && !m_device->isCurrentCustomKeymap()) {
505505
emit m_device->postGoHome();
506506
}
507507
}
@@ -580,7 +580,7 @@ void VideoForm::mouseDoubleClickEvent(QMouseEvent *event)
580580
}
581581
}
582582

583-
if (event->button() == Qt::RightButton && m_device) {
583+
if (event->button() == Qt::RightButton && m_device && !m_device->isCurrentCustomKeymap()) {
584584
emit m_device->postBackOrScreenOn();
585585
}
586586

@@ -701,7 +701,7 @@ void VideoForm::dropEvent(QDropEvent *event)
701701
const QMimeData *qm = event->mimeData();
702702
QList<QUrl> urls = qm->urls();
703703

704-
for (const QUrl& url : urls) {
704+
for (const QUrl &url : urls) {
705705
QString file = url.toLocalFile();
706706
QFileInfo fileInfo(file);
707707

0 commit comments

Comments
 (0)