qt/Compass/layer.cpp
2025-03-14 15:23:08 +08:00

316 lines
12 KiB
C++

#include "layer.h"
#include "main.h"
#include "planpanel.h"
#include <QDirIterator>
#include <QLabel>
#include <QPainter>
#include <QSpinBox>
#include <QtMath>
#include <QMouseEvent>
Layer::Layer(int idx, const QString &name, QWidget *parent) : QWidget(parent), idx(idx), name(name) {
mSidePen.setCapStyle(Qt::FlatCap);
mSidePen.setDashPattern(QVector<qreal>{1,3});
}
void Layer::paintEvent(QPaintEvent *event) {
QPainter painter(this);
if(isSelected) {
mSidePen.setColor(Qt::green);
painter.setPen(mSidePen);
painter.drawRect(0, 0, width(), height());
m_rLT = QRectF(-HandleSize/2, -HandleSize/2, HandleSize, HandleSize);//左上角
m_rT = QRectF(width()/2 - HandleSize/2, -HandleSize/2, HandleSize, HandleSize);//上中
m_rRT = QRectF(width() - HandleSize/2, - HandleSize/2, HandleSize, HandleSize);//右上角
m_rL = QRectF(-HandleSize/2, height()/2 - HandleSize/2, HandleSize, HandleSize);
m_rR = QRectF(width() - HandleSize/2, height()/2 - HandleSize/2, HandleSize, HandleSize);
m_rLB = QRectF(-HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize);
m_rB = QRectF(width()/2 - HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize);
m_rRB = QRectF(width() - HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize);
painter.setPen(Qt::green);
painter.drawRect(m_rLT);
painter.drawRect(m_rT);
painter.drawRect(m_rRT);
painter.drawRect(m_rL);
painter.drawRect(m_rR);
painter.drawRect(m_rLB);
painter.drawRect(m_rB);
painter.drawRect(m_rRB);
} else {
mSidePen.setColor(Qt::darkGreen);
painter.setPen(mSidePen);
painter.drawRect(0, 0, width(), height());
}
//磁条吸附时两化吸附的边
static QPen snapPen(Qt::green);
painter.setPen(snapPen);
if(snapLR==1) painter.drawLine(0, 0, 0, height());
else if(snapLR==2) painter.drawLine(width(), 0, width(), height());
if(snapTB==1) painter.drawLine(0, 0, width(), 0);
else if(snapTB==2) painter.drawLine(0, height(), width(), height());
QRectF rect(8, 8, width()-16, height()-16);
painter.drawText(rect, QString("%1 %2").arg(name).arg(idx), QTextOption(Qt::AlignLeft | Qt::AlignTop));
painter.drawText(rect, QString("%1*%2").arg(sSize.width()).arg(sSize.height()), QTextOption(Qt::AlignRight | Qt::AlignBottom));
}
void Layer::mousePressEvent(QMouseEvent *e) {
QWidget::mousePressEvent(e);
if(e->button() != Qt::LeftButton) return;
if(! isSelected) {
isSelected = true;
otherLayers.clear();
auto parent = this->parentWidget();
if(parent) {
auto children = parent->children();
for(auto child : children) if(child!=this) {
auto layer = dynamic_cast<Layer*>(child);
if(layer==0) continue;
layer->isSelected = false;
otherLayers.emplace_back(layer);
}
}
}
setFrmSec(e->pos());
auto mousePos = e->globalPosition();
auto elePos = pos();
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = elePos - mousePos;
else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPointF(width() - mousePos.x(), height() - mousePos.y());
else if(mFrmSec==Qt::RightSection ) mPressRel = QPointF(width() - mousePos.x(), height() );
else if(mFrmSec==Qt::BottomSection ) mPressRel = QPointF(width() , height() - mousePos.y());
else if(mFrmSec==Qt::TopRightSection ) mPressRel = QPointF(elePos.x()+width() - mousePos.x(), elePos.y() - mousePos.y());
else if(mFrmSec==Qt::BottomLeftSection ) mPressRel = QPointF(elePos.x() - mousePos.x(), elePos.y()+height() - mousePos.y());
else if(mFrmSec==Qt::NoSection) mPressRel.setX(FLT_MAX);
rowIdx = 0;
for(; rowIdx<gTableV->rowCount(); ++rowIdx) if((Layer*)gTableV->data(rowIdx, 0).toULongLong()==this) break;
}
void Layer::mouseReleaseEvent(QMouseEvent *event) {
QWidget::mouseReleaseEvent(event);
if(Qt::LeftButton == event->button()) {
mPressRel.setX(FLT_MAX);
clearSnap();
for(auto ele : otherLayers) ele->clearSnap();
}
}
#define SnapSpace 6
void Layer::mouseMoveEvent(QMouseEvent *e) {
if(! (e->buttons() & Qt::LeftButton)) {
setFrmSec(e->pos());
return;
}
if(! isSelected) return;
if(mFrmSec==Qt::NoSection || mPressRel.x()>=FLT_MAX) return;
auto mousePos = e->globalPosition();
auto dstHor = mPressRel.x() + mousePos.x();
auto dstVer = mPressRel.y() + mousePos.y();
snapLR = snapTB = 0;
for(auto ele : otherLayers) ele->clearSnap();
if(mFrmSec==Qt::TitleBarArea) {
if(snapLR==0) for(auto ele : otherLayers) {//左右
if(fabs(dstHor - ele->x()) < SnapSpace) {
dstHor = ele->x();
snapLR = 1;
ele->snapLR = 1;
ele->update();
break;
}
auto eleRight = ele->x() + ele->width();
if(fabs(dstHor - eleRight) < SnapSpace) {
dstHor = eleRight;
snapLR = 1;
ele->snapLR = 2;
ele->update();
break;
}
auto right = dstHor + width();
if(fabs(right - ele->x()) < SnapSpace && ele->x() - width() >= 0) {
dstHor = ele->x() - width();
snapLR = 2;
ele->snapLR = 1;
ele->update();
break;
}
if(fabs(right - eleRight) < SnapSpace && eleRight - width() >= 0) {
dstHor = eleRight - width();
snapLR = 2;
ele->snapLR = 2;
ele->update();
break;
}
}
if(snapTB==0) for(auto ele : otherLayers) {//上下
if(fabs(dstVer-ele->y()) < SnapSpace) {
dstVer = ele->y();
snapTB = 1;
ele->snapTB = 1;
ele->update();
break;
}
auto eleBtm = ele->y() + ele->height();
if(fabs(dstVer - eleBtm) < SnapSpace) {
dstVer = eleBtm;
snapTB = 1;
ele->snapTB = 2;
ele->update();
break;
}
auto btm = dstVer + height();
if(fabs(btm - ele->y()) < SnapSpace && ele->y() - height() >= 0) {
dstVer = ele->y() - height();
snapTB = 2;
ele->snapTB = 1;
ele->update();
break;
}
if(fabs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) {
dstVer = eleBtm - height();
snapTB = 2;
ele->snapTB = 2;
ele->update();
break;
}
}
move(dstHor, dstVer);
} else if(mFrmSec==Qt::BottomRightSection) {
if(dstHor < HandleSize) dstHor = HandleSize;
if(dstVer < HandleSize) dstVer = HandleSize;
resize(dstHor, dstVer);
} else if(mFrmSec==Qt::RightSection) {
if(dstHor < HandleSize) dstHor = HandleSize;
auto right = x() + dstHor;
for(Layer *ele : otherLayers) {//左右
if(fabs(right - ele->x()) < SnapSpace) {
dstHor = ele->x() - x();
snapLR = 2;
ele->snapLR = 1;
ele->update();
break;
}
auto eleRight = ele->x() + ele->width();
if(fabs(right - eleRight) < SnapSpace) {
dstHor = eleRight - x();
snapLR = 2;
ele->snapLR = 2;
ele->update();
break;
}
}
resize(dstHor, mPressRel.y());
} else if(mFrmSec==Qt::BottomSection) {
if(dstVer < HandleSize) dstVer = HandleSize;
auto btm = y() + dstVer;
for(Layer *ele : otherLayers) {//上下
auto eleBtm = ele->y() + ele->height();
if(fabs(btm - ele->y()) < SnapSpace) {
dstVer = ele->y() - y();
snapTB = 2;
ele->snapTB = 1;
ele->update();
break;
}
if(fabs(btm - eleBtm) < SnapSpace) {
dstVer = eleBtm - y();
snapTB = 2;
ele->snapTB = 2;
ele->update();
break;
}
}
resize(mPressRel.rx(), dstVer);
} else {
QRectF geo(x(), y(), width(), height());
if(mFrmSec==Qt::LeftSection) {
dstHor = qMin(dstHor, geo.right() - HandleSize);
if(dstHor > 8) for(auto ele : otherLayers) {//左右
if(fabs(dstHor - ele->x()) < SnapSpace) {
dstHor = ele->x();
snapLR = 1;
ele->snapLR = 1;
ele->update();
break;
}
auto eleRight = ele->x() + ele->width();
if(fabs(dstHor - eleRight) < SnapSpace) {
dstHor = eleRight;
snapLR = 1;
ele->snapLR = 2;
ele->update();
break;
}
}
geo.setLeft(dstHor);
} else if(mFrmSec==Qt::TopSection) {
dstVer = qMin(dstVer, geo.bottom() - HandleSize);
if(dstVer > 8) for(Layer *ele : otherLayers) {//上下
if(fabs(dstVer - ele->y()) < SnapSpace) {
dstVer = ele->y();
snapTB = 1;
ele->snapTB = 1;
ele->update();
break;
}
auto eleBtm = ele->y() + ele->height();
if(fabs(dstVer - eleBtm) < SnapSpace) {
dstVer = eleBtm;
snapTB = 1;
ele->snapTB = 2;
ele->update();
break;
}
}
geo.setTop(dstVer);
} else if(mFrmSec==Qt::TopLeftSection) {
dstHor = qMin(dstHor, geo.right() - HandleSize);
dstVer = qMin(dstVer, geo.bottom() - HandleSize);
geo.setLeft(dstHor);
geo.setTop(dstVer);
} else if(mFrmSec==Qt::TopRightSection) {
dstHor = qMax(dstHor, geo.x() + HandleSize);
dstVer = qMin(dstVer, geo.bottom() - HandleSize);
geo.setRight(dstHor);
geo.setTop(dstVer);
} else if(mFrmSec==Qt::BottomLeftSection) {
dstHor = qMin(dstHor, geo.right() - HandleSize);
dstVer = qMax(dstVer, geo.y() + HandleSize);
geo.setLeft(dstHor);
geo.setBottom(dstVer);
}
setGeometry(geo.toRect());
}
sPos = (pos()-gOrigin) / gScale;
auto cell = (Cell*) gTable->data(rowIdx, gPlayinC).toULongLong();
if(cell) cell->wgt->setPos(sPos);
}
void Layer::leaveEvent(QEvent *) {
setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor);
mPressRel.setX(FLT_MAX);
}
void Layer::setFrmSec(const QPointF &pos) {
if(m_rLT.contains(pos)) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor);
else if(m_rT.contains(pos)) setFrmSecIfNeed(Qt::TopSection, Qt::SizeVerCursor);
else if(m_rRT.contains(pos)) setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor);
else if(m_rL.contains(pos)) setFrmSecIfNeed(Qt::LeftSection, Qt::SizeHorCursor);
else if(m_rR.contains(pos)) setFrmSecIfNeed(Qt::RightSection, Qt::SizeHorCursor);
else if(m_rLB.contains(pos)) setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor);
else if(m_rB.contains(pos)) setFrmSecIfNeed(Qt::BottomSection, Qt::SizeVerCursor);
else if(m_rRB.contains(pos)) setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor);
else if(pos.x()>=0 && pos.x()<=width() && pos.y()>=0 && pos.y()<=height()) setFrmSecIfNeed(Qt::TitleBarArea, Qt::SizeAllCursor);
else setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor);
}
void Layer::setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor) {
if(mFrmSec==frmSec) return;
mFrmSec = frmSec;
if(cursor==Qt::ArrowCursor) unsetCursor();
else setCursor(cursor);
}
void Layer::clearSnap() {
if(snapLR==0 && snapTB==0) return;
snapLR = snapTB = 0;
update();
}