mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-04-20 11:35:56 +00:00
commit
a6f3020f15
38 changed files with 1310 additions and 837 deletions
|
@ -62,16 +62,16 @@ void AdbProcess::initSignals()
|
|||
|
||||
connect(this, &QProcess::readyReadStandardError, this,
|
||||
[this](){
|
||||
QString tmp = QString::fromLocal8Bit(readAllStandardError()).trimmed();
|
||||
QString tmp = QString::fromUtf8(readAllStandardError()).trimmed();
|
||||
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,
|
||||
[this](){
|
||||
QString tmp = QString::fromLocal8Bit(readAllStandardOutput()).trimmed();
|
||||
QString tmp = QString::fromUtf8(readAllStandardOutput()).trimmed();
|
||||
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,
|
||||
|
|
|
@ -39,7 +39,10 @@ void Controller::postControlMsg(ControlMsg *controlMsg)
|
|||
void Controller::test(QRect rc)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -192,7 +195,7 @@ void Controller::keyEvent(const QKeyEvent *from, const QSize &frameSize, const Q
|
|||
|
||||
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);
|
||||
if (controlMsg) {
|
||||
sendControl(controlMsg->serializeData());
|
||||
|
@ -209,7 +212,7 @@ bool Controller::sendControl(const QByteArray &buffer)
|
|||
}
|
||||
qint32 len = 0;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -42,9 +42,8 @@ void InputConvertGame::mouseEvent(const QMouseEvent *from, const QSize &frameSiz
|
|||
if (processMouseClick(from)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
InputConvertNormal::mouseEvent(from, frameSize, showSize);
|
||||
}
|
||||
InputConvertNormal::mouseEvent(from, frameSize, 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
|
||||
&& KeyMap::KMT_CLICK == node.type
|
||||
&& node.click.switchMap) {
|
||||
&& node.data.click.switchMap) {
|
||||
updateSize(frameSize, showSize);
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -93,13 +92,13 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize& frameSize, c
|
|||
return;
|
||||
// 处理普通按键
|
||||
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;
|
||||
case KeyMap::KMT_CLICK_TWICE:
|
||||
processKeyClick(node.clickTwice.keyNode.pos, true, false, from);
|
||||
processKeyClick(node.data.clickTwice.keyNode.pos, true, false, from);
|
||||
return;
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
|
@ -112,25 +111,18 @@ void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize& frameSize, c
|
|||
void InputConvertGame::loadKeyMap(const QString &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)
|
||||
{
|
||||
if (showSize != m_showSize) {
|
||||
if (m_gameMap && m_keyMap.isValidMouseMoveMap()) {
|
||||
// show size change, resize grab cursor
|
||||
emit grabCursor(true);
|
||||
}
|
||||
}
|
||||
m_frameSize = frameSize;
|
||||
m_showSize = showSize;
|
||||
if(m_ctrlMouseMove.valid){
|
||||
m_ctrlMouseMove.startPosPixel = calcScreenAbsolutePos(m_ctrlMouseMove.startPosRel);
|
||||
}
|
||||
}
|
||||
|
||||
void InputConvertGame::sendTouchDownEvent(int id, QPointF pos)
|
||||
|
@ -159,7 +151,11 @@ void InputConvertGame::sendTouchEvent(int id, QPointF pos, AndroidMotioneventAct
|
|||
if (!controlMsg) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -181,25 +177,20 @@ QPointF InputConvertGame::calcScreenAbsolutePos(QPointF relativePos)
|
|||
|
||||
int InputConvertGame::attachTouchID(int key)
|
||||
{
|
||||
//QMetaEnum map = QMetaEnum::fromType<Qt::Key>();
|
||||
for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) {
|
||||
if (0 == multiTouchID[i]) {
|
||||
multiTouchID[i] = key;
|
||||
//qDebug() << "attach "<<key<<" ("<<map.valueToKey(key)<<") as "<<i;
|
||||
if (0 == m_multiTouchID[i]) {
|
||||
m_multiTouchID[i] = key;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
//qDebug() << "attach "<<key<<" ("<<map.valueToKey(key)<<") failed ";
|
||||
return -1;
|
||||
}
|
||||
|
||||
void InputConvertGame::detachTouchID(int key)
|
||||
{
|
||||
//QMetaEnum map = QMetaEnum::fromType<Qt::Key>();
|
||||
for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) {
|
||||
if (key == multiTouchID[i]) {
|
||||
multiTouchID[i] = 0;
|
||||
//qDebug() << "detach "<<key<<" ("<<map.valueToKey(key)<<") from "<<i;
|
||||
if (key == m_multiTouchID[i]) {
|
||||
m_multiTouchID[i] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +199,7 @@ void InputConvertGame::detachTouchID(int key)
|
|||
int InputConvertGame::getTouchID(int key)
|
||||
{
|
||||
for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) {
|
||||
if (key == multiTouchID[i]) {
|
||||
if (key == m_multiTouchID[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -222,49 +213,54 @@ void InputConvertGame::processSteerWheel(const KeyMap::KeyMapNode &node, const Q
|
|||
int key = from->key();
|
||||
bool flag = from->type() == QEvent::KeyPress;
|
||||
// identify keys
|
||||
if(key == node.steerWheel.up.key){
|
||||
if (key == node.data.steerWheel.up.key) {
|
||||
m_ctrlSteerWheel.pressedUp = flag;
|
||||
}else if(key == node.steerWheel.right.key){
|
||||
} else if (key == node.data.steerWheel.right.key) {
|
||||
m_ctrlSteerWheel.pressedRight = flag;
|
||||
}else if(key == node.steerWheel.down.key){
|
||||
} else if (key == node.data.steerWheel.down.key) {
|
||||
m_ctrlSteerWheel.pressedDown = flag;
|
||||
}else{ // left
|
||||
} else { // left
|
||||
m_ctrlSteerWheel.pressedLeft = flag;
|
||||
}
|
||||
|
||||
// calc offset and pressed number
|
||||
QPointF offset(0.0, 0.0);
|
||||
int nPressed = 0;
|
||||
if(m_ctrlSteerWheel.pressedUp){
|
||||
++nPressed;
|
||||
offset.ry() -= node.steerWheel.up.offset;
|
||||
int pressedNum = 0;
|
||||
if (m_ctrlSteerWheel.pressedUp) {
|
||||
++pressedNum;
|
||||
offset.ry() -= node.data.steerWheel.up.extendOffset;
|
||||
}
|
||||
if(m_ctrlSteerWheel.pressedRight){
|
||||
++nPressed;
|
||||
offset.rx() += node.steerWheel.right.offset;
|
||||
if (m_ctrlSteerWheel.pressedRight) {
|
||||
++pressedNum;
|
||||
offset.rx() += node.data.steerWheel.right.extendOffset;
|
||||
}
|
||||
if(m_ctrlSteerWheel.pressedDown){
|
||||
++nPressed;
|
||||
offset.ry() += node.steerWheel.down.offset;
|
||||
if (m_ctrlSteerWheel.pressedDown) {
|
||||
++pressedNum;
|
||||
offset.ry() += node.data.steerWheel.down.extendOffset;
|
||||
}
|
||||
if(m_ctrlSteerWheel.pressedLeft){
|
||||
++nPressed;
|
||||
offset.rx() -= node.steerWheel.left.offset;
|
||||
if (m_ctrlSteerWheel.pressedLeft) {
|
||||
++pressedNum;
|
||||
offset.rx() -= node.data.steerWheel.left.extendOffset;
|
||||
}
|
||||
|
||||
// action
|
||||
//qDebug()<<nPressed<<"-"<<char(from->key())<<"-"<<from->type()<<"-"<<offset;
|
||||
if(nPressed == 0){ // release all
|
||||
if(pressedNum == 0){
|
||||
// touch up release all
|
||||
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);
|
||||
}else{
|
||||
} else {
|
||||
int id;
|
||||
if(nPressed == 1 && flag){ // first press
|
||||
// first press, get key and touch down
|
||||
if (pressedNum == 1 && flag) {
|
||||
m_ctrlSteerWheel.touchKey = from->key();
|
||||
id = attachTouchID(m_ctrlSteerWheel.touchKey);
|
||||
sendTouchDownEvent(id, node.steerWheel.centerPos);
|
||||
}else{
|
||||
sendTouchDownEvent(id, node.data.steerWheel.centerPos);
|
||||
} else {
|
||||
// jsut get touch id and move
|
||||
id = getTouchID(m_ctrlSteerWheel.touchKey);
|
||||
}
|
||||
sendTouchMoveEvent(id, node.steerWheel.centerPos + offset);
|
||||
sendTouchMoveEvent(id, node.data.steerWheel.centerPos + offset);
|
||||
}
|
||||
m_ctrlSteerWheel.lastOffset = offset;
|
||||
return;
|
||||
|
@ -299,10 +295,14 @@ void InputConvertGame::processKeyClick(
|
|||
|
||||
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());
|
||||
sendTouchDownEvent(id, startPos);
|
||||
sendTouchMoveEvent(id, endPos);
|
||||
}
|
||||
|
||||
if (QEvent::KeyRelease == from->type()) {
|
||||
int id = getTouchID(from->key());
|
||||
sendTouchUpEvent(id, endPos);
|
||||
detachTouchID(from->key());
|
||||
}
|
||||
|
@ -317,16 +317,19 @@ bool InputConvertGame::processMouseClick(const QMouseEvent *from)
|
|||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "mouse event " << from->type();
|
||||
if (QEvent::MouseButtonPress == from->type() || QEvent::MouseButtonDblClick == from->type()) {
|
||||
int id = attachTouchID(from->button());
|
||||
sendTouchDownEvent(id, node.click.keyNode.pos);
|
||||
} else if (QEvent::MouseButtonRelease == from->type()) {
|
||||
sendTouchUpEvent(getTouchID(from->button()), node.click.keyNode.pos);
|
||||
detachTouchID(from->button());
|
||||
} else {
|
||||
return false;
|
||||
sendTouchDownEvent(id, node.data.click.keyNode.pos);
|
||||
return true;
|
||||
}
|
||||
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)
|
||||
|
@ -334,30 +337,61 @@ bool InputConvertGame::processMouseMove(const QMouseEvent *from)
|
|||
if (QEvent::MouseMove != from->type()) {
|
||||
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) {
|
||||
//qDebug()<<"reset";
|
||||
if (checkCursorPos(from)) {
|
||||
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();
|
||||
mouseMoveStartTouch(from);
|
||||
}
|
||||
offset /= m_keyMap.getMouseMoveMap().speedRatio;
|
||||
m_ctrlMouseMove.lastPosRel = m_ctrlMouseMove.startPosRel + offset;
|
||||
mouseMoveMovingTouch(m_ctrlMouseMove.lastPosRel);
|
||||
} else {
|
||||
m_ctrlMouseMove.touching = true;
|
||||
mouseMoveStartTouch(from);
|
||||
int left = from->globalX() - from->x();
|
||||
int top = from->globalY() - from->y();
|
||||
|
||||
sendTouchMoveEvent(getTouchID(Qt::ExtraButton24), m_ctrlMouseMove.lastConverPos);
|
||||
}
|
||||
m_ctrlMouseMove.lastPos = from->localPos();
|
||||
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)
|
||||
{
|
||||
QPoint posOffset = from->pos() - localPosPixel;
|
||||
|
@ -369,53 +403,56 @@ void InputConvertGame::moveCursorTo(const QMouseEvent *from, const QPoint &local
|
|||
|
||||
void InputConvertGame::mouseMoveStartTouch(const QMouseEvent* from)
|
||||
{
|
||||
moveCursorTo(from, m_ctrlMouseMove.startPosPixel.toPoint());
|
||||
int id = attachTouchID(m_ctrlMouseMove.touchKey);
|
||||
sendTouchDownEvent(id, m_ctrlMouseMove.startPosRel);
|
||||
m_ctrlMouseMove.lastPosRel = m_ctrlMouseMove.startPosRel;
|
||||
m_ctrlMouseMove.touching = true;
|
||||
}
|
||||
|
||||
void InputConvertGame::mouseMoveMovingTouch(const QPointF& target)
|
||||
{
|
||||
sendTouchMoveEvent(getTouchID(m_ctrlMouseMove.touchKey), target);
|
||||
Q_UNUSED(from)
|
||||
if (!m_ctrlMouseMove.touching) {
|
||||
QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().data.mouseMove.startPos;
|
||||
int id = attachTouchID(Qt::ExtraButton24);
|
||||
sendTouchDownEvent(id, mouseMoveStartPos);
|
||||
m_ctrlMouseMove.lastConverPos = mouseMoveStartPos;
|
||||
m_ctrlMouseMove.touching = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InputConvertGame::mouseMoveStopTouch()
|
||||
{
|
||||
int id = getTouchID(m_ctrlMouseMove.touchKey);
|
||||
sendTouchUpEvent(id, m_ctrlMouseMove.lastPosRel);
|
||||
detachTouchID(m_ctrlMouseMove.touchKey);
|
||||
m_ctrlMouseMove.touching = false;
|
||||
if (m_ctrlMouseMove.touching) {
|
||||
sendTouchUpEvent(getTouchID(Qt::ExtraButton24), m_ctrlMouseMove.lastConverPos);
|
||||
detachTouchID(Qt::ExtraButton24);
|
||||
m_ctrlMouseMove.touching = false;
|
||||
}
|
||||
}
|
||||
|
||||
void InputConvertGame::startMouseMoveTimer()
|
||||
{
|
||||
stopMouseMoveTimer();
|
||||
m_mouseMoveTimer = startTimer(1000);
|
||||
m_ctrlMouseMove.timer = startTimer(1000);
|
||||
}
|
||||
|
||||
void InputConvertGame::stopMouseMoveTimer()
|
||||
{
|
||||
if (0 != m_mouseMoveTimer) {
|
||||
killTimer(m_mouseMoveTimer);
|
||||
m_mouseMoveTimer = 0;
|
||||
if (0 != m_ctrlMouseMove.timer) {
|
||||
killTimer(m_ctrlMouseMove.timer);
|
||||
m_ctrlMouseMove.timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool InputConvertGame::switchGameMap()
|
||||
{
|
||||
m_gameMap = !m_gameMap;
|
||||
|
||||
if (!m_keyMap.isValidMouseMoveMap()) {
|
||||
return m_gameMap;
|
||||
}
|
||||
|
||||
// grab cursor and set cursor only mouse move map
|
||||
emit grabCursor(m_gameMap);
|
||||
if (m_gameMap) {
|
||||
#ifdef QT_NO_DEBUG
|
||||
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||
#else
|
||||
QGuiApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
|
||||
#endif
|
||||
#ifdef QT_NO_DEBUG
|
||||
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||
#else
|
||||
QGuiApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
|
||||
#endif
|
||||
} else {
|
||||
if(m_ctrlMouseMove.touching)
|
||||
mouseMoveStopTouch();
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
}
|
||||
return m_gameMap;
|
||||
|
@ -423,7 +460,7 @@ bool InputConvertGame::switchGameMap()
|
|||
|
||||
void InputConvertGame::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (m_mouseMoveTimer == event->timerId()) {
|
||||
if (m_ctrlMouseMove.timer == event->timerId()) {
|
||||
stopMouseMoveTimer();
|
||||
mouseMoveStopTouch();
|
||||
}
|
||||
|
|
|
@ -48,13 +48,12 @@ protected:
|
|||
bool processMouseMove(const QMouseEvent* from);
|
||||
void moveCursorTo(const QMouseEvent* from, const QPoint& localPosPixel);
|
||||
void mouseMoveStartTouch(const QMouseEvent* from);
|
||||
void mouseMoveMovingTouch(const QPointF& target);
|
||||
void mouseMoveStopTouch();
|
||||
|
||||
void startMouseMoveTimer();
|
||||
void stopMouseMoveTimer();
|
||||
|
||||
bool switchGameMap();
|
||||
bool checkCursorPos(const QMouseEvent *from);
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event);
|
||||
|
@ -63,37 +62,29 @@ private:
|
|||
QSize m_frameSize;
|
||||
QSize m_showSize;
|
||||
bool m_gameMap = false;
|
||||
|
||||
int multiTouchID[MULTI_TOUCH_MAX_NUM] = { 0 };
|
||||
bool m_needSwitchGameAgain = false;
|
||||
int m_multiTouchID[MULTI_TOUCH_MAX_NUM] = { 0 };
|
||||
KeyMap m_keyMap;
|
||||
|
||||
// steer wheel
|
||||
struct{
|
||||
bool valid = false;
|
||||
bool touching = false;
|
||||
int touchKey = Qt::Key_unknown; // the first key pressed
|
||||
int nKeyPressed = 0;
|
||||
bool pressedUp = false, pressedDown = false;
|
||||
bool pressedLeft = false, pressedRight = false;
|
||||
QPointF centerPos;
|
||||
struct {
|
||||
// the first key pressed
|
||||
int touchKey = Qt::Key_unknown;
|
||||
bool pressedUp = false;
|
||||
bool pressedDown = false;
|
||||
bool pressedLeft = false;
|
||||
bool pressedRight = false;
|
||||
// for last up
|
||||
QPointF lastOffset;
|
||||
} m_ctrlSteerWheel;
|
||||
|
||||
// mouse move
|
||||
struct{
|
||||
bool valid = false;
|
||||
struct {
|
||||
QPointF lastConverPos;
|
||||
QPointF lastPos = {0.0, 0.0};
|
||||
bool touching = false;
|
||||
const int touchKey = Qt::ExtraButton24;
|
||||
QPointF startPosRel; // in [0, 1)
|
||||
QPointF startPosPixel; // in [0, size)
|
||||
QPointF lastPosRel;
|
||||
//QPointF lastPosPixel;
|
||||
int timer = 0;
|
||||
} m_ctrlMouseMove;
|
||||
|
||||
int m_mouseMoveTimer = 0;
|
||||
|
||||
bool m_needSwitchGameAgain = false;
|
||||
|
||||
KeyMap m_keyMap;
|
||||
};
|
||||
|
||||
#endif // INPUTCONVERTGAME_H
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QMetaEnum>
|
||||
#include <QFileInfo>
|
||||
|
@ -40,51 +39,57 @@ void KeyMap::loadKeyMap(const QString &json)
|
|||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc;
|
||||
QJsonObject rootObj;
|
||||
QPair<ActionType, int> switchKey;
|
||||
|
||||
jsonDoc = QJsonDocument::fromJson(json.toUtf8(), &jsonError);
|
||||
|
||||
if(jsonError.error != QJsonParseError::NoError)
|
||||
{
|
||||
if(jsonError.error != QJsonParseError::NoError) {
|
||||
errorString = QString("json error: %1").arg(jsonError.errorString());
|
||||
goto parseError;
|
||||
}
|
||||
|
||||
// switchKey
|
||||
rootObj = jsonDoc.object();
|
||||
if (rootObj.contains("switchKey") && rootObj.value("switchKey").isString()) {
|
||||
QPair<ActionType, int> p = getItemKey(rootObj, "switchKey");
|
||||
if(p.first == AT_INVALID){
|
||||
errorString = QString("json error: switchKey invalid");
|
||||
goto parseError;
|
||||
}
|
||||
m_switchType = p.first;
|
||||
m_switchKey = p.second;
|
||||
} else {
|
||||
|
||||
if (!checkItemString(rootObj, "switchKey")) {
|
||||
errorString = QString("json error: no find switchKey");
|
||||
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
|
||||
if (rootObj.contains("mouseMoveMap") && rootObj.value("mouseMoveMap").isObject()) {
|
||||
QJsonObject mouseMoveMap = rootObj.value("mouseMoveMap").toObject();
|
||||
if (mouseMoveMap.contains("speedRatio") && mouseMoveMap.value("speedRatio").isDouble()) {
|
||||
m_mouseMoveMap.speedRatio = mouseMoveMap.value("speedRatio").toInt();
|
||||
} else {
|
||||
if (checkItemObject(rootObj, "mouseMoveMap")) {
|
||||
QJsonObject mouseMoveMap = getItemObject(rootObj, "mouseMoveMap");
|
||||
KeyMapNode keyMapNode;
|
||||
keyMapNode.type = KMT_MOUSE_MOVE;
|
||||
|
||||
if (!checkItemDouble(mouseMoveMap, "speedRatio")) {
|
||||
errorString = QString("json error: mouseMoveMap on find speedRatio");
|
||||
goto parseError;
|
||||
}
|
||||
if (mouseMoveMap.contains("startPos") && mouseMoveMap.value("startPos").isObject()) {
|
||||
QJsonObject startPos = mouseMoveMap.value("startPos").toObject();
|
||||
if (startPos.contains("x") && startPos.value("x").isDouble()) {
|
||||
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 {
|
||||
keyMapNode.data.mouseMove.speedRatio = static_cast<int>(getItemDouble(mouseMoveMap, "speedRatio"));
|
||||
|
||||
if (!checkItemObject(mouseMoveMap, "startPos")) {
|
||||
errorString = QString("json error: mouseMoveMap on find startPos");
|
||||
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
|
||||
|
@ -103,7 +108,7 @@ void KeyMap::loadKeyMap(const QString &json)
|
|||
goto parseError;
|
||||
}
|
||||
|
||||
KeyMap::KeyMapType type = getItemType(node, "type");
|
||||
KeyMap::KeyMapType type = getItemKeyMapType(node, "type");
|
||||
switch (type) {
|
||||
case KeyMap::KMT_CLICK:
|
||||
{
|
||||
|
@ -113,45 +118,45 @@ void KeyMap::loadKeyMap(const QString &json)
|
|||
break;
|
||||
}
|
||||
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();
|
||||
break;
|
||||
}
|
||||
KeyMapNode keyMapNode;
|
||||
keyMapNode.type = type;
|
||||
keyMapNode.click.keyNode.type = key.first;
|
||||
keyMapNode.click.keyNode.key = key.second;
|
||||
keyMapNode.click.keyNode.pos = getItemPos(node, "pos");
|
||||
keyMapNode.click.switchMap = getItemSwitchMap(node, "switchMap");
|
||||
keyMapNode.data.click.keyNode.type = key.first;
|
||||
keyMapNode.data.click.keyNode.key = key.second;
|
||||
keyMapNode.data.click.keyNode.pos = getItemPos(node, "pos");
|
||||
keyMapNode.data.click.switchMap = getItemBool(node, "switchMap");
|
||||
m_keyMapNodes.push_back(keyMapNode);
|
||||
}
|
||||
break;
|
||||
case KeyMap::KMT_CLICK_TWICE:
|
||||
{
|
||||
// safe check
|
||||
if (!checkForClickDouble(node)) {
|
||||
if (!checkForClickTwice(node)) {
|
||||
qWarning() << "json error: keyMapNodes node format error";
|
||||
break;
|
||||
}
|
||||
|
||||
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();
|
||||
break;
|
||||
}
|
||||
KeyMapNode keyMapNode;
|
||||
keyMapNode.type = type;
|
||||
keyMapNode.click.keyNode.type = key.first;
|
||||
keyMapNode.click.keyNode.key = key.second;
|
||||
keyMapNode.click.keyNode.pos = getItemPos(node, "pos");
|
||||
keyMapNode.click.switchMap = getItemSwitchMap(node, "switchMap");
|
||||
keyMapNode.data.click.keyNode.type = key.first;
|
||||
keyMapNode.data.click.keyNode.key = key.second;
|
||||
keyMapNode.data.click.keyNode.pos = getItemPos(node, "pos");
|
||||
keyMapNode.data.click.switchMap = getItemBool(node, "switchMap");
|
||||
m_keyMapNodes.push_back(keyMapNode);
|
||||
}
|
||||
break;
|
||||
case KeyMap::KMT_STEER_WHEEL:
|
||||
{
|
||||
// safe check
|
||||
if(!checkForSteerWhell(node)){
|
||||
if (!checkForSteerWhell(node)) {
|
||||
qWarning() << "json error: keyMapNodes node format error";
|
||||
break;
|
||||
}
|
||||
|
@ -159,33 +164,40 @@ void KeyMap::loadKeyMap(const QString &json)
|
|||
QPair<ActionType, int> rightKey = getItemKey(node, "rightKey");
|
||||
QPair<ActionType, int> upKey = getItemKey(node, "upKey");
|
||||
QPair<ActionType, int> downKey = getItemKey(node, "downKey");
|
||||
if(leftKey.first == AT_INVALID || rightKey.first == AT_INVALID
|
||||
|| upKey.first == AT_INVALID || downKey.first == AT_INVALID)
|
||||
{
|
||||
if(leftKey.first == AT_INVALID)
|
||||
if (leftKey.first == AT_INVALID || rightKey.first == AT_INVALID
|
||||
|| upKey.first == AT_INVALID || downKey.first == AT_INVALID) {
|
||||
if (leftKey.first == AT_INVALID) {
|
||||
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();
|
||||
if(upKey.first == AT_INVALID)
|
||||
}
|
||||
if (upKey.first == AT_INVALID) {
|
||||
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();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
KeyMapNode keyMapNode;
|
||||
keyMapNode.type = type;
|
||||
|
||||
keyMapNode.steerWheel.left = { leftKey.first, leftKey.second,
|
||||
getItemNumber(node, "leftOffset") };
|
||||
keyMapNode.steerWheel.right = { rightKey.first, rightKey.second,
|
||||
getItemNumber(node, "rightOffset") };
|
||||
keyMapNode.steerWheel.up = { upKey.first, upKey.second,
|
||||
getItemNumber(node, "upOffset") };
|
||||
keyMapNode.steerWheel.down = { downKey.first, downKey.second,
|
||||
getItemNumber(node, "downOffset") };
|
||||
keyMapNode.data.steerWheel.left = { leftKey.first, leftKey.second,
|
||||
QPointF(0, 0), QPointF(0, 0),
|
||||
getItemDouble(node, "leftOffset") };
|
||||
keyMapNode.data.steerWheel.right = { rightKey.first, rightKey.second,
|
||||
QPointF(0, 0), QPointF(0, 0),
|
||||
getItemDouble(node, "rightOffset") };
|
||||
keyMapNode.data.steerWheel.up = { upKey.first, upKey.second,
|
||||
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_keyMapNodes.push_back(keyMapNode);
|
||||
}
|
||||
|
@ -193,22 +205,22 @@ void KeyMap::loadKeyMap(const QString &json)
|
|||
case KeyMap::KMT_DRAG:
|
||||
{
|
||||
// safe check
|
||||
if(!checkForDrag(node)){
|
||||
if (!checkForDrag(node)) {
|
||||
qWarning() << "json error: keyMapNodes node format error";
|
||||
break;
|
||||
}
|
||||
|
||||
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();
|
||||
break;
|
||||
}
|
||||
KeyMapNode keyMapNode;
|
||||
keyMapNode.type = type;
|
||||
keyMapNode.drag.type = key.first;
|
||||
keyMapNode.drag.key = key.second;
|
||||
keyMapNode.drag.startPos = getItemPos(node, "startPos");
|
||||
keyMapNode.drag.endPos = getItemPos(node, "endPos");
|
||||
keyMapNode.data.drag.keyNode.type = key.first;
|
||||
keyMapNode.data.drag.keyNode.key = key.second;
|
||||
keyMapNode.data.drag.keyNode.pos = getItemPos(node, "startPos");
|
||||
keyMapNode.data.drag.keyNode.extendPos = getItemPos(node, "endPos");
|
||||
m_keyMapNodes.push_back(keyMapNode);
|
||||
break;
|
||||
}
|
||||
|
@ -220,7 +232,7 @@ void KeyMap::loadKeyMap(const QString &json)
|
|||
}
|
||||
// this must be called after m_keyMapNodes is stable
|
||||
makeReverseMap();
|
||||
qWarning() << "Script updated.";
|
||||
qInfo() << "Script updated.";
|
||||
|
||||
parseError:
|
||||
if (!errorString.isEmpty()) {
|
||||
|
@ -231,45 +243,41 @@ parseError:
|
|||
|
||||
const KeyMap::KeyMapNode& KeyMap::getKeyMapNode(int key)
|
||||
{
|
||||
auto p = rmapKey.value(key, &m_invalidNode);
|
||||
if(p == &m_invalidNode)
|
||||
return *rmapMouse.value(key, &m_invalidNode);
|
||||
auto p = m_rmapKey.value(key, &m_invalidNode);
|
||||
if (p == &m_invalidNode) {
|
||||
return *m_rmapMouse.value(key, &m_invalidNode);
|
||||
}
|
||||
return *p;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return *rmapMouse.value(key, &m_invalidNode);
|
||||
return *m_rmapMouse.value(key, &m_invalidNode);
|
||||
}
|
||||
|
||||
bool KeyMap::isSwitchOnKeyboard()
|
||||
{
|
||||
return m_switchType == AT_KEY;
|
||||
return m_switchKey.type == AT_KEY;
|
||||
}
|
||||
|
||||
int KeyMap::getSwitchKey()
|
||||
{
|
||||
return m_switchKey;
|
||||
return m_switchKey.key;
|
||||
}
|
||||
|
||||
const KeyMap::MouseMoveMap& KeyMap::getMouseMoveMap()
|
||||
const KeyMap::KeyMapNode& KeyMap::getMouseMoveMap()
|
||||
{
|
||||
return m_mouseMoveMap;
|
||||
}
|
||||
|
||||
const KeyMap::KeyMapNode& KeyMap::getSteerWheelMap()
|
||||
{
|
||||
return m_keyMapNodes[m_idxSteerWheel];
|
||||
return m_keyMapNodes[m_idxMouseMove];
|
||||
}
|
||||
|
||||
bool KeyMap::isValidMouseMoveMap()
|
||||
{
|
||||
return !m_mouseMoveMap.startPos.isNull();
|
||||
return m_idxMouseMove != -1;
|
||||
}
|
||||
|
||||
bool KeyMap::isValidSteerWheelMap()
|
||||
|
@ -279,39 +287,39 @@ bool KeyMap::isValidSteerWheelMap()
|
|||
|
||||
void KeyMap::makeReverseMap()
|
||||
{
|
||||
rmapKey.clear();
|
||||
rmapMouse.clear();
|
||||
for(int i = 0 ;i < m_keyMapNodes.size(); ++i) {
|
||||
m_rmapKey.clear();
|
||||
m_rmapMouse.clear();
|
||||
for (int i = 0 ; i < m_keyMapNodes.size(); ++i) {
|
||||
auto& node = m_keyMapNodes[i];
|
||||
switch (node.type) {
|
||||
case KMT_CLICK:
|
||||
{
|
||||
QMultiHash<int, KeyMapNode*>& m = node.click.keyNode.type == AT_KEY ? rmapKey : rmapMouse;
|
||||
m.insert(node.click.keyNode.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& m = node.data.click.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
|
||||
m.insert(node.data.click.keyNode.key, &node);
|
||||
}
|
||||
break;
|
||||
case KMT_CLICK_TWICE:
|
||||
{
|
||||
QMultiHash<int, KeyMapNode*>& m = node.clickTwice.keyNode.type == AT_KEY ? rmapKey : rmapMouse;
|
||||
m.insert(node.clickTwice.keyNode.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& m = node.data.clickTwice.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
|
||||
m.insert(node.data.clickTwice.keyNode.key, &node);
|
||||
}
|
||||
break;
|
||||
case KMT_STEER_WHEEL:
|
||||
{
|
||||
QMultiHash<int, KeyMapNode*>& ml = node.steerWheel.left.type == AT_KEY ? rmapKey : rmapMouse;
|
||||
ml.insert(node.steerWheel.left.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& mr = node.steerWheel.right.type == AT_KEY ? rmapKey : rmapMouse;
|
||||
mr.insert(node.steerWheel.right.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& mu = node.steerWheel.up.type == AT_KEY ? rmapKey : rmapMouse;
|
||||
mu.insert(node.steerWheel.up.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& md = node.steerWheel.down.type == AT_KEY ? rmapKey : rmapMouse;
|
||||
md.insert(node.steerWheel.down.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& ml = node.data.steerWheel.left.type == AT_KEY ? m_rmapKey : m_rmapMouse;
|
||||
ml.insert(node.data.steerWheel.left.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& mr = node.data.steerWheel.right.type == AT_KEY ? m_rmapKey : m_rmapMouse;
|
||||
mr.insert(node.data.steerWheel.right.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& mu = node.data.steerWheel.up.type == AT_KEY ? m_rmapKey : m_rmapMouse;
|
||||
mu.insert(node.data.steerWheel.up.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& md = node.data.steerWheel.down.type == AT_KEY ? m_rmapKey : m_rmapMouse;
|
||||
md.insert(node.data.steerWheel.down.key, &node);
|
||||
}
|
||||
break;
|
||||
case KMT_DRAG:
|
||||
{
|
||||
QMultiHash<int, KeyMapNode*>& m = node.drag.type == AT_KEY ? rmapKey : rmapMouse;
|
||||
m.insert(node.drag.key, &node);
|
||||
QMultiHash<int, KeyMapNode*>& m = node.data.drag.keyNode.type == AT_KEY ? m_rmapKey : m_rmapMouse;
|
||||
m.insert(node.data.drag.keyNode.key, &node);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -320,51 +328,24 @@ void KeyMap::makeReverseMap()
|
|||
}
|
||||
}
|
||||
|
||||
// ---- check and get of json item ----
|
||||
|
||||
bool KeyMap::checkItemKey(const QJsonObject& node, const QString& name)
|
||||
QString KeyMap::getItemString(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()){
|
||||
QJsonObject pos = node.value(name).toObject();
|
||||
return pos.contains("x") && pos.value("x").isDouble()
|
||||
&& pos.contains("y") && pos.value("y").isDouble();
|
||||
}
|
||||
return false;
|
||||
return node.value(name).toDouble();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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};
|
||||
}
|
||||
return node.value(name).toObject();
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return checkItemKey(node, "key") && checkItemPos(node, "pos")
|
||||
&& checkItemSwitchMap(node, "switchMap");
|
||||
return checkForClickTwice(node) && checkItemBool(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)
|
||||
{
|
||||
return checkItemKey(node, "leftKey") && checkItemKey(node, "rightKey")
|
||||
&& checkItemKey(node, "upKey") && checkItemKey(node, "downKey")
|
||||
return checkItemString(node, "leftKey") && checkItemString(node, "rightKey")
|
||||
&& checkItemString(node, "upKey") && checkItemString(node, "downKey")
|
||||
&& checkItemDouble(node, "leftOffset") && checkItemDouble(node, "rightOffset")
|
||||
&& checkItemDouble(node, "upOffset") && checkItemDouble(node, "downOffset")
|
||||
&& checkItemPos(node, "centerPos");
|
||||
|
@ -408,8 +425,7 @@ bool KeyMap::checkForSteerWhell(const QJsonObject& node)
|
|||
|
||||
bool KeyMap::checkForDrag(const QJsonObject& node)
|
||||
{
|
||||
return checkItemKey(node, "key")
|
||||
&& checkItemPos(node, "startPos") && checkItemPos(node, "endPos")
|
||||
&& checkItemSwitchMap(node, "switchMap");
|
||||
return checkItemString(node, "key")
|
||||
&& checkItemPos(node, "startPos") && checkItemPos(node, "endPos");
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
#include <QPair>
|
||||
#include <QMetaEnum>
|
||||
#include <QMultiHash>
|
||||
|
||||
class QJsonObject;
|
||||
#include <QJsonObject>
|
||||
|
||||
class KeyMap : public QObject
|
||||
{
|
||||
|
@ -20,6 +19,7 @@ public:
|
|||
KMT_CLICK_TWICE,
|
||||
KMT_STEER_WHEEL,
|
||||
KMT_DRAG,
|
||||
KMT_MOUSE_MOVE
|
||||
};
|
||||
Q_ENUM(KeyMapType)
|
||||
|
||||
|
@ -33,12 +33,14 @@ public:
|
|||
struct KeyNode {
|
||||
ActionType type = AT_INVALID;
|
||||
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 {
|
||||
KeyMapType type = KMT_INVALID;
|
||||
union {
|
||||
union DATA {
|
||||
struct {
|
||||
KeyNode keyNode;
|
||||
bool switchMap = false;
|
||||
|
@ -48,29 +50,22 @@ public:
|
|||
} clickTwice;
|
||||
struct {
|
||||
QPointF centerPos = {0.0, 0.0};
|
||||
struct DirInfo{
|
||||
ActionType type = AT_KEY; // keyboard/mouse
|
||||
int key = Qt::Key_unknown; // key/button
|
||||
double offset = 0.0;
|
||||
};
|
||||
DirInfo left, right, up, down;
|
||||
KeyNode left, right, up, down;
|
||||
} steerWheel;
|
||||
struct {
|
||||
ActionType type = AT_KEY;
|
||||
int key = Qt::Key_unknown;
|
||||
QPointF startPos = QPointF(0, 0);
|
||||
QPointF endPos = QPointF(0, 0);
|
||||
KeyNode keyNode;
|
||||
} drag;
|
||||
};
|
||||
struct {
|
||||
QPointF startPos = {0.0, 0.0};
|
||||
int speedRatio = 1;
|
||||
} mouseMove;
|
||||
DATA() {}
|
||||
~DATA() {}
|
||||
} data;
|
||||
KeyMapNode() {}
|
||||
~KeyMapNode() {}
|
||||
};
|
||||
|
||||
struct MouseMoveMap {
|
||||
QPointF startPos = {0.0, 0.0};
|
||||
int speedRatio = 1;
|
||||
};
|
||||
|
||||
KeyMap(QObject *parent = Q_NULLPTR);
|
||||
virtual ~KeyMap();
|
||||
|
||||
|
@ -83,8 +78,7 @@ public:
|
|||
|
||||
bool isValidMouseMoveMap();
|
||||
bool isValidSteerWheelMap();
|
||||
const MouseMoveMap& getMouseMoveMap();
|
||||
const KeyMapNode& getSteerWheelMap();
|
||||
const KeyMap::KeyMapNode& getMouseMoveMap();
|
||||
|
||||
static const QString& getKeyMapPath();
|
||||
|
||||
|
@ -92,41 +86,50 @@ private:
|
|||
// set up the reverse map from key/event event to keyMapNode
|
||||
void makeReverseMap();
|
||||
|
||||
// parse json of the mapping script
|
||||
bool checkItemKey(const QJsonObject& node, const QString& name="key");
|
||||
bool checkItemPos(const QJsonObject& node, const QString& name="pos");
|
||||
// safe check for base
|
||||
bool checkItemString(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");
|
||||
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:
|
||||
// safe check for KeyMapNode
|
||||
bool checkForClick(const QJsonObject& node);
|
||||
bool checkForClickDouble(const QJsonObject& node);
|
||||
bool checkForClickTwice(const QJsonObject& node);
|
||||
bool checkForSteerWhell(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:
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
// mouse move index
|
||||
int m_idxMouseMove = -1;
|
||||
|
||||
// mapping of key/mouse event name to index
|
||||
QMetaEnum m_metaEnumKey = QMetaEnum::fromType<Qt::Key>();
|
||||
QMetaEnum m_metaEnumMouseButtons = QMetaEnum::fromType<Qt::MouseButtons>();
|
||||
QMetaEnum m_metaEnumKeyMapType = QMetaEnum::fromType<KeyMap::KeyMapType>();
|
||||
// reverse map of key/mouse event
|
||||
QMultiHash<int, KeyMapNode*> rmapKey;
|
||||
QMultiHash<int, KeyMapNode*> rmapMouse;
|
||||
QMultiHash<int, KeyMapNode*> m_rmapKey;
|
||||
QMultiHash<int, KeyMapNode*> m_rmapMouse;
|
||||
};
|
||||
|
||||
#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_srcHeight = srcHeight;
|
||||
|
@ -20,21 +20,21 @@ void AVFrameConvert::setSrcFrameInfo(quint32 srcWidth, quint32 srcHeight, AVPixe
|
|||
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;
|
||||
srcHeight = m_srcHeight;
|
||||
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_dstHeight = dstHeight;
|
||||
m_dstFormat = dstFormat;
|
||||
}
|
||||
|
||||
void AVFrameConvert::getDstFrameInfo(quint32& dstWidth, quint32& dstHeight, AVPixelFormat& dstFormat)
|
||||
void AVFrameConvert::getDstFrameInfo(int& dstWidth, int& dstHeight, AVPixelFormat& dstFormat)
|
||||
{
|
||||
dstWidth = m_dstWidth;
|
||||
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) {
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -16,22 +16,22 @@ public:
|
|||
virtual ~AVFrameConvert();
|
||||
|
||||
public:
|
||||
void setSrcFrameInfo(quint32 srcWidth, quint32 srcHeight, AVPixelFormat srcFormat);
|
||||
void getSrcFrameInfo(quint32& srcWidth, quint32& srcHeight, AVPixelFormat& srcFormat);
|
||||
void setDstFrameInfo(quint32 dstWidth, quint32 dstHeight, AVPixelFormat dstFormat);
|
||||
void getDstFrameInfo(quint32& dstWidth, quint32& dstHeight, AVPixelFormat& dstFormat);
|
||||
void setSrcFrameInfo(int srcWidth, int srcHeight, AVPixelFormat srcFormat);
|
||||
void getSrcFrameInfo(int& srcWidth, int& srcHeight, AVPixelFormat& srcFormat);
|
||||
void setDstFrameInfo(int dstWidth, int dstHeight, AVPixelFormat dstFormat);
|
||||
void getDstFrameInfo(int& dstWidth, int& dstHeight, AVPixelFormat& dstFormat);
|
||||
|
||||
bool init();
|
||||
bool isInit();
|
||||
void deInit();
|
||||
bool convert(AVFrame* srcFrame, AVFrame* dstFrame);
|
||||
bool convert(const AVFrame* srcFrame, AVFrame* dstFrame);
|
||||
|
||||
private:
|
||||
quint32 m_srcWidth = 0;
|
||||
quint32 m_srcHeight = 0;
|
||||
int m_srcWidth = 0;
|
||||
int m_srcHeight = 0;
|
||||
AVPixelFormat m_srcFormat = AV_PIX_FMT_NONE;
|
||||
quint32 m_dstWidth = 0;
|
||||
quint32 m_dstHeight = 0;
|
||||
int m_dstWidth = 0;
|
||||
int m_dstHeight = 0;
|
||||
AVPixelFormat m_dstFormat = AV_PIX_FMT_NONE;
|
||||
|
||||
struct SwsContext *m_convertCtx = Q_NULLPTR;
|
||||
|
|
|
@ -9,6 +9,3 @@ SOURCES += \
|
|||
$$PWD/fpscounter.cpp \
|
||||
$$PWD/avframeconvert.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();
|
||||
if (!m_decodingFrame) {
|
||||
goto error;
|
||||
|
@ -71,17 +72,17 @@ void VideoBuffer::offerDecodedFrame(bool& previousFrameSkipped)
|
|||
{
|
||||
m_mutex.lock();
|
||||
|
||||
#ifndef SKIP_FRAMES
|
||||
// if SKIP_FRAMES is disabled, then the decoder must wait for the current
|
||||
// frame to be consumed
|
||||
while (!m_renderingFrameConsumed && !m_interrupted) {
|
||||
m_renderingFrameConsumedCond.wait(&m_mutex);
|
||||
}
|
||||
#else
|
||||
if (m_fpsCounter.isStarted() && !m_renderingFrameConsumed) {
|
||||
m_fpsCounter.addSkippedFrame();
|
||||
if (m_renderExpiredFrames) {
|
||||
// if m_renderExpiredFrames is enable, then the decoder must wait for the current
|
||||
// frame to be consumed
|
||||
while (!m_renderingFrameConsumed && !m_interrupted) {
|
||||
m_renderingFrameConsumedCond.wait(&m_mutex);
|
||||
}
|
||||
} else {
|
||||
if (m_fpsCounter.isStarted() && !m_renderingFrameConsumed) {
|
||||
m_fpsCounter.addSkippedFrame();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
swap();
|
||||
previousFrameSkipped = !m_renderingFrameConsumed;
|
||||
|
@ -96,23 +97,23 @@ const AVFrame *VideoBuffer::consumeRenderedFrame()
|
|||
if (m_fpsCounter.isStarted()) {
|
||||
m_fpsCounter.addRenderedFrame();
|
||||
}
|
||||
#ifndef SKIP_FRAMES
|
||||
// if SKIP_FRAMES is disabled, then notify the decoder the current frame is
|
||||
// consumed, so that it may push a new one
|
||||
m_renderingFrameConsumedCond.wakeOne();
|
||||
#endif
|
||||
if (m_renderExpiredFrames) {
|
||||
// if m_renderExpiredFrames is enable, then notify the decoder the current frame is
|
||||
// consumed, so that it may push a new one
|
||||
m_renderingFrameConsumedCond.wakeOne();
|
||||
}
|
||||
return m_renderingframe;
|
||||
}
|
||||
|
||||
void VideoBuffer::interrupt()
|
||||
{
|
||||
#ifndef SKIP_FRAMES
|
||||
m_mutex.lock();
|
||||
m_interrupted = true;
|
||||
m_mutex.unlock();
|
||||
// wake up blocking wait
|
||||
m_renderingFrameConsumedCond.wakeOne();
|
||||
#endif
|
||||
if (m_renderExpiredFrames) {
|
||||
m_mutex.lock();
|
||||
m_interrupted = true;
|
||||
m_mutex.unlock();
|
||||
// wake up blocking wait
|
||||
m_renderingFrameConsumedCond.wakeOne();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoBuffer::swap()
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
VideoBuffer();
|
||||
virtual ~VideoBuffer();
|
||||
|
||||
bool init();
|
||||
bool init(bool renderExpiredFrames = false);
|
||||
void deInit();
|
||||
void lock();
|
||||
void unLock();
|
||||
|
@ -45,10 +45,12 @@ private:
|
|||
bool m_renderingFrameConsumed = true;
|
||||
FpsCounter m_fpsCounter;
|
||||
|
||||
#ifndef SKIP_FRAMES
|
||||
bool m_renderExpiredFrames = false;
|
||||
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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <QTimer>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
|
||||
#include "device.h"
|
||||
#include "recorder.h"
|
||||
|
@ -11,6 +12,11 @@
|
|||
#include "videoform.h"
|
||||
#include "controller.h"
|
||||
#include "config.h"
|
||||
#include "avframeconvert.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "libavutil/imgutils.h"
|
||||
}
|
||||
|
||||
Device::Device(DeviceParams params, QObject *parent)
|
||||
: QObject(parent)
|
||||
|
@ -24,7 +30,7 @@ Device::Device(DeviceParams params, QObject *parent)
|
|||
|
||||
if (params.display) {
|
||||
m_vb = new VideoBuffer();
|
||||
m_vb->init();
|
||||
m_vb->init(params.renderExpiredFrames);
|
||||
m_decoder = new Decoder(m_vb, this);
|
||||
m_fileHandler = new FileHandler(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()
|
||||
{
|
||||
if (m_controller && m_videoForm) {
|
||||
connect(m_controller, &Controller::grabCursor, m_videoForm, &VideoForm::onGrabCursor);
|
||||
connect(m_videoForm, &VideoForm::screenshot, this, &Device::onScreenshot);
|
||||
}
|
||||
if (m_videoForm) {
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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){
|
||||
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());
|
||||
|
||||
// update ui
|
||||
|
@ -189,6 +201,12 @@ void Device::initSignals()
|
|||
if (m_videoForm) {
|
||||
m_videoForm->updateRender(frame);
|
||||
}
|
||||
|
||||
// screenshot
|
||||
if (m_screenshot) {
|
||||
saveFrame(frame);
|
||||
m_screenshot = false;
|
||||
}
|
||||
m_vb->unLock();
|
||||
},Qt::QueuedConnection);
|
||||
}
|
||||
|
@ -216,3 +234,56 @@ void Device::startServer()
|
|||
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 VideoForm;
|
||||
class Controller;
|
||||
struct AVFrame;
|
||||
class Device : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct DeviceParams {
|
||||
QString recordFileName = ""; // 视频录制文件名
|
||||
QString serial = ""; // 设备序列号
|
||||
quint16 localPort = 27183; // reverse时本地监听端口
|
||||
quint16 maxSize = 720; // 视频分辨率
|
||||
quint32 bitRate = 8000000; // 视频比特率
|
||||
quint32 maxFps = 60; // 视频最大帧率
|
||||
bool closeScreen = false; // 启动时自动息屏
|
||||
bool useReverse = true; // true:先使用adb reverse,失败后自动使用adb forward;false:直接使用adb forward
|
||||
bool display = true; // 是否显示画面(或者仅仅后台录制)
|
||||
QString gameScript = ""; // 游戏映射脚本
|
||||
QString recordFileName = ""; // 视频录制文件名
|
||||
QString serial = ""; // 设备序列号
|
||||
quint16 localPort = 27183; // reverse时本地监听端口
|
||||
quint16 maxSize = 720; // 视频分辨率
|
||||
quint32 bitRate = 8000000; // 视频比特率
|
||||
quint32 maxFps = 60; // 视频最大帧率
|
||||
bool closeScreen = false; // 启动时自动息屏
|
||||
bool useReverse = true; // true:先使用adb reverse,失败后自动使用adb forward;false:直接使用adb forward
|
||||
bool display = true; // 是否显示画面(或者仅仅后台录制)
|
||||
QString gameScript = ""; // 游戏映射脚本
|
||||
bool renderExpiredFrames = false; // 是否渲染延迟视频帧
|
||||
};
|
||||
explicit Device(DeviceParams params, QObject *parent = nullptr);
|
||||
virtual ~Device();
|
||||
|
@ -40,9 +42,13 @@ public:
|
|||
signals:
|
||||
void deviceDisconnect(QString serial);
|
||||
|
||||
public slots:
|
||||
void onScreenshot();
|
||||
|
||||
private:
|
||||
void initSignals();
|
||||
void startServer();
|
||||
bool saveFrame(const AVFrame* frame);
|
||||
|
||||
private:
|
||||
// server relevant
|
||||
|
@ -59,6 +65,8 @@ private:
|
|||
|
||||
QTime m_startTimeCount;
|
||||
DeviceParams m_params;
|
||||
|
||||
bool m_screenshot = false;
|
||||
};
|
||||
|
||||
#endif // DEVICE_H
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "filehandler.h"
|
||||
|
||||
#define DEVICE_SDCARD_PATH "/sdcard/"
|
||||
|
||||
FileHandler::FileHandler(QObject *parent)
|
||||
: QObject (parent)
|
||||
{
|
||||
|
@ -32,12 +30,9 @@ void FileHandler::pushFileRequest(const QString &serial, const QString &file, co
|
|||
emit fileHandlerResult(FAR_IS_RUNNING, false);
|
||||
return;
|
||||
}
|
||||
m_devicePath = devicePath;
|
||||
if (m_devicePath.isEmpty()) {
|
||||
m_devicePath = DEVICE_SDCARD_PATH;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -46,12 +41,6 @@ void FileHandler::installApkRequest(const QString &serial, const QString &apkFil
|
|||
emit fileHandlerResult(FAR_IS_RUNNING, true);
|
||||
return;
|
||||
}
|
||||
m_devicePath = "";
|
||||
m_isApk = true;
|
||||
m_adb.install(serial, apkFile);
|
||||
}
|
||||
|
||||
const QString &FileHandler::getDevicePath()
|
||||
{
|
||||
return m_devicePath;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "server.h"
|
||||
#include "config.h"
|
||||
|
||||
#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
|
||||
#define DEVICE_NAME_FIELD_LENGTH 64
|
||||
#define SOCKET_NAME "scrcpy"
|
||||
#define MAX_CONNECT_COUNT 30
|
||||
|
@ -68,7 +67,7 @@ bool Server::pushServer()
|
|||
if (m_workProcess.isRuning()) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -126,7 +125,7 @@ bool Server::execute()
|
|||
}
|
||||
QStringList args;
|
||||
args << "shell";
|
||||
args << QString("CLASSPATH=%1").arg(DEVICE_SERVER_PATH);
|
||||
args << QString("CLASSPATH=%1").arg(Config::getInstance().getServerPath());
|
||||
args << "app_process";
|
||||
args << "/"; // unused;
|
||||
args << "com.genymobile.scrcpy.Server";
|
||||
|
|
|
@ -82,8 +82,8 @@ private:
|
|||
QPointer<QTcpSocket> m_controlSocket = Q_NULLPTR;
|
||||
bool m_tunnelEnabled = false;
|
||||
bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse"
|
||||
quint32 m_acceptTimeoutTimer = 0;
|
||||
quint32 m_connectTimeoutTimer = 0;
|
||||
int m_acceptTimeoutTimer = 0;
|
||||
int m_connectTimeoutTimer = 0;
|
||||
quint32 m_connectCount = 0;
|
||||
quint32 m_restartCount = 0;
|
||||
QString m_deviceName = "";
|
||||
|
|
|
@ -20,9 +20,6 @@ ToolForm::ToolForm(QWidget* adsorbWidget, AdsorbPositions adsorbPos)
|
|||
m_videoForm = dynamic_cast<VideoForm*>(adsorbWidget);
|
||||
|
||||
initStyle();
|
||||
|
||||
// TODO
|
||||
ui->screenShotBtn->hide();
|
||||
}
|
||||
|
||||
ToolForm::~ToolForm()
|
||||
|
@ -69,11 +66,13 @@ void ToolForm::mouseMoveEvent(QMouseEvent *event)
|
|||
|
||||
void ToolForm::showEvent(QShowEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
qDebug() << "show event";
|
||||
}
|
||||
|
||||
void ToolForm::hideEvent(QHideEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
qDebug() << "hide event";
|
||||
}
|
||||
|
||||
|
@ -121,7 +120,7 @@ void ToolForm::on_powerBtn_clicked()
|
|||
|
||||
void ToolForm::on_screenShotBtn_clicked()
|
||||
{
|
||||
// TODO
|
||||
emit screenshot();
|
||||
}
|
||||
|
||||
void ToolForm::on_volumeUpBtn_clicked()
|
||||
|
|
|
@ -27,6 +27,9 @@ protected:
|
|||
void showEvent(QShowEvent *event);
|
||||
void hideEvent(QHideEvent *event);
|
||||
|
||||
signals:
|
||||
void screenshot();
|
||||
|
||||
private slots:
|
||||
void on_fullScreenBtn_clicked();
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "toolform.h"
|
||||
#include "controller.h"
|
||||
#include "filehandler.h"
|
||||
#include "config.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "libavutil/frame.h"
|
||||
|
@ -92,6 +93,8 @@ void VideoForm::showToolForm(bool show)
|
|||
if (!m_toolForm) {
|
||||
m_toolForm = new ToolForm(this, ToolForm::AP_OUTSIDE_RIGHT);
|
||||
m_toolForm->move(pos().x() + geometry().width(), pos().y() + 30);
|
||||
|
||||
connect(m_toolForm, &ToolForm::screenshot, this, &VideoForm::screenshot);
|
||||
}
|
||||
m_toolForm->setVisible(show);
|
||||
}
|
||||
|
@ -349,7 +352,6 @@ void VideoForm::keyPressEvent(QKeyEvent *event)
|
|||
return;
|
||||
}
|
||||
|
||||
//qDebug() << "keyPressEvent" << event->isAutoRepeat();
|
||||
m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size());
|
||||
}
|
||||
|
||||
|
@ -358,7 +360,6 @@ void VideoForm::keyReleaseEvent(QKeyEvent *event)
|
|||
if (!m_controller) {
|
||||
return;
|
||||
}
|
||||
//qDebug() << "keyReleaseEvent" << event->isAutoRepeat();
|
||||
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);
|
||||
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 setSerial(const QString &serial);
|
||||
|
||||
signals:
|
||||
void screenshot();
|
||||
|
||||
public slots:
|
||||
void onGrabCursor(bool grab);
|
||||
|
||||
|
|
|
@ -49,6 +49,10 @@ bool DeviceManage::connectDevice(Device::DeviceParams params)
|
|||
|
||||
void DeviceManage::updateScript(QString script)
|
||||
{
|
||||
if (m_devices.isEmpty()) {
|
||||
qWarning() << "no device connect!!!";
|
||||
return;
|
||||
}
|
||||
QMapIterator<QString, QPointer<Device>> i(m_devices);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <QKeyEvent>
|
||||
#include <QFileDialog>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
#include "dialog.h"
|
||||
#include "ui_dialog.h"
|
||||
|
@ -46,14 +47,18 @@ Dialog::Dialog(QWidget *parent) :
|
|||
}
|
||||
} else if (args.contains("show") && args.contains("wlan0")) {
|
||||
QString ip = m_adb.getDeviceIPFromStdOut();
|
||||
if (!ip.isEmpty()) {
|
||||
ui->deviceIpEdt->setText(ip);
|
||||
if (ip.isEmpty()) {
|
||||
log = "ip not find, connect to wifi?";
|
||||
break;
|
||||
}
|
||||
ui->deviceIpEdt->setText(ip);
|
||||
} else if (args.contains("ifconfig") && args.contains("wlan0")) {
|
||||
QString ip = m_adb.getDeviceIPFromStdOut();
|
||||
if (!ip.isEmpty()) {
|
||||
ui->deviceIpEdt->setText(ip);
|
||||
if (ip.isEmpty()) {
|
||||
log = "ip not find, connect to wifi?";
|
||||
break;
|
||||
}
|
||||
ui->deviceIpEdt->setText(ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -91,11 +96,6 @@ void Dialog::initUI()
|
|||
ui->formatBox->addItem("mp4");
|
||||
ui->formatBox->addItem("mkv");
|
||||
|
||||
#ifndef Q_OS_WIN32
|
||||
// game only windows
|
||||
ui->gameCheck->setEnabled(false);
|
||||
#endif
|
||||
|
||||
ui->recordPathEdt->setText(Config::getInstance().getRecordPath());
|
||||
}
|
||||
|
||||
|
@ -137,14 +137,16 @@ void Dialog::on_startServerBtn_clicked()
|
|||
outLog("start server...", false);
|
||||
|
||||
QString absFilePath;
|
||||
QString fileDir(ui->recordPathEdt->text().trimmed());
|
||||
if (!fileDir.isEmpty()) {
|
||||
QDateTime dateTime = QDateTime::currentDateTime();
|
||||
QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz");
|
||||
QString ext = ui->formatBox->currentText().trimmed();
|
||||
fileName = windowTitle() + fileName + "." + ext;
|
||||
QDir dir(fileDir);
|
||||
absFilePath = dir.absoluteFilePath(fileName);
|
||||
if (ui->recordScreenCheck->isChecked()) {
|
||||
QString fileDir(ui->recordPathEdt->text().trimmed());
|
||||
if (!fileDir.isEmpty()) {
|
||||
QDateTime dateTime = QDateTime::currentDateTime();
|
||||
QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz");
|
||||
QString ext = ui->formatBox->currentText().trimmed();
|
||||
fileName = windowTitle() + fileName + "." + ext;
|
||||
QDir dir(fileDir);
|
||||
absFilePath = dir.absoluteFilePath(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
quint32 bitRate = ui->bitRateBox->currentText().trimmed().toUInt();
|
||||
|
@ -155,18 +157,13 @@ void Dialog::on_startServerBtn_clicked()
|
|||
params.maxSize = videoSize;
|
||||
params.bitRate = bitRate;
|
||||
// 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.closeScreen = ui->closeScreenCheck->isChecked();
|
||||
params.useReverse = ui->useReverseCheck->isChecked();
|
||||
params.display = !ui->notDisplayCheck->isChecked();
|
||||
if (ui->gameCheck->isChecked()) {
|
||||
if (ui->gameBox->currentText().isEmpty()) {
|
||||
outLog("no keymap script selected", true);
|
||||
} else {
|
||||
params.gameScript = getGameScript(ui->gameBox->currentText());
|
||||
}
|
||||
}
|
||||
params.renderExpiredFrames = Config::getInstance().getRenderExpiredFrames();
|
||||
|
||||
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()
|
||||
{
|
||||
if (m_adb.isRuning()) {
|
||||
|
@ -340,9 +348,15 @@ void Dialog::on_applyScriptBtn_clicked()
|
|||
m_deviceManage.updateScript(getGameScript(ui->gameBox->currentText()));
|
||||
}
|
||||
|
||||
void Dialog::on_gameCheck_clicked(bool checked)
|
||||
void Dialog::on_recordScreenCheck_clicked(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
on_refreshGameScriptBtn_clicked();
|
||||
if (!checked) {
|
||||
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();
|
||||
|
||||
void outLog(const QString& log, bool newLine = true);
|
||||
bool filterLog(const QString & log);
|
||||
|
||||
private slots:
|
||||
void on_updateDevice_clicked();
|
||||
|
@ -50,8 +51,10 @@ private slots:
|
|||
void on_stopAllServerBtn_clicked();
|
||||
|
||||
void on_refreshGameScriptBtn_clicked();
|
||||
|
||||
void on_applyScriptBtn_clicked();
|
||||
void on_gameCheck_clicked(bool checked);
|
||||
|
||||
void on_recordScreenCheck_clicked(bool checked);
|
||||
|
||||
private:
|
||||
bool checkAdbRun();
|
||||
|
|
|
@ -6,119 +6,431 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>513</width>
|
||||
<height>495</height>
|
||||
<width>420</width>
|
||||
<height>471</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>2160</height>
|
||||
<width>420</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">QtScrcpy</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="usbGroupBox">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="configGroupBox">
|
||||
<property name="title">
|
||||
<string>USB line</string>
|
||||
<string>Start Config</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="serialBox"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>device serial:</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<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="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>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QPushButton" name="getIPBtn">
|
||||
<property name="text">
|
||||
<string>get device IP</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="configWidget2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<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_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>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="updateDevice">
|
||||
<property name="text">
|
||||
<string>refresh devices</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="configWidget4" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<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="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>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="startServerBtn">
|
||||
<property name="text">
|
||||
<string>start server</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="stopAllServerBtn">
|
||||
<property name="text">
|
||||
<string>stop all server</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="stopServerBtn">
|
||||
<property name="text">
|
||||
<string>stop server</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QPushButton" name="startAdbdBtn">
|
||||
<property name="text">
|
||||
<string>start adbd</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="configWidget3" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<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 row="0" column="0">
|
||||
<widget class="QCheckBox" name="recordScreenCheck">
|
||||
<property name="text">
|
||||
<string>record screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<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="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>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</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">
|
||||
<property name="title">
|
||||
<string>Wireless</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4" columnstretch="2,0,0,1,2,0">
|
||||
<item row="4" column="4">
|
||||
<widget class="QPushButton" name="wirelessConnectBtn">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" 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 row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<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="QLineEdit" name="deviceIpEdt">
|
||||
<property name="text">
|
||||
<string/>
|
||||
|
@ -131,7 +443,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
|
@ -150,8 +462,20 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<item>
|
||||
<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">
|
||||
<string/>
|
||||
</property>
|
||||
|
@ -163,10 +487,26 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
|
@ -182,7 +522,87 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</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">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
|
@ -201,232 +621,10 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<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>devicePortEdt</tabstop>
|
||||
<tabstop>wirelessConnectBtn</tabstop>
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
#include "mousetap/mousetap.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 installTranslator();
|
||||
|
||||
|
@ -91,6 +91,7 @@ void installTranslator() {
|
|||
static QTranslator translator;
|
||||
QLocale locale;
|
||||
QLocale::Language language = locale.language();
|
||||
//language = QLocale::English;
|
||||
QString languagePath = ":/i18n/";
|
||||
switch (language) {
|
||||
case QLocale::Chinese:
|
||||
|
@ -112,7 +113,7 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -16,22 +16,22 @@
|
|||
<translation type="vanished">file transfer failed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="115"/>
|
||||
<location filename="../../device/device.cpp" line="127"/>
|
||||
<source>install apk</source>
|
||||
<translation>install apk</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="117"/>
|
||||
<location filename="../../device/device.cpp" line="129"/>
|
||||
<source>file transfer</source>
|
||||
<translation>file transfer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="120"/>
|
||||
<location filename="../../device/device.cpp" line="132"/>
|
||||
<source>wait current %1 to complete</source>
|
||||
<translation>wait current %1 to complete</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="123"/>
|
||||
<location filename="../../device/device.cpp" line="135"/>
|
||||
<source>%1 complete, save in %2</source>
|
||||
<translation>%1 complete, save in %2</translation>
|
||||
</message>
|
||||
|
@ -41,7 +41,7 @@
|
|||
<translation type="vanished">%1 complete\n save in %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="126"/>
|
||||
<location filename="../../device/device.cpp" line="138"/>
|
||||
<source>%1 failed</source>
|
||||
<translation>%1 failed</translation>
|
||||
</message>
|
||||
|
@ -49,128 +49,132 @@
|
|||
<context>
|
||||
<name>Dialog</name>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="102"/>
|
||||
<location filename="../../dialog.ui" line="415"/>
|
||||
<source>Wireless</source>
|
||||
<translation>Wireless</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="114"/>
|
||||
<location filename="../../dialog.ui" line="499"/>
|
||||
<source>wireless connect</source>
|
||||
<translation>wireless connect</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="175"/>
|
||||
<location filename="../../dialog.ui" line="515"/>
|
||||
<source>wireless disconnect</source>
|
||||
<translation>wireless disconnect</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="254"/>
|
||||
<location filename="../../dialog.ui" line="32"/>
|
||||
<source>Start Config</source>
|
||||
<translation>Start Config</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="274"/>
|
||||
<location filename="../../dialog.ui" line="127"/>
|
||||
<source>record save path:</source>
|
||||
<translation>record save path:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="362"/>
|
||||
<location filename="../../dialog.cpp" line="287"/>
|
||||
<location filename="../../dialog.ui" line="144"/>
|
||||
<location filename="../../dialog.cpp" line="294"/>
|
||||
<source>select path</source>
|
||||
<translation>select path</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="267"/>
|
||||
<location filename="../../dialog.ui" line="99"/>
|
||||
<source>record format:</source>
|
||||
<translation>record format:</translation>
|
||||
</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>
|
||||
<translation>stop all server</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="213"/>
|
||||
<location filename="../../dialog.ui" line="549"/>
|
||||
<source>adb command:</source>
|
||||
<translation>adb command:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="223"/>
|
||||
<location filename="../../dialog.ui" line="585"/>
|
||||
<source>terminate</source>
|
||||
<translation>terminate</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="230"/>
|
||||
<location filename="../../dialog.ui" line="572"/>
|
||||
<source>execute</source>
|
||||
<translation>execute</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="244"/>
|
||||
<location filename="../../dialog.ui" line="598"/>
|
||||
<source>clear</source>
|
||||
<translation>clear</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="300"/>
|
||||
<location filename="../../dialog.ui" line="256"/>
|
||||
<source>reverse connection</source>
|
||||
<translation>reverse connection</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="310"/>
|
||||
<source>auto enable</source>
|
||||
<translation>auto enable</translation>
|
||||
<translation type="vanished">auto enable</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="339"/>
|
||||
<location filename="../../dialog.ui" line="240"/>
|
||||
<source>background record</source>
|
||||
<translation>background record</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="355"/>
|
||||
<location filename="../../dialog.ui" line="227"/>
|
||||
<source>screen-off</source>
|
||||
<translation>screen-off</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="392"/>
|
||||
<location filename="../../dialog.ui" line="189"/>
|
||||
<source>apply</source>
|
||||
<translation>apply</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="406"/>
|
||||
<location filename="../../dialog.ui" line="85"/>
|
||||
<source>max size:</source>
|
||||
<translation>max size:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="323"/>
|
||||
<location filename="../../dialog.ui" line="272"/>
|
||||
<source>always on top</source>
|
||||
<translation>always on top</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="287"/>
|
||||
<location filename="../../dialog.ui" line="182"/>
|
||||
<source>refresh script</source>
|
||||
<translation>refresh script</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="42"/>
|
||||
<location filename="../../dialog.ui" line="389"/>
|
||||
<source>get device IP</source>
|
||||
<translation>get device IP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="26"/>
|
||||
<location filename="../../dialog.ui" line="288"/>
|
||||
<source>USB line</source>
|
||||
<translation>USB line</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="79"/>
|
||||
<location filename="../../dialog.ui" line="344"/>
|
||||
<source>stop server</source>
|
||||
<translation>stop server</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="62"/>
|
||||
<location filename="../../dialog.ui" line="334"/>
|
||||
<source>start server</source>
|
||||
<translation>start server</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="35"/>
|
||||
<location filename="../../dialog.ui" line="324"/>
|
||||
<source>device serial:</source>
|
||||
<translation>device serial:</translation>
|
||||
</message>
|
||||
|
@ -179,17 +183,17 @@
|
|||
<translation type="vanished">Config</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="260"/>
|
||||
<location filename="../../dialog.ui" line="68"/>
|
||||
<source>bit rate:</source>
|
||||
<translation>bit rate:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="89"/>
|
||||
<location filename="../../dialog.ui" line="399"/>
|
||||
<source>start adbd</source>
|
||||
<translation>start adbd</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="52"/>
|
||||
<location filename="../../dialog.ui" line="379"/>
|
||||
<source>refresh devices</source>
|
||||
<translation>refresh devices</translation>
|
||||
</message>
|
||||
|
@ -280,7 +284,7 @@
|
|||
<translation type="vanished">file transfer failed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/ui/videoform.cpp" line="407"/>
|
||||
<location filename="../../device/ui/videoform.cpp" line="408"/>
|
||||
<source>file does not exist</source>
|
||||
<translation>file does not exist</translation>
|
||||
</message>
|
||||
|
|
Binary file not shown.
|
@ -16,22 +16,22 @@
|
|||
<translation type="vanished">文件传输失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="115"/>
|
||||
<location filename="../../device/device.cpp" line="127"/>
|
||||
<source>install apk</source>
|
||||
<translation>安装apk</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="117"/>
|
||||
<location filename="../../device/device.cpp" line="129"/>
|
||||
<source>file transfer</source>
|
||||
<translation>文件传输</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="120"/>
|
||||
<location filename="../../device/device.cpp" line="132"/>
|
||||
<source>wait current %1 to complete</source>
|
||||
<translation>等待当前%1完成</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="123"/>
|
||||
<location filename="../../device/device.cpp" line="135"/>
|
||||
<source>%1 complete, save in %2</source>
|
||||
<translation>%1完成,保存在%2</translation>
|
||||
</message>
|
||||
|
@ -41,7 +41,7 @@
|
|||
<translation type="vanished">%1完成\n 保存在 %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/device.cpp" line="126"/>
|
||||
<location filename="../../device/device.cpp" line="138"/>
|
||||
<source>%1 failed</source>
|
||||
<translation>%1 失败</translation>
|
||||
</message>
|
||||
|
@ -49,128 +49,132 @@
|
|||
<context>
|
||||
<name>Dialog</name>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="102"/>
|
||||
<location filename="../../dialog.ui" line="415"/>
|
||||
<source>Wireless</source>
|
||||
<translation>无线</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="114"/>
|
||||
<location filename="../../dialog.ui" line="499"/>
|
||||
<source>wireless connect</source>
|
||||
<translation>无线连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="175"/>
|
||||
<location filename="../../dialog.ui" line="515"/>
|
||||
<source>wireless disconnect</source>
|
||||
<translation>无线断开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="254"/>
|
||||
<location filename="../../dialog.ui" line="32"/>
|
||||
<source>Start Config</source>
|
||||
<translation>启动配置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="274"/>
|
||||
<location filename="../../dialog.ui" line="127"/>
|
||||
<source>record save path:</source>
|
||||
<translation>录像保存路径:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="362"/>
|
||||
<location filename="../../dialog.cpp" line="287"/>
|
||||
<location filename="../../dialog.ui" line="144"/>
|
||||
<location filename="../../dialog.cpp" line="294"/>
|
||||
<source>select path</source>
|
||||
<translation>选择路径</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="267"/>
|
||||
<location filename="../../dialog.ui" line="99"/>
|
||||
<source>record format:</source>
|
||||
<translation>录制格式:</translation>
|
||||
</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>
|
||||
<translation>停止所有服务</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="213"/>
|
||||
<location filename="../../dialog.ui" line="549"/>
|
||||
<source>adb command:</source>
|
||||
<translation>adb命令:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="223"/>
|
||||
<location filename="../../dialog.ui" line="585"/>
|
||||
<source>terminate</source>
|
||||
<translation>终止</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="230"/>
|
||||
<location filename="../../dialog.ui" line="572"/>
|
||||
<source>execute</source>
|
||||
<translation>执行</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="244"/>
|
||||
<location filename="../../dialog.ui" line="598"/>
|
||||
<source>clear</source>
|
||||
<translation>清理</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="300"/>
|
||||
<location filename="../../dialog.ui" line="256"/>
|
||||
<source>reverse connection</source>
|
||||
<translation>反向连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="310"/>
|
||||
<source>auto enable</source>
|
||||
<translation>自动启用脚本</translation>
|
||||
<translation type="vanished">自动启用脚本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="339"/>
|
||||
<location filename="../../dialog.ui" line="240"/>
|
||||
<source>background record</source>
|
||||
<translation>后台录制</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="355"/>
|
||||
<location filename="../../dialog.ui" line="227"/>
|
||||
<source>screen-off</source>
|
||||
<translation>自动息屏</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="392"/>
|
||||
<location filename="../../dialog.ui" line="189"/>
|
||||
<source>apply</source>
|
||||
<translation>应用脚本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="406"/>
|
||||
<location filename="../../dialog.ui" line="85"/>
|
||||
<source>max size:</source>
|
||||
<translation>最大尺寸:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="323"/>
|
||||
<location filename="../../dialog.ui" line="272"/>
|
||||
<source>always on top</source>
|
||||
<translation>窗口置顶</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="287"/>
|
||||
<location filename="../../dialog.ui" line="182"/>
|
||||
<source>refresh script</source>
|
||||
<translation>刷新脚本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="42"/>
|
||||
<location filename="../../dialog.ui" line="389"/>
|
||||
<source>get device IP</source>
|
||||
<translation>获取设备IP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="26"/>
|
||||
<location filename="../../dialog.ui" line="288"/>
|
||||
<source>USB line</source>
|
||||
<translation>USB线</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="79"/>
|
||||
<location filename="../../dialog.ui" line="344"/>
|
||||
<source>stop server</source>
|
||||
<translation>停止服务</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="62"/>
|
||||
<location filename="../../dialog.ui" line="334"/>
|
||||
<source>start server</source>
|
||||
<translation>启动服务</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="35"/>
|
||||
<location filename="../../dialog.ui" line="324"/>
|
||||
<source>device serial:</source>
|
||||
<translation>设备序列号:</translation>
|
||||
</message>
|
||||
|
@ -179,17 +183,17 @@
|
|||
<translation type="vanished">配置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="260"/>
|
||||
<location filename="../../dialog.ui" line="68"/>
|
||||
<source>bit rate:</source>
|
||||
<translation>比特率:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="89"/>
|
||||
<location filename="../../dialog.ui" line="399"/>
|
||||
<source>start adbd</source>
|
||||
<translation>启动adbd</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../dialog.ui" line="52"/>
|
||||
<location filename="../../dialog.ui" line="379"/>
|
||||
<source>refresh devices</source>
|
||||
<translation>刷新设备列表</translation>
|
||||
</message>
|
||||
|
@ -280,7 +284,7 @@
|
|||
<translation type="vanished">文件传输失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../device/ui/videoform.cpp" line="407"/>
|
||||
<location filename="../../device/ui/videoform.cpp" line="408"/>
|
||||
<source>file does not exist</source>
|
||||
<translation>文件不存在</translation>
|
||||
</message>
|
||||
|
|
|
@ -12,9 +12,15 @@
|
|||
#define COMMON_RECORD_KEY "RecordPath"
|
||||
#define COMMON_RECORD_DEF ""
|
||||
|
||||
#define COMMON_PUSHFILE_KEY "PushFilePath"
|
||||
#define COMMON_PUSHFILE_DEF "/sdcard/"
|
||||
|
||||
#define COMMON_SERVER_VERSION_KEY "ServerVersion"
|
||||
#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_DEF 60
|
||||
|
||||
|
@ -24,6 +30,9 @@
|
|||
#define COMMON_SKIN_KEY "UseSkin"
|
||||
#define COMMON_SKIN_DEF 1
|
||||
|
||||
#define COMMON_RENDER_EXPIRED_FRAMES_KEY "RenderExpiredFrames"
|
||||
#define COMMON_RENDER_EXPIRED_FRAMES_DEF 0
|
||||
|
||||
QString Config::s_configPath = "";
|
||||
|
||||
Config::Config(QObject *parent) : QObject(parent)
|
||||
|
@ -102,6 +111,33 @@ int Config::getSkin()
|
|||
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 title;
|
||||
|
|
|
@ -17,6 +17,9 @@ public:
|
|||
int getMaxFps();
|
||||
int getDesktopOpenGL();
|
||||
int getSkin();
|
||||
int getRenderExpiredFrames();
|
||||
QString getPushFilePath();
|
||||
QString getServerPath();
|
||||
|
||||
private:
|
||||
explicit Config(QObject *parent = nullptr);
|
||||
|
|
|
@ -32,7 +32,7 @@ It focuses on:
|
|||
## 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.
|
||||
|
||||
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
|
||||
- Click `refresh script` to check whether it can be found
|
||||
- Select your script
|
||||
- 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
|
||||
- (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平台开启)
|
||||
可以根据需要,自己编写脚本将PC键盘按键映射为手机的触摸点击,编写规则在[这里](docs/按键映射说明.md)。
|
||||
|
||||
默认自带了针对和平精英手游进行键鼠映射的映射脚本,开启后可以用键鼠像玩端游一样玩和平精英手游,你也可以按照[编写规则](docs/按键映射说明.md)编写其他游戏的映射文件,默认按键映射如下:
|
||||
默认自带了针对和平精英手游和抖音进行键鼠映射的映射脚本,开启平精英手游后可以用键鼠像玩端游一样玩和平精英手游,开启抖音映射以后可以使用上下左右方向键模拟上下左右滑动,你也可以按照[编写规则](docs/按键映射说明.md)编写其他游戏的映射文件,默认按键映射如下:
|
||||
|
||||

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