ledset
|
@ -24,6 +24,6 @@ build-*
|
||||||
|
|
||||||
*.autosave
|
*.autosave
|
||||||
|
|
||||||
*-old/*
|
*OK-*/*
|
||||||
*-leyide/*
|
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "expertboxlayoutwin.h"
|
#include "expertboxlayoutwin.h"
|
||||||
#include "moduleunit.h"
|
#include "expertwin.h"
|
||||||
#include "gutil/qgui.h"
|
#include "gutil/qgui.h"
|
||||||
#include "gutil/qjson.h"
|
#include "gutil/qjson.h"
|
||||||
#include "globalfunc.h"
|
#include "globalfunc.h"
|
||||||
|
@ -8,16 +8,21 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} {
|
ExpertBoxLayoutWin::ExpertBoxLayoutWin(ExpertWin *parent) : BaseWin{parent} {
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
setWindowTitle("箱体高级布局");
|
setWindowTitle("箱体高级布局");
|
||||||
resize(1024, 720);
|
resize(1024, 720);
|
||||||
|
setStyleSheet("QToolButton {border: none; }");
|
||||||
|
|
||||||
auto vBox = new VBox(center);
|
auto vBox = new VBox(center);
|
||||||
vBox->setContentsMargins(0,0,0,0);
|
vBox->setContentsMargins(0,0,0,0);
|
||||||
vBox->setSpacing(3);
|
vBox->setSpacing(3);
|
||||||
vBox->addLayout(addBtns(new QHBoxLayout()));
|
vBox->addLayout(addBtns(new QHBoxLayout));
|
||||||
|
|
||||||
auto hBox = new HBox(vBox);
|
auto hBox = new HBox(vBox);
|
||||||
vBox = new VBox(hBox);
|
vBox = new VBox(hBox);
|
||||||
|
@ -26,22 +31,53 @@ ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} {
|
||||||
|
|
||||||
auto grid = new Grid(vBox);
|
auto grid = new Grid(vBox);
|
||||||
auto btnAdd = new QPushButton("添加");
|
auto btnAdd = new QPushButton("添加");
|
||||||
connect(btnAdd, &QPushButton::clicked, this, [this] {
|
connect(btnAdd, &QPushButton::clicked, this, [=] {
|
||||||
auto file = QFileDialog::getOpenFileName(this, tr("打开单元板文件"), gFileHome, tr("单元板文件 (*.module)"));
|
auto file = QFileDialog::getOpenFileName(this, tr("打开单元板文件"), gFileHome, tr("单元板文件 (*.module)"));
|
||||||
if(file.isEmpty()) return;
|
if(file.isEmpty()) return;
|
||||||
|
gFileHome = QFileInfo(file).absolutePath();
|
||||||
QFile qFile(file);
|
QFile qFile(file);
|
||||||
if(! qFile.open(QFile::ReadOnly)) {
|
if(! qFile.open(QFile::ReadOnly)) {
|
||||||
QMessageBox::critical(this, tr("打开单元板文件失败"), file);
|
QMessageBox::critical(this, tr("打开单元板文件失败"), file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString err;
|
QString err;
|
||||||
auto json = JFrom(&qFile, &err).toObj();
|
auto json = JFrom(&qFile, &err);
|
||||||
qFile.close();
|
qFile.close();
|
||||||
if(! err.isEmpty()) {
|
if(! err.isEmpty()) {
|
||||||
QMessageBox::critical(this, tr("解析 json 失败"), err+" "+file);
|
QMessageBox::critical(this, tr("解析 json 失败"), err+" "+file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new ModuleUnit(this, "J1", 0, 0, json["ModuleWidth"].toInt(), json["ModuleHeight"].toInt(), box);
|
QDialog dlg(this);
|
||||||
|
dlg.setWindowTitle(tr("添加模组"));
|
||||||
|
auto vBox = new VBox(&dlg);
|
||||||
|
auto hBox = new HBox(vBox);
|
||||||
|
hBox->addLabel(tr("横向数量"));
|
||||||
|
auto fdHNum = new QSpinBox;
|
||||||
|
fdHNum->setRange(1, 999);
|
||||||
|
fdHNum->setValue(1);
|
||||||
|
hBox->addWidget(fdHNum);
|
||||||
|
hBox->addStretch();
|
||||||
|
|
||||||
|
hBox = new HBox(vBox);
|
||||||
|
hBox->addLabel(tr("纵向数量"));
|
||||||
|
auto fdVNum = new QSpinBox;
|
||||||
|
fdVNum->setRange(1, 999);
|
||||||
|
fdVNum->setValue(1);
|
||||||
|
hBox->addWidget(fdVNum);
|
||||||
|
hBox->addStretch();
|
||||||
|
vBox->addStretch();
|
||||||
|
connect(vBox->addBtnBox(&dlg), &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
|
||||||
|
if(dlg.exec()!=QDialog::Accepted) return;
|
||||||
|
auto hNum = fdHNum->value();
|
||||||
|
auto vNum = fdVNum->value();
|
||||||
|
auto width = json["ModuleWidth"].toInt();
|
||||||
|
auto height = json["ModuleHeight"].toInt();
|
||||||
|
for(int vv=0; vv < vNum; ++vv) for(int hh=0; hh < hNum; ++hh) {
|
||||||
|
auto unit = new ModuleUnit(width*hh, height*vv, width, height, json.toObj(), "", box);
|
||||||
|
unit->show();
|
||||||
|
}
|
||||||
|
fdModNum->setNum(box->children().size());
|
||||||
|
box->fitSize();
|
||||||
});
|
});
|
||||||
grid->addWidget(btnAdd, 0, 0);
|
grid->addWidget(btnAdd, 0, 0);
|
||||||
auto btnDel = new QPushButton("删除");
|
auto btnDel = new QPushButton("删除");
|
||||||
|
@ -51,50 +87,532 @@ ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} {
|
||||||
auto btnRotate = new QPushButton("旋转");
|
auto btnRotate = new QPushButton("旋转");
|
||||||
grid->addWidget(btnRotate, 1, 1);
|
grid->addWidget(btnRotate, 1, 1);
|
||||||
|
|
||||||
vBox->addWidget(new QLabel("HUB口编辑"));
|
auto btnDraw = new QPushButton("开始走线");
|
||||||
|
btnDraw->setCheckable(true);
|
||||||
|
connect(btnDraw, &QPushButton::clicked, this, [=](bool checked) {
|
||||||
|
box->isDrawing = checked;
|
||||||
|
btnDraw->setText(checked ? "结束走线" : "开始走线");
|
||||||
|
});
|
||||||
|
grid->addWidget(btnDraw, 2, 0);
|
||||||
|
|
||||||
|
auto btnClearLines = new QPushButton("清空所有走线");
|
||||||
|
connect(btnClearLines, &QPushButton::clicked, this, [=] {
|
||||||
|
for(auto btn : grpGrp->buttons()) if(btn->property("mods").isValid()) btn->setProperty("mods", QVariant());
|
||||||
|
for(auto child : box->children()) ((ModuleUnit*)child)->name = QString();
|
||||||
|
box->update();
|
||||||
|
});
|
||||||
|
grid->addWidget(btnClearLines, 3, 0);
|
||||||
|
|
||||||
|
auto btnClearLine = new QPushButton("清空当前走线");
|
||||||
|
connect(btnClearLine, &QPushButton::clicked, this, [=] {
|
||||||
|
for(auto btn : grpGrp->buttons()) {
|
||||||
|
auto mods = btn->property("mods").toList();
|
||||||
|
for(auto mod : mods) if(((ModuleUnit*) mod.value<void*>())->isSel) {
|
||||||
|
btn->setProperty("mods", QVariant());
|
||||||
|
for(auto mod : mods) ((ModuleUnit*) mod.value<void*>())->name = QString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
box->update();
|
||||||
|
});
|
||||||
|
grid->addWidget(btnClearLine, 3, 1);
|
||||||
|
|
||||||
|
vBox->addLabel("数据组数设置");
|
||||||
|
auto hh = new HBox(vBox);
|
||||||
|
|
||||||
|
hh->addLabel("组数:");
|
||||||
|
auto fdGNum = new QSpinBox;
|
||||||
|
fdGNum->setRange(1, 128);
|
||||||
|
fdGNum->setValue(16);
|
||||||
|
hh->addWidget(fdGNum);
|
||||||
|
|
||||||
|
auto btnSet = new QPushButton("设置");
|
||||||
|
hh->addWidget(btnSet);
|
||||||
|
|
||||||
grid = new Grid(vBox);
|
grid = new Grid(vBox);
|
||||||
auto btnPort = new QPushButton("端口");
|
grpGrp = new QButtonGroup(fdGNum);
|
||||||
grid->addWidget(btnPort, 0, 0);
|
connect(btnSet, &QPushButton::clicked, this, [=] {
|
||||||
auto btnManual = new QPushButton("手动");
|
auto newCnt = fdGNum->value();
|
||||||
grid->addWidget(btnManual, 0, 1);
|
auto oldCnt = grpGrp->buttons().size();
|
||||||
auto btnUp = new QPushButton("上移");
|
if(newCnt>oldCnt) for(int i=oldCnt; i<newCnt; ++i) {
|
||||||
grid->addWidget(btnUp, 1, 0);
|
auto btn = new QPushButton("G"+QString::number(i+1));
|
||||||
auto btnDown = new QPushButton("下移");
|
btn->setCheckable(true);
|
||||||
grid->addWidget(btnDown, 1, 1);
|
btn->setMaximumWidth(40);
|
||||||
|
btn->setFixedHeight(24);
|
||||||
|
grpGrp->addButton(btn, i);
|
||||||
|
grid->addWidget(btn, i / 4, i % 4);
|
||||||
|
} else if(newCnt<oldCnt) for(int i=oldCnt-1; i>=newCnt; --i) {
|
||||||
|
auto btn = grpGrp->button(i);
|
||||||
|
grpGrp->removeButton(btn);
|
||||||
|
grid->removeWidget(btn);
|
||||||
|
delete btn;
|
||||||
|
}
|
||||||
|
if(grpGrp->checkedButton()==0) grpGrp->buttons()[0]->setChecked(true);
|
||||||
|
});
|
||||||
|
emit btnSet->clicked();
|
||||||
|
|
||||||
vBox->addWidget(new QLabel("HUB口编辑"));
|
|
||||||
|
vBox->addWidget(new QLabel("显示"));
|
||||||
|
|
||||||
grid = new Grid(vBox);
|
grid = new Grid(vBox);
|
||||||
auto fdHasPos = new QCheckBox("位置");
|
fdHasPos = new QCheckBox("位置");
|
||||||
|
fdHasPos->setChecked(true);
|
||||||
grid->addWidget(fdHasPos, 0, 0);
|
grid->addWidget(fdHasPos, 0, 0);
|
||||||
auto fdHasSize = new QCheckBox("大小");
|
fdHasSize = new QCheckBox("大小");
|
||||||
|
fdHasSize->setChecked(true);
|
||||||
grid->addWidget(fdHasSize, 0, 1);
|
grid->addWidget(fdHasSize, 0, 1);
|
||||||
auto fdHasConn = new QCheckBox("连接");
|
fdHasConn = new QCheckBox("连接");
|
||||||
|
fdHasConn->setChecked(true);
|
||||||
grid->addWidget(fdHasConn, 1, 0);
|
grid->addWidget(fdHasConn, 1, 0);
|
||||||
auto fdHasName = new QCheckBox("名称");
|
fdHasName = new QCheckBox("名称");
|
||||||
|
fdHasName->setChecked(true);
|
||||||
grid->addWidget(fdHasName, 1, 1);
|
grid->addWidget(fdHasName, 1, 1);
|
||||||
auto fdHasOutline = new QCheckBox("轮廓");
|
fdHasOutline = new QCheckBox("轮廓");
|
||||||
|
fdHasOutline->setChecked(true);
|
||||||
grid->addWidget(fdHasOutline, 2, 0);
|
grid->addWidget(fdHasOutline, 2, 0);
|
||||||
auto fdHasRotate = new QCheckBox("旋转");
|
|
||||||
grid->addWidget(fdHasRotate, 2, 1);
|
vBox->addWidget(new QLabel("对齐"));
|
||||||
|
hh = new HBox(vBox);
|
||||||
|
|
||||||
|
QSize imgSize(32,32);
|
||||||
|
|
||||||
|
auto bnAlignLeft = new QToolButton;
|
||||||
|
bnAlignLeft->setIconSize(imgSize);
|
||||||
|
bnAlignLeft->setIcon(QIcon(":/imgs/align-left.png"));
|
||||||
|
connect(bnAlignLeft, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MAX;
|
||||||
|
ModuleUnit* mod;
|
||||||
|
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->x() < bound) bound = mod->x();
|
||||||
|
bool needFit = false;
|
||||||
|
if(bound != INT_MAX) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->x() != bound) {
|
||||||
|
mod->move(bound, mod->y());
|
||||||
|
mod->mX = qRound(mod->x() / box->rate);
|
||||||
|
needFit = true;
|
||||||
|
}
|
||||||
|
if(needFit) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnAlignLeft);
|
||||||
|
|
||||||
|
auto bnAlignRight = new QToolButton;
|
||||||
|
bnAlignRight->setIconSize(imgSize);
|
||||||
|
bnAlignRight->setIcon(QIcon(":/imgs/align-right.png"));
|
||||||
|
connect(bnAlignRight, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MIN, temp;
|
||||||
|
ModuleUnit* mod;
|
||||||
|
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && (temp = mod->x()+mod->width()) > bound) bound = temp;
|
||||||
|
bool needFit = false;
|
||||||
|
if(bound != INT_MIN) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->x() != (temp = bound-mod->width())) {
|
||||||
|
mod->move(temp, mod->y());
|
||||||
|
mod->mX = qRound(mod->x() / box->rate);
|
||||||
|
needFit = true;
|
||||||
|
}
|
||||||
|
if(needFit) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnAlignRight);
|
||||||
|
|
||||||
|
auto bnAlignTop = new QToolButton;
|
||||||
|
bnAlignTop->setIconSize(imgSize);
|
||||||
|
bnAlignTop->setIcon(QIcon(":/imgs/align-top.png"));
|
||||||
|
connect(bnAlignTop, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MAX;
|
||||||
|
ModuleUnit* mod;
|
||||||
|
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->y() < bound) bound = mod->y();
|
||||||
|
bool needFit = false;
|
||||||
|
if(bound != INT_MAX) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->y() != bound) {
|
||||||
|
mod->move(mod->x(), bound);
|
||||||
|
mod->mY = qRound(mod->y() / box->rate);
|
||||||
|
needFit = true;
|
||||||
|
}
|
||||||
|
if(needFit) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnAlignTop);
|
||||||
|
|
||||||
|
auto bnAlignBottom = new QToolButton;
|
||||||
|
bnAlignBottom->setIconSize(imgSize);
|
||||||
|
bnAlignBottom->setIcon(QIcon(":/imgs/align-bottom.png"));
|
||||||
|
connect(bnAlignBottom, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MIN, temp;
|
||||||
|
ModuleUnit* mod;
|
||||||
|
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && (temp = mod->y()+mod->height()) > bound) bound = temp;
|
||||||
|
bool needFit = false;
|
||||||
|
if(bound != INT_MIN) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->y() != (temp = bound-mod->height())) {
|
||||||
|
mod->move(mod->x(), temp);
|
||||||
|
mod->mY = qRound(mod->y() / box->rate);
|
||||||
|
needFit = true;
|
||||||
|
}
|
||||||
|
if(needFit) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnAlignBottom);
|
||||||
|
|
||||||
|
vBox->addWidget(new QLabel("排列"));
|
||||||
|
hh = new HBox(vBox);
|
||||||
|
|
||||||
|
auto bnArrangeLeft = new QToolButton;
|
||||||
|
bnArrangeLeft->setIconSize(imgSize);
|
||||||
|
bnArrangeLeft->setIcon(QIcon(":/imgs/arrange-left.png"));
|
||||||
|
connect(bnArrangeLeft, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MAX;
|
||||||
|
ModuleUnit* tmod;
|
||||||
|
std::vector<ModuleUnit*> mods;
|
||||||
|
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||||
|
auto it = mods.begin();
|
||||||
|
while(it!=mods.end() && (*it)->y() <= tmod->y()) it++;
|
||||||
|
mods.insert(it, tmod);
|
||||||
|
if(tmod->x() < bound) bound = tmod->x();
|
||||||
|
}
|
||||||
|
tmod = 0;
|
||||||
|
for(auto mod : mods) {
|
||||||
|
mod->move(bound, tmod ? tmod->y()+tmod->height() : mod->y());
|
||||||
|
tmod = mod;
|
||||||
|
mod->mX = qRound(mod->x() / box->rate);
|
||||||
|
mod->mY = qRound(mod->y() / box->rate);
|
||||||
|
}
|
||||||
|
if(! mods.empty()) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnArrangeLeft);
|
||||||
|
|
||||||
|
auto bnArrangeRight = new QToolButton;
|
||||||
|
bnArrangeRight->setIconSize(imgSize);
|
||||||
|
bnArrangeRight->setIcon(QIcon(":/imgs/arrange-right.png"));
|
||||||
|
connect(bnArrangeRight, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MIN;
|
||||||
|
ModuleUnit* tmod;
|
||||||
|
std::vector<ModuleUnit*> mods;
|
||||||
|
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||||
|
auto it = mods.begin();
|
||||||
|
while(it!=mods.end() && (*it)->y() <= tmod->y()) it++;
|
||||||
|
mods.insert(it, tmod);
|
||||||
|
if(tmod->x()+tmod->width() > bound) bound = tmod->x()+tmod->width();
|
||||||
|
}
|
||||||
|
tmod = 0;
|
||||||
|
for(auto mod : mods) {
|
||||||
|
mod->move(bound-mod->width(), tmod ? tmod->y()+tmod->height() : mod->y());
|
||||||
|
tmod = mod;
|
||||||
|
mod->mX = qRound(mod->x() / box->rate);
|
||||||
|
mod->mY = qRound(mod->y() / box->rate);
|
||||||
|
}
|
||||||
|
if(! mods.empty()) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnArrangeRight);
|
||||||
|
|
||||||
|
auto bnArrangeTop = new QToolButton;
|
||||||
|
bnArrangeTop->setIconSize(imgSize);
|
||||||
|
bnArrangeTop->setIcon(QIcon(":/imgs/arrange-top.png"));
|
||||||
|
connect(bnArrangeTop, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MAX;
|
||||||
|
ModuleUnit* tmod;
|
||||||
|
std::vector<ModuleUnit*> mods;
|
||||||
|
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||||
|
auto it = mods.begin();
|
||||||
|
while(it!=mods.end() && (*it)->x() <= tmod->x()) it++;
|
||||||
|
mods.insert(it, tmod);
|
||||||
|
if(tmod->y() < bound) bound = tmod->y();
|
||||||
|
}
|
||||||
|
tmod = 0;
|
||||||
|
for(auto mod : mods) {
|
||||||
|
mod->move(tmod ? tmod->x()+tmod->width() : mod->x(), bound);
|
||||||
|
tmod = mod;
|
||||||
|
mod->mX = qRound(mod->x() / box->rate);
|
||||||
|
mod->mY = qRound(mod->y() / box->rate);
|
||||||
|
}
|
||||||
|
if(! mods.empty()) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnArrangeTop);
|
||||||
|
|
||||||
|
auto bnArrangeBottom = new QToolButton;
|
||||||
|
bnArrangeBottom->setIconSize(imgSize);
|
||||||
|
bnArrangeBottom->setIcon(QIcon(":/imgs/arrange-bottom.png"));
|
||||||
|
connect(bnArrangeBottom, &QToolButton::clicked, this, [=] {
|
||||||
|
int bound = INT_MIN;
|
||||||
|
ModuleUnit* tmod;
|
||||||
|
std::vector<ModuleUnit*> mods;
|
||||||
|
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||||
|
auto it = mods.begin();
|
||||||
|
while(it!=mods.end() && (*it)->x() <= tmod->x()) it++;
|
||||||
|
mods.insert(it, tmod);
|
||||||
|
if(tmod->y()+tmod->height() > bound) bound = tmod->y()+tmod->height();
|
||||||
|
}
|
||||||
|
tmod = 0;
|
||||||
|
for(auto mod : mods) {
|
||||||
|
mod->move(tmod ? tmod->x()+tmod->width() : mod->x(), bound-mod->height());
|
||||||
|
tmod = mod;
|
||||||
|
mod->mX = qRound(mod->x() / box->rate);
|
||||||
|
mod->mY = qRound(mod->y() / box->rate);
|
||||||
|
}
|
||||||
|
if(! mods.empty()) box->fitSize();
|
||||||
|
});
|
||||||
|
hh->addWidget(bnArrangeBottom);
|
||||||
|
|
||||||
vBox->addStretch();
|
vBox->addStretch();
|
||||||
|
|
||||||
vBox = new VBox(hBox);
|
vBox = new VBox(hBox);
|
||||||
hBox = new HBox(vBox);
|
hBox = new HBox(vBox);
|
||||||
|
auto fdRoom = new QComboBox;
|
||||||
|
fdRoom->setEditable(true);
|
||||||
|
fdRoom->addItem("1600%");
|
||||||
|
fdRoom->addItem("800%");
|
||||||
|
fdRoom->addItem("400%");
|
||||||
|
fdRoom->addItem("200%");
|
||||||
|
fdRoom->addItem("100%");
|
||||||
|
fdRoom->addItem("50%");
|
||||||
|
fdRoom->addItem("25%");
|
||||||
|
connect(fdRoom, &QComboBox::currentTextChanged, this, [=](const QString &text) {
|
||||||
|
if(box==0) return;
|
||||||
|
box->rate = text.trimmed().replace('%',"").toInt() / 100.0;
|
||||||
|
auto childs = box->children();
|
||||||
|
foreach(auto child, childs) {
|
||||||
|
auto mod = (ModuleUnit*)child;
|
||||||
|
mod->setGeometry(mod->mX*box->rate, mod->mY*box->rate, mod->mW*box->rate, mod->mH*box->rate);
|
||||||
|
}
|
||||||
|
box->fitSize();
|
||||||
|
});
|
||||||
|
hBox->addWidget(fdRoom);
|
||||||
|
|
||||||
|
hBox->addLabel("模组数量: ");
|
||||||
|
fdModNum = hBox->addLabel();
|
||||||
|
hBox->addSpacing(20);
|
||||||
|
|
||||||
|
hBox->addLabel("箱体大小: ");
|
||||||
|
fdBoxSize = hBox->addLabel();
|
||||||
|
|
||||||
hBox->addStretch();
|
hBox->addStretch();
|
||||||
|
|
||||||
auto scroll = new QScrollArea;
|
auto scroll = new QScrollArea;
|
||||||
vBox->addWidget(scroll);
|
vBox->addWidget(scroll);
|
||||||
|
|
||||||
box = new QWidget;
|
box = new BoxPanel(this);
|
||||||
scroll->setWidget(box);
|
scroll->setWidget(box);
|
||||||
box->resize(1024, 1024);
|
box->resize(1024, 1024);
|
||||||
box->setAutoFillBackground(true);
|
box->setAutoFillBackground(true);
|
||||||
auto pal = palette();
|
auto pal = palette();
|
||||||
pal.setColor(QPalette::Window, QColor(0x222222));
|
pal.setColor(QPalette::Window, QColor(0x222222));
|
||||||
box->setPalette(pal);
|
box->setPalette(pal);
|
||||||
|
SetCurText(fdRoom, "200%");
|
||||||
|
|
||||||
new ModuleUnit(this, "J1", 0, 0, 128, 128, box);
|
connect(fdHasPos, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||||
|
connect(fdHasSize, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||||
|
connect(fdHasConn, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||||
|
connect(fdHasName, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||||
|
connect(fdHasOutline, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||||
|
|
||||||
|
auto ModuleWidth = parent->mModule["ModuleWidth"].toInt();
|
||||||
|
auto ModuleHeight = parent->mModule["ModuleHeight"].toInt();
|
||||||
|
new ModuleUnit(0, 0, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||||
|
new ModuleUnit(ModuleWidth, 0, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||||
|
new ModuleUnit(0, ModuleHeight, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||||
|
new ModuleUnit(ModuleWidth, ModuleHeight, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||||
|
fdModNum->setNum(4);
|
||||||
|
box->fitSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BoxPanel::mousePressEvent(QMouseEvent *event) {
|
||||||
|
if(event->button() != Qt::LeftButton) return;
|
||||||
|
if(isDrawing) return;
|
||||||
|
rect = QRectF(event->localPos(), event->localPos());
|
||||||
|
for(auto child : children()) ((ModuleUnit*) child)->isSel = false;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
void BoxPanel::mouseReleaseEvent(QMouseEvent *event) {
|
||||||
|
if(event->button() != Qt::LeftButton) return;
|
||||||
|
if(rect.isNull()) return;
|
||||||
|
rect = QRectF();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
void BoxPanel::mouseMoveEvent(QMouseEvent *event) {
|
||||||
|
if(! (event->buttons() & Qt::LeftButton)) return;
|
||||||
|
if(isDrawing) {
|
||||||
|
auto mod = (ModuleUnit*) childAt(event->pos());
|
||||||
|
if(mod && mod->name.isEmpty()) mod->drawed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rect.setBottomRight(event->localPos());
|
||||||
|
for(auto child : children()) {
|
||||||
|
auto mod = (ModuleUnit*) child;
|
||||||
|
mod->isSel = rect.intersects(mod->geometry());
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
void BoxPanel::paintEvent(QPaintEvent *) {
|
||||||
|
QPainter painter(this);
|
||||||
|
ModuleUnit *mod;
|
||||||
|
for(auto child : children()) {
|
||||||
|
mod = (ModuleUnit*) child;
|
||||||
|
QPointF pos(mod->x(), mod->y());
|
||||||
|
painter.translate(pos);
|
||||||
|
painter.fillRect(QRectF(1, 1, mod->width()-2, mod->height()-2), mod->isSel ? QColor(0, 0xaa, 0, 0xaa) : QColor(0, 0x44, 0xff, 0x77));
|
||||||
|
painter.setPen(QColor(mod->isSel ? 0xffffff : 0xdddddd));
|
||||||
|
if(boxWin->fdHasOutline->isChecked()) painter.drawRect(QRectF(0.5, 0.5, mod->width()-1, mod->height()-1));
|
||||||
|
int off = 0;
|
||||||
|
if(boxWin->fdHasPos->isChecked()) painter.drawText(2, off+=15, QString::number(mod->mX)+", "+QString::number(mod->mY));
|
||||||
|
if(boxWin->fdHasSize->isChecked()) painter.drawText(2, off+=15, QString::number(mod->mW)+" x "+QString::number(mod->mH));
|
||||||
|
if(! mod->name.isEmpty()) painter.drawText(2, off+15, mod->name);
|
||||||
|
painter.translate(-pos);
|
||||||
|
}
|
||||||
|
QPen pen(0xff8800);
|
||||||
|
pen.setCapStyle(Qt::FlatCap);
|
||||||
|
pen.setDashPattern(QVector<qreal>{4, 4});
|
||||||
|
painter.setPen(pen);
|
||||||
|
painter.drawRect(QRectF(boxRect.x()-0.5, boxRect.y()-0.5, boxRect.width()+1, boxRect.height()+1));
|
||||||
|
|
||||||
|
if(boxWin->fdHasConn->isChecked()) {
|
||||||
|
QBrush brush(0x0088ff);
|
||||||
|
painter.setPen(QPen(brush, 3));
|
||||||
|
QPainterPath path;
|
||||||
|
for(auto btn : boxWin->grpGrp->buttons()) {
|
||||||
|
auto mods = btn->property("mods").toList();
|
||||||
|
if(mods.isEmpty()) continue;
|
||||||
|
QPointF last = ((ModuleUnit*) mods[0].value<void*>())->geometry().center();
|
||||||
|
for(int mm=1; mm<mods.size(); mm++) {
|
||||||
|
QPointF pos = ((ModuleUnit*) mods[mm].value<void*>())->geometry().center();
|
||||||
|
painter.drawLine(last, pos);
|
||||||
|
auto deg = 180 / 3.1415926535 * atan((pos.y()-last.y()) / (pos.x()-last.x()));
|
||||||
|
if(pos.x()<last.x()) deg += 180;
|
||||||
|
last = pos;
|
||||||
|
painter.translate(pos);
|
||||||
|
painter.rotate(deg);
|
||||||
|
path.clear();
|
||||||
|
path.lineTo(-30,6);
|
||||||
|
path.lineTo(-30,-6);
|
||||||
|
path.closeSubpath();
|
||||||
|
painter.fillPath(path, brush);
|
||||||
|
painter.rotate(-deg);
|
||||||
|
painter.translate(-pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rect.isNull()) return;
|
||||||
|
painter.setPen(0x00aa00);
|
||||||
|
painter.drawRect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModuleUnit::ModuleUnit(int x, int y, int w, int h, const JObj &module, const QString &name, QWidget *parent) : QWidget{parent}, mX{x}, mY{y}, mW{w}, mH{h}, mModule{module}, name{name} {
|
||||||
|
box = (BoxPanel*)parent;
|
||||||
|
setGeometry(x*box->rate, y*box->rate, w*box->rate, h*box->rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModuleUnit::drawed() {
|
||||||
|
auto btn = box->boxWin->grpGrp->checkedButton();
|
||||||
|
if(btn==0) return;
|
||||||
|
auto mods = btn->property("mods").toList();
|
||||||
|
mods.append(QVariant::fromValue((void*)this));
|
||||||
|
btn->setProperty("mods", mods);
|
||||||
|
name = "G"+QString::number(box->boxWin->grpGrp->id(btn)+1)+"-"+QString::number(mods.size());
|
||||||
|
box->update();
|
||||||
|
}
|
||||||
|
void ModuleUnit::mousePressEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mousePressEvent(event);
|
||||||
|
if(event->button() != Qt::LeftButton) return;
|
||||||
|
event->accept();
|
||||||
|
if(box->isDrawing) return;
|
||||||
|
setCursor(Qt::SizeAllCursor);
|
||||||
|
auto glbPos = event->globalPos();
|
||||||
|
box->grpRect = geometry();
|
||||||
|
if(isSel) {
|
||||||
|
mOtherSels.clear();
|
||||||
|
ModuleUnit* mod;
|
||||||
|
for(auto child : box->children()) if(child!=this && (mod = (ModuleUnit*)child)->isSel) {
|
||||||
|
mod->mPressRel = mod->pos() - pos();
|
||||||
|
box->grpRect |= mod->geometry();
|
||||||
|
mOtherSels.emplace_back(mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPressRel = pos() - box->grpRect.topLeft();
|
||||||
|
box->grpRect.translate(-glbPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModuleUnit::mouseReleaseEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mouseReleaseEvent(event);
|
||||||
|
if(Qt::LeftButton != event->button()) return;
|
||||||
|
event->accept();
|
||||||
|
if(box->isDrawing) {
|
||||||
|
if(name.isEmpty()) drawed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsetCursor();
|
||||||
|
mPressRel.setX(INT_MIN);
|
||||||
|
if(! isSel) {
|
||||||
|
isSel = true;
|
||||||
|
update();
|
||||||
|
for(auto item : box->children()) if(item!=this && ((ModuleUnit*)item)->isSel) {
|
||||||
|
((ModuleUnit*)item)->isSel = false;
|
||||||
|
((ModuleUnit*)item)->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(auto sel : mOtherSels) sel->mPressRel.setX(INT_MIN);
|
||||||
|
mOtherSels.clear();
|
||||||
|
}
|
||||||
|
#define SnapSpace 6
|
||||||
|
void ModuleUnit::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
if(! (e->buttons() & Qt::LeftButton)) return;
|
||||||
|
if(box->isDrawing) {
|
||||||
|
if(name.isEmpty()) drawed();
|
||||||
|
else {
|
||||||
|
auto mod = (ModuleUnit*) box->childAt(x()+e->x(), y()+e->y());
|
||||||
|
if(mod && mod!=this && mod->name.isEmpty()) mod->drawed();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(mPressRel.x()==INT_MIN) return;
|
||||||
|
if(! isSel) {
|
||||||
|
isSel = true;
|
||||||
|
for(auto child : box->children()) if(child!=this && ((ModuleUnit*)child)->isSel) ((ModuleUnit*)child)->isSel = false;
|
||||||
|
}
|
||||||
|
auto mousePos = e->globalPos();
|
||||||
|
auto dstHor = box->grpRect.x() + mousePos.x();
|
||||||
|
auto dstVer = box->grpRect.y() + mousePos.y();
|
||||||
|
dstHor = qMax(0, dstHor);
|
||||||
|
dstVer = qMax(0, dstVer);
|
||||||
|
// if(dstHor) for(ModuleUnit *ele : mOtherEles) {//左右
|
||||||
|
// if(abs(dstHor - ele->x()) < SnapSpace) {
|
||||||
|
// dstHor = ele->x();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// auto eleRight = ele->x() + ele->width();
|
||||||
|
// if(abs(dstHor - eleRight) < SnapSpace) {
|
||||||
|
// dstHor = eleRight;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// auto right = dstHor + width();
|
||||||
|
// if(abs(right - ele->x()) < SnapSpace && ele->x() - width() >= 0) {
|
||||||
|
// dstHor = ele->x() - width();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if(abs(right - eleRight) < SnapSpace && eleRight - width() >= 0) {
|
||||||
|
// dstHor = eleRight - width();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if(dstVer) for(ModuleUnit *ele : mOtherEles) {//上下
|
||||||
|
// if(abs(dstVer-ele->y()) < SnapSpace) {
|
||||||
|
// dstVer = ele->y();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// auto eleBtm = ele->y() + ele->height();
|
||||||
|
// if(abs(dstVer - eleBtm) < SnapSpace) {
|
||||||
|
// dstVer = eleBtm;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// auto btm = dstVer + height();
|
||||||
|
// if(abs(btm - ele->y()) < SnapSpace && ele->y() - height() >= 0) {
|
||||||
|
// dstVer = ele->y() - height();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if(abs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) {
|
||||||
|
// dstVer = eleBtm - height();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
move(mPressRel.x() + dstHor, mPressRel.y() + dstVer);
|
||||||
|
mX = qRound(x() / box->rate);
|
||||||
|
mY = qRound(y() / box->rate);
|
||||||
|
for(auto sel : mOtherSels) {
|
||||||
|
if(sel->mPressRel.x()==INT_MIN) continue;
|
||||||
|
sel->move(sel->mPressRel.x() + x(), sel->mPressRel.y() + y());
|
||||||
|
sel->mX = qRound(sel->x() / box->rate);
|
||||||
|
sel->mY = qRound(sel->y() / box->rate);
|
||||||
|
}
|
||||||
|
box->fitSize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,69 @@
|
||||||
#define EXPERTBOXLAYOUTWIN_H
|
#define EXPERTBOXLAYOUTWIN_H
|
||||||
|
|
||||||
#include "basewin.h"
|
#include "basewin.h"
|
||||||
|
#include "gutil/qjson.h"
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QSpinBox>
|
#include <QButtonGroup>
|
||||||
#include <QComboBox>
|
#include <QCheckBox>
|
||||||
|
|
||||||
|
class ExpertWin;
|
||||||
|
class BoxPanel;
|
||||||
class ExpertBoxLayoutWin : public BaseWin {
|
class ExpertBoxLayoutWin : public BaseWin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ExpertBoxLayoutWin(QWidget *parent = 0);
|
explicit ExpertBoxLayoutWin(ExpertWin *parent = 0);
|
||||||
|
|
||||||
|
QCheckBox *fdHasPos, *fdHasSize, *fdHasConn, *fdHasName, *fdHasOutline;
|
||||||
|
QButtonGroup *grpGrp;
|
||||||
|
BoxPanel *box{0};
|
||||||
|
QLabel *fdModNum, *fdBoxSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModuleUnit;
|
||||||
|
class BoxPanel : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit BoxPanel(ExpertBoxLayoutWin *boxWin) : boxWin(boxWin) {}
|
||||||
|
|
||||||
|
void fitSize() {
|
||||||
|
boxRect = childrenRect();
|
||||||
|
auto www = qMax(1000, boxRect.x()+boxRect.width()+1);
|
||||||
|
auto hhh = qMax(1000, boxRect.y()+boxRect.height()+1);
|
||||||
|
if(www!=width() || hhh!=height()) resize(www, hhh);
|
||||||
|
else update();
|
||||||
|
boxWin->fdBoxSize->setText(QString("%1 x %2").arg(boxRect.width()).arg(boxRect.height()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect boxRect, grpRect;
|
||||||
|
ExpertBoxLayoutWin *boxWin;
|
||||||
double rate{1};
|
double rate{1};
|
||||||
QWidget *box;
|
QRectF rect;
|
||||||
|
bool isDrawing{false};
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModuleUnit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ModuleUnit(int, int, int, int, const JObj &module, const QString &name, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void drawed();
|
||||||
|
int mX, mY, mW, mH;
|
||||||
|
JObj mModule;
|
||||||
|
QString name;
|
||||||
|
BoxPanel *box;
|
||||||
|
QPoint mPressRel{INT_MIN, INT_MIN};
|
||||||
|
bool isSel{false};
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *) override;
|
||||||
|
|
||||||
|
std::vector<ModuleUnit *> mOtherSels;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EXPERTBOXLAYOUTWIN_H
|
#endif // EXPERTBOXLAYOUTWIN_H
|
||||||
|
|
|
@ -709,7 +709,8 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e
|
||||||
vBox->addLayout(hhh);
|
vBox->addLayout(hhh);
|
||||||
|
|
||||||
table = new Table;
|
table = new Table;
|
||||||
table->setNoEdit()->setSelectionMode(QTableWidget::SingleSelection);
|
table->setEditTriggers(Table::NoEditTriggers);
|
||||||
|
table->setSelectionMode(QTableWidget::SingleSelection);
|
||||||
table->setColWidth(35)->setRowHeight(24, QHeaderView::Fixed);
|
table->setColWidth(35)->setRowHeight(24, QHeaderView::Fixed);
|
||||||
table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
|
table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
|
||||||
table->verticalHeader()->setMinimumWidth(35);
|
table->verticalHeader()->setMinimumWidth(35);
|
||||||
|
@ -750,7 +751,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e
|
||||||
vBox->addWidget(table);
|
vBox->addWidget(table);
|
||||||
|
|
||||||
tableRow = new Table(2, 0);
|
tableRow = new Table(2, 0);
|
||||||
tableRow->setNoEdit();
|
tableRow->setEditTriggers(Table::NoEditTriggers);
|
||||||
tableRow->setSelectionMode(QTableWidget::NoSelection);
|
tableRow->setSelectionMode(QTableWidget::NoSelection);
|
||||||
tableRow->setColWidth(35);
|
tableRow->setColWidth(35);
|
||||||
tableRow->setRowHeight(24);
|
tableRow->setRowHeight(24);
|
||||||
|
|
|
@ -134,6 +134,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
||||||
qFile.close();
|
qFile.close();
|
||||||
auto json = JFrom(data).toObj();
|
auto json = JFrom(data).toObj();
|
||||||
if(! json.empty()) {
|
if(! json.empty()) {
|
||||||
|
cfg = json;
|
||||||
mBox = json["ModuleConnectionInfo"].toObj();
|
mBox = json["ModuleConnectionInfo"].toObj();
|
||||||
mModule = mBox["ModuleInfo"].toObj();
|
mModule = mBox["ModuleInfo"].toObj();
|
||||||
}
|
}
|
||||||
|
@ -247,7 +248,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
||||||
fdNormal->setChecked(true);
|
fdNormal->setChecked(true);
|
||||||
vvv->addWidget(fdNormal);
|
vvv->addWidget(fdNormal);
|
||||||
|
|
||||||
auto fdAdvacned = new QRadioButton("高级设计");
|
fdAdvacned = new QRadioButton("高级设计");
|
||||||
vvv->addWidget(fdAdvacned);
|
vvv->addWidget(fdAdvacned);
|
||||||
|
|
||||||
hh->addSpacing(20);
|
hh->addSpacing(20);
|
||||||
|
@ -308,7 +309,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
||||||
fdSectorCount->addItem(tr("六开"), 6);
|
fdSectorCount->addItem(tr("六开"), 6);
|
||||||
fdSectorCount->addItem(tr("七开"), 7);
|
fdSectorCount->addItem(tr("七开"), 7);
|
||||||
fdSectorCount->addItem(tr("八开"), 8);
|
fdSectorCount->addItem(tr("八开"), 8);
|
||||||
setCurrentData(fdSectorCount, mBox["SectorCount"].toInt());
|
SetCurData(fdSectorCount, mBox["SectorCount"].toInt());
|
||||||
vvv->addWidget(fdSectorCount);
|
vvv->addWidget(fdSectorCount);
|
||||||
|
|
||||||
fdDirection = new QComboBox();
|
fdDirection = new QComboBox();
|
||||||
|
@ -344,12 +345,15 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
||||||
connect(btn, &QPushButton::clicked, this, [=] {
|
connect(btn, &QPushButton::clicked, this, [=] {
|
||||||
auto win = new ExpertBoxLayoutWin(this);
|
auto win = new ExpertBoxLayoutWin(this);
|
||||||
win->show();
|
win->show();
|
||||||
|
win->raise();
|
||||||
|
win->activateWindow();
|
||||||
});
|
});
|
||||||
vvv->addWidget(btn);
|
vvv->addWidget(btn);
|
||||||
}
|
}
|
||||||
connect(fdNormal, &QRadioButton::toggled, this, [=](bool checked) {
|
connect(fdNormal, &QRadioButton::toggled, this, [=](bool checked) {
|
||||||
stack->setCurrentWidget(checked ? normalPanel : advacnedPanel);
|
stack->setCurrentWidget(checked ? normalPanel : advacnedPanel);
|
||||||
});
|
});
|
||||||
|
if(cfg["is_irr"].toBool()) fdAdvacned->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
gBox = new QGroupBox(tr("效果测试"));
|
gBox = new QGroupBox(tr("效果测试"));
|
||||||
|
@ -589,7 +593,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
||||||
}
|
}
|
||||||
void ExpertWin::closeEvent(QCloseEvent *event) {
|
void ExpertWin::closeEvent(QCloseEvent *event) {
|
||||||
BaseWin::closeEvent(event);
|
BaseWin::closeEvent(event);
|
||||||
QFile qFile(QApplication::applicationDirPath()+"/temp.screen");
|
QFile qFile("temp.screen");
|
||||||
if(! qFile.open(QFile::WriteOnly)) return;
|
if(! qFile.open(QFile::WriteOnly)) return;
|
||||||
qFile.write(savedData());
|
qFile.write(savedData());
|
||||||
qFile.close();
|
qFile.close();
|
||||||
|
@ -602,7 +606,10 @@ QByteArray ExpertWin::savedData() {
|
||||||
mBox.insert("ModuleCol", (fdCardHeight->value() + ModuleHeight - 1) / ModuleHeight);
|
mBox.insert("ModuleCol", (fdCardHeight->value() + ModuleHeight - 1) / ModuleHeight);
|
||||||
mBox.insert("ModuleDirection", fdDirection->currentIndex());
|
mBox.insert("ModuleDirection", fdDirection->currentIndex());
|
||||||
mBox.insert("SectorCount", fdSectorCount->currentData().toInt());
|
mBox.insert("SectorCount", fdSectorCount->currentData().toInt());
|
||||||
JObj obj{{"ModuleConnectionInfo", mBox}};
|
JObj obj{
|
||||||
|
{"ModuleConnectionInfo", mBox},
|
||||||
|
{"is_irr", fdAdvacned->isChecked()},
|
||||||
|
};
|
||||||
return JToBytes(obj, " ");
|
return JToBytes(obj, " ");
|
||||||
}
|
}
|
||||||
void ExpertWin::addMapData(QByteArray &data) {
|
void ExpertWin::addMapData(QByteArray &data) {
|
||||||
|
@ -716,80 +723,3 @@ void ExpertWin::addMapData(QByteArray &data) {
|
||||||
data[start-2] = len>>8;
|
data[start-2] = len>>8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_ONCE 1482
|
|
||||||
void run() {
|
|
||||||
// quint32 idx = 0;
|
|
||||||
// while(2) {
|
|
||||||
// QByteArray bytes;
|
|
||||||
// bytes.append("\x55\x55\x9a\x3d"); //前导, 版本号, 服务类型
|
|
||||||
// bytes.append("\0\x4", 2); //数据长度
|
|
||||||
// bytes.append(4, '\xff'); //目的地址
|
|
||||||
// bytes.append(4, 0); //源地址
|
|
||||||
// bytes.append("\xB1\x04\0\0", 4); //内存指针
|
|
||||||
// bytes.append(2, 0); //应答填充项
|
|
||||||
// auto crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
|
|
||||||
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32); //包头校验
|
|
||||||
|
|
||||||
// crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-4, 4);
|
|
||||||
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
|
||||||
// //发送帧开始指令包
|
|
||||||
// auto queue = pcap_sendqueue_alloc(img.width()*img.height()*4);
|
|
||||||
// {
|
|
||||||
// struct pcap_pkthdr pktheader;
|
|
||||||
// pktheader.len = pktheader.caplen = bytes.size();
|
|
||||||
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
|
|
||||||
// onErr(QString("添加开始失败: ")+pcap_geterr(pcap));
|
|
||||||
// goto end;
|
|
||||||
// }
|
|
||||||
// idx = 0;
|
|
||||||
// //按行发送图像数据包
|
|
||||||
// for(int i=0; i<img.height(); i++) for(int j=0; j<lineLen; j+=once) {
|
|
||||||
// int dataLen = lineLen - j;
|
|
||||||
// if(dataLen > once) dataLen = once;
|
|
||||||
// dataLen += 4;
|
|
||||||
// bytes.clear();
|
|
||||||
// bytes.append("\x55\x55\x1\x33"); //前导, 版本号, 服务类型
|
|
||||||
// bytes.append(dataLen>>8).append(dataLen); //数据长度
|
|
||||||
// bytes.append(4, '\xff'); //目的地址
|
|
||||||
// bytes.append(4, 0); //源地址
|
|
||||||
// bytes.append(i>>8).append(i).append(j>>8).append(j); //内存指针
|
|
||||||
// bytes.append(2, 0); //应答填充项
|
|
||||||
// crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
|
|
||||||
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
|
||||||
// bytes.append(idx>>24).append(idx>>16).append(idx>>8).append(idx);//包序号
|
|
||||||
// idx++;
|
|
||||||
// bytes.append((const char*)bits + i * bytesPerLine + j, dataLen - 4);
|
|
||||||
// crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen);
|
|
||||||
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
|
||||||
// pktheader.len = pktheader.caplen = bytes.size();
|
|
||||||
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
|
|
||||||
// onErr(QString("添加数据失败: ")+pcap_geterr(pcap));
|
|
||||||
// goto end;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// bytes.clear();
|
|
||||||
// bytes.append("\x55\x55\x9a\x3d"); //前导, 版本号, 服务类型
|
|
||||||
// bytes.append(2, 0); //数据长度
|
|
||||||
// bytes.append(4, '\xff'); //目的地址
|
|
||||||
// bytes.append(4, 0); //源地址
|
|
||||||
// bytes.append("\x35\0\xc\xcc", 4); //内存指针
|
|
||||||
// bytes.append(2, 0); //应答填充项
|
|
||||||
// crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
|
|
||||||
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
|
|
||||||
// pktheader.len = pktheader.caplen = bytes.size();
|
|
||||||
// //发送帧结束指令包
|
|
||||||
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
|
|
||||||
// onErr(QString("添加结束失败: ")+pcap_geterr(pcap));
|
|
||||||
// goto end;
|
|
||||||
// }
|
|
||||||
// u_int res;
|
|
||||||
// if((res = pcap_sendqueue_transmit(pcap, queue, 0)) < queue->len) {
|
|
||||||
// onErr(QString::asprintf("发送包出错: %s. 仅发了 %d / %d bytes", pcap_geterr(pcap), res, queue->len));
|
|
||||||
// goto end;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// end:
|
|
||||||
// pcap_sendqueue_destroy(queue);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QJsonObject>
|
#include <QRadioButton>
|
||||||
|
|
||||||
class ExpertWin : public BaseWin {
|
class ExpertWin : public BaseWin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -21,6 +21,13 @@ public:
|
||||||
|
|
||||||
QLabel *fdModuleWidth, *fdModuleHeight, *fdGroupNum, *fdScanNum;
|
QLabel *fdModuleWidth, *fdModuleHeight, *fdGroupNum, *fdScanNum;
|
||||||
QLabel *fdChipType, *fdDecodeMode;
|
QLabel *fdChipType, *fdDecodeMode;
|
||||||
|
JObj cfg;
|
||||||
|
JObj mBox {
|
||||||
|
{"ModuleRow", 1},
|
||||||
|
{"ModuleCol", 1},
|
||||||
|
{"Direction", 1},
|
||||||
|
{"SectorCount", 1}
|
||||||
|
};
|
||||||
JObj mModule {
|
JObj mModule {
|
||||||
{"ModuleWidth", 32},
|
{"ModuleWidth", 32},
|
||||||
{"ModuleHeight", 16},
|
{"ModuleHeight", 16},
|
||||||
|
@ -30,15 +37,10 @@ public:
|
||||||
{"DecodeMode", "138译码"},
|
{"DecodeMode", "138译码"},
|
||||||
{"GroupMode", "三线并行"}
|
{"GroupMode", "三线并行"}
|
||||||
};
|
};
|
||||||
JObj mBox {
|
|
||||||
{"ModuleRow", 1},
|
|
||||||
{"ModuleCol", 1},
|
|
||||||
{"Direction", 1},
|
|
||||||
{"SectorCount", 1}
|
|
||||||
};
|
|
||||||
|
|
||||||
QSpinBox *fdCardWidth, *fdCardHeight;
|
QSpinBox *fdCardWidth, *fdCardHeight;
|
||||||
QComboBox *fdDirection, *fdSectorCount;
|
QComboBox *fdDirection, *fdSectorCount;
|
||||||
|
QRadioButton *fdAdvacned;
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *) override;
|
void closeEvent(QCloseEvent *) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,6 +73,10 @@ public:
|
||||||
Vector(std::initializer_list<V> _Ilist) {
|
Vector(std::initializer_list<V> _Ilist) {
|
||||||
this->ptr = new SharedData<std::vector<V>>{_Ilist, 1};
|
this->ptr = new SharedData<std::vector<V>>{_Ilist, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool empty() const noexcept {
|
||||||
|
return this->ptr ? this->ptr->data.empty() : true;
|
||||||
|
}
|
||||||
uint64_t size() const noexcept {
|
uint64_t size() const noexcept {
|
||||||
return this->ptr ? this->ptr->data.size() : 0;
|
return this->ptr ? this->ptr->data.size() : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ Table::Table(std::initializer_list<ColAttr> colAttrs, int rows, QWidget *parent)
|
||||||
noStretch = false;
|
noStretch = false;
|
||||||
} else horizontalHeader()->setSectionResizeMode(i, (QHeaderView::ResizeMode)it->resizeMode);
|
} else horizontalHeader()->setSectionResizeMode(i, (QHeaderView::ResizeMode)it->resizeMode);
|
||||||
}
|
}
|
||||||
mFieldMap.insert(it->field, i++);
|
mFieldMap.emplace(it->field, i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,3 +37,8 @@ void Table::resizeSec() {
|
||||||
if(remainWidth<=0 || stretchWidth==0) return;
|
if(remainWidth<=0 || stretchWidth==0) return;
|
||||||
for(int cc=0; cc<colCnt; cc++) if((item = horizontalHeaderItem(cc)) && (secWidth = item->data(0x99).toInt()) > 0) header->resizeSection(cc, secWidth * remainWidth / stretchWidth);
|
for(int cc=0; cc<colCnt; cc++) if((item = horizontalHeaderItem(cc)) && (secWidth = item->data(0x99).toInt()) > 0) header->resizeSection(cc, secWidth * remainWidth / stretchWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Table::updateGeometries() {
|
||||||
|
QTableWidget::updateGeometries();
|
||||||
|
emit updGeos();
|
||||||
|
}
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
#define QGUI_H
|
#define QGUI_H
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QStackedLayout>
|
#include <QDialog>
|
||||||
#include <QSplitter>
|
#include <QDialogButtonBox>
|
||||||
#include <QListWidget>
|
|
||||||
#include <QTableWidget>
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QStackedLayout>
|
||||||
|
#include <QTableWidget>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
|
|
||||||
#define MainMust \
|
#define MainMust \
|
||||||
|
@ -22,11 +24,28 @@
|
||||||
|
|
||||||
extern const int AlignRight;
|
extern const int AlignRight;
|
||||||
|
|
||||||
inline int setCurrentData(QComboBox *combo, const QVariant &data) {
|
inline QWidget *parentWgt(QObject *obj) {
|
||||||
|
while(obj && ! obj->isWidgetType()) obj = obj->parent();
|
||||||
|
return (QWidget*) obj;
|
||||||
|
}
|
||||||
|
inline QWidget *parentWin(QObject *obj) {
|
||||||
|
while(obj) {
|
||||||
|
if(obj->isWidgetType()) return ((QWidget*) obj)->window();
|
||||||
|
obj = obj->parent();
|
||||||
|
}
|
||||||
|
return (QWidget*) obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int SetCurData(QComboBox *combo, const QVariant &data) {
|
||||||
auto idx = combo->findData(data);
|
auto idx = combo->findData(data);
|
||||||
if(idx>-1) combo->setCurrentIndex(idx);
|
if(idx>-1) combo->setCurrentIndex(idx);
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
inline int SetCurText(QComboBox *combo, const QString &text) {
|
||||||
|
auto idx = combo->findText(text);
|
||||||
|
if(idx>-1) combo->setCurrentIndex(idx);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
inline void gFont(QWidget *wgt, int size, bool bold = false, bool italic = false) {
|
inline void gFont(QWidget *wgt, int size, bool bold = false, bool italic = false) {
|
||||||
auto ft = wgt->font();
|
auto ft = wgt->font();
|
||||||
ft.setPixelSize(size);
|
ft.setPixelSize(size);
|
||||||
|
@ -70,11 +89,22 @@ public:
|
||||||
splitter->addWidget(parentWidget());
|
splitter->addWidget(parentWidget());
|
||||||
setContentsMargins(0,0,0,0);
|
setContentsMargins(0,0,0,0);
|
||||||
};
|
};
|
||||||
|
inline QLabel *addLabel() {
|
||||||
|
auto lb = new QLabel;
|
||||||
|
addWidget(lb);
|
||||||
|
return lb;
|
||||||
|
}
|
||||||
inline QLabel *addLabel(const QString &text) {
|
inline QLabel *addLabel(const QString &text) {
|
||||||
auto lb = new QLabel(text);
|
auto lb = new QLabel(text);
|
||||||
addWidget(lb);
|
addWidget(lb);
|
||||||
return lb;
|
return lb;
|
||||||
}
|
}
|
||||||
|
inline QDialogButtonBox *addBtnBox(QDialog *dlg = 0) {
|
||||||
|
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
if(dlg) connect(btnBox, &QDialogButtonBox::rejected, dlg, &QDialog::reject);
|
||||||
|
addWidget(btnBox);
|
||||||
|
return btnBox;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
class HBox : public QBoxLayout {
|
class HBox : public QBoxLayout {
|
||||||
public:
|
public:
|
||||||
|
@ -90,6 +120,11 @@ public:
|
||||||
splitter->addWidget(parentWidget());
|
splitter->addWidget(parentWidget());
|
||||||
setContentsMargins(0,0,0,0);
|
setContentsMargins(0,0,0,0);
|
||||||
};
|
};
|
||||||
|
inline QLabel *addLabel() {
|
||||||
|
auto lb = new QLabel;
|
||||||
|
addWidget(lb);
|
||||||
|
return lb;
|
||||||
|
}
|
||||||
inline QLabel *addLabel(const QString &text) {
|
inline QLabel *addLabel(const QString &text) {
|
||||||
auto lb = new QLabel(text);
|
auto lb = new QLabel(text);
|
||||||
addWidget(lb);
|
addWidget(lb);
|
||||||
|
@ -143,10 +178,6 @@ public:
|
||||||
Table() {}
|
Table() {}
|
||||||
Table(std::initializer_list<ColAttr> colAttrs, int rows = 0, QWidget *parent = 0);
|
Table(std::initializer_list<ColAttr> colAttrs, int rows = 0, QWidget *parent = 0);
|
||||||
|
|
||||||
inline auto setNoEdit() {
|
|
||||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
inline auto setDefs() {
|
inline auto setDefs() {
|
||||||
setSelectionBehavior(QTableWidget::SelectRows);
|
setSelectionBehavior(QTableWidget::SelectRows);
|
||||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
@ -279,13 +310,15 @@ public:
|
||||||
setCellWidget(row, col, widget);
|
setCellWidget(row, col, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<QString, int> mFieldMap;
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
inline void clearRows() {setRowCount(0);}
|
inline void clearRows() {setRowCount(0);}
|
||||||
|
signals:
|
||||||
|
void updGeos();
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
void updateGeometries() override;
|
||||||
void resizeSec();
|
void resizeSec();
|
||||||
QMap<QString,int> mFieldMap;
|
|
||||||
bool noStretch{true};
|
bool noStretch{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -94,13 +94,23 @@ public:
|
||||||
if(type==Array) return *(JArray*) data;
|
if(type==Array) return *(JArray*) data;
|
||||||
return JArray();
|
return JArray();
|
||||||
}
|
}
|
||||||
|
const JValue operator[](const QString &key) const {
|
||||||
|
return type==Obj ? (*(JObj*) data)[key] : JValue();
|
||||||
|
}
|
||||||
|
const JValue operator[](int i) const {
|
||||||
|
return type==Array ? (*(JArray*) data)[i] : JValue();
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
JValue(const void *) = delete; // avoid implicit conversions from char * to bool
|
JValue(const void *) = delete; // avoid implicit conversions from char * to bool
|
||||||
};
|
};
|
||||||
|
|
||||||
class JParser {
|
class JParser {
|
||||||
public:
|
public:
|
||||||
JParser(QTextStream &in) : in(in) {}
|
JParser(QTextStream &in) : in(in) {
|
||||||
|
#if(QT_VERSION_MAJOR < 6)
|
||||||
|
in.setCodec("UTF-8");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline JValue read() {
|
inline JValue read() {
|
||||||
skipSpace();
|
skipSpace();
|
||||||
|
@ -144,7 +154,11 @@ inline JValue JFrom(QIODevice *device, QString *err = 0) {
|
||||||
|
|
||||||
class JOut {
|
class JOut {
|
||||||
public:
|
public:
|
||||||
JOut(QTextStream &out, QString indent = "") : out(out), indent(indent) {}
|
JOut(QTextStream &out, QString indent = "") : out(out), indent(indent) {
|
||||||
|
#if(QT_VERSION_MAJOR < 6)
|
||||||
|
out.setCodec("UTF-8");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void write(const JValue &obj);
|
void write(const JValue &obj);
|
||||||
void writeStr(const QString &str);
|
void writeStr(const QString &str);
|
||||||
|
|
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 406 B |
After Width: | Height: | Size: 403 B |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 537 B |
|
@ -10,6 +10,7 @@ CONFIG += embed_translations
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
TARGET = $$quote(LedSet Express)
|
TARGET = $$quote(LedSet Express)
|
||||||
|
DEFINES += __VER__=\\\"0.0.1\\\"
|
||||||
|
|
||||||
msvc {
|
msvc {
|
||||||
contains(QT_ARCH, i386) {
|
contains(QT_ARCH, i386) {
|
||||||
|
@ -29,6 +30,22 @@ win32 {
|
||||||
RC_ICONS = 128.ico
|
RC_ICONS = 128.ico
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
copydir.files += translations
|
||||||
|
|
||||||
|
win32 {
|
||||||
|
EXE_SUFFIX = .exe
|
||||||
|
copydir.path = $$OUT_PWD
|
||||||
|
CONFIG += file_copies
|
||||||
|
COPIES += copydir
|
||||||
|
}
|
||||||
|
osx {
|
||||||
|
DIR_SUFFIX = -mac
|
||||||
|
copydir.path = Contents/MacOS
|
||||||
|
QMAKE_BUNDLE_DATA += copydir
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/npcap-sdk-1.13/Include
|
INCLUDEPATH += $$PWD/npcap-sdk-1.13/Include
|
||||||
LIBS += -L$$PWD/npcap-sdk-1.13/Lib/\
|
LIBS += -L$$PWD/npcap-sdk-1.13/Lib/\
|
||||||
-lwpcap\
|
-lwpcap\
|
||||||
|
@ -51,7 +68,6 @@ SOURCES += \
|
||||||
gutil/qjson.cpp \
|
gutil/qjson.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwin.cpp \
|
mainwin.cpp \
|
||||||
moduleunit.cpp \
|
|
||||||
pcaprethread.cpp \
|
pcaprethread.cpp \
|
||||||
screenunit.cpp \
|
screenunit.cpp \
|
||||||
testwin.cpp \
|
testwin.cpp \
|
||||||
|
@ -72,7 +88,6 @@ HEADERS += \
|
||||||
gutil/qgui.h \
|
gutil/qgui.h \
|
||||||
gutil/qjson.h \
|
gutil/qjson.h \
|
||||||
mainwin.h \
|
mainwin.h \
|
||||||
moduleunit.h \
|
|
||||||
pcaprethread.h \
|
pcaprethread.h \
|
||||||
screenunit.h \
|
screenunit.h \
|
||||||
testwin.h \
|
testwin.h \
|
||||||
|
@ -80,14 +95,7 @@ HEADERS += \
|
||||||
waitingdlg.h
|
waitingdlg.h
|
||||||
|
|
||||||
TRANSLATIONS += \
|
TRANSLATIONS += \
|
||||||
translations/app_en.ts
|
ts/app_en.ts
|
||||||
|
|
||||||
EXTRA_TRANSLATIONS += \
|
|
||||||
translations/qt_zh_CN.ts \
|
|
||||||
translations/qt_zh_TW.ts \
|
|
||||||
translations/qt_ja.ts \
|
|
||||||
translations/qt_en.ts
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
|
|
|
@ -1,31 +1,29 @@
|
||||||
#include "mainwin.h"
|
#include "mainwin.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QLocale>
|
|
||||||
#include <QTranslator>
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QLocale>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QStyleFactory>
|
#include <QTranslator>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER //MSVC编译器
|
#ifdef _MSC_VER //MSVC编译器
|
||||||
#define _WINSOCKAPI_
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <DbgHelp.h>
|
#include <DbgHelp.h>
|
||||||
LONG WINAPI handleException(_EXCEPTION_POINTERS *excep) {
|
LONG WINAPI handleException(_EXCEPTION_POINTERS *excep) {
|
||||||
QString errCode = QString::number(excep->ExceptionRecord->ExceptionCode, 16);
|
auto errCode = QString::number(excep->ExceptionRecord->ExceptionCode, 16);
|
||||||
QString errAddr = QString::number((uint)excep->ExceptionRecord->ExceptionAddress, 16);
|
auto errAddr = QString::number((uint)excep->ExceptionRecord->ExceptionAddress, 16);
|
||||||
HANDLE hDumpFile = CreateFile(L"c:/ledset-crash.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
auto hDumpFile = CreateFile(L"ledset-crash.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if(hDumpFile == INVALID_HANDLE_VALUE) return EXCEPTION_CONTINUE_SEARCH; //未处理异常, 让 windows 弹出错误框并结束 (Qt会卡死一段时间)
|
if(hDumpFile == INVALID_HANDLE_VALUE) {
|
||||||
|
qCritical()<<"CreateFile ledset-crash.dmp Failed! ExceptionCode"<<errCode<<"ExceptionAddress"<<errAddr;
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
MINIDUMP_EXCEPTION_INFORMATION dumpInfo{GetCurrentThreadId(), excep, TRUE};
|
MINIDUMP_EXCEPTION_INFORMATION dumpInfo{GetCurrentThreadId(), excep, TRUE};
|
||||||
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);//写入Dump文件内容
|
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);//写入Dump文件内容
|
||||||
CloseHandle(hDumpFile);
|
CloseHandle(hDumpFile);
|
||||||
QMessageBox::critical(nullptr, "程序出错", "<b>程序出错!</b> (code: "+errCode+". addr: "+errAddr+")<br/>请将C盘下的 ledok-crash.dmp 文件发送到 gangphon@qq.com 邮箱, 研发人员会尽快处理.");
|
QMessageBox::critical(0, "程序出错 (V" __VER__" - " __DATE__", Code: "+errCode+")", "<b>程序出错!</b><br/>请将安装目录下的 ledok-crash.dmp 文件发送到 gangphon@qq.com 邮箱, 研发人员会尽快处理.");
|
||||||
return EXCEPTION_EXECUTE_HANDLER; //已处理异常, 让 windows 正常结束
|
return EXCEPTION_EXECUTE_HANDLER; //已处理异常, 让 windows 正常结束
|
||||||
// EXCEPTION_CONTINUE_EXECUTION 已修复错误, 让 windows 从异常发生处继续执行
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void test();
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
|
qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
|
||||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
@ -35,7 +33,7 @@ int main(int argc, char *argv[]) {
|
||||||
QApplication::setOrganizationDomain("ledok.cn");
|
QApplication::setOrganizationDomain("ledok.cn");
|
||||||
QApplication::setApplicationName("LedSet Express");
|
QApplication::setApplicationName("LedSet Express");
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
a.setStyle(QStyleFactory::create("Fusion"));
|
QApplication::setStyle("Fusion");
|
||||||
a.setWindowIcon(QIcon(":/128.ico"));
|
a.setWindowIcon(QIcon(":/128.ico"));
|
||||||
a.setStyleSheet(R"rrr(
|
a.setStyleSheet(R"rrr(
|
||||||
QLineEdit {border: 1px solid #777; border-radius: 2px; padding: 2px;}
|
QLineEdit {border: 1px solid #777; border-radius: 2px; padding: 2px;}
|
||||||
|
@ -49,6 +47,7 @@ QRadioButton::indicator:checked {border-image: url(:/imgs/radio-check.png);}
|
||||||
QCheckBox::indicator {border-image: url(:/imgs/checkbox-un.png); width: 1em; height: 1em;}
|
QCheckBox::indicator {border-image: url(:/imgs/checkbox-un.png); width: 1em; height: 1em;}
|
||||||
QCheckBox::indicator:checked {border-image: url(:/imgs/checkbox-check.png);}
|
QCheckBox::indicator:checked {border-image: url(:/imgs/checkbox-check.png);}
|
||||||
|
|
||||||
|
QPushButton:checked {border: 2px solid #0a0; border-radius: 3px; padding-top: 2px; padding-bottom: 2px; }
|
||||||
QPushButton:disabled {color: #777;}
|
QPushButton:disabled {color: #777;}
|
||||||
|
|
||||||
QPushButton[ss="min"]{padding: 0; width: 30px; height: 25px; }
|
QPushButton[ss="min"]{padding: 0; width: 30px; height: 25px; }
|
||||||
|
@ -59,8 +58,6 @@ QPushButton[ss="blue"] {background: #059;}
|
||||||
QGroupBox {border: 1px solid #777; border-radius: 3px; margin-top: 0.5em; padding-top: 0.4em;}
|
QGroupBox {border: 1px solid #777; border-radius: 3px; margin-top: 0.5em; padding-top: 0.4em;}
|
||||||
QGroupBox::title {color: #fff; subcontrol-origin: margin; left: 0.5em;}
|
QGroupBox::title {color: #fff; subcontrol-origin: margin; left: 0.5em;}
|
||||||
)rrr");
|
)rrr");
|
||||||
/*
|
|
||||||
*/
|
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setFamilies(QStringList{"Arial","Microsoft YaHei UI"});
|
font.setFamilies(QStringList{"Arial","Microsoft YaHei UI"});
|
||||||
a.setFont(font);
|
a.setFont(font);
|
||||||
|
@ -84,18 +81,13 @@ QGroupBox::title {color: #fff; subcontrol-origin: margin; left: 0.5em;}
|
||||||
a.setPalette(plt);
|
a.setPalette(plt);
|
||||||
|
|
||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
if(translator.load(QLocale::system(), "app", "_", ":/i18n")) a.installTranslator(&translator);
|
if(translator.load(QLocale(), "app", "_", ":/i18n")) a.installTranslator(&translator);
|
||||||
QTranslator qtTrans;
|
QTranslator qtTrans;
|
||||||
if(qtTrans.load(QLocale::system(), "qt", "_", ":/i18n")) a.installTranslator(&qtTrans);
|
if(qtTrans.load(QLocale(), "qt", "_", "translations")) a.installTranslator(&qtTrans);
|
||||||
|
|
||||||
MainWin w;
|
MainWin w;
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
SetUnhandledExceptionFilter(handleException);
|
SetUnhandledExceptionFilter(handleException);
|
||||||
#endif
|
#endif
|
||||||
//test();
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "mainwin.h"
|
#include "mainwin.h"
|
||||||
|
#include "gutil/qjson.h"
|
||||||
#include "pcaprethread.h"
|
#include "pcaprethread.h"
|
||||||
#include "fast.h"
|
#include "fast.h"
|
||||||
#include "expertwin.h"
|
#include "expertwin.h"
|
||||||
|
@ -21,6 +22,8 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QtEndian>
|
#include <QtEndian>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QNetworkDatagram>
|
||||||
|
#include <QNetworkInterface>
|
||||||
|
|
||||||
class ImgBtn : public QToolButton {
|
class ImgBtn : public QToolButton {
|
||||||
public:
|
public:
|
||||||
|
@ -132,9 +135,9 @@ MainWin::MainWin() {
|
||||||
table->setDefs();
|
table->setDefs();
|
||||||
vBox->addWidget(table);
|
vBox->addWidget(table);
|
||||||
|
|
||||||
auto hstatus = new QHBoxLayout;
|
auto hBox = new HBox(vBox);
|
||||||
hstatus->addWidget(new QLabel(tr("编译日期")+": "+__DATE__));
|
hBox->addLabel("V" __VER__" - " __DATE__);
|
||||||
hstatus->addStretch();
|
hBox->addStretch();
|
||||||
|
|
||||||
auto btnNetSelect = new QPushButton("通讯选择");
|
auto btnNetSelect = new QPushButton("通讯选择");
|
||||||
connect(btnNetSelect, &QPushButton::clicked, this, [this] {
|
connect(btnNetSelect, &QPushButton::clicked, this, [this] {
|
||||||
|
@ -160,13 +163,11 @@ MainWin::MainWin() {
|
||||||
reThd->start();
|
reThd->start();
|
||||||
QSettings().setValue("net_name", net_name = name);
|
QSettings().setValue("net_name", net_name = name);
|
||||||
});
|
});
|
||||||
hstatus->addWidget(btnNetSelect);
|
hBox->addWidget(btnNetSelect);
|
||||||
|
|
||||||
auto btnRefresh = new QPushButton(tr("刷新"));
|
auto btnRefresh = new QPushButton(tr("刷新"));
|
||||||
connect(btnRefresh, &QPushButton::clicked, this, &MainWin::getCard);
|
connect(btnRefresh, &QPushButton::clicked, this, &MainWin::getCard);
|
||||||
hstatus->addWidget(btnRefresh);
|
hBox->addWidget(btnRefresh);
|
||||||
|
|
||||||
vBox->addLayout(hstatus);
|
|
||||||
|
|
||||||
show();
|
show();
|
||||||
|
|
||||||
|
@ -189,10 +190,53 @@ MainWin::MainWin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] {
|
||||||
|
while(mUdpSocket.hasPendingDatagrams()) {
|
||||||
|
auto gram = mUdpSocket.receiveDatagram();
|
||||||
|
auto data = gram.data();
|
||||||
|
if(data.isEmpty()) continue;
|
||||||
|
auto senderAddress = gram.senderAddress();
|
||||||
|
bool ok = true;
|
||||||
|
if(senderAddress.protocol()==QUdpSocket::IPv6Protocol) senderAddress.setAddress(senderAddress.toIPv4Address(&ok));
|
||||||
|
auto addr = ok ? senderAddress.toString() : "";
|
||||||
|
int cnt = table->rowCount();
|
||||||
|
if(data.startsWith("{\"")) {
|
||||||
|
QString error;
|
||||||
|
auto json = JFrom(gram.data(), &error);
|
||||||
|
if(! error.isEmpty()) {
|
||||||
|
qDebug()<<"Json Error: "+error;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto cardId = json["cardId"].toStr();
|
||||||
|
for(int rr=0; rr<cnt; rr++) if(table->text(rr, "name")==cardId) {
|
||||||
|
table->setText(rr, "link", addr);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
table->setRowCount(cnt+1);
|
||||||
|
//table->setText(cnt, "type", tr("虚拟设备"));
|
||||||
|
table->setText(cnt, "name", cardId);
|
||||||
|
table->setText(cnt, "link", addr);
|
||||||
|
//table->setText(cnt, "vcsNum", QString::number(*(quint32_be*)(data.data()+headMap.body)));
|
||||||
|
//table->setText(cnt, "netPorts", "P:"+QString::number(virtualVCM));
|
||||||
|
//table->setText(cnt, "info", "备注:可直接配屏,无需发送卡");
|
||||||
|
} else {
|
||||||
|
auto bytes = gram.data();
|
||||||
|
auto packet = (UDPPacket *)bytes.data();
|
||||||
|
for(int rr=0; rr<cnt; rr++) if(table->text(rr, "name")==packet->serialCode) {
|
||||||
|
table->setText(rr, "link", addr);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
table->setRowCount(cnt+1);
|
||||||
|
table->setText(cnt, "name", packet->serialCode);
|
||||||
|
table->setText(cnt, "link", addr);
|
||||||
|
}
|
||||||
|
end:;
|
||||||
|
}
|
||||||
|
});
|
||||||
getCard();
|
getCard();
|
||||||
}
|
}
|
||||||
MainWin::~MainWin() {
|
MainWin::~MainWin() {
|
||||||
|
mUdpSocket.close();
|
||||||
QSettings config;
|
QSettings config;
|
||||||
config.setValue("FileHome", gFileHome);
|
config.setValue("FileHome", gFileHome);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +256,28 @@ void MainWin::getCard() {
|
||||||
table->setText(rr, "netPorts", "P:"+QString::number(virtualVCM));
|
table->setText(rr, "netPorts", "P:"+QString::number(virtualVCM));
|
||||||
table->setText(rr, "info", "备注:可直接配屏,无需发送卡");
|
table->setText(rr, "info", "备注:可直接配屏,无需发送卡");
|
||||||
});
|
});
|
||||||
if(res) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend)));
|
if(res) {
|
||||||
|
QString err = pcap_geterr(pcapSend);
|
||||||
|
if(! err.endsWith("(2150891551)")) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend)));
|
||||||
|
}
|
||||||
|
auto data = JToBytes(JObj{{"action", "getInfo"}});
|
||||||
|
uchar ccc[]{0x7E, 0x7E, 0x7E, 0x90, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x21,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x9F};
|
||||||
|
if(mUdpSocket.writeDatagram(data, QHostAddress("255.255.255.255"), 22222) != data.length()) qDebug() << "getInfo write to 255.255.255.255 failed";
|
||||||
|
if(mUdpSocket.writeDatagram((char *)ccc, sizeof(ccc), QHostAddress("255.255.255.255"), 31296) != sizeof(ccc)) qDebug() << "getInfo write to 255.255.255.255 failed";
|
||||||
|
auto networkinterfaces = QNetworkInterface::allInterfaces();
|
||||||
|
foreach(auto face, networkinterfaces) {
|
||||||
|
auto flags = face.flags();
|
||||||
|
bool can = (flags & QNetworkInterface::IsRunning) && (flags & QNetworkInterface::CanBroadcast) && ! (flags & QNetworkInterface::IsLoopBack);
|
||||||
|
if(! can) continue;
|
||||||
|
auto addrEntries = face.addressEntries();
|
||||||
|
foreach(QNetworkAddressEntry addrEntry, addrEntries) {
|
||||||
|
auto ip = addrEntry.ip();
|
||||||
|
if(ip.protocol()!=QAbstractSocket::IPv4Protocol) continue;
|
||||||
|
auto broadcast = addrEntry.broadcast();
|
||||||
|
if(mUdpSocket.writeDatagram(data, broadcast, 22222) != data.length()) qDebug() << "getInfo write failed." << ip.toString() << "->" << broadcast.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "basewin.h"
|
#include "basewin.h"
|
||||||
#include "gutil/qgui.h"
|
#include "gutil/qgui.h"
|
||||||
|
#include <QUdpSocket>
|
||||||
|
|
||||||
class MainWin : public BaseWin {
|
class MainWin : public BaseWin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -12,9 +13,17 @@ public:
|
||||||
QWidget *win{0};
|
QWidget *win{0};
|
||||||
QByteArray net_name;
|
QByteArray net_name;
|
||||||
Table *table{0};
|
Table *table{0};
|
||||||
|
QUdpSocket mUdpSocket;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void getCard();
|
void getCard();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UDPPacket {
|
||||||
|
unsigned char SyncHead[3];
|
||||||
|
unsigned char ucCommType;
|
||||||
|
char serialCode[20];
|
||||||
|
unsigned int iLength;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // MAINWIN_H
|
#endif // MAINWIN_H
|
||||||
|
|
|
@ -1,198 +0,0 @@
|
||||||
#include "moduleunit.h"
|
|
||||||
#include "expertboxlayoutwin.h"
|
|
||||||
#include <QDirIterator>
|
|
||||||
#include <QGraphicsScene>
|
|
||||||
#include <QGraphicsSceneMouseEvent>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QSpinBox>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
|
|
||||||
ModuleUnit::ModuleUnit(ExpertBoxLayoutWin *expertWin, const QString &name, int x, int y, int w, int h, QWidget *parent) : QWidget{parent}, expertWin{expertWin}, name{name}, mX{x}, mY{y}, mW{w}, mH{h} {
|
|
||||||
setGeometry(x, y, w, h);
|
|
||||||
setMouseTracking(true);
|
|
||||||
auto font = this->font();
|
|
||||||
font.setPixelSize(12);
|
|
||||||
setFont(font);
|
|
||||||
|
|
||||||
mSidePen.setCapStyle(Qt::FlatCap);
|
|
||||||
mSidePen.setDashPattern(QVector<qreal>{2,2});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleUnit::paintEvent(QPaintEvent *) {
|
|
||||||
QPainter painter(this);
|
|
||||||
painter.setPen(mSidePen);
|
|
||||||
painter.drawRect(QRectF(0.5, 0.5, width()-1, height()-1));
|
|
||||||
painter.drawText(2, 16, name);
|
|
||||||
painter.drawText(2, 32, "位置: "+QString::number(mX)+", "+QString::number(mY));
|
|
||||||
painter.drawText(2, 48, "大小: "+QString::number(mW)+" x "+QString::number(mH));
|
|
||||||
//磁条吸附时两化吸附的边
|
|
||||||
static QPen snapPen(QColor(0x00ff00), 2);
|
|
||||||
painter.setPen(snapPen);
|
|
||||||
if(mLRSnap==1) painter.drawLine(QPointF(1, 0), QPointF(1, height()));
|
|
||||||
else if(mLRSnap==2) painter.drawLine(QPointF(width()-1, 0), QPointF(width()-1, height()));
|
|
||||||
if(mTBSnap==1) painter.drawLine(QPointF(0, 1), QPointF(width(), 1));
|
|
||||||
else if(mTBSnap==2) painter.drawLine(QPointF(0, height()-1), QPointF(width(), height()-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleUnit::setFrmSec(const QPoint &pos) {
|
|
||||||
if(isMaximized()) return;
|
|
||||||
if(pos.y()<8) {
|
|
||||||
if(pos.x()<16) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor);
|
|
||||||
else if(pos.x()<width()-16) setFrmSecIfNeed(Qt::TopSection, Qt::SizeVerCursor);
|
|
||||||
else setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor);
|
|
||||||
} else if(pos.y()>=height()-8) {
|
|
||||||
if(pos.x()<16) setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor);
|
|
||||||
else if(pos.x()<width()-16) setFrmSecIfNeed(Qt::BottomSection, Qt::SizeVerCursor);
|
|
||||||
else setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor);
|
|
||||||
} else if(pos.x()<8) {
|
|
||||||
if(pos.y()<16) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor);
|
|
||||||
else if(pos.y()<height()-16) setFrmSecIfNeed(Qt::LeftSection, Qt::SizeHorCursor);
|
|
||||||
else setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor);
|
|
||||||
} else if(pos.x()>=width()-8) {
|
|
||||||
if(pos.y()<16) setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor);
|
|
||||||
else if(pos.y()<height()-16) setFrmSecIfNeed(Qt::RightSection, Qt::SizeHorCursor);
|
|
||||||
else setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor);
|
|
||||||
} else setFrmSecIfNeed(Qt::TitleBarArea, Qt::SizeAllCursor);
|
|
||||||
}
|
|
||||||
void ModuleUnit::mousePressEvent(QMouseEvent *e) {
|
|
||||||
QWidget::mousePressEvent(e);
|
|
||||||
if(e->button() != Qt::LeftButton) return;
|
|
||||||
setFrmSec(e->pos());
|
|
||||||
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = mPressRel = pos() - e->globalPos();
|
|
||||||
else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(width() - e->globalX(), height() - e->globalY());
|
|
||||||
else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(width() - e->globalX(), height() );
|
|
||||||
else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(width() , height() - e->globalY());
|
|
||||||
else if(mFrmSec==Qt::TopRightSection ) mPressRel = geometry().topRight() - e->globalPos();
|
|
||||||
else if(mFrmSec==Qt::BottomLeftSection ) mPressRel = geometry().bottomLeft() - e->globalPos();
|
|
||||||
else if(mFrmSec==Qt::NoSection) mPressRel.setX(INT_MIN);
|
|
||||||
if(mPressRel.x()!=INT_MIN) {
|
|
||||||
mOtherEles.clear();
|
|
||||||
auto parent = this->parentWidget();
|
|
||||||
if(0 == parent) return;
|
|
||||||
auto items = parent->children();
|
|
||||||
foreach(auto item, items) {
|
|
||||||
if(item==this) continue;
|
|
||||||
auto ele = static_cast<ModuleUnit*>(item);
|
|
||||||
mOtherEles.append(ele);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleUnit::mouseReleaseEvent(QMouseEvent *event) {
|
|
||||||
QWidget::mouseReleaseEvent(event);
|
|
||||||
if(Qt::LeftButton == event->button()) {
|
|
||||||
mPressRel.setX(INT_MIN);
|
|
||||||
clearSnap();
|
|
||||||
foreach(auto ele, mOtherEles) ele->clearSnap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#define SnapSpace 6
|
|
||||||
void ModuleUnit::mouseMoveEvent(QMouseEvent *e){
|
|
||||||
if(! (e->buttons() & Qt::LeftButton)) {
|
|
||||||
setFrmSec(e->pos());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(mFrmSec==Qt::NoSection || mPressRel.x()==INT_MIN) return;
|
|
||||||
auto mousePos = e->globalPos();
|
|
||||||
auto dstHor = mPressRel.x() + mousePos.x();
|
|
||||||
auto dstVer = mPressRel.y() + mousePos.y();
|
|
||||||
mLRSnap = mTBSnap = 0;
|
|
||||||
foreach(auto ele, mOtherEles) ele->clearSnap();
|
|
||||||
if(mFrmSec==Qt::TitleBarArea) {
|
|
||||||
dstHor = qMax(0, dstHor);
|
|
||||||
dstVer = qMax(0, dstVer);
|
|
||||||
auto needw = qMax(1024, dstHor+width());
|
|
||||||
auto needh = qMax(1024, dstVer+height());
|
|
||||||
if(needw != expertWin->box->width() || needh != expertWin->box->height()) expertWin->box->resize(needw, needh);
|
|
||||||
if(dstHor==0) mLRSnap = 1;
|
|
||||||
if(dstVer==0) mTBSnap = 1;
|
|
||||||
if(mLRSnap==0) foreach(ModuleUnit *ele, mOtherEles) {//左右
|
|
||||||
if(abs(dstHor - ele->x()) < SnapSpace) {
|
|
||||||
dstHor = ele->x();
|
|
||||||
mLRSnap = 1;
|
|
||||||
ele->mLRSnap = 1;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto eleRight = ele->x() + ele->width();
|
|
||||||
if(abs(dstHor - eleRight) < SnapSpace) {
|
|
||||||
dstHor = eleRight;
|
|
||||||
mLRSnap = 1;
|
|
||||||
ele->mLRSnap = 2;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto right = dstHor + width();
|
|
||||||
if(abs(right - ele->x()) < SnapSpace && ele->x() - width() >= 0) {
|
|
||||||
dstHor = ele->x() - width();
|
|
||||||
mLRSnap = 2;
|
|
||||||
ele->mLRSnap = 1;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(abs(right - eleRight) < SnapSpace && eleRight - width() >= 0) {
|
|
||||||
dstHor = eleRight - width();
|
|
||||||
mLRSnap = 2;
|
|
||||||
ele->mLRSnap = 2;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(mTBSnap==0) foreach(ModuleUnit *ele, mOtherEles) {//上下
|
|
||||||
if(abs(dstVer-ele->y()) < SnapSpace) {
|
|
||||||
dstVer = ele->y();
|
|
||||||
mTBSnap = 1;
|
|
||||||
ele->mTBSnap = 1;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto eleBtm = ele->y() + ele->height();
|
|
||||||
if(abs(dstVer - eleBtm) < SnapSpace) {
|
|
||||||
dstVer = eleBtm;
|
|
||||||
mTBSnap = 1;
|
|
||||||
ele->mTBSnap = 2;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto btm = dstVer + height();
|
|
||||||
if(abs(btm - ele->y()) < SnapSpace && ele->y() - height() >= 0) {
|
|
||||||
dstVer = ele->y() - height();
|
|
||||||
mTBSnap = 2;
|
|
||||||
ele->mTBSnap = 1;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(abs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) {
|
|
||||||
dstVer = eleBtm - height();
|
|
||||||
mTBSnap = 2;
|
|
||||||
ele->mTBSnap = 2;
|
|
||||||
ele->update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
move(dstHor, dstVer);
|
|
||||||
mX = qRound(dstHor / expertWin->rate);
|
|
||||||
mY = qRound(dstVer / expertWin->rate);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ModuleUnit::leaveEvent(QEvent *) {
|
|
||||||
setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor);
|
|
||||||
mPressRel.setX(INT_MIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleUnit::setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor) {
|
|
||||||
if(mFrmSec==frmSec) return;
|
|
||||||
mFrmSec = frmSec;
|
|
||||||
if(cursor==Qt::ArrowCursor) unsetCursor();
|
|
||||||
else setCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleUnit::clearSnap() {
|
|
||||||
if(mLRSnap==0 && mTBSnap==0) return;
|
|
||||||
mLRSnap = mTBSnap = 0;
|
|
||||||
update();
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
#ifndef MODULEUNIT_H
|
|
||||||
#define MODULEUNIT_H
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QPen>
|
|
||||||
|
|
||||||
#define m_handleLen 10
|
|
||||||
class ExpertBoxLayoutWin;
|
|
||||||
class ModuleUnit : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit ModuleUnit(ExpertBoxLayoutWin *, const QString &name, int x, int y, int w, int h, QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
ExpertBoxLayoutWin *expertWin{0};
|
|
||||||
QString name;
|
|
||||||
int mX, mY, mW, mH;
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *) override;
|
|
||||||
void mousePressEvent(QMouseEvent *) override;
|
|
||||||
void mouseReleaseEvent(QMouseEvent *) override;
|
|
||||||
void mouseMoveEvent(QMouseEvent *) override;
|
|
||||||
void leaveEvent(QEvent *) override;
|
|
||||||
|
|
||||||
void setFrmSec(const QPoint &);
|
|
||||||
void setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor);
|
|
||||||
void clearSnap();
|
|
||||||
QPen mSidePen{Qt::white};
|
|
||||||
|
|
||||||
QPoint mPressRel{INT_MIN, INT_MIN};
|
|
||||||
Qt::WindowFrameSection mFrmSec{Qt::NoSection};
|
|
||||||
char mLRSnap{0}, mTBSnap{0};
|
|
||||||
QList<ModuleUnit *> mOtherEles;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MODULEUNIT_H
|
|
|
@ -1,6 +1,14 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>128.ico</file>
|
<file>128.ico</file>
|
||||||
|
<file>imgs/align-left.png</file>
|
||||||
|
<file>imgs/align-right.png</file>
|
||||||
|
<file>imgs/align-top.png</file>
|
||||||
|
<file>imgs/align-bottom.png</file>
|
||||||
|
<file>imgs/arrange-left.png</file>
|
||||||
|
<file>imgs/arrange-right.png</file>
|
||||||
|
<file>imgs/arrange-top.png</file>
|
||||||
|
<file>imgs/arrange-bottom.png</file>
|
||||||
<file>imgs/checkbox-check.png</file>
|
<file>imgs/checkbox-check.png</file>
|
||||||
<file>imgs/checkbox-un.png</file>
|
<file>imgs/checkbox-un.png</file>
|
||||||
<file>imgs/radio-check.png</file>
|
<file>imgs/radio-check.png</file>
|
||||||
|
|
|
@ -62,7 +62,7 @@ void ScreenUnit::mousePressEvent(QMouseEvent *e) {
|
||||||
QWidget::mousePressEvent(e);
|
QWidget::mousePressEvent(e);
|
||||||
if(e->button() != Qt::LeftButton) return;
|
if(e->button() != Qt::LeftButton) return;
|
||||||
setFrmSec(e->pos());
|
setFrmSec(e->pos());
|
||||||
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = mPressRel = pos() - e->globalPos();
|
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = pos() - e->globalPos();
|
||||||
else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(width() - e->globalX(), height() - e->globalY());
|
else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(width() - e->globalX(), height() - e->globalY());
|
||||||
else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(width() - e->globalX(), height() );
|
else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(width() - e->globalX(), height() );
|
||||||
else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(width() , height() - e->globalY());
|
else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(width() , height() - e->globalY());
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE TS>
|
|
||||||
<TS version="2.1" language="zh_TW">
|
|
||||||
</TS>
|
|
|
@ -33,7 +33,6 @@ public:
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
QPushButton *btnAbort;
|
|
||||||
QLabel *fdText;
|
QLabel *fdText;
|
||||||
QString sucText;
|
QString sucText;
|
||||||
WaitingIndicator *mIndicator;
|
WaitingIndicator *mIndicator;
|
||||||
|
|