qt/ledset/expertsendpanel.cpp
2023-09-05 10:02:20 +08:00

442 lines
17 KiB
C++

#include "expertsendpanel.h"
#include "gutil/qgui.h"
#include <QLineEdit>
#include <QMouseEvent>
#include <QPainter>
QColor colors[] {QColor(0xdd0000), QColor(0xdd6600), QColor(0x008800), QColor(0x008888), QColor(0x0000ff), QColor(0x777777), QColor(0xaaaaaa)};
ExpertSendPanel::ExpertSendPanel(QWidget *parent) : QWidget{parent} {
auto vBox = new VBox(this);
vBox->setContentsMargins(4, 4, 4, 4);
auto splitter = new QSplitter;
vBox->addWidget(splitter);
auto vLeft = new VBox(splitter);
auto hBox = new HBox(vLeft);
hBox->addWidget(new QLabel("分辨率: "));
auto fdW = new QLineEdit(QString::number(screenWidth));
hBox->addWidget(fdW);
hBox->addWidget(new QLabel("X"));
auto fdH = new QLineEdit(QString::number(screenHeight));
hBox->addWidget(fdH);
hBox = new HBox(vLeft);
hBox->addStretch();
auto btnGet = new QPushButton("刷新");
btnGet->setMinimumWidth(80);
hBox->addWidget(btnGet);
hBox->addSpacing(40);
auto btnSet = new QPushButton("设置");
btnSet->setMinimumWidth(80);
hBox->addWidget(btnSet);
hBox->addStretch();
auto table = new TreeWidget{
{"face", "网口", 32},
{"x", "X", 32},
{"y", "Y", 32},
{"w", "宽度", 32},
{"h", "高度", 32},
{"audio", "音频开关", QHeaderView::Stretch},
{"backup", "备份开关", QHeaderView::Stretch}
};
table->setDefs();
table->setStyleSheet("TreeWidget::item{height: 24px;}");
vLeft->addWidget(table);
auto canvas = new ResizeEmitedWgt;
auto screen = new QWidget(canvas);
screen->setGeometry(0, 0, screenWidth, screenHeight);
screen->setAutoFillBackground(true);
auto pal = palette();
pal.setColor(QPalette::Window, QColor(0, 0, 0));
screen->setPalette(pal);
connect(canvas, &ResizeEmitedWgt::resized, this, [this, canvas, screen] {
rate = qMin(canvas->width()/(double)screenWidth, canvas->height()/(double)screenHeight);
if(rate==0) return;
screen->resize(qRound(screenWidth*rate), qRound(screenHeight*rate));
auto children = screen->children();
foreach(auto childObj, children) {
auto unit = static_cast<ScreenUnit*>(childObj);
unit->setGeometry(qRound(unit->mX*rate), qRound(unit->mY*rate), qRound(unit->mW*rate), qRound(unit->mH*rate));
}
});
splitter->addWidget(canvas);
splitter->setStretchFactor(0,0);
splitter->setStretchFactor(1,1);
splitter->setSizes({280, 1});
hBox = new HBox(vBox);
auto btn = new QPushButton(tr("保存到文件"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
});
hBox->addWidget(btn);
hBox->addStretch();
btn = new QPushButton(tr("发送发送卡参数"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
});
hBox->addWidget(btn);
btn = new QPushButton(tr("固化发送卡参数"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
});
hBox->addWidget(btn);
btnSendReadBack = new QPushButton(tr("回读发送卡参数"));
btnSendReadBack->setProperty("ss","blue");
connect(btnSendReadBack, &QPushButton::clicked, this, [=] {
});
hBox->addWidget(btnSendReadBack);
for(int rr=0; rr<4; rr++) {
auto item = new TreeWidgetItem(table);
QString name = "P"+QString::number(rr+1);
item->setText("face", name);
item->setText("x", QString::number(rr*128));
item->setText("y", "0");
item->setText("w", "128");
item->setText("h", "128");
item->setText("audio", "0");
item->setText("backup", "0");
auto unit = new ScreenUnit(this, name, rr*128, 0, 128, 128, screen);
unit->setAutoFillBackground(true);
pal.setColor(QPalette::Window, colors[rr]);
unit->setPalette(pal);
}
}
ScreenUnit::ScreenUnit(ExpertSendPanel *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 ScreenUnit::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 ScreenUnit::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 ScreenUnit::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 = 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<ScreenUnit*>(item);
mOtherEles.emplace_back(ele);
}
}
}
void ScreenUnit::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 ScreenUnit::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 = qBound(0, dstHor, expertWin->screenWidth - width());
dstVer = qBound(0, dstVer, expertWin->screenHeight - height());
if(dstHor==0) mLRSnap = 1;
else if(dstHor==expertWin->screenWidth - width()) mLRSnap = 2;
if(dstVer==0) mTBSnap = 1;
else if(dstVer==expertWin->screenHeight - height()) mTBSnap = 2;
if(mLRSnap==0) for(ScreenUnit *ele : mOtherEles) {//左右
if(abs(dstHor - ele->x()) < SnapSpace && ele->x() <= expertWin->screenWidth - width()) {
dstHor = ele->x();
mLRSnap = 1;
ele->mLRSnap = 1;
ele->update();
break;
}
auto eleRight = ele->x() + ele->width();
if(abs(dstHor - eleRight) < SnapSpace && eleRight <= expertWin->screenWidth - width()) {
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) for(ScreenUnit *ele : mOtherEles) {//上下
if(abs(dstVer-ele->y()) < SnapSpace && ele->y() <= expertWin->screenHeight - height()) {
dstVer = ele->y();
mTBSnap = 1;
ele->mTBSnap = 1;
ele->update();
break;
}
auto eleBtm = ele->y() + ele->height();
if(abs(dstVer - eleBtm) < SnapSpace && eleBtm <= expertWin->screenHeight - height()) {
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();
} else if(mFrmSec==Qt::BottomRightSection) {
if(dstHor < m_handleLen) dstHor = m_handleLen;
if(dstVer < m_handleLen) dstVer = m_handleLen;
if(expertWin->screenWidth>0 && expertWin->screenHeight>0) {
dstHor = qMin(dstHor, expertWin->screenWidth - x());
dstVer = qMin(dstVer, expertWin->screenHeight - y());
}
resize(dstHor, dstVer);
mW = qRound(dstHor / expertWin->rate);
mH = qRound(dstVer / expertWin->rate);
} else if(mFrmSec==Qt::RightSection) {
if(dstHor < m_handleLen) dstHor = m_handleLen;
if(expertWin->screenWidth>0 && expertWin->screenHeight>0) dstHor = qMin(dstHor, expertWin->screenWidth - x());
auto right = x() + dstHor;
if(right < expertWin->screenWidth-8) for(ScreenUnit *ele : mOtherEles) {//左右
if(abs(right - ele->x()) < SnapSpace) {
dstHor = ele->x() - x();
mLRSnap = 2;
ele->mLRSnap = 1;
ele->update();
break;
}
auto eleRight = ele->x() + ele->width();
if(abs(right - eleRight) < SnapSpace) {
dstHor = eleRight - x();
mLRSnap = 2;
ele->mLRSnap = 2;
ele->update();
break;
}
}
resize(dstHor, mPressRel.y());
mW = qRound(dstHor / expertWin->rate);
} else if(mFrmSec==Qt::BottomSection) {
if(dstVer < m_handleLen) dstVer = m_handleLen;
if(expertWin->screenWidth>0 && expertWin->screenHeight>0) dstVer = qMin(dstVer, expertWin->screenHeight - y());
auto btm = y() + dstVer;
if(btm < expertWin->screenHeight-8) for(ScreenUnit *ele : mOtherEles) {//上下
auto eleBtm = ele->y() + ele->height();
if(abs(btm - ele->y()) < SnapSpace) {
dstVer = ele->y() - y();
mTBSnap = 2;
ele->mTBSnap = 1;
ele->update();
break;
}
if(abs(btm - eleBtm) < SnapSpace) {
dstVer = eleBtm - y();
mTBSnap = 2;
ele->mTBSnap = 2;
ele->update();
break;
}
}
resize(mPressRel.rx(), dstVer);
mH = qRound(dstVer / expertWin->rate);
} else {
auto geo = geometry();
if(mFrmSec==Qt::LeftSection) {
dstHor = qMin(dstHor, geo.right() - m_handleLen);
if(dstHor < 0) dstHor = 0;
if(dstHor > 8) for(ScreenUnit *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;
}
}
geo.setLeft(dstHor);
} else if(mFrmSec==Qt::TopSection) {
dstVer = qMin(dstVer, geo.bottom() - m_handleLen);
if(dstVer < 0) dstVer = 0;
if(dstVer > 8) for(ScreenUnit *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;
}
}
geo.setTop(dstVer);
} else if(mFrmSec==Qt::TopLeftSection) {
dstHor = qMin(dstHor, geo.right() - m_handleLen);
dstVer = qMin(dstVer, geo.bottom() - m_handleLen);
if(dstHor < 0) dstHor = 0;
if(dstVer < 0) dstVer = 0;
geo.setLeft(dstHor);
geo.setTop(dstVer);
} else if(mFrmSec==Qt::TopRightSection) {
dstHor = qMax(dstHor, geo.x() + m_handleLen);
dstVer = qMin(dstVer, geo.bottom() - m_handleLen);
if(dstHor > expertWin->screenWidth) dstHor = expertWin->screenWidth;
if(dstVer < 0) dstVer = 0;
geo.setRight(dstHor);
geo.setTop(dstVer);
} else if(mFrmSec==Qt::BottomLeftSection) {
dstHor = qMin(dstHor, geo.right() - m_handleLen);
dstVer = qMax(dstVer, geo.y() + m_handleLen);
if(dstHor < 0) dstHor = 0;
if(dstVer > expertWin->screenHeight) dstVer = expertWin->screenHeight;
geo.setLeft(dstHor);
geo.setBottom(dstVer);
}
setGeometry(geo);
mX = qRound(geo.x() / expertWin->rate);
mY = qRound(geo.y() / expertWin->rate);
mW = qRound(geo.width() / expertWin->rate);
mH = qRound(geo.height() / expertWin->rate);
}
}
void ScreenUnit::leaveEvent(QEvent *) {
setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor);
mPressRel.setX(INT_MIN);
}
void ScreenUnit::setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor) {
if(mFrmSec==frmSec) return;
mFrmSec = frmSec;
if(cursor==Qt::ArrowCursor) unsetCursor();
else setCursor(cursor);
}
void ScreenUnit::clearSnap() {
if(mLRSnap==0 && mTBSnap==0) return;
mLRSnap = mTBSnap = 0;
update();
}