mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-07-23 09:21:33 +00:00
commit
0830b2479a
38 changed files with 1310 additions and 837 deletions
|
@ -62,16 +62,16 @@ void AdbProcess::initSignals()
|
||||||
|
|
||||||
connect(this, &QProcess::readyReadStandardError, this,
|
connect(this, &QProcess::readyReadStandardError, this,
|
||||||
[this](){
|
[this](){
|
||||||
QString tmp = QString::fromLocal8Bit(readAllStandardError()).trimmed();
|
QString tmp = QString::fromUtf8(readAllStandardError()).trimmed();
|
||||||
m_errorOutput += tmp;
|
m_errorOutput += tmp;
|
||||||
qWarning(QString("AdbProcess::error:%1").arg(tmp).toUtf8());
|
qWarning(QString("AdbProcess::error:%1").arg(tmp).toStdString().data());
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &QProcess::readyReadStandardOutput, this,
|
connect(this, &QProcess::readyReadStandardOutput, this,
|
||||||
[this](){
|
[this](){
|
||||||
QString tmp = QString::fromLocal8Bit(readAllStandardOutput()).trimmed();
|
QString tmp = QString::fromUtf8(readAllStandardOutput()).trimmed();
|
||||||
m_standardOutput += tmp;
|
m_standardOutput += tmp;
|
||||||
qInfo(QString("AdbProcess::out:%1").arg(tmp).toUtf8());
|
qInfo(QString("AdbProcess::out:%1").arg(tmp).toStdString().data());
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &QProcess::started, this,
|
connect(this, &QProcess::started, this,
|
||||||
|
|
|
@ -39,7 +39,10 @@ void Controller::postControlMsg(ControlMsg *controlMsg)
|
||||||
void Controller::test(QRect rc)
|
void Controller::test(QRect rc)
|
||||||
{
|
{
|
||||||
ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_TOUCH);
|
ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_TOUCH);
|
||||||
controlMsg->setInjectTouchMsgData(POINTER_ID_MOUSE, AMOTION_EVENT_ACTION_DOWN, AMOTION_EVENT_BUTTON_PRIMARY, rc, 1.0f);
|
controlMsg->setInjectTouchMsgData(POINTER_ID_MOUSE,
|
||||||
|
AMOTION_EVENT_ACTION_DOWN,
|
||||||
|
AMOTION_EVENT_BUTTON_PRIMARY,
|
||||||
|
rc, 1.0f);
|
||||||
postControlMsg(controlMsg);
|
postControlMsg(controlMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +195,7 @@ void Controller::keyEvent(const QKeyEvent *from, const QSize &frameSize, const Q
|
||||||
|
|
||||||
bool Controller::event(QEvent *event)
|
bool Controller::event(QEvent *event)
|
||||||
{
|
{
|
||||||
if (event && event->type() == ControlMsg::Control) {
|
if (event && static_cast<ControlMsg::Type>(event->type()) == ControlMsg::Control) {
|
||||||
ControlMsg* controlMsg = dynamic_cast<ControlMsg*>(event);
|
ControlMsg* controlMsg = dynamic_cast<ControlMsg*>(event);
|
||||||
if (controlMsg) {
|
if (controlMsg) {
|
||||||
sendControl(controlMsg->serializeData());
|
sendControl(controlMsg->serializeData());
|
||||||
|
@ -209,7 +212,7 @@ bool Controller::sendControl(const QByteArray &buffer)
|
||||||
}
|
}
|
||||||
qint32 len = 0;
|
qint32 len = 0;
|
||||||
if (m_controlSocket) {
|
if (m_controlSocket) {
|
||||||
len = m_controlSocket->write(buffer.data(), buffer.length());
|
len = static_cast<qint32>(m_controlSocket->write(buffer.data(), buffer.length()));
|
||||||
}
|
}
|
||||||
return len == buffer.length() ? true : false;
|
return len == buffer.length() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,8 @@ void InputConvertGame::mouseEvent(const QMouseEvent *from, const QSize &frameSiz
|
||||||
if (processMouseClick(from)) {
|
if (processMouseClick(from)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
InputConvertNormal::mouseEvent(from, frameSize, showSize);
|
|
||||||
}
|
}
|
||||||
|
InputConvertNormal::mouseEvent(from, frameSize, showSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputConvertGame::wheelEvent(const QWheelEvent *from, const QSize &frameSize, const QSize &showSize)
|
void InputConvertGame::wheelEvent(const QWheelEvent *from, const QSize &frameSize, const QSize &showSize)
|
||||||
|
@ -73,10 +72,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 +92,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;
|
||||||
|
@ -112,25 +111,18 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize& frameSize, c
|
||||||
void InputConvertGame::loadKeyMap(const QString &json)
|
void InputConvertGame::loadKeyMap(const QString &json)
|
||||||
{
|
{
|
||||||
m_keyMap.loadKeyMap(json);
|
m_keyMap.loadKeyMap(json);
|
||||||
if (m_keyMap.isValidMouseMoveMap()) {
|
|
||||||
m_ctrlMouseMove.valid = true;
|
|
||||||
m_ctrlMouseMove.touching = false;
|
|
||||||
m_ctrlMouseMove.startPosRel = m_keyMap.getMouseMoveMap().startPos;
|
|
||||||
m_ctrlMouseMove.startPosPixel = calcFrameAbsolutePos(m_ctrlMouseMove.startPosRel);
|
|
||||||
}
|
|
||||||
if(m_keyMap.isValidSteerWheelMap()){
|
|
||||||
m_ctrlSteerWheel.valid = true;
|
|
||||||
m_ctrlMouseMove.touching = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputConvertGame::updateSize(const QSize &frameSize, const QSize &showSize)
|
void InputConvertGame::updateSize(const QSize &frameSize, const QSize &showSize)
|
||||||
{
|
{
|
||||||
|
if (showSize != m_showSize) {
|
||||||
|
if (m_gameMap && m_keyMap.isValidMouseMoveMap()) {
|
||||||
|
// show size change, resize grab cursor
|
||||||
|
emit grabCursor(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
m_frameSize = frameSize;
|
m_frameSize = frameSize;
|
||||||
m_showSize = showSize;
|
m_showSize = showSize;
|
||||||
if(m_ctrlMouseMove.valid){
|
|
||||||
m_ctrlMouseMove.startPosPixel = calcScreenAbsolutePos(m_ctrlMouseMove.startPosRel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputConvertGame::sendTouchDownEvent(int id, QPointF pos)
|
void InputConvertGame::sendTouchDownEvent(int id, QPointF pos)
|
||||||
|
@ -159,7 +151,11 @@ void InputConvertGame::sendTouchEvent(int id, QPointF pos, AndroidMotioneventAct
|
||||||
if (!controlMsg) {
|
if (!controlMsg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
controlMsg->setInjectTouchMsgData(id, action, (AndroidMotioneventButtons)0, QRect(calcFrameAbsolutePos(pos).toPoint(), m_frameSize), 1.0f);
|
controlMsg->setInjectTouchMsgData(static_cast<quint64>(id),
|
||||||
|
action,
|
||||||
|
static_cast<AndroidMotioneventButtons>(0),
|
||||||
|
QRect(calcFrameAbsolutePos(pos).toPoint(),m_frameSize),
|
||||||
|
1.0f);
|
||||||
sendControlMsg(controlMsg);
|
sendControlMsg(controlMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,25 +177,20 @@ QPointF InputConvertGame::calcScreenAbsolutePos(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 == m_multiTouchID[i]) {
|
||||||
multiTouchID[i] = key;
|
m_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 == m_multiTouchID[i]) {
|
||||||
multiTouchID[i] = 0;
|
m_multiTouchID[i] = 0;
|
||||||
//qDebug() << "detach "<<key<<" ("<<map.valueToKey(key)<<") from "<<i;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +199,7 @@ void InputConvertGame::detachTouchID(int key)
|
||||||
int InputConvertGame::getTouchID(int key)
|
int InputConvertGame::getTouchID(int 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 == m_multiTouchID[i]) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,49 +213,54 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calc offset and pressed number
|
||||||
QPointF offset(0.0, 0.0);
|
QPointF offset(0.0, 0.0);
|
||||||
int nPressed = 0;
|
int pressedNum = 0;
|
||||||
if(m_ctrlSteerWheel.pressedUp){
|
if (m_ctrlSteerWheel.pressedUp) {
|
||||||
++nPressed;
|
++pressedNum;
|
||||||
offset.ry() -= node.steerWheel.up.offset;
|
offset.ry() -= node.data.steerWheel.up.extendOffset;
|
||||||
}
|
}
|
||||||
if(m_ctrlSteerWheel.pressedRight){
|
if (m_ctrlSteerWheel.pressedRight) {
|
||||||
++nPressed;
|
++pressedNum;
|
||||||
offset.rx() += node.steerWheel.right.offset;
|
offset.rx() += node.data.steerWheel.right.extendOffset;
|
||||||
}
|
}
|
||||||
if(m_ctrlSteerWheel.pressedDown){
|
if (m_ctrlSteerWheel.pressedDown) {
|
||||||
++nPressed;
|
++pressedNum;
|
||||||
offset.ry() += node.steerWheel.down.offset;
|
offset.ry() += node.data.steerWheel.down.extendOffset;
|
||||||
}
|
}
|
||||||
if(m_ctrlSteerWheel.pressedLeft){
|
if (m_ctrlSteerWheel.pressedLeft) {
|
||||||
++nPressed;
|
++pressedNum;
|
||||||
offset.rx() -= node.steerWheel.left.offset;
|
offset.rx() -= node.data.steerWheel.left.extendOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// action
|
// action
|
||||||
//qDebug()<<nPressed<<"-"<<char(from->key())<<"-"<<from->type()<<"-"<<offset;
|
if(pressedNum == 0){
|
||||||
if(nPressed == 0){ // release all
|
// touch up 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
|
// first press, get key and touch down
|
||||||
|
if (pressedNum == 1 && flag) {
|
||||||
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 {
|
||||||
|
// jsut get touch id and move
|
||||||
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;
|
||||||
|
@ -299,10 +295,14 @@ void InputConvertGame::processKeyClick(
|
||||||
|
|
||||||
void InputConvertGame::processKeyDrag(const QPointF& startPos, QPointF endPos, const QKeyEvent* from)
|
void InputConvertGame::processKeyDrag(const QPointF& startPos, QPointF endPos, const QKeyEvent* from)
|
||||||
{
|
{
|
||||||
if(QEvent::KeyPress == from->type()){
|
if (QEvent::KeyPress == from->type()){
|
||||||
int id = attachTouchID(from->key());
|
int id = attachTouchID(from->key());
|
||||||
sendTouchDownEvent(id, startPos);
|
sendTouchDownEvent(id, startPos);
|
||||||
sendTouchMoveEvent(id, endPos);
|
sendTouchMoveEvent(id, endPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QEvent::KeyRelease == from->type()) {
|
||||||
|
int id = getTouchID(from->key());
|
||||||
sendTouchUpEvent(id, endPos);
|
sendTouchUpEvent(id, endPos);
|
||||||
detachTouchID(from->key());
|
detachTouchID(from->key());
|
||||||
}
|
}
|
||||||
|
@ -317,16 +317,19 @@ bool InputConvertGame::processMouseClick(const QMouseEvent *from)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "mouse event " << from->type();
|
||||||
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()) {
|
return true;
|
||||||
sendTouchUpEvent(getTouchID(from->button()), node.click.keyNode.pos);
|
|
||||||
detachTouchID(from->button());
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
if (QEvent::MouseButtonRelease == from->type()) {
|
||||||
|
int id = getTouchID(from->button());
|
||||||
|
sendTouchUpEvent(id, node.data.click.keyNode.pos);
|
||||||
|
detachTouchID(from->button());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputConvertGame::processMouseMove(const QMouseEvent *from)
|
bool InputConvertGame::processMouseMove(const QMouseEvent *from)
|
||||||
|
@ -334,30 +337,61 @@ bool InputConvertGame::processMouseMove(const QMouseEvent *from)
|
||||||
if (QEvent::MouseMove != from->type()) {
|
if (QEvent::MouseMove != from->type()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (m_ctrlMouseMove.touching) {
|
|
||||||
QPointF mousePos = from->localPos();
|
|
||||||
mousePos.rx() /= m_showSize.width();
|
|
||||||
mousePos.ry() /= m_showSize.height();
|
|
||||||
QPointF offset = mousePos - m_ctrlMouseMove.startPosRel;
|
|
||||||
//qDebug()<<from->localPos()<<" - "<<m_mouseMoveLastConverPos<<" - "<<offset<<" - "<<offset.manhattanLength();
|
|
||||||
|
|
||||||
if(mousePos.x()<0.05 || mousePos.x()>0.95 || mousePos.y()<0.05 || mousePos.y()>0.95) {
|
if (checkCursorPos(from)) {
|
||||||
//qDebug()<<"reset";
|
m_ctrlMouseMove.lastPos = QPointF(0.0, 0.0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_ctrlMouseMove.lastPos.isNull()) {
|
||||||
|
QPointF distance = from->localPos() - m_ctrlMouseMove.lastPos;
|
||||||
|
distance /= m_keyMap.getMouseMoveMap().data.mouseMove.speedRatio;
|
||||||
|
|
||||||
|
mouseMoveStartTouch(from);
|
||||||
|
startMouseMoveTimer();
|
||||||
|
|
||||||
|
m_ctrlMouseMove.lastConverPos.setX(m_ctrlMouseMove.lastConverPos.x() + distance.x() / m_showSize.width());
|
||||||
|
m_ctrlMouseMove.lastConverPos.setY(m_ctrlMouseMove.lastConverPos.y() + distance.y() / m_showSize.height());
|
||||||
|
|
||||||
|
if (m_ctrlMouseMove.lastConverPos.x() < 0.1
|
||||||
|
|| m_ctrlMouseMove.lastConverPos.x() > 0.8
|
||||||
|
|| m_ctrlMouseMove.lastConverPos.y() < 0.1
|
||||||
|
|| m_ctrlMouseMove.lastConverPos.y() > 0.8) {
|
||||||
mouseMoveStopTouch();
|
mouseMoveStopTouch();
|
||||||
mouseMoveStartTouch(from);
|
mouseMoveStartTouch(from);
|
||||||
}
|
}
|
||||||
offset /= m_keyMap.getMouseMoveMap().speedRatio;
|
|
||||||
m_ctrlMouseMove.lastPosRel = m_ctrlMouseMove.startPosRel + offset;
|
sendTouchMoveEvent(getTouchID(Qt::ExtraButton24), m_ctrlMouseMove.lastConverPos);
|
||||||
mouseMoveMovingTouch(m_ctrlMouseMove.lastPosRel);
|
|
||||||
} else {
|
|
||||||
m_ctrlMouseMove.touching = true;
|
|
||||||
mouseMoveStartTouch(from);
|
|
||||||
int left = from->globalX() - from->x();
|
|
||||||
int top = from->globalY() - from->y();
|
|
||||||
}
|
}
|
||||||
|
m_ctrlMouseMove.lastPos = from->localPos();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputConvertGame::checkCursorPos(const QMouseEvent *from)
|
||||||
|
{
|
||||||
|
bool moveCursor = false;
|
||||||
|
QPoint pos = from->pos();
|
||||||
|
if (pos.x() < CURSOR_POS_CHECK) {
|
||||||
|
pos.setX(m_showSize.width() - CURSOR_POS_CHECK);
|
||||||
|
moveCursor = true;
|
||||||
|
} else if (pos.x() > m_showSize.width() - CURSOR_POS_CHECK) {
|
||||||
|
pos.setX(CURSOR_POS_CHECK);
|
||||||
|
moveCursor = true;
|
||||||
|
} else if (pos.y() < CURSOR_POS_CHECK) {
|
||||||
|
pos.setY(m_showSize.height() - CURSOR_POS_CHECK);
|
||||||
|
moveCursor = true;
|
||||||
|
} else if (pos.y() > m_showSize.height() - CURSOR_POS_CHECK) {
|
||||||
|
pos.setY(CURSOR_POS_CHECK);
|
||||||
|
moveCursor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moveCursor) {
|
||||||
|
moveCursorTo(from, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moveCursor;
|
||||||
|
}
|
||||||
|
|
||||||
void InputConvertGame::moveCursorTo(const QMouseEvent *from, const QPoint &localPosPixel)
|
void InputConvertGame::moveCursorTo(const QMouseEvent *from, const QPoint &localPosPixel)
|
||||||
{
|
{
|
||||||
QPoint posOffset = from->pos() - localPosPixel;
|
QPoint posOffset = from->pos() - localPosPixel;
|
||||||
|
@ -369,53 +403,56 @@ void InputConvertGame::moveCursorTo(const QMouseEvent *from, const QPoint &local
|
||||||
|
|
||||||
void InputConvertGame::mouseMoveStartTouch(const QMouseEvent* from)
|
void InputConvertGame::mouseMoveStartTouch(const QMouseEvent* from)
|
||||||
{
|
{
|
||||||
moveCursorTo(from, m_ctrlMouseMove.startPosPixel.toPoint());
|
Q_UNUSED(from)
|
||||||
int id = attachTouchID(m_ctrlMouseMove.touchKey);
|
if (!m_ctrlMouseMove.touching) {
|
||||||
sendTouchDownEvent(id, m_ctrlMouseMove.startPosRel);
|
QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().data.mouseMove.startPos;
|
||||||
m_ctrlMouseMove.lastPosRel = m_ctrlMouseMove.startPosRel;
|
int id = attachTouchID(Qt::ExtraButton24);
|
||||||
m_ctrlMouseMove.touching = true;
|
sendTouchDownEvent(id, mouseMoveStartPos);
|
||||||
}
|
m_ctrlMouseMove.lastConverPos = mouseMoveStartPos;
|
||||||
|
m_ctrlMouseMove.touching = true;
|
||||||
void InputConvertGame::mouseMoveMovingTouch(const QPointF& target)
|
}
|
||||||
{
|
|
||||||
sendTouchMoveEvent(getTouchID(m_ctrlMouseMove.touchKey), target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputConvertGame::mouseMoveStopTouch()
|
void InputConvertGame::mouseMoveStopTouch()
|
||||||
{
|
{
|
||||||
int id = getTouchID(m_ctrlMouseMove.touchKey);
|
if (m_ctrlMouseMove.touching) {
|
||||||
sendTouchUpEvent(id, m_ctrlMouseMove.lastPosRel);
|
sendTouchUpEvent(getTouchID(Qt::ExtraButton24), m_ctrlMouseMove.lastConverPos);
|
||||||
detachTouchID(m_ctrlMouseMove.touchKey);
|
detachTouchID(Qt::ExtraButton24);
|
||||||
m_ctrlMouseMove.touching = false;
|
m_ctrlMouseMove.touching = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputConvertGame::startMouseMoveTimer()
|
void InputConvertGame::startMouseMoveTimer()
|
||||||
{
|
{
|
||||||
stopMouseMoveTimer();
|
stopMouseMoveTimer();
|
||||||
m_mouseMoveTimer = startTimer(1000);
|
m_ctrlMouseMove.timer = startTimer(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputConvertGame::stopMouseMoveTimer()
|
void InputConvertGame::stopMouseMoveTimer()
|
||||||
{
|
{
|
||||||
if (0 != m_mouseMoveTimer) {
|
if (0 != m_ctrlMouseMove.timer) {
|
||||||
killTimer(m_mouseMoveTimer);
|
killTimer(m_ctrlMouseMove.timer);
|
||||||
m_mouseMoveTimer = 0;
|
m_ctrlMouseMove.timer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputConvertGame::switchGameMap()
|
bool InputConvertGame::switchGameMap()
|
||||||
{
|
{
|
||||||
m_gameMap = !m_gameMap;
|
m_gameMap = !m_gameMap;
|
||||||
|
|
||||||
|
if (!m_keyMap.isValidMouseMoveMap()) {
|
||||||
|
return m_gameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// grab cursor and set cursor only mouse move map
|
||||||
emit grabCursor(m_gameMap);
|
emit grabCursor(m_gameMap);
|
||||||
if (m_gameMap) {
|
if (m_gameMap) {
|
||||||
#ifdef QT_NO_DEBUG
|
#ifdef QT_NO_DEBUG
|
||||||
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||||
#else
|
#else
|
||||||
QGuiApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
|
QGuiApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if(m_ctrlMouseMove.touching)
|
|
||||||
mouseMoveStopTouch();
|
|
||||||
QGuiApplication::restoreOverrideCursor();
|
QGuiApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
return m_gameMap;
|
return m_gameMap;
|
||||||
|
@ -423,7 +460,7 @@ bool InputConvertGame::switchGameMap()
|
||||||
|
|
||||||
void InputConvertGame::timerEvent(QTimerEvent *event)
|
void InputConvertGame::timerEvent(QTimerEvent *event)
|
||||||
{
|
{
|
||||||
if (m_mouseMoveTimer == event->timerId()) {
|
if (m_ctrlMouseMove.timer == event->timerId()) {
|
||||||
stopMouseMoveTimer();
|
stopMouseMoveTimer();
|
||||||
mouseMoveStopTouch();
|
mouseMoveStopTouch();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,13 +48,12 @@ protected:
|
||||||
bool processMouseMove(const QMouseEvent* from);
|
bool processMouseMove(const QMouseEvent* from);
|
||||||
void moveCursorTo(const QMouseEvent* from, const QPoint& localPosPixel);
|
void moveCursorTo(const QMouseEvent* from, const QPoint& localPosPixel);
|
||||||
void mouseMoveStartTouch(const QMouseEvent* from);
|
void mouseMoveStartTouch(const QMouseEvent* from);
|
||||||
void mouseMoveMovingTouch(const QPointF& target);
|
|
||||||
void mouseMoveStopTouch();
|
void mouseMoveStopTouch();
|
||||||
|
|
||||||
void startMouseMoveTimer();
|
void startMouseMoveTimer();
|
||||||
void stopMouseMoveTimer();
|
void stopMouseMoveTimer();
|
||||||
|
|
||||||
bool switchGameMap();
|
bool switchGameMap();
|
||||||
|
bool checkCursorPos(const QMouseEvent *from);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent *event);
|
void timerEvent(QTimerEvent *event);
|
||||||
|
@ -63,37 +62,29 @@ private:
|
||||||
QSize m_frameSize;
|
QSize m_frameSize;
|
||||||
QSize m_showSize;
|
QSize m_showSize;
|
||||||
bool m_gameMap = false;
|
bool m_gameMap = false;
|
||||||
|
bool m_needSwitchGameAgain = false;
|
||||||
int multiTouchID[MULTI_TOUCH_MAX_NUM] = { 0 };
|
int m_multiTouchID[MULTI_TOUCH_MAX_NUM] = { 0 };
|
||||||
|
KeyMap m_keyMap;
|
||||||
|
|
||||||
// steer wheel
|
// steer wheel
|
||||||
struct{
|
struct {
|
||||||
bool valid = false;
|
// the first key pressed
|
||||||
bool touching = false;
|
int touchKey = Qt::Key_unknown;
|
||||||
int touchKey = Qt::Key_unknown; // the first key pressed
|
bool pressedUp = false;
|
||||||
int nKeyPressed = 0;
|
bool pressedDown = false;
|
||||||
bool pressedUp = false, pressedDown = false;
|
bool pressedLeft = false;
|
||||||
bool pressedLeft = false, pressedRight = false;
|
bool pressedRight = false;
|
||||||
QPointF centerPos;
|
// for last up
|
||||||
QPointF lastOffset;
|
QPointF lastOffset;
|
||||||
} m_ctrlSteerWheel;
|
} m_ctrlSteerWheel;
|
||||||
|
|
||||||
// mouse move
|
// mouse move
|
||||||
struct{
|
struct {
|
||||||
bool valid = false;
|
QPointF lastConverPos;
|
||||||
|
QPointF lastPos = {0.0, 0.0};
|
||||||
bool touching = false;
|
bool touching = false;
|
||||||
const int touchKey = Qt::ExtraButton24;
|
int timer = 0;
|
||||||
QPointF startPosRel; // in [0, 1)
|
|
||||||
QPointF startPosPixel; // in [0, size)
|
|
||||||
QPointF lastPosRel;
|
|
||||||
//QPointF lastPosPixel;
|
|
||||||
} m_ctrlMouseMove;
|
} m_ctrlMouseMove;
|
||||||
|
|
||||||
int m_mouseMoveTimer = 0;
|
|
||||||
|
|
||||||
bool m_needSwitchGameAgain = false;
|
|
||||||
|
|
||||||
KeyMap m_keyMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INPUTCONVERTGAME_H
|
#endif // INPUTCONVERTGAME_H
|
||||||
|
|
|
@ -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,45 +118,45 @@ 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;
|
||||||
case KeyMap::KMT_CLICK_TWICE:
|
case KeyMap::KMT_CLICK_TWICE:
|
||||||
{
|
{
|
||||||
// safe check
|
// safe check
|
||||||
if (!checkForClickDouble(node)) {
|
if (!checkForClickTwice(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.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,34 +354,70 @@ 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 checkForClickTwice(node) && checkItemBool(node, "switchMap");
|
||||||
&& checkItemSwitchMap(node, "switchMap");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyMap::checkForClickDouble(const QJsonObject& node)
|
bool KeyMap::checkForClickTwice(const QJsonObject& node)
|
||||||
{
|
{
|
||||||
return checkForClick(node);
|
return checkItemString(node, "key") && checkItemPos(node, "pos");
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +425,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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,29 +50,22 @@ 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 {
|
||||||
|
QPointF startPos = {0.0, 0.0};
|
||||||
|
int speedRatio = 1;
|
||||||
|
} mouseMove;
|
||||||
|
DATA() {}
|
||||||
|
~DATA() {}
|
||||||
|
} data;
|
||||||
KeyMapNode() {}
|
KeyMapNode() {}
|
||||||
~KeyMapNode() {}
|
~KeyMapNode() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MouseMoveMap {
|
|
||||||
QPointF startPos = {0.0, 0.0};
|
|
||||||
int speedRatio = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
KeyMap(QObject *parent = Q_NULLPTR);
|
KeyMap(QObject *parent = Q_NULLPTR);
|
||||||
virtual ~KeyMap();
|
virtual ~KeyMap();
|
||||||
|
|
||||||
|
@ -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 checkForClickTwice(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
|
||||||
|
|
|
@ -12,7 +12,7 @@ AVFrameConvert::~AVFrameConvert()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVFrameConvert::setSrcFrameInfo(quint32 srcWidth, quint32 srcHeight, AVPixelFormat srcFormat)
|
void AVFrameConvert::setSrcFrameInfo(int srcWidth, int srcHeight, AVPixelFormat srcFormat)
|
||||||
{
|
{
|
||||||
m_srcWidth = srcWidth;
|
m_srcWidth = srcWidth;
|
||||||
m_srcHeight = srcHeight;
|
m_srcHeight = srcHeight;
|
||||||
|
@ -20,21 +20,21 @@ void AVFrameConvert::setSrcFrameInfo(quint32 srcWidth, quint32 srcHeight, AVPixe
|
||||||
qDebug() << "Convert::src frame info " << srcWidth << "x" << srcHeight;
|
qDebug() << "Convert::src frame info " << srcWidth << "x" << srcHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVFrameConvert::getSrcFrameInfo(quint32& srcWidth, quint32& srcHeight, AVPixelFormat& srcFormat)
|
void AVFrameConvert::getSrcFrameInfo(int& srcWidth, int& srcHeight, AVPixelFormat& srcFormat)
|
||||||
{
|
{
|
||||||
srcWidth = m_srcWidth;
|
srcWidth = m_srcWidth;
|
||||||
srcHeight = m_srcHeight;
|
srcHeight = m_srcHeight;
|
||||||
srcFormat = m_srcFormat;
|
srcFormat = m_srcFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVFrameConvert::setDstFrameInfo(quint32 dstWidth, quint32 dstHeight, AVPixelFormat dstFormat)
|
void AVFrameConvert::setDstFrameInfo(int dstWidth, int dstHeight, AVPixelFormat dstFormat)
|
||||||
{
|
{
|
||||||
m_dstWidth = dstWidth;
|
m_dstWidth = dstWidth;
|
||||||
m_dstHeight = dstHeight;
|
m_dstHeight = dstHeight;
|
||||||
m_dstFormat = dstFormat;
|
m_dstFormat = dstFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVFrameConvert::getDstFrameInfo(quint32& dstWidth, quint32& dstHeight, AVPixelFormat& dstFormat)
|
void AVFrameConvert::getDstFrameInfo(int& dstWidth, int& dstHeight, AVPixelFormat& dstFormat)
|
||||||
{
|
{
|
||||||
dstWidth = m_dstWidth;
|
dstWidth = m_dstWidth;
|
||||||
dstHeight = m_dstHeight;
|
dstHeight = m_dstHeight;
|
||||||
|
@ -67,12 +67,15 @@ void AVFrameConvert::deInit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AVFrameConvert::convert(AVFrame* srcFrame, AVFrame* dstFrame)
|
bool AVFrameConvert::convert(const AVFrame* srcFrame, AVFrame* dstFrame)
|
||||||
{
|
{
|
||||||
if(!m_convertCtx || !srcFrame || !dstFrame) {
|
if(!m_convertCtx || !srcFrame || !dstFrame) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qint32 ret = sws_scale(m_convertCtx, (const uint8_t* const*)srcFrame->data, srcFrame->linesize, 0, m_srcHeight, dstFrame->data, dstFrame->linesize);
|
qint32 ret = sws_scale(m_convertCtx,
|
||||||
|
static_cast<const uint8_t* const*>(srcFrame->data),
|
||||||
|
srcFrame->linesize, 0, m_srcHeight, dstFrame->data,
|
||||||
|
dstFrame->linesize);
|
||||||
if (0 == ret) {
|
if (0 == ret) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,22 +16,22 @@ public:
|
||||||
virtual ~AVFrameConvert();
|
virtual ~AVFrameConvert();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setSrcFrameInfo(quint32 srcWidth, quint32 srcHeight, AVPixelFormat srcFormat);
|
void setSrcFrameInfo(int srcWidth, int srcHeight, AVPixelFormat srcFormat);
|
||||||
void getSrcFrameInfo(quint32& srcWidth, quint32& srcHeight, AVPixelFormat& srcFormat);
|
void getSrcFrameInfo(int& srcWidth, int& srcHeight, AVPixelFormat& srcFormat);
|
||||||
void setDstFrameInfo(quint32 dstWidth, quint32 dstHeight, AVPixelFormat dstFormat);
|
void setDstFrameInfo(int dstWidth, int dstHeight, AVPixelFormat dstFormat);
|
||||||
void getDstFrameInfo(quint32& dstWidth, quint32& dstHeight, AVPixelFormat& dstFormat);
|
void getDstFrameInfo(int& dstWidth, int& dstHeight, AVPixelFormat& dstFormat);
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
bool isInit();
|
bool isInit();
|
||||||
void deInit();
|
void deInit();
|
||||||
bool convert(AVFrame* srcFrame, AVFrame* dstFrame);
|
bool convert(const AVFrame* srcFrame, AVFrame* dstFrame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
quint32 m_srcWidth = 0;
|
int m_srcWidth = 0;
|
||||||
quint32 m_srcHeight = 0;
|
int m_srcHeight = 0;
|
||||||
AVPixelFormat m_srcFormat = AV_PIX_FMT_NONE;
|
AVPixelFormat m_srcFormat = AV_PIX_FMT_NONE;
|
||||||
quint32 m_dstWidth = 0;
|
int m_dstWidth = 0;
|
||||||
quint32 m_dstHeight = 0;
|
int m_dstHeight = 0;
|
||||||
AVPixelFormat m_dstFormat = AV_PIX_FMT_NONE;
|
AVPixelFormat m_dstFormat = AV_PIX_FMT_NONE;
|
||||||
|
|
||||||
struct SwsContext *m_convertCtx = Q_NULLPTR;
|
struct SwsContext *m_convertCtx = Q_NULLPTR;
|
||||||
|
|
|
@ -9,6 +9,3 @@ SOURCES += \
|
||||||
$$PWD/fpscounter.cpp \
|
$$PWD/fpscounter.cpp \
|
||||||
$$PWD/avframeconvert.cpp \
|
$$PWD/avframeconvert.cpp \
|
||||||
$$PWD/videobuffer.cpp
|
$$PWD/videobuffer.cpp
|
||||||
|
|
||||||
#DEFINES += SKIP_FRAMES
|
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,9 @@ VideoBuffer::~VideoBuffer()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoBuffer::init()
|
bool VideoBuffer::init(bool renderExpiredFrames)
|
||||||
{
|
{
|
||||||
|
m_renderExpiredFrames = renderExpiredFrames;
|
||||||
m_decodingFrame = av_frame_alloc();
|
m_decodingFrame = av_frame_alloc();
|
||||||
if (!m_decodingFrame) {
|
if (!m_decodingFrame) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -71,17 +72,17 @@ void VideoBuffer::offerDecodedFrame(bool& previousFrameSkipped)
|
||||||
{
|
{
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
|
|
||||||
#ifndef SKIP_FRAMES
|
if (m_renderExpiredFrames) {
|
||||||
// if SKIP_FRAMES is disabled, then the decoder must wait for the current
|
// if m_renderExpiredFrames is enable, then the decoder must wait for the current
|
||||||
// frame to be consumed
|
// frame to be consumed
|
||||||
while (!m_renderingFrameConsumed && !m_interrupted) {
|
while (!m_renderingFrameConsumed && !m_interrupted) {
|
||||||
m_renderingFrameConsumedCond.wait(&m_mutex);
|
m_renderingFrameConsumedCond.wait(&m_mutex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_fpsCounter.isStarted() && !m_renderingFrameConsumed) {
|
||||||
|
m_fpsCounter.addSkippedFrame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (m_fpsCounter.isStarted() && !m_renderingFrameConsumed) {
|
|
||||||
m_fpsCounter.addSkippedFrame();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
swap();
|
swap();
|
||||||
previousFrameSkipped = !m_renderingFrameConsumed;
|
previousFrameSkipped = !m_renderingFrameConsumed;
|
||||||
|
@ -96,23 +97,23 @@ const AVFrame *VideoBuffer::consumeRenderedFrame()
|
||||||
if (m_fpsCounter.isStarted()) {
|
if (m_fpsCounter.isStarted()) {
|
||||||
m_fpsCounter.addRenderedFrame();
|
m_fpsCounter.addRenderedFrame();
|
||||||
}
|
}
|
||||||
#ifndef SKIP_FRAMES
|
if (m_renderExpiredFrames) {
|
||||||
// if SKIP_FRAMES is disabled, then notify the decoder the current frame is
|
// if m_renderExpiredFrames is enable, then notify the decoder the current frame is
|
||||||
// consumed, so that it may push a new one
|
// consumed, so that it may push a new one
|
||||||
m_renderingFrameConsumedCond.wakeOne();
|
m_renderingFrameConsumedCond.wakeOne();
|
||||||
#endif
|
}
|
||||||
return m_renderingframe;
|
return m_renderingframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBuffer::interrupt()
|
void VideoBuffer::interrupt()
|
||||||
{
|
{
|
||||||
#ifndef SKIP_FRAMES
|
if (m_renderExpiredFrames) {
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
m_interrupted = true;
|
m_interrupted = true;
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
// wake up blocking wait
|
// wake up blocking wait
|
||||||
m_renderingFrameConsumedCond.wakeOne();
|
m_renderingFrameConsumedCond.wakeOne();
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBuffer::swap()
|
void VideoBuffer::swap()
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
VideoBuffer();
|
VideoBuffer();
|
||||||
virtual ~VideoBuffer();
|
virtual ~VideoBuffer();
|
||||||
|
|
||||||
bool init();
|
bool init(bool renderExpiredFrames = false);
|
||||||
void deInit();
|
void deInit();
|
||||||
void lock();
|
void lock();
|
||||||
void unLock();
|
void unLock();
|
||||||
|
@ -45,10 +45,12 @@ private:
|
||||||
bool m_renderingFrameConsumed = true;
|
bool m_renderingFrameConsumed = true;
|
||||||
FpsCounter m_fpsCounter;
|
FpsCounter m_fpsCounter;
|
||||||
|
|
||||||
#ifndef SKIP_FRAMES
|
bool m_renderExpiredFrames = false;
|
||||||
QWaitCondition m_renderingFrameConsumedCond;
|
QWaitCondition m_renderingFrameConsumedCond;
|
||||||
bool m_interrupted = true;
|
|
||||||
#endif
|
// interrupted is not used if expired frames are not rendered
|
||||||
|
// since offering a frame will never block
|
||||||
|
bool m_interrupted = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VIDEO_BUFFER_H
|
#endif // VIDEO_BUFFER_H
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "recorder.h"
|
#include "recorder.h"
|
||||||
|
@ -11,6 +12,11 @@
|
||||||
#include "videoform.h"
|
#include "videoform.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "avframeconvert.h"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include "libavutil/imgutils.h"
|
||||||
|
}
|
||||||
|
|
||||||
Device::Device(DeviceParams params, QObject *parent)
|
Device::Device(DeviceParams params, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
@ -24,7 +30,7 @@ Device::Device(DeviceParams params, QObject *parent)
|
||||||
|
|
||||||
if (params.display) {
|
if (params.display) {
|
||||||
m_vb = new VideoBuffer();
|
m_vb = new VideoBuffer();
|
||||||
m_vb->init();
|
m_vb->init(params.renderExpiredFrames);
|
||||||
m_decoder = new Decoder(m_vb, this);
|
m_decoder = new Decoder(m_vb, this);
|
||||||
m_fileHandler = new FileHandler(this);
|
m_fileHandler = new FileHandler(this);
|
||||||
m_controller = new Controller(params.gameScript, this);
|
m_controller = new Controller(params.gameScript, this);
|
||||||
|
@ -97,10 +103,16 @@ void Device::updateScript(QString script)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::onScreenshot()
|
||||||
|
{
|
||||||
|
m_screenshot = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Device::initSignals()
|
void Device::initSignals()
|
||||||
{
|
{
|
||||||
if (m_controller && m_videoForm) {
|
if (m_controller && m_videoForm) {
|
||||||
connect(m_controller, &Controller::grabCursor, m_videoForm, &VideoForm::onGrabCursor);
|
connect(m_controller, &Controller::grabCursor, m_videoForm, &VideoForm::onGrabCursor);
|
||||||
|
connect(m_videoForm, &VideoForm::screenshot, this, &Device::onScreenshot);
|
||||||
}
|
}
|
||||||
if (m_videoForm) {
|
if (m_videoForm) {
|
||||||
connect(m_videoForm, &VideoForm::destroyed, this, [this](QObject *obj){
|
connect(m_videoForm, &VideoForm::destroyed, this, [this](QObject *obj){
|
||||||
|
@ -120,7 +132,7 @@ void Device::initSignals()
|
||||||
QMessageBox::warning(m_videoForm, "QtScrcpy", tr("wait current %1 to complete").arg(tips), QMessageBox::Ok);
|
QMessageBox::warning(m_videoForm, "QtScrcpy", tr("wait current %1 to complete").arg(tips), QMessageBox::Ok);
|
||||||
}
|
}
|
||||||
if (FileHandler::FAR_SUCCESS_EXEC == processResult && m_videoForm) {
|
if (FileHandler::FAR_SUCCESS_EXEC == processResult && m_videoForm) {
|
||||||
QMessageBox::information(m_videoForm, "QtScrcpy", tr("%1 complete, save in %2").arg(tips).arg(m_fileHandler->getDevicePath()), QMessageBox::Ok);
|
QMessageBox::information(m_videoForm, "QtScrcpy", tr("%1 complete, save in %2").arg(tips).arg(Config::getInstance().getPushFilePath()), QMessageBox::Ok);
|
||||||
}
|
}
|
||||||
if (FileHandler::FAR_ERROR_EXEC == processResult && m_videoForm) {
|
if (FileHandler::FAR_ERROR_EXEC == processResult && m_videoForm) {
|
||||||
QMessageBox::information(m_videoForm, "QtScrcpy", tr("%1 failed").arg(tips), QMessageBox::Ok);
|
QMessageBox::information(m_videoForm, "QtScrcpy", tr("%1 failed").arg(tips), QMessageBox::Ok);
|
||||||
|
@ -138,7 +150,7 @@ void Device::initSignals()
|
||||||
});
|
});
|
||||||
connect(m_server, &Server::connectToResult, this, [this](bool success, const QString &deviceName, const QSize &size){
|
connect(m_server, &Server::connectToResult, this, [this](bool success, const QString &deviceName, const QSize &size){
|
||||||
if (success) {
|
if (success) {
|
||||||
float diff = m_startTimeCount.elapsed() / 1000.0f;
|
double diff = m_startTimeCount.elapsed() / 1000.0;
|
||||||
qInfo(QString("server start finish in %1s").arg(diff).toStdString().c_str());
|
qInfo(QString("server start finish in %1s").arg(diff).toStdString().c_str());
|
||||||
|
|
||||||
// update ui
|
// update ui
|
||||||
|
@ -189,6 +201,12 @@ void Device::initSignals()
|
||||||
if (m_videoForm) {
|
if (m_videoForm) {
|
||||||
m_videoForm->updateRender(frame);
|
m_videoForm->updateRender(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// screenshot
|
||||||
|
if (m_screenshot) {
|
||||||
|
saveFrame(frame);
|
||||||
|
m_screenshot = false;
|
||||||
|
}
|
||||||
m_vb->unLock();
|
m_vb->unLock();
|
||||||
},Qt::QueuedConnection);
|
},Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
@ -216,3 +234,56 @@ void Device::startServer()
|
||||||
m_server->start(params);
|
m_server->start(params);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Device::saveFrame(const AVFrame* frame)
|
||||||
|
{
|
||||||
|
if (!frame) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create buffer
|
||||||
|
QImage rgbImage(frame->width, frame->height, QImage::Format_RGB32);
|
||||||
|
AVFrame* rgbFrame = av_frame_alloc();
|
||||||
|
if (!rgbFrame) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind buffer to AVFrame
|
||||||
|
av_image_fill_arrays(rgbFrame->data, rgbFrame->linesize, rgbImage.bits(), AV_PIX_FMT_RGB32, frame->width, frame->height, 4);
|
||||||
|
|
||||||
|
// convert
|
||||||
|
AVFrameConvert convert;
|
||||||
|
convert.setSrcFrameInfo(frame->width, frame->height, AV_PIX_FMT_YUV420P);
|
||||||
|
convert.setDstFrameInfo(frame->width, frame->height, AV_PIX_FMT_RGB32);
|
||||||
|
bool ret = false;
|
||||||
|
ret = convert.init();
|
||||||
|
if (!ret) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ret = convert.convert(frame, rgbFrame);
|
||||||
|
if (!ret) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
convert.deInit();
|
||||||
|
av_free(rgbFrame);
|
||||||
|
|
||||||
|
// save
|
||||||
|
QString absFilePath;
|
||||||
|
QString fileDir(Config::getInstance().getRecordPath());
|
||||||
|
if (fileDir.isEmpty()) {
|
||||||
|
qWarning() << "please select record save path!!!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QDateTime dateTime = QDateTime::currentDateTime();
|
||||||
|
QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz");
|
||||||
|
fileName = Config::getInstance().getTitle() + fileName + ".jpg";
|
||||||
|
QDir dir(fileDir);
|
||||||
|
absFilePath = dir.absoluteFilePath(fileName);
|
||||||
|
ret = rgbImage.save(absFilePath);
|
||||||
|
if (!ret) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qInfo() << "screenshot save to " << absFilePath;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -12,21 +12,23 @@ class FileHandler;
|
||||||
class Stream;
|
class Stream;
|
||||||
class VideoForm;
|
class VideoForm;
|
||||||
class Controller;
|
class Controller;
|
||||||
|
struct AVFrame;
|
||||||
class Device : public QObject
|
class Device : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
struct DeviceParams {
|
struct DeviceParams {
|
||||||
QString recordFileName = ""; // 视频录制文件名
|
QString recordFileName = ""; // 视频录制文件名
|
||||||
QString serial = ""; // 设备序列号
|
QString serial = ""; // 设备序列号
|
||||||
quint16 localPort = 27183; // reverse时本地监听端口
|
quint16 localPort = 27183; // reverse时本地监听端口
|
||||||
quint16 maxSize = 720; // 视频分辨率
|
quint16 maxSize = 720; // 视频分辨率
|
||||||
quint32 bitRate = 8000000; // 视频比特率
|
quint32 bitRate = 8000000; // 视频比特率
|
||||||
quint32 maxFps = 60; // 视频最大帧率
|
quint32 maxFps = 60; // 视频最大帧率
|
||||||
bool closeScreen = false; // 启动时自动息屏
|
bool closeScreen = false; // 启动时自动息屏
|
||||||
bool useReverse = true; // true:先使用adb reverse,失败后自动使用adb forward;false:直接使用adb forward
|
bool useReverse = true; // true:先使用adb reverse,失败后自动使用adb forward;false:直接使用adb forward
|
||||||
bool display = true; // 是否显示画面(或者仅仅后台录制)
|
bool display = true; // 是否显示画面(或者仅仅后台录制)
|
||||||
QString gameScript = ""; // 游戏映射脚本
|
QString gameScript = ""; // 游戏映射脚本
|
||||||
|
bool renderExpiredFrames = false; // 是否渲染延迟视频帧
|
||||||
};
|
};
|
||||||
explicit Device(DeviceParams params, QObject *parent = nullptr);
|
explicit Device(DeviceParams params, QObject *parent = nullptr);
|
||||||
virtual ~Device();
|
virtual ~Device();
|
||||||
|
@ -40,9 +42,13 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void deviceDisconnect(QString serial);
|
void deviceDisconnect(QString serial);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onScreenshot();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initSignals();
|
void initSignals();
|
||||||
void startServer();
|
void startServer();
|
||||||
|
bool saveFrame(const AVFrame* frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// server relevant
|
// server relevant
|
||||||
|
@ -59,6 +65,8 @@ private:
|
||||||
|
|
||||||
QTime m_startTimeCount;
|
QTime m_startTimeCount;
|
||||||
DeviceParams m_params;
|
DeviceParams m_params;
|
||||||
|
|
||||||
|
bool m_screenshot = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICE_H
|
#endif // DEVICE_H
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "filehandler.h"
|
#include "filehandler.h"
|
||||||
|
|
||||||
#define DEVICE_SDCARD_PATH "/sdcard/"
|
|
||||||
|
|
||||||
FileHandler::FileHandler(QObject *parent)
|
FileHandler::FileHandler(QObject *parent)
|
||||||
: QObject (parent)
|
: QObject (parent)
|
||||||
{
|
{
|
||||||
|
@ -32,12 +30,9 @@ void FileHandler::pushFileRequest(const QString &serial, const QString &file, co
|
||||||
emit fileHandlerResult(FAR_IS_RUNNING, false);
|
emit fileHandlerResult(FAR_IS_RUNNING, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_devicePath = devicePath;
|
|
||||||
if (m_devicePath.isEmpty()) {
|
|
||||||
m_devicePath = DEVICE_SDCARD_PATH;
|
|
||||||
}
|
|
||||||
m_isApk = false;
|
m_isApk = false;
|
||||||
m_adb.push(serial, file, m_devicePath);
|
m_adb.push(serial, file, devicePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileHandler::installApkRequest(const QString &serial, const QString &apkFile)
|
void FileHandler::installApkRequest(const QString &serial, const QString &apkFile)
|
||||||
|
@ -46,12 +41,6 @@ void FileHandler::installApkRequest(const QString &serial, const QString &apkFil
|
||||||
emit fileHandlerResult(FAR_IS_RUNNING, true);
|
emit fileHandlerResult(FAR_IS_RUNNING, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_devicePath = "";
|
|
||||||
m_isApk = true;
|
m_isApk = true;
|
||||||
m_adb.install(serial, apkFile);
|
m_adb.install(serial, apkFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &FileHandler::getDevicePath()
|
|
||||||
{
|
|
||||||
return m_devicePath;
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
|
|
||||||
#define DEVICE_NAME_FIELD_LENGTH 64
|
#define DEVICE_NAME_FIELD_LENGTH 64
|
||||||
#define SOCKET_NAME "scrcpy"
|
#define SOCKET_NAME "scrcpy"
|
||||||
#define MAX_CONNECT_COUNT 30
|
#define MAX_CONNECT_COUNT 30
|
||||||
|
@ -68,7 +67,7 @@ bool Server::pushServer()
|
||||||
if (m_workProcess.isRuning()) {
|
if (m_workProcess.isRuning()) {
|
||||||
m_workProcess.kill();
|
m_workProcess.kill();
|
||||||
}
|
}
|
||||||
m_workProcess.push(m_params.serial, getServerPath(), DEVICE_SERVER_PATH);
|
m_workProcess.push(m_params.serial, getServerPath(), Config::getInstance().getServerPath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +125,7 @@ bool Server::execute()
|
||||||
}
|
}
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << "shell";
|
args << "shell";
|
||||||
args << QString("CLASSPATH=%1").arg(DEVICE_SERVER_PATH);
|
args << QString("CLASSPATH=%1").arg(Config::getInstance().getServerPath());
|
||||||
args << "app_process";
|
args << "app_process";
|
||||||
args << "/"; // unused;
|
args << "/"; // unused;
|
||||||
args << "com.genymobile.scrcpy.Server";
|
args << "com.genymobile.scrcpy.Server";
|
||||||
|
|
|
@ -82,8 +82,8 @@ private:
|
||||||
QPointer<QTcpSocket> m_controlSocket = Q_NULLPTR;
|
QPointer<QTcpSocket> m_controlSocket = Q_NULLPTR;
|
||||||
bool m_tunnelEnabled = false;
|
bool m_tunnelEnabled = false;
|
||||||
bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse"
|
bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse"
|
||||||
quint32 m_acceptTimeoutTimer = 0;
|
int m_acceptTimeoutTimer = 0;
|
||||||
quint32 m_connectTimeoutTimer = 0;
|
int m_connectTimeoutTimer = 0;
|
||||||
quint32 m_connectCount = 0;
|
quint32 m_connectCount = 0;
|
||||||
quint32 m_restartCount = 0;
|
quint32 m_restartCount = 0;
|
||||||
QString m_deviceName = "";
|
QString m_deviceName = "";
|
||||||
|
|
|
@ -20,9 +20,6 @@ ToolForm::ToolForm(QWidget* adsorbWidget, AdsorbPositions adsorbPos)
|
||||||
m_videoForm = dynamic_cast<VideoForm*>(adsorbWidget);
|
m_videoForm = dynamic_cast<VideoForm*>(adsorbWidget);
|
||||||
|
|
||||||
initStyle();
|
initStyle();
|
||||||
|
|
||||||
// TODO
|
|
||||||
ui->screenShotBtn->hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolForm::~ToolForm()
|
ToolForm::~ToolForm()
|
||||||
|
@ -69,11 +66,13 @@ void ToolForm::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
|
||||||
void ToolForm::showEvent(QShowEvent *event)
|
void ToolForm::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
qDebug() << "show event";
|
qDebug() << "show event";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolForm::hideEvent(QHideEvent *event)
|
void ToolForm::hideEvent(QHideEvent *event)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
qDebug() << "hide event";
|
qDebug() << "hide event";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +120,7 @@ void ToolForm::on_powerBtn_clicked()
|
||||||
|
|
||||||
void ToolForm::on_screenShotBtn_clicked()
|
void ToolForm::on_screenShotBtn_clicked()
|
||||||
{
|
{
|
||||||
// TODO
|
emit screenshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolForm::on_volumeUpBtn_clicked()
|
void ToolForm::on_volumeUpBtn_clicked()
|
||||||
|
|
|
@ -27,6 +27,9 @@ protected:
|
||||||
void showEvent(QShowEvent *event);
|
void showEvent(QShowEvent *event);
|
||||||
void hideEvent(QHideEvent *event);
|
void hideEvent(QHideEvent *event);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void screenshot();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_fullScreenBtn_clicked();
|
void on_fullScreenBtn_clicked();
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "toolform.h"
|
#include "toolform.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "filehandler.h"
|
#include "filehandler.h"
|
||||||
|
#include "config.h"
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "libavutil/frame.h"
|
#include "libavutil/frame.h"
|
||||||
|
@ -92,6 +93,8 @@ void VideoForm::showToolForm(bool show)
|
||||||
if (!m_toolForm) {
|
if (!m_toolForm) {
|
||||||
m_toolForm = new ToolForm(this, ToolForm::AP_OUTSIDE_RIGHT);
|
m_toolForm = new ToolForm(this, ToolForm::AP_OUTSIDE_RIGHT);
|
||||||
m_toolForm->move(pos().x() + geometry().width(), pos().y() + 30);
|
m_toolForm->move(pos().x() + geometry().width(), pos().y() + 30);
|
||||||
|
|
||||||
|
connect(m_toolForm, &ToolForm::screenshot, this, &VideoForm::screenshot);
|
||||||
}
|
}
|
||||||
m_toolForm->setVisible(show);
|
m_toolForm->setVisible(show);
|
||||||
}
|
}
|
||||||
|
@ -349,7 +352,6 @@ void VideoForm::keyPressEvent(QKeyEvent *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//qDebug() << "keyPressEvent" << event->isAutoRepeat();
|
|
||||||
m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size());
|
m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +360,6 @@ void VideoForm::keyReleaseEvent(QKeyEvent *event)
|
||||||
if (!m_controller) {
|
if (!m_controller) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//qDebug() << "keyReleaseEvent" << event->isAutoRepeat();
|
|
||||||
m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size());
|
m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,5 +413,5 @@ void VideoForm::dropEvent(QDropEvent *event)
|
||||||
m_fileHandler->installApkRequest(m_serial, file);
|
m_fileHandler->installApkRequest(m_serial, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_fileHandler->pushFileRequest(m_serial, file);
|
m_fileHandler->pushFileRequest(m_serial, file, Config::getInstance().getPushFilePath() + fileInfo.fileName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ public:
|
||||||
void setFileHandler(FileHandler *fileHandler);
|
void setFileHandler(FileHandler *fileHandler);
|
||||||
void setSerial(const QString &serial);
|
void setSerial(const QString &serial);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void screenshot();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onGrabCursor(bool grab);
|
void onGrabCursor(bool grab);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,10 @@ bool DeviceManage::connectDevice(Device::DeviceParams params)
|
||||||
|
|
||||||
void DeviceManage::updateScript(QString script)
|
void DeviceManage::updateScript(QString script)
|
||||||
{
|
{
|
||||||
|
if (m_devices.isEmpty()) {
|
||||||
|
qWarning() << "no device connect!!!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
QMapIterator<QString, QPointer<Device>> i(m_devices);
|
QMapIterator<QString, QPointer<Device>> i(m_devices);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
#include "ui_dialog.h"
|
#include "ui_dialog.h"
|
||||||
|
@ -46,14 +47,18 @@ Dialog::Dialog(QWidget *parent) :
|
||||||
}
|
}
|
||||||
} else if (args.contains("show") && args.contains("wlan0")) {
|
} else if (args.contains("show") && args.contains("wlan0")) {
|
||||||
QString ip = m_adb.getDeviceIPFromStdOut();
|
QString ip = m_adb.getDeviceIPFromStdOut();
|
||||||
if (!ip.isEmpty()) {
|
if (ip.isEmpty()) {
|
||||||
ui->deviceIpEdt->setText(ip);
|
log = "ip not find, connect to wifi?";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
ui->deviceIpEdt->setText(ip);
|
||||||
} else if (args.contains("ifconfig") && args.contains("wlan0")) {
|
} else if (args.contains("ifconfig") && args.contains("wlan0")) {
|
||||||
QString ip = m_adb.getDeviceIPFromStdOut();
|
QString ip = m_adb.getDeviceIPFromStdOut();
|
||||||
if (!ip.isEmpty()) {
|
if (ip.isEmpty()) {
|
||||||
ui->deviceIpEdt->setText(ip);
|
log = "ip not find, connect to wifi?";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
ui->deviceIpEdt->setText(ip);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -91,11 +96,6 @@ void Dialog::initUI()
|
||||||
ui->formatBox->addItem("mp4");
|
ui->formatBox->addItem("mp4");
|
||||||
ui->formatBox->addItem("mkv");
|
ui->formatBox->addItem("mkv");
|
||||||
|
|
||||||
#ifndef Q_OS_WIN32
|
|
||||||
// game only windows
|
|
||||||
ui->gameCheck->setEnabled(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ui->recordPathEdt->setText(Config::getInstance().getRecordPath());
|
ui->recordPathEdt->setText(Config::getInstance().getRecordPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,14 +137,16 @@ void Dialog::on_startServerBtn_clicked()
|
||||||
outLog("start server...", false);
|
outLog("start server...", false);
|
||||||
|
|
||||||
QString absFilePath;
|
QString absFilePath;
|
||||||
QString fileDir(ui->recordPathEdt->text().trimmed());
|
if (ui->recordScreenCheck->isChecked()) {
|
||||||
if (!fileDir.isEmpty()) {
|
QString fileDir(ui->recordPathEdt->text().trimmed());
|
||||||
QDateTime dateTime = QDateTime::currentDateTime();
|
if (!fileDir.isEmpty()) {
|
||||||
QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz");
|
QDateTime dateTime = QDateTime::currentDateTime();
|
||||||
QString ext = ui->formatBox->currentText().trimmed();
|
QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz");
|
||||||
fileName = windowTitle() + fileName + "." + ext;
|
QString ext = ui->formatBox->currentText().trimmed();
|
||||||
QDir dir(fileDir);
|
fileName = windowTitle() + fileName + "." + ext;
|
||||||
absFilePath = dir.absoluteFilePath(fileName);
|
QDir dir(fileDir);
|
||||||
|
absFilePath = dir.absoluteFilePath(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 bitRate = ui->bitRateBox->currentText().trimmed().toUInt();
|
quint32 bitRate = ui->bitRateBox->currentText().trimmed().toUInt();
|
||||||
|
@ -155,18 +157,13 @@ void Dialog::on_startServerBtn_clicked()
|
||||||
params.maxSize = videoSize;
|
params.maxSize = videoSize;
|
||||||
params.bitRate = bitRate;
|
params.bitRate = bitRate;
|
||||||
// on devices with Android >= 10, the capture frame rate can be limited
|
// on devices with Android >= 10, the capture frame rate can be limited
|
||||||
params.maxFps = Config::getInstance().getMaxFps();
|
params.maxFps = static_cast<quint32>(Config::getInstance().getMaxFps());
|
||||||
params.recordFileName = absFilePath;
|
params.recordFileName = absFilePath;
|
||||||
params.closeScreen = ui->closeScreenCheck->isChecked();
|
params.closeScreen = ui->closeScreenCheck->isChecked();
|
||||||
params.useReverse = ui->useReverseCheck->isChecked();
|
params.useReverse = ui->useReverseCheck->isChecked();
|
||||||
params.display = !ui->notDisplayCheck->isChecked();
|
params.display = !ui->notDisplayCheck->isChecked();
|
||||||
if (ui->gameCheck->isChecked()) {
|
params.renderExpiredFrames = Config::getInstance().getRenderExpiredFrames();
|
||||||
if (ui->gameBox->currentText().isEmpty()) {
|
|
||||||
outLog("no keymap script selected", true);
|
|
||||||
} else {
|
|
||||||
params.gameScript = getGameScript(ui->gameBox->currentText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_deviceManage.connectDevice(params);
|
m_deviceManage.connectDevice(params);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -232,6 +229,17 @@ void Dialog::outLog(const QString &log, bool newLine)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Dialog::filterLog(const QString &log)
|
||||||
|
{
|
||||||
|
if (log.contains("app_proces")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (log.contains("Unable to set geometry")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Dialog::checkAdbRun()
|
bool Dialog::checkAdbRun()
|
||||||
{
|
{
|
||||||
if (m_adb.isRuning()) {
|
if (m_adb.isRuning()) {
|
||||||
|
@ -340,9 +348,15 @@ void Dialog::on_applyScriptBtn_clicked()
|
||||||
m_deviceManage.updateScript(getGameScript(ui->gameBox->currentText()));
|
m_deviceManage.updateScript(getGameScript(ui->gameBox->currentText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialog::on_gameCheck_clicked(bool checked)
|
void Dialog::on_recordScreenCheck_clicked(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (!checked) {
|
||||||
on_refreshGameScriptBtn_clicked();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fileDir(ui->recordPathEdt->text().trimmed());
|
||||||
|
if (fileDir.isEmpty()) {
|
||||||
|
qWarning() << "please select record save path!!!";
|
||||||
|
ui->recordScreenCheck->setChecked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
~Dialog();
|
~Dialog();
|
||||||
|
|
||||||
void outLog(const QString& log, bool newLine = true);
|
void outLog(const QString& log, bool newLine = true);
|
||||||
|
bool filterLog(const QString & log);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_updateDevice_clicked();
|
void on_updateDevice_clicked();
|
||||||
|
@ -50,8 +51,10 @@ private slots:
|
||||||
void on_stopAllServerBtn_clicked();
|
void on_stopAllServerBtn_clicked();
|
||||||
|
|
||||||
void on_refreshGameScriptBtn_clicked();
|
void on_refreshGameScriptBtn_clicked();
|
||||||
|
|
||||||
void on_applyScriptBtn_clicked();
|
void on_applyScriptBtn_clicked();
|
||||||
void on_gameCheck_clicked(bool checked);
|
|
||||||
|
void on_recordScreenCheck_clicked(bool checked);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool checkAdbRun();
|
bool checkAdbRun();
|
||||||
|
|
|
@ -6,119 +6,431 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>513</width>
|
<width>420</width>
|
||||||
<height>495</height>
|
<height>471</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>420</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>600</width>
|
<width>420</width>
|
||||||
<height>2160</height>
|
<height>16777215</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">QtScrcpy</string>
|
<string notr="true">QtScrcpy</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item row="2" column="0">
|
<item>
|
||||||
<widget class="QGroupBox" name="usbGroupBox">
|
<widget class="QGroupBox" name="configGroupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>USB line</string>
|
<string>Start Config</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item row="0" column="1">
|
<property name="spacing">
|
||||||
<widget class="QComboBox" name="serialBox"/>
|
<number>3</number>
|
||||||
</item>
|
</property>
|
||||||
<item row="0" column="0">
|
<property name="leftMargin">
|
||||||
<widget class="QLabel" name="label_2">
|
<number>5</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>device serial:</string>
|
<property name="topMargin">
|
||||||
</property>
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="configWidget1" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>bit rate:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="bitRateBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="currentText">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>max size:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="maxSizeBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>record format:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="formatBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="2">
|
<item>
|
||||||
<widget class="QPushButton" name="getIPBtn">
|
<widget class="QWidget" name="configWidget2" native="true">
|
||||||
<property name="text">
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
<string>get device IP</string>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="autoDefault">
|
</property>
|
||||||
<bool>false</bool>
|
<property name="topMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>record save path:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>recordPathEdt</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="recordPathEdt">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectRecordPathBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>select path</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item>
|
||||||
<widget class="QPushButton" name="updateDevice">
|
<widget class="QWidget" name="configWidget4" native="true">
|
||||||
<property name="text">
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
<string>refresh devices</string>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="autoDefault">
|
</property>
|
||||||
<bool>false</bool>
|
<property name="topMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="gameBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="refreshGameScriptBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>refresh script</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="applyScriptBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>apply</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
<item>
|
||||||
<widget class="QPushButton" name="startServerBtn">
|
<widget class="QWidget" name="configWidget3" native="true">
|
||||||
<property name="text">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<string>start server</string>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="autoDefault">
|
</property>
|
||||||
<bool>false</bool>
|
<property name="topMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="rightMargin">
|
||||||
<item row="3" column="0">
|
<number>0</number>
|
||||||
<widget class="QPushButton" name="stopAllServerBtn">
|
</property>
|
||||||
<property name="text">
|
<property name="bottomMargin">
|
||||||
<string>stop all server</string>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<item row="0" column="0">
|
||||||
</item>
|
<widget class="QCheckBox" name="recordScreenCheck">
|
||||||
<item row="0" column="3">
|
<property name="text">
|
||||||
<widget class="QPushButton" name="stopServerBtn">
|
<string>record screen</string>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>stop server</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="autoDefault">
|
<item row="1" column="1">
|
||||||
<bool>false</bool>
|
<widget class="QCheckBox" name="closeScreenCheck">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
</widget>
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
</item>
|
<horstretch>0</horstretch>
|
||||||
<item row="3" column="3">
|
<verstretch>0</verstretch>
|
||||||
<widget class="QPushButton" name="startAdbdBtn">
|
</sizepolicy>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>start adbd</string>
|
<property name="text">
|
||||||
</property>
|
<string>screen-off</string>
|
||||||
<property name="autoDefault">
|
</property>
|
||||||
<bool>false</bool>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QCheckBox" name="notDisplayCheck">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>background record</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QCheckBox" name="useReverseCheck">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>reverse connection</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="alwaysTopCheck">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>always on top</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item>
|
||||||
|
<widget class="QGroupBox" name="usbGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>USB line</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="usbWidget1" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>device serial:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="serialBox"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="startServerBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>start server</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="stopServerBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>stop server</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="usbWidget2" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="stopAllServerBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>stop all server</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="updateDevice">
|
||||||
|
<property name="text">
|
||||||
|
<string>refresh devices</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="getIPBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>get device IP</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="startAdbdBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>start adbd</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QGroupBox" name="wirelessGroupBox">
|
<widget class="QGroupBox" name="wirelessGroupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Wireless</string>
|
<string>Wireless</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_4" columnstretch="2,0,0,1,2,0">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item row="4" column="4">
|
<property name="spacing">
|
||||||
<widget class="QPushButton" name="wirelessConnectBtn">
|
<number>3</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<property name="leftMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>5</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="topMargin">
|
||||||
</property>
|
<number>5</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>wireless connect</string>
|
<property name="rightMargin">
|
||||||
</property>
|
<number>5</number>
|
||||||
<property name="autoDefault">
|
</property>
|
||||||
<bool>false</bool>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>5</number>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<item>
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLineEdit" name="deviceIpEdt">
|
<widget class="QLineEdit" name="deviceIpEdt">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
|
@ -131,7 +443,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="2">
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
|
@ -150,8 +462,20 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="3">
|
<item>
|
||||||
<widget class="QLineEdit" name="devicePortEdt">
|
<widget class="QLineEdit" name="devicePortEdt">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
@ -163,10 +487,26 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="5">
|
<item>
|
||||||
|
<widget class="QPushButton" name="wirelessConnectBtn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>wireless connect</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QPushButton" name="wirelessDisConnectBtn">
|
<widget class="QPushButton" name="wirelessDisConnectBtn">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
|
@ -182,7 +522,87 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item>
|
||||||
|
<widget class="QGroupBox" name="adbGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string notr="true">adb</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>adb command:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>adbCommandEdt</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="adbCommandEdt">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">devices</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="adbCommandBtn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>execute</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="stopAdbBtn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>terminate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="clearOut">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>clear</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QTextEdit" name="outEdit">
|
<widget class="QTextEdit" name="outEdit">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
|
@ -201,232 +621,10 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QGroupBox" name="adbGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string notr="true">adb</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_5">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>adb command:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>adbCommandEdt</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3">
|
|
||||||
<widget class="QPushButton" name="stopAdbBtn">
|
|
||||||
<property name="text">
|
|
||||||
<string>terminate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QPushButton" name="adbCommandBtn">
|
|
||||||
<property name="text">
|
|
||||||
<string>execute</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="adbCommandEdt">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">devices</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="4">
|
|
||||||
<widget class="QPushButton" name="clearOut">
|
|
||||||
<property name="text">
|
|
||||||
<string>clear</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QGroupBox" name="configGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Start Config</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>bit rate:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="9" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>record format:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>record save path:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>recordPathEdt</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="11">
|
|
||||||
<widget class="QComboBox" name="formatBox"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="6" colspan="2">
|
|
||||||
<widget class="QPushButton" name="refreshGameScriptBtn">
|
|
||||||
<property name="text">
|
|
||||||
<string>refresh script</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="9" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="useReverseCheck">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>reverse connection</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="10" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="gameCheck">
|
|
||||||
<property name="text">
|
|
||||||
<string>auto enable</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="3" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="alwaysTopCheck">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>always on top</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="notDisplayCheck">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>background record</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="6" colspan="3">
|
|
||||||
<widget class="QCheckBox" name="closeScreenCheck">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>screen-off</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="10" colspan="2">
|
|
||||||
<widget class="QPushButton" name="selectRecordPathBtn">
|
|
||||||
<property name="text">
|
|
||||||
<string>select path</string>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="6">
|
|
||||||
<widget class="QComboBox" name="gameBox"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="3" colspan="7">
|
|
||||||
<widget class="QLineEdit" name="recordPathEdt">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2" colspan="2">
|
|
||||||
<widget class="QComboBox" name="bitRateBox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="currentText">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="8" colspan="2">
|
|
||||||
<widget class="QPushButton" name="applyScriptBtn">
|
|
||||||
<property name="text">
|
|
||||||
<string>apply</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="7" colspan="2">
|
|
||||||
<widget class="QComboBox" name="maxSizeBox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="4" colspan="3">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>max size:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>bitRateBox</tabstop>
|
|
||||||
<tabstop>formatBox</tabstop>
|
|
||||||
<tabstop>recordPathEdt</tabstop>
|
|
||||||
<tabstop>selectRecordPathBtn</tabstop>
|
|
||||||
<tabstop>gameBox</tabstop>
|
|
||||||
<tabstop>refreshGameScriptBtn</tabstop>
|
|
||||||
<tabstop>serialBox</tabstop>
|
|
||||||
<tabstop>startServerBtn</tabstop>
|
|
||||||
<tabstop>stopServerBtn</tabstop>
|
|
||||||
<tabstop>stopAllServerBtn</tabstop>
|
|
||||||
<tabstop>updateDevice</tabstop>
|
|
||||||
<tabstop>getIPBtn</tabstop>
|
|
||||||
<tabstop>startAdbdBtn</tabstop>
|
|
||||||
<tabstop>deviceIpEdt</tabstop>
|
<tabstop>deviceIpEdt</tabstop>
|
||||||
<tabstop>devicePortEdt</tabstop>
|
<tabstop>devicePortEdt</tabstop>
|
||||||
<tabstop>wirelessConnectBtn</tabstop>
|
<tabstop>wirelessConnectBtn</tabstop>
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
#include "mousetap/mousetap.h"
|
#include "mousetap/mousetap.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
Dialog* g_mainDlg = Q_NULLPTR;
|
static Dialog* g_mainDlg = Q_NULLPTR;
|
||||||
|
|
||||||
QtMessageHandler g_oldMessageHandler = Q_NULLPTR;
|
static QtMessageHandler g_oldMessageHandler = Q_NULLPTR;
|
||||||
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||||
void installTranslator();
|
void installTranslator();
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ void installTranslator() {
|
||||||
static QTranslator translator;
|
static QTranslator translator;
|
||||||
QLocale locale;
|
QLocale locale;
|
||||||
QLocale::Language language = locale.language();
|
QLocale::Language language = locale.language();
|
||||||
|
//language = QLocale::English;
|
||||||
QString languagePath = ":/i18n/";
|
QString languagePath = ":/i18n/";
|
||||||
switch (language) {
|
switch (language) {
|
||||||
case QLocale::Chinese:
|
case QLocale::Chinese:
|
||||||
|
@ -112,7 +113,7 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QtDebugMsg < type) {
|
if (QtDebugMsg < type) {
|
||||||
if (g_mainDlg && g_mainDlg->isVisible() && !msg.contains("app_proces")) {
|
if (g_mainDlg && g_mainDlg->isVisible() && !g_mainDlg->filterLog(msg)) {
|
||||||
g_mainDlg->outLog(msg);
|
g_mainDlg->outLog(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -16,22 +16,22 @@
|
||||||
<translation type="vanished">file transfer failed</translation>
|
<translation type="vanished">file transfer failed</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="115"/>
|
<location filename="../../device/device.cpp" line="127"/>
|
||||||
<source>install apk</source>
|
<source>install apk</source>
|
||||||
<translation>install apk</translation>
|
<translation>install apk</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="117"/>
|
<location filename="../../device/device.cpp" line="129"/>
|
||||||
<source>file transfer</source>
|
<source>file transfer</source>
|
||||||
<translation>file transfer</translation>
|
<translation>file transfer</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="120"/>
|
<location filename="../../device/device.cpp" line="132"/>
|
||||||
<source>wait current %1 to complete</source>
|
<source>wait current %1 to complete</source>
|
||||||
<translation>wait current %1 to complete</translation>
|
<translation>wait current %1 to complete</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="123"/>
|
<location filename="../../device/device.cpp" line="135"/>
|
||||||
<source>%1 complete, save in %2</source>
|
<source>%1 complete, save in %2</source>
|
||||||
<translation>%1 complete, save in %2</translation>
|
<translation>%1 complete, save in %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<translation type="vanished">%1 complete\n save in %2</translation>
|
<translation type="vanished">%1 complete\n save in %2</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="126"/>
|
<location filename="../../device/device.cpp" line="138"/>
|
||||||
<source>%1 failed</source>
|
<source>%1 failed</source>
|
||||||
<translation>%1 failed</translation>
|
<translation>%1 failed</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -49,128 +49,132 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Dialog</name>
|
<name>Dialog</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="102"/>
|
<location filename="../../dialog.ui" line="415"/>
|
||||||
<source>Wireless</source>
|
<source>Wireless</source>
|
||||||
<translation>Wireless</translation>
|
<translation>Wireless</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="114"/>
|
<location filename="../../dialog.ui" line="499"/>
|
||||||
<source>wireless connect</source>
|
<source>wireless connect</source>
|
||||||
<translation>wireless connect</translation>
|
<translation>wireless connect</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="175"/>
|
<location filename="../../dialog.ui" line="515"/>
|
||||||
<source>wireless disconnect</source>
|
<source>wireless disconnect</source>
|
||||||
<translation>wireless disconnect</translation>
|
<translation>wireless disconnect</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="254"/>
|
<location filename="../../dialog.ui" line="32"/>
|
||||||
<source>Start Config</source>
|
<source>Start Config</source>
|
||||||
<translation>Start Config</translation>
|
<translation>Start Config</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="274"/>
|
<location filename="../../dialog.ui" line="127"/>
|
||||||
<source>record save path:</source>
|
<source>record save path:</source>
|
||||||
<translation>record save path:</translation>
|
<translation>record save path:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="362"/>
|
<location filename="../../dialog.ui" line="144"/>
|
||||||
<location filename="../../dialog.cpp" line="287"/>
|
<location filename="../../dialog.cpp" line="294"/>
|
||||||
<source>select path</source>
|
<source>select path</source>
|
||||||
<translation>select path</translation>
|
<translation>select path</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="267"/>
|
<location filename="../../dialog.ui" line="99"/>
|
||||||
<source>record format:</source>
|
<source>record format:</source>
|
||||||
<translation>record format:</translation>
|
<translation>record format:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="72"/>
|
<location filename="../../dialog.ui" line="214"/>
|
||||||
|
<source>record screen</source>
|
||||||
|
<translation>record screen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../dialog.ui" line="372"/>
|
||||||
<source>stop all server</source>
|
<source>stop all server</source>
|
||||||
<translation>stop all server</translation>
|
<translation>stop all server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="213"/>
|
<location filename="../../dialog.ui" line="549"/>
|
||||||
<source>adb command:</source>
|
<source>adb command:</source>
|
||||||
<translation>adb command:</translation>
|
<translation>adb command:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="223"/>
|
<location filename="../../dialog.ui" line="585"/>
|
||||||
<source>terminate</source>
|
<source>terminate</source>
|
||||||
<translation>terminate</translation>
|
<translation>terminate</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="230"/>
|
<location filename="../../dialog.ui" line="572"/>
|
||||||
<source>execute</source>
|
<source>execute</source>
|
||||||
<translation>execute</translation>
|
<translation>execute</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="244"/>
|
<location filename="../../dialog.ui" line="598"/>
|
||||||
<source>clear</source>
|
<source>clear</source>
|
||||||
<translation>clear</translation>
|
<translation>clear</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="300"/>
|
<location filename="../../dialog.ui" line="256"/>
|
||||||
<source>reverse connection</source>
|
<source>reverse connection</source>
|
||||||
<translation>reverse connection</translation>
|
<translation>reverse connection</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="310"/>
|
|
||||||
<source>auto enable</source>
|
<source>auto enable</source>
|
||||||
<translation>auto enable</translation>
|
<translation type="vanished">auto enable</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="339"/>
|
<location filename="../../dialog.ui" line="240"/>
|
||||||
<source>background record</source>
|
<source>background record</source>
|
||||||
<translation>background record</translation>
|
<translation>background record</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="355"/>
|
<location filename="../../dialog.ui" line="227"/>
|
||||||
<source>screen-off</source>
|
<source>screen-off</source>
|
||||||
<translation>screen-off</translation>
|
<translation>screen-off</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="392"/>
|
<location filename="../../dialog.ui" line="189"/>
|
||||||
<source>apply</source>
|
<source>apply</source>
|
||||||
<translation>apply</translation>
|
<translation>apply</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="406"/>
|
<location filename="../../dialog.ui" line="85"/>
|
||||||
<source>max size:</source>
|
<source>max size:</source>
|
||||||
<translation>max size:</translation>
|
<translation>max size:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="323"/>
|
<location filename="../../dialog.ui" line="272"/>
|
||||||
<source>always on top</source>
|
<source>always on top</source>
|
||||||
<translation>always on top</translation>
|
<translation>always on top</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="287"/>
|
<location filename="../../dialog.ui" line="182"/>
|
||||||
<source>refresh script</source>
|
<source>refresh script</source>
|
||||||
<translation>refresh script</translation>
|
<translation>refresh script</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="42"/>
|
<location filename="../../dialog.ui" line="389"/>
|
||||||
<source>get device IP</source>
|
<source>get device IP</source>
|
||||||
<translation>get device IP</translation>
|
<translation>get device IP</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="26"/>
|
<location filename="../../dialog.ui" line="288"/>
|
||||||
<source>USB line</source>
|
<source>USB line</source>
|
||||||
<translation>USB line</translation>
|
<translation>USB line</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="79"/>
|
<location filename="../../dialog.ui" line="344"/>
|
||||||
<source>stop server</source>
|
<source>stop server</source>
|
||||||
<translation>stop server</translation>
|
<translation>stop server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="62"/>
|
<location filename="../../dialog.ui" line="334"/>
|
||||||
<source>start server</source>
|
<source>start server</source>
|
||||||
<translation>start server</translation>
|
<translation>start server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="35"/>
|
<location filename="../../dialog.ui" line="324"/>
|
||||||
<source>device serial:</source>
|
<source>device serial:</source>
|
||||||
<translation>device serial:</translation>
|
<translation>device serial:</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -179,17 +183,17 @@
|
||||||
<translation type="vanished">Config</translation>
|
<translation type="vanished">Config</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="260"/>
|
<location filename="../../dialog.ui" line="68"/>
|
||||||
<source>bit rate:</source>
|
<source>bit rate:</source>
|
||||||
<translation>bit rate:</translation>
|
<translation>bit rate:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="89"/>
|
<location filename="../../dialog.ui" line="399"/>
|
||||||
<source>start adbd</source>
|
<source>start adbd</source>
|
||||||
<translation>start adbd</translation>
|
<translation>start adbd</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="52"/>
|
<location filename="../../dialog.ui" line="379"/>
|
||||||
<source>refresh devices</source>
|
<source>refresh devices</source>
|
||||||
<translation>refresh devices</translation>
|
<translation>refresh devices</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -280,7 +284,7 @@
|
||||||
<translation type="vanished">file transfer failed</translation>
|
<translation type="vanished">file transfer failed</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/ui/videoform.cpp" line="407"/>
|
<location filename="../../device/ui/videoform.cpp" line="408"/>
|
||||||
<source>file does not exist</source>
|
<source>file does not exist</source>
|
||||||
<translation>file does not exist</translation>
|
<translation>file does not exist</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
Binary file not shown.
|
@ -16,22 +16,22 @@
|
||||||
<translation type="vanished">文件传输失败</translation>
|
<translation type="vanished">文件传输失败</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="115"/>
|
<location filename="../../device/device.cpp" line="127"/>
|
||||||
<source>install apk</source>
|
<source>install apk</source>
|
||||||
<translation>安装apk</translation>
|
<translation>安装apk</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="117"/>
|
<location filename="../../device/device.cpp" line="129"/>
|
||||||
<source>file transfer</source>
|
<source>file transfer</source>
|
||||||
<translation>文件传输</translation>
|
<translation>文件传输</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="120"/>
|
<location filename="../../device/device.cpp" line="132"/>
|
||||||
<source>wait current %1 to complete</source>
|
<source>wait current %1 to complete</source>
|
||||||
<translation>等待当前%1完成</translation>
|
<translation>等待当前%1完成</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="123"/>
|
<location filename="../../device/device.cpp" line="135"/>
|
||||||
<source>%1 complete, save in %2</source>
|
<source>%1 complete, save in %2</source>
|
||||||
<translation>%1完成,保存在%2</translation>
|
<translation>%1完成,保存在%2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<translation type="vanished">%1完成\n 保存在 %2</translation>
|
<translation type="vanished">%1完成\n 保存在 %2</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/device.cpp" line="126"/>
|
<location filename="../../device/device.cpp" line="138"/>
|
||||||
<source>%1 failed</source>
|
<source>%1 failed</source>
|
||||||
<translation>%1 失败</translation>
|
<translation>%1 失败</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -49,128 +49,132 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Dialog</name>
|
<name>Dialog</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="102"/>
|
<location filename="../../dialog.ui" line="415"/>
|
||||||
<source>Wireless</source>
|
<source>Wireless</source>
|
||||||
<translation>无线</translation>
|
<translation>无线</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="114"/>
|
<location filename="../../dialog.ui" line="499"/>
|
||||||
<source>wireless connect</source>
|
<source>wireless connect</source>
|
||||||
<translation>无线连接</translation>
|
<translation>无线连接</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="175"/>
|
<location filename="../../dialog.ui" line="515"/>
|
||||||
<source>wireless disconnect</source>
|
<source>wireless disconnect</source>
|
||||||
<translation>无线断开</translation>
|
<translation>无线断开</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="254"/>
|
<location filename="../../dialog.ui" line="32"/>
|
||||||
<source>Start Config</source>
|
<source>Start Config</source>
|
||||||
<translation>启动配置</translation>
|
<translation>启动配置</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="274"/>
|
<location filename="../../dialog.ui" line="127"/>
|
||||||
<source>record save path:</source>
|
<source>record save path:</source>
|
||||||
<translation>录像保存路径:</translation>
|
<translation>录像保存路径:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="362"/>
|
<location filename="../../dialog.ui" line="144"/>
|
||||||
<location filename="../../dialog.cpp" line="287"/>
|
<location filename="../../dialog.cpp" line="294"/>
|
||||||
<source>select path</source>
|
<source>select path</source>
|
||||||
<translation>选择路径</translation>
|
<translation>选择路径</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="267"/>
|
<location filename="../../dialog.ui" line="99"/>
|
||||||
<source>record format:</source>
|
<source>record format:</source>
|
||||||
<translation>录制格式:</translation>
|
<translation>录制格式:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="72"/>
|
<location filename="../../dialog.ui" line="214"/>
|
||||||
|
<source>record screen</source>
|
||||||
|
<translation>录制屏幕</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../dialog.ui" line="372"/>
|
||||||
<source>stop all server</source>
|
<source>stop all server</source>
|
||||||
<translation>停止所有服务</translation>
|
<translation>停止所有服务</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="213"/>
|
<location filename="../../dialog.ui" line="549"/>
|
||||||
<source>adb command:</source>
|
<source>adb command:</source>
|
||||||
<translation>adb命令:</translation>
|
<translation>adb命令:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="223"/>
|
<location filename="../../dialog.ui" line="585"/>
|
||||||
<source>terminate</source>
|
<source>terminate</source>
|
||||||
<translation>终止</translation>
|
<translation>终止</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="230"/>
|
<location filename="../../dialog.ui" line="572"/>
|
||||||
<source>execute</source>
|
<source>execute</source>
|
||||||
<translation>执行</translation>
|
<translation>执行</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="244"/>
|
<location filename="../../dialog.ui" line="598"/>
|
||||||
<source>clear</source>
|
<source>clear</source>
|
||||||
<translation>清理</translation>
|
<translation>清理</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="300"/>
|
<location filename="../../dialog.ui" line="256"/>
|
||||||
<source>reverse connection</source>
|
<source>reverse connection</source>
|
||||||
<translation>反向连接</translation>
|
<translation>反向连接</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="310"/>
|
|
||||||
<source>auto enable</source>
|
<source>auto enable</source>
|
||||||
<translation>自动启用脚本</translation>
|
<translation type="vanished">自动启用脚本</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="339"/>
|
<location filename="../../dialog.ui" line="240"/>
|
||||||
<source>background record</source>
|
<source>background record</source>
|
||||||
<translation>后台录制</translation>
|
<translation>后台录制</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="355"/>
|
<location filename="../../dialog.ui" line="227"/>
|
||||||
<source>screen-off</source>
|
<source>screen-off</source>
|
||||||
<translation>自动息屏</translation>
|
<translation>自动息屏</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="392"/>
|
<location filename="../../dialog.ui" line="189"/>
|
||||||
<source>apply</source>
|
<source>apply</source>
|
||||||
<translation>应用脚本</translation>
|
<translation>应用脚本</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="406"/>
|
<location filename="../../dialog.ui" line="85"/>
|
||||||
<source>max size:</source>
|
<source>max size:</source>
|
||||||
<translation>最大尺寸:</translation>
|
<translation>最大尺寸:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="323"/>
|
<location filename="../../dialog.ui" line="272"/>
|
||||||
<source>always on top</source>
|
<source>always on top</source>
|
||||||
<translation>窗口置顶</translation>
|
<translation>窗口置顶</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="287"/>
|
<location filename="../../dialog.ui" line="182"/>
|
||||||
<source>refresh script</source>
|
<source>refresh script</source>
|
||||||
<translation>刷新脚本</translation>
|
<translation>刷新脚本</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="42"/>
|
<location filename="../../dialog.ui" line="389"/>
|
||||||
<source>get device IP</source>
|
<source>get device IP</source>
|
||||||
<translation>获取设备IP</translation>
|
<translation>获取设备IP</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="26"/>
|
<location filename="../../dialog.ui" line="288"/>
|
||||||
<source>USB line</source>
|
<source>USB line</source>
|
||||||
<translation>USB线</translation>
|
<translation>USB线</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="79"/>
|
<location filename="../../dialog.ui" line="344"/>
|
||||||
<source>stop server</source>
|
<source>stop server</source>
|
||||||
<translation>停止服务</translation>
|
<translation>停止服务</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="62"/>
|
<location filename="../../dialog.ui" line="334"/>
|
||||||
<source>start server</source>
|
<source>start server</source>
|
||||||
<translation>启动服务</translation>
|
<translation>启动服务</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="35"/>
|
<location filename="../../dialog.ui" line="324"/>
|
||||||
<source>device serial:</source>
|
<source>device serial:</source>
|
||||||
<translation>设备序列号:</translation>
|
<translation>设备序列号:</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -179,17 +183,17 @@
|
||||||
<translation type="vanished">配置</translation>
|
<translation type="vanished">配置</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="260"/>
|
<location filename="../../dialog.ui" line="68"/>
|
||||||
<source>bit rate:</source>
|
<source>bit rate:</source>
|
||||||
<translation>比特率:</translation>
|
<translation>比特率:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="89"/>
|
<location filename="../../dialog.ui" line="399"/>
|
||||||
<source>start adbd</source>
|
<source>start adbd</source>
|
||||||
<translation>启动adbd</translation>
|
<translation>启动adbd</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../dialog.ui" line="52"/>
|
<location filename="../../dialog.ui" line="379"/>
|
||||||
<source>refresh devices</source>
|
<source>refresh devices</source>
|
||||||
<translation>刷新设备列表</translation>
|
<translation>刷新设备列表</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -280,7 +284,7 @@
|
||||||
<translation type="vanished">文件传输失败</translation>
|
<translation type="vanished">文件传输失败</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../device/ui/videoform.cpp" line="407"/>
|
<location filename="../../device/ui/videoform.cpp" line="408"/>
|
||||||
<source>file does not exist</source>
|
<source>file does not exist</source>
|
||||||
<translation>文件不存在</translation>
|
<translation>文件不存在</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -12,9 +12,15 @@
|
||||||
#define COMMON_RECORD_KEY "RecordPath"
|
#define COMMON_RECORD_KEY "RecordPath"
|
||||||
#define COMMON_RECORD_DEF ""
|
#define COMMON_RECORD_DEF ""
|
||||||
|
|
||||||
|
#define COMMON_PUSHFILE_KEY "PushFilePath"
|
||||||
|
#define COMMON_PUSHFILE_DEF "/sdcard/"
|
||||||
|
|
||||||
#define COMMON_SERVER_VERSION_KEY "ServerVersion"
|
#define COMMON_SERVER_VERSION_KEY "ServerVersion"
|
||||||
#define COMMON_SERVER_VERSION_DEF "1.12.1"
|
#define COMMON_SERVER_VERSION_DEF "1.12.1"
|
||||||
|
|
||||||
|
#define COMMON_SERVER_PATH_KEY "ServerPath"
|
||||||
|
#define COMMON_SERVER_PATH_DEF "/data/local/tmp/scrcpy-server.jar"
|
||||||
|
|
||||||
#define COMMON_MAX_FPS_KEY "MaxFps"
|
#define COMMON_MAX_FPS_KEY "MaxFps"
|
||||||
#define COMMON_MAX_FPS_DEF 60
|
#define COMMON_MAX_FPS_DEF 60
|
||||||
|
|
||||||
|
@ -24,6 +30,9 @@
|
||||||
#define COMMON_SKIN_KEY "UseSkin"
|
#define COMMON_SKIN_KEY "UseSkin"
|
||||||
#define COMMON_SKIN_DEF 1
|
#define COMMON_SKIN_DEF 1
|
||||||
|
|
||||||
|
#define COMMON_RENDER_EXPIRED_FRAMES_KEY "RenderExpiredFrames"
|
||||||
|
#define COMMON_RENDER_EXPIRED_FRAMES_DEF 0
|
||||||
|
|
||||||
QString Config::s_configPath = "";
|
QString Config::s_configPath = "";
|
||||||
|
|
||||||
Config::Config(QObject *parent) : QObject(parent)
|
Config::Config(QObject *parent) : QObject(parent)
|
||||||
|
@ -102,6 +111,33 @@ int Config::getSkin()
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Config::getRenderExpiredFrames()
|
||||||
|
{
|
||||||
|
int renderExpiredFrames = 1;
|
||||||
|
m_settings->beginGroup(GROUP_COMMON);
|
||||||
|
renderExpiredFrames = m_settings->value(COMMON_RENDER_EXPIRED_FRAMES_KEY, COMMON_RENDER_EXPIRED_FRAMES_DEF).toInt();
|
||||||
|
m_settings->endGroup();
|
||||||
|
return renderExpiredFrames;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Config::getPushFilePath()
|
||||||
|
{
|
||||||
|
QString pushFile;
|
||||||
|
m_settings->beginGroup(GROUP_COMMON);
|
||||||
|
pushFile = m_settings->value(COMMON_PUSHFILE_KEY, COMMON_PUSHFILE_DEF).toString();
|
||||||
|
m_settings->endGroup();
|
||||||
|
return pushFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Config::getServerPath()
|
||||||
|
{
|
||||||
|
QString serverPath;
|
||||||
|
m_settings->beginGroup(GROUP_COMMON);
|
||||||
|
serverPath = m_settings->value(COMMON_SERVER_PATH_KEY, COMMON_SERVER_PATH_DEF).toString();
|
||||||
|
m_settings->endGroup();
|
||||||
|
return serverPath;
|
||||||
|
}
|
||||||
|
|
||||||
QString Config::getTitle()
|
QString Config::getTitle()
|
||||||
{
|
{
|
||||||
QString title;
|
QString title;
|
||||||
|
|
|
@ -17,6 +17,9 @@ public:
|
||||||
int getMaxFps();
|
int getMaxFps();
|
||||||
int getDesktopOpenGL();
|
int getDesktopOpenGL();
|
||||||
int getSkin();
|
int getSkin();
|
||||||
|
int getRenderExpiredFrames();
|
||||||
|
QString getPushFilePath();
|
||||||
|
QString getServerPath();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Config(QObject *parent = nullptr);
|
explicit Config(QObject *parent = nullptr);
|
||||||
|
|
|
@ -32,7 +32,7 @@ It focuses on:
|
||||||
## Customized key mapping (Windows only)
|
## Customized key mapping (Windows only)
|
||||||
You can write your own script to map keyboard and mouse actions to touches and clicks of the mobile phone according to your needs. [Here](docs/按键映射说明.md) are the rules.
|
You can write your own script to map keyboard and mouse actions to touches and clicks of the mobile phone according to your needs. [Here](docs/按键映射说明.md) are the rules.
|
||||||
|
|
||||||
A script for "PUBG mobile" mapping is provided by default. Once enabled, you can play the game with your keyboard and mouse as the PC version. You can also write your own mapping files for other games according to [writing rules](docs/按键映射说明.md). The default key mapping is as follows:
|
A script for "PUBG mobile" and TikTok mapping is provided by default. Once enabled, you can play the game with your keyboard and mouse as the PC version. or you can use up/down/left/right direction keys to simulate up/down/left/right sliding. You can also write your own mapping files for other games according to [writing rules](docs/按键映射说明.md). The default key mapping is as follows:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -42,8 +42,9 @@ Here is the instruction of adding new customized mapping files.
|
||||||
|
|
||||||
- Write a customized script and put it in the `keymap` directory
|
- Write a customized script and put it in the `keymap` directory
|
||||||
- Click `refresh script` to check whether it can be found
|
- Click `refresh script` to check whether it can be found
|
||||||
|
- Select your script
|
||||||
- Connect your phone, start service and click `apply`
|
- Connect your phone, start service and click `apply`
|
||||||
- Start the game and press `~` key (left side of the number key 1) to switch to the mapping mode (It can be changed in the script as `switchkey`)
|
- Press `~` key (left side of the number key 1) to switch to the custom mapping mode (It can be changed in the script as `switchkey`)
|
||||||
- Press the ~ key again to switch back to normal mode
|
- Press the ~ key again to switch back to normal mode
|
||||||
- (For PUBG and similar games) If you want to drive cars with WASD, you need to check the `single rocker mode` in the game setting.
|
- (For PUBG and similar games) If you want to drive cars with WASD, you need to check the `single rocker mode` in the game setting.
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备,并进行显示和
|
||||||
## 自定义按键映射(仅windows平台开启)
|
## 自定义按键映射(仅windows平台开启)
|
||||||
可以根据需要,自己编写脚本将PC键盘按键映射为手机的触摸点击,编写规则在[这里](docs/按键映射说明.md)。
|
可以根据需要,自己编写脚本将PC键盘按键映射为手机的触摸点击,编写规则在[这里](docs/按键映射说明.md)。
|
||||||
|
|
||||||
默认自带了针对和平精英手游进行键鼠映射的映射脚本,开启后可以用键鼠像玩端游一样玩和平精英手游,你也可以按照[编写规则](docs/按键映射说明.md)编写其他游戏的映射文件,默认按键映射如下:
|
默认自带了针对和平精英手游和抖音进行键鼠映射的映射脚本,开启平精英手游后可以用键鼠像玩端游一样玩和平精英手游,开启抖音映射以后可以使用上下左右方向键模拟上下左右滑动,你也可以按照[编写规则](docs/按键映射说明.md)编写其他游戏的映射文件,默认按键映射如下:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -42,8 +42,9 @@ QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备,并进行显示和
|
||||||
自定义按键映射操作方法如下:
|
自定义按键映射操作方法如下:
|
||||||
- 编写自定义脚本放入keymap目录
|
- 编写自定义脚本放入keymap目录
|
||||||
- 点击刷新脚本,确保脚本可以被检测到
|
- 点击刷新脚本,确保脚本可以被检测到
|
||||||
|
- 选择需要的脚本
|
||||||
- 连接手机并启动服务之后,点击应用脚本
|
- 连接手机并启动服务之后,点击应用脚本
|
||||||
- 进入游戏场景,按~键(数字键1左边)切换为游戏映射模式即可体验(具体按什么键要看你按键脚本定义的switchKey)
|
- 按~键(数字键1左边)切换为自定义映射模式即可体验(具体按什么键要看你按键脚本定义的switchKey)
|
||||||
- 再次按~键切换为正常控制模式
|
- 再次按~键切换为正常控制模式
|
||||||
- 要想wasd控制开车记得在载具设置中设置为单摇杆模式
|
- 要想wasd控制开车记得在载具设置中设置为单摇杆模式
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
[common]
|
[common]
|
||||||
# 窗口标题
|
# 窗口标题
|
||||||
WindowTitle=QtScrcpy
|
WindowTitle=QtScrcpy
|
||||||
# 录制文件路径
|
# 录制文件保存路径(必须以/作为分隔符)
|
||||||
RecordPath=
|
RecordPath=
|
||||||
|
# 推送到安卓设备的文件保存路径(必须以/结尾)
|
||||||
|
PushFilePath=/sdcard/
|
||||||
# 最大fps(仅支持Android 10以上)
|
# 最大fps(仅支持Android 10以上)
|
||||||
MaxFps=60
|
MaxFps=60
|
||||||
# scrcpy-server的版本号(不要修改)
|
|
||||||
ServerVersion=1.12.1
|
|
||||||
# 是否显示手机皮肤,0不显示
|
# 是否显示手机皮肤,0不显示
|
||||||
UseSkin=1
|
UseSkin=1
|
||||||
|
# 是否渲染过期视频帧(跳过过期视频帧意味着更低的延迟)
|
||||||
|
RenderExpiredFrames=0
|
||||||
# 视频解码方式:-1 自动,0 软解,1 dx硬解,2 opengl硬解
|
# 视频解码方式:-1 自动,0 软解,1 dx硬解,2 opengl硬解
|
||||||
UseDesktopOpenGL=-1
|
UseDesktopOpenGL=-1
|
||||||
|
# scrcpy-server的版本号(不要修改)
|
||||||
|
ServerVersion=1.12.1
|
||||||
|
# scrcpy-server推送到安卓设备的路径
|
||||||
|
ServerPath=/data/local/tmp/scrcpy-server.jar
|
||||||
|
|
|
@ -3,18 +3,16 @@
|
||||||
# TODO
|
# TODO
|
||||||
## 低优先级
|
## 低优先级
|
||||||
- 中文输入(server需要改为apk,作为一个输入法,暂不实现)(或者有其他方式案件注入方式,例如搜狗手机输入法可以监听当前注入?)
|
- 中文输入(server需要改为apk,作为一个输入法,暂不实现)(或者有其他方式案件注入方式,例如搜狗手机输入法可以监听当前注入?)
|
||||||
- [跳过帧改为动态配置,而不是静态编译](https://github.com/Genymobile/scrcpy/commit/ebccb9f6cc111e8acfbe10d656cac5c1f1b744a0)
|
|
||||||
- [单独线程统计帧率](https://github.com/Genymobile/scrcpy/commit/e2a272bf99ecf48fcb050177113f903b3fb323c4)
|
- [单独线程统计帧率](https://github.com/Genymobile/scrcpy/commit/e2a272bf99ecf48fcb050177113f903b3fb323c4)
|
||||||
- text转换 https://github.com/Genymobile/scrcpy/commit/c916af0984f72a60301d13fa8ef9a85112f54202?tdsourcetag=s_pctim_aiomsg
|
- text转换 https://github.com/Genymobile/scrcpy/commit/c916af0984f72a60301d13fa8ef9a85112f54202?tdsourcetag=s_pctim_aiomsg
|
||||||
- ui提供show touch设置
|
- ui提供show touch设置
|
||||||
|
|
||||||
## 中优先级
|
## 中优先级
|
||||||
- [截屏保存为jpg](https://blog.csdn.net/m0_37684310/article/details/77950390)
|
|
||||||
- 自动打包脚本
|
- 自动打包脚本
|
||||||
- 脚本
|
- 脚本
|
||||||
- 群控
|
- 群控
|
||||||
- 竖屏全屏不拉伸画面
|
- 竖屏全屏不拉伸画面
|
||||||
- 分辨率码率可自定义
|
- 软解
|
||||||
- opengles 3.0
|
- opengles 3.0
|
||||||
|
|
||||||
## 高优先级
|
## 高优先级
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
- switchKey:切换自定义按键映射的开关键,默认为普通映射,需要使用这个按键在普通映射和自定义映射之间切换。
|
- switchKey:切换自定义按键映射的开关键,默认为普通映射,需要使用这个按键在普通映射和自定义映射之间切换。
|
||||||
|
|
||||||
- mouseMoveMap:鼠标移动映射,鼠标的移动将被映射为以startPos为起点,以鼠标移动方向为移动方向的手指拖动操作。
|
- mouseMoveMap:鼠标移动映射,鼠标的移动将被映射为以startPos为起点,以鼠标移动方向为移动方向的手指拖动操作(开启鼠标移动映射以后会隐藏鼠标,限制鼠标移动范围)。
|
||||||
一般在FPS手游中用来调整人物视野。
|
一般在FPS手游中用来调整人物视野。
|
||||||
- startPos 手指拖动起始点
|
- startPos 手指拖动起始点
|
||||||
- speedRatio 鼠标移动映射为手指拖动的比例,可以控制鼠标灵敏度
|
- speedRatio 鼠标移动映射为手指拖动的比例,可以控制鼠标灵敏度
|
||||||
|
@ -26,8 +26,9 @@
|
||||||
一般按键映射有如下几种类型:
|
一般按键映射有如下几种类型:
|
||||||
|
|
||||||
- type 按键映射的类型,每个keyMapNodes中的元素都需要指明,可以是如下类型:
|
- type 按键映射的类型,每个keyMapNodes中的元素都需要指明,可以是如下类型:
|
||||||
- KMT_CLICK 普通点击,键盘按下模拟为手指按下,键盘抬起映射为手指抬起
|
- KMT_CLICK 普通点击,按键按下模拟为手指按下,按键抬起模拟为手指抬起
|
||||||
- KMT_CLICK_TWICE 两次点击,键盘按下模拟为手指按下再抬起,键盘抬起映射为手指按下再抬起
|
- KMT_CLICK_TWICE 两次点击,按键按下模拟为手指按下再抬起,按键抬起模拟为手指按下再抬起
|
||||||
|
- KMT_DRAG 拖拽,按键按下模拟为手指按下并拖动一段距离,按键抬起模拟为手指抬起
|
||||||
- KMT_STEER_WHEEL 方向盘映射,专用于FPS游戏中移动人物脚步的方向盘的映射,需要4个按键来配合。
|
- KMT_STEER_WHEEL 方向盘映射,专用于FPS游戏中移动人物脚步的方向盘的映射,需要4个按键来配合。
|
||||||
|
|
||||||
不同按键映射类型的专有属性说明:
|
不同按键映射类型的专有属性说明:
|
||||||
|
@ -41,6 +42,11 @@
|
||||||
- key 要映射的按键码
|
- key 要映射的按键码
|
||||||
- pos 模拟触摸的位置
|
- pos 模拟触摸的位置
|
||||||
|
|
||||||
|
- KMT_DRAG
|
||||||
|
- key 要映射的按键码
|
||||||
|
- startPos 模拟触摸拖动的开始位置
|
||||||
|
- endPos 模拟触摸拖动的结束位置
|
||||||
|
|
||||||
- KMT_STEER_WHEEL
|
- KMT_STEER_WHEEL
|
||||||
- centerPos 方向盘中心点
|
- centerPos 方向盘中心点
|
||||||
- leftKey 左方向的按键控制
|
- leftKey 左方向的按键控制
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
},
|
},
|
||||||
"speedRatio": 10
|
"speedRatio": 10
|
||||||
},
|
},
|
||||||
"keyMapNodes": [{
|
"keyMapNodes": [
|
||||||
|
{
|
||||||
"comment": "方向盘",
|
"comment": "方向盘",
|
||||||
"type": "KMT_STEER_WHEEL",
|
"type": "KMT_STEER_WHEEL",
|
||||||
"centerPos": {
|
"centerPos": {
|
||||||
|
|
67
keymap/tiktok.json
Normal file
67
keymap/tiktok.json
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
"switchKey": "Key_QuoteLeft",
|
||||||
|
"keyMapNodes": [
|
||||||
|
{
|
||||||
|
"comment": "暂停/继续",
|
||||||
|
"type": "KMT_CLICK",
|
||||||
|
"key": "Key_Space",
|
||||||
|
"pos": {
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"switchMap": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment": "上滑",
|
||||||
|
"type": "KMT_DRAG",
|
||||||
|
"key": "Key_Up",
|
||||||
|
"startPos": {
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.7
|
||||||
|
},
|
||||||
|
"endPos": {
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment": "下滑",
|
||||||
|
"type": "KMT_DRAG",
|
||||||
|
"key": "Key_Down",
|
||||||
|
"startPos": {
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.3
|
||||||
|
},
|
||||||
|
"endPos": {
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment": "左滑",
|
||||||
|
"type": "KMT_DRAG",
|
||||||
|
"key": "Key_Left",
|
||||||
|
"startPos": {
|
||||||
|
"x": 0.7,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"endPos": {
|
||||||
|
"x": 0.3,
|
||||||
|
"y": 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment": "右滑",
|
||||||
|
"type": "KMT_DRAG",
|
||||||
|
"key": "Key_Right",
|
||||||
|
"startPos": {
|
||||||
|
"x": 0.3,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"endPos": {
|
||||||
|
"x": 0.7,
|
||||||
|
"y": 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue