qt/LedOK/wProgramManager/wEditProgram/wElement/eobject.cpp
2022-01-07 18:22:58 +08:00

630 lines
18 KiB
C++

#include "eobject.h"
#include "eobjectattr.h"
#include <QGraphicsSceneMouseEvent>
eObject::eObject(InteractiveType type, QGraphicsItem *parent) : QGraphicsObject(parent),
m_interactiveType(type),
m_movable(false),
m_handleLen(10),
m_rLimit(INVALID_RECT) {
setGeometry(0, 0, 100, 100);
init();
}
eObject::eObject(QRectF rect, InteractiveType type, QGraphicsItem *parent) : QGraphicsObject(parent),
m_interactiveType(type),
m_movable(false),
m_handleLen(10),
m_rLimit(INVALID_RECT) {
setGeometry(rect);
init();
}
eObject::eObject(const QJsonObject &json, InteractiveType type, QGraphicsItem *parent) : QGraphicsObject(parent),
m_interactiveType(type),
m_movable(false),
m_handleLen(10),
m_rLimit(INVALID_RECT) {
setZValue(json["order"].toInt());
setGeometry(QRectF(json["x"].toInt(), json["y"].toInt(),
json["w"].toInt(), json["h"].toInt()));
init();
}
void eObject::init(){
qDebug()<<"eObject::init()";
setInteractiveType(m_interactiveType);
m_handlePen.setBrush(QBrush(QColor::fromRgb(0, 255, 0)));
m_handlePen.setWidth(1);
QVector<qreal> dashes;
qreal space = 2;
qreal solid = 2;
dashes << solid << space << solid <<space;
m_borderPen.setBrush(QBrush(QColor::fromRgb(0, 255, 0)));
m_borderPen.setDashPattern(dashes);
m_borderPen.setWidth(1);
connect(this, SIGNAL(sPlayBQ()), this, SLOT(playElectment()), Qt::BlockingQueuedConnection);
connect(this, SIGNAL(sStopBQ()), this, SLOT(stopElectment()), Qt::BlockingQueuedConnection);
}
void eObject::setInteractiveType(InteractiveType type){
qDebug()<<"eObject::setInteractiveType(InteractiveType)";
m_interactiveType = type;
GraphicsItemFlags flag = flags();
if(Dynamic == m_interactiveType) {
flag |= ItemIsMovable;
flag |= ItemIsSelectable;
flag &= ~ItemIsFocusable;
} else {
flag &= ~ItemIsMovable;
flag &= ~ItemIsSelectable;
flag &= ~ItemIsFocusable;
}
setFlags(flag);
}
QWidget* eObject::wAttr(){
qDebug()<<"eObject::wAttr()";
m_wAttr = new eObjectAttr(geometry(), rLimit());
connect(this, SIGNAL(geometryChanged(const QRectF &)), m_wAttr, SLOT(onAttrSetting(const QRectF &)));
connect(m_wAttr, SIGNAL(sAttrChanged(const QRectF &)), this, SLOT(onAttrChanged(const QRectF &)));
void(QComboBox::*currentIndexChanged)(int) = &QComboBox::currentIndexChanged;
connect(m_wAttr->borderFd, currentIndexChanged, this, [this](int idx){
//m_wAttr->borderFd->itemIcon(idx).data_ptr().;
});
return m_wAttr;
}
QJsonObject eObject::elementJson() const {
qDebug()<<"eObject::elementJson()";
QJsonObject oRoot;
QRectF r = geometry();
oRoot["order"] = zValue();
oRoot["x"] = (int)r.x();
oRoot["y"] = (int)r.y();
oRoot["w"] = (int)r.width();
oRoot["h"] = (int)r.height();
return oRoot;
}
void eObject::setRLimit(const QRectF &r) {
qDebug()<<"eObject::setRLimit(QRectF)";
if(isSelected()) m_wAttr->setRLimit(r);
if(m_rLimit != INVALID_RECT) {
qreal mx, my, mw, mh;
qreal scale_w = r.width() / m_rLimit.width();
qreal scale_h = r.height() / m_rLimit.height();
mx = std::round(x() * scale_w);
my = std::round(y() * scale_h);
mw = std::round(m_w * scale_w);
mh = std::round(m_h * scale_h);
setPos(mx, my);
m_w = mw;
m_h = mh;
adjustHandle();
geometryChanged(geometry());
}
m_rLimit = r;
}
void eObject::onAttrChanged(const QRectF &rect){
qDebug()<<"eObject::onAttrChanged(QRectF)";
setGeometry(rect);
}
QRectF eObject::boundingRect() const {
int m2 = m_handleLen * 2;
return QRectF(-m_handleLen, -m_handleLen, m_w+m2, m_h+m2);
}
//绘制选中和未选中的区域边框
void eObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
//qDebug()<<"eObject::paint(QPainter, QStyleOptionGraphicsItem)";
Q_UNUSED(option);
Q_UNUSED(widget);
painter->save();
//绘制边框
QPixmap img("borders/M8_8.bmp");
int borderWidth = img.height();
QBrush brush(img);
QPainterPath path(QPointF(0, 0));
path.lineTo(m_w, 0);
path.lineTo(m_w - borderWidth, borderWidth);
path.lineTo(borderWidth, borderWidth);
path.closeSubpath();
painter->fillPath(path, brush);
QTransform transform;
transform.rotate(90);
brush.setTransform(transform);
path = QPainterPath(QPointF(m_w, 0));
path.lineTo(m_w, m_h);
path.lineTo(m_w - borderWidth, m_h - borderWidth);
path.lineTo(m_w - borderWidth, borderWidth);
path.closeSubpath();
painter->fillPath(path, brush);
transform.rotate(90);
brush.setTransform(transform);
path = QPainterPath(QPointF(m_w, m_h));
path.lineTo(0, m_h);
path.lineTo(borderWidth, m_h - borderWidth);
path.lineTo(m_w - borderWidth, m_h - borderWidth);
path.closeSubpath();
painter->fillPath(path, brush);
transform.rotate(90);
brush.setTransform(transform);
path = QPainterPath(QPointF(0, m_h));
path.lineTo(0, 0);
path.lineTo(borderWidth, borderWidth);
path.lineTo(borderWidth, m_h - borderWidth);
path.closeSubpath();
painter->fillPath(path, brush);
if(isSelected()) {
QPainterPath pRect;
pRect.addRect(rect());
m_borderPen.setBrush(QBrush(QColor::fromRgb(0, 255, 0)));
painter->setPen(m_borderPen);
painter->drawPath(pRect);
QPainterPath pHandle;
pHandle.addRect(m_rLT);
pHandle.addRect(m_rT);
pHandle.addRect(m_rRT);
pHandle.addRect(m_rL);
pHandle.addRect(m_rR);
pHandle.addRect(m_rLB);
pHandle.addRect(m_rB);
pHandle.addRect(m_rRB);
painter->setPen(m_handlePen);
painter->drawPath(pHandle);
} else {
m_borderPen.setBrush(QBrush(QColor::fromRgb(0, 125, 0)));
QPainterPath pRect;
pRect.addRect(rect());
painter->setPen(m_borderPen);
painter->drawPath(pRect);
}
//磁条吸附时两化吸附的边
QPen CitiePen=QPen(QColor::fromRgb(0, 255, 0),1,Qt::SolidLine);
painter->setPen(CitiePen);
//if(bMousePress)
{
if (bLeftCitie) {
painter->setPen(CitiePen);
//painter->drawLine(QPointF(rect().x(),rect().y()-100),QPointF(rect().x(),rect().bottom()+100));
painter->drawLine(QPointF(rect().topLeft()),QPointF(rect().bottomLeft()));
}
if (bTopCitie) {
painter->setPen(CitiePen);
painter->drawLine(QPointF(rect().topLeft()),QPointF(rect().topRight()));
}
if (bRightCitie) {
painter->setPen(CitiePen);
painter->drawLine(QPointF(rect().topRight()),QPointF(rect().bottomRight()));
}
if (bBottomCitie) {
painter->setPen(CitiePen);
painter->drawLine(QPointF(rect().bottomLeft()),QPointF(rect().bottomRight()));
}
}
// QPen(const QBrush &brush,
// qreal width,
// Qt::PenStyle style = Qt::SolidLine,
// Qt::PenCapStyle cap = Qt::SquareCap,
// Qt::PenJoinStyle join = Qt::BevelJoin);
// QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
//painter->drawLine(QPointF(rect().bottomLeft()),QPointF(rect().bottomRight()));
painter->restore();
}
void eObject::mousePressEvent(QGraphicsSceneMouseEvent *event){
if(Qt::LeftButton == event->button()) {
m_hDir = handleDir(event->pos());
m_pOrg = pointToParent(event->pos());
m_rOrg = geometry();
m_movable = true;
bMousePress=true;
}
QGraphicsItem::mousePressEvent(event);
}
void eObject::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
bMousePress=false;
if(Qt::LeftButton == event->button()) {
m_hDir = NONE;
m_movable = false;
bLeftCitie=false;
bRightCitie=false;
bTopCitie=false;
bBottomCitie=false;
m_keyPressId++;
emit sigCiTie(false,m_keyPressId);
}
QGraphicsItem::mouseReleaseEvent(event);
}
void eObject::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
if(false == m_movable) return;
qreal cx, cy, cw, ch;
qreal mx, my, mw, mh;
QPointF ePos = pointToParent(event->pos());
QPointF absoluteOfs = ePos - m_pOrg;
mx = m_rOrg.x();
my = m_rOrg.y();
mw = m_w;
mh = m_h;
if(m_hDir != NONE) {
prepareGeometryChange();
switch(m_hDir) {
case LT:
cx = m_rOrg.x() + absoluteOfs.x();
cy = m_rOrg.y() + absoluteOfs.y();
if(m_rOrg.right() - cx < m_handleLen) cx = m_rOrg.right() - m_handleLen;
if(m_rOrg.bottom() - cy < m_handleLen) cy = m_rOrg.bottom() - m_handleLen;
mx = cx;
my = cy;
if(m_rLimit != INVALID_RECT) {
if(mx < 0) mx = 0;
if(my < 0) my = 0;
}
mw = m_rOrg.right() - mx;
mh = m_rOrg.bottom() - my;
break;
case T:
cy = m_rOrg.y() + absoluteOfs.y();
if(m_rOrg.bottom() - cy < m_handleLen) cy = m_rOrg.bottom() - m_handleLen;
my = cy;
if(m_rLimit != INVALID_RECT) {
if(my < 0) my = 0;
}
mh = m_rOrg.bottom() - my;
break;
case RT:
cy = m_rOrg.y() + absoluteOfs.y();
cw = m_rOrg.width() + absoluteOfs.x();
if(m_rOrg.bottom() - cy < m_handleLen) cy = m_rOrg.bottom() - m_handleLen;
if(cw < m_handleLen) cw = m_handleLen;
my = cy;
mw = cw;
if(m_rLimit != INVALID_RECT) {
if(my < 0) my = 0;
if(mx + mw > m_rLimit.width()) mw = m_rLimit.width() - mx;
}
mh = m_rOrg.bottom() - my;
break;
case L:
cx = m_rOrg.x() + absoluteOfs.x();
if(m_rOrg.right() - cx < m_handleLen) cx = m_rOrg.right() - m_handleLen;
mx = cx;
if(m_rLimit != INVALID_RECT) {
if(mx < 0) mx = 0;
}
mw = m_rOrg.right() - mx;
break;
case R:
cw = m_rOrg.width() + absoluteOfs.x();
if(cw < m_handleLen) cw = m_handleLen;
mw = cw;
if(m_rLimit != INVALID_RECT) {
if(mx + mw > m_rLimit.width()) mw = m_rLimit.width() - mx;
}
break;
case LB:
cx = m_rOrg.x() + absoluteOfs.x();
ch = m_rOrg.height() + absoluteOfs.y();
if(m_rOrg.right() - cx < m_handleLen) cx = m_rOrg.right() - m_handleLen;
if(ch < m_handleLen) ch = m_handleLen;
mx = cx;
if(m_rLimit != INVALID_RECT) {
if(mx < 0) mx = 0;
}
mw = m_rOrg.right() - mx;
mh = ch;
if(m_rLimit != INVALID_RECT) {
if(my + mh > m_rLimit.height()) mh = m_rLimit.height() - my;
}
break;
case B:
ch = m_rOrg.height() + absoluteOfs.y();
if(ch < m_handleLen) ch = m_handleLen;
mh = ch;
if(m_rLimit != INVALID_RECT) {
if(my + mh > m_rLimit.height()) mh = m_rLimit.height() - my;
}
break;
case RB:
cw = m_rOrg.width() + absoluteOfs.x();
ch = m_rOrg.height() + absoluteOfs.y();
if(cw < m_handleLen) cw = m_handleLen;
if(ch < m_handleLen) ch = m_handleLen;
mw = cw;
mh = ch;
if(m_rLimit != INVALID_RECT) {
if(mx + mw > m_rLimit.width()) mw = m_rLimit.width() - mx;
if(my + mh > m_rLimit.height()) mh = m_rLimit.height() - my;
}
break;
default:
break;
}
setPos(mx, my);
m_w = mw;
m_h = mh;
adjustHandle();
updateGeometry(m_rOrg);
rectChanged(rect());
} else {
mx = m_rOrg.x() + absoluteOfs.x();
my = m_rOrg.y() + absoluteOfs.y();
if(m_rLimit != INVALID_RECT) {
if(mx < 0) mx = 0;
if(my < 0) my = 0;
if(mx + mw > m_rLimit.width()) mx = m_rLimit.width() - mw;
if(my + mh > m_rLimit.height()) my = m_rLimit.height() - mh;
}
setPos(mx, my);
}
geometryChanged(geometry());
if(bMousePress)
{
emit sigCiTie(true,m_hDir);
}
}
void eObject::setBrightBianLeft(bool b){
qDebug()<<"eObject::setBrightBianLeft(bool)";
//if(bMousePress)
// {
// bLeftCitie=b;
// }
// else {
// bLeftCitie=false;
// }
bLeftCitie=b;
updateGeometry();
}
void eObject::setBrightBianRight(bool b){
qDebug()<<"eObject::setBrightBianRight(bool)";
// if(bMousePress)
// {
// bRightCitie=b;
// }
// else {
// bRightCitie=false;
// }
bRightCitie=b;
updateGeometry();
}
void eObject::setBrightBianTop(bool b){
qDebug()<<"eObject::setBrightBianTop(bool)";
// if(bMousePress)
// {
// bTopCitie=b;
// }
// else {
// bTopCitie=false;
// }
bTopCitie=b;
updateGeometry();
}
void eObject::setBrightBianbottom(bool b){
qDebug()<<"eObject::setBrightBianbottom(bool)";
// if(bMousePress)
// {
// bBottomCitie=b;
// }
// else {
// bBottomCitie=false;
// }
bBottomCitie=b;
updateGeometry();
}
void eObject::setGeometry(const QRectF &r){
qDebug()<<"eObject::setGeometry(QRectF)";
if(r != geometry()) {
prepareGeometryChange();
setPos(r.x(), r.y());
m_w = r.width();
m_h = r.height();
adjustHandle();
emit rectChanged(rect());
}
}
void eObject::updateGeometry(){
qDebug()<<"eObject::updateGeometry()";
QRectF r = geometry();
qreal x, y, w, h;
x = r.x() - m_handleLen;
y = r.y() - m_handleLen;
w = r.width() + m_handleLen * 2;
h = r.height() + m_handleLen * 2;
r = QRectF(x, y, w, h);
if(nullptr != scene()) {
scene()->update(r);
}
emit requestUpdate(r);
}
void eObject::updateGeometry(const QRectF &gC, const QRectF &gL){
qDebug()<<"eObject::updateGeometry(QRectF,QRectF)";
qreal x, y, w, h;
QRectF gCur, gLast;
x = gC.x() - m_handleLen;
y = gC.y() - m_handleLen;
w = gC.width() + m_handleLen * 2;
h = gC.height() + m_handleLen * 2;
gCur = QRectF(x, y, w, h);
x = gL.x() - m_handleLen;
y = gL.y() - m_handleLen;
w = gL.width() + m_handleLen * 2;
h = gL.height() + m_handleLen * 2;
gLast = QRectF(x, y, w, h);
qreal l = (gCur.left() < gLast.left()) ? gCur.left() : gLast.left();
qreal t = (gCur.top() < gLast.top()) ? gCur.top() : gLast.top();
qreal r = (gCur.right() > gLast.right()) ? gCur.right() : gLast.right();
qreal b = (gCur.bottom() > gLast.bottom()) ? gCur.bottom() : gLast.bottom();
QRectF gFlash = QRectF(QPointF(l, t), QPointF(r, b));
if(nullptr != scene()) {
scene()->update(gFlash);
}
emit requestUpdate(gFlash);
}
QPointF eObject::pointToParent(const QPointF &p){
qDebug()<<"eObject::pointToParent(QPointF)";
qreal px, py;
px = p.x() + x();
py = p.y() + y();
return QPointF(px, py);
}
eObject::HANDLE_DIR eObject::handleDir(const QPointF &p){
qDebug()<<"eObject::handleDir(QPointF)";
HANDLE_DIR hDir = NONE;
if(isSelected()) {
if(m_rLT.contains(p)) hDir = LT;
else if(m_rT.contains(p)) hDir = T;
else if(m_rRT.contains(p)) hDir = RT;
else if(m_rL.contains(p)) hDir = L;
else if(m_rR.contains(p)) hDir = R;
else if(m_rLB.contains(p)) hDir = LB;
else if(m_rB.contains(p)) hDir = B;
else if(m_rRB.contains(p)) hDir = RB;
}
return hDir;
}
//拖拽的虚线矩形
void eObject::adjustHandle(){
qDebug()<<"eObject::adjustHandle()";
const QRectF &r = rect();
//左上角
m_rLT = QRectF(r.left() - m_handleLen/2,
r.top() - m_handleLen/2,
m_handleLen, m_handleLen);
//上中
m_rT = QRectF(r.center().x() - m_handleLen / 2,
r.top() - m_handleLen/2,
m_handleLen, m_handleLen);
//右上角
m_rRT = QRectF(r.right()-m_handleLen/2,
r.top() - m_handleLen/2,
m_handleLen, m_handleLen);
//左中
m_rL = QRectF(r.left() - m_handleLen/2,
r.center().y() - m_handleLen / 2,
m_handleLen, m_handleLen);
//右中
m_rR = QRectF(r.right()-m_handleLen/2,
r.center().y() - m_handleLen / 2,
m_handleLen, m_handleLen);
//左下角
m_rLB = QRectF(r.left() - m_handleLen/2,
r.bottom()-m_handleLen / 2,
m_handleLen, m_handleLen);
//中下
m_rB = QRectF(r.center().x() - m_handleLen / 2,
r.bottom()-m_handleLen / 2,
m_handleLen, m_handleLen);
//右下角
m_rRB = QRectF(r.right()-m_handleLen / 2,
r.bottom()-m_handleLen / 2,
m_handleLen, m_handleLen);
}
QString eObject::getFileMd5(QString filePath){
qDebug()<<"eObject::getFileMd5(QString)";
QFile localFile(filePath);
if (!localFile.open(QFile::ReadOnly))
{
qDebug() << "file open error.";
return 0;
}
QCryptographicHash ch(QCryptographicHash::Md5);
quint64 totalBytes = 0;
quint64 bytesWritten = 0;
quint64 bytesToWrite = 0;
quint64 loadSize = 1024 * 4;
QByteArray buf;
totalBytes = localFile.size();
bytesToWrite = totalBytes;
while (1)
{
if(bytesToWrite > 0)
{
buf = localFile.read(qMin(bytesToWrite, loadSize));
ch.addData(buf);
bytesWritten += buf.length();
bytesToWrite -= buf.length();
buf.resize(0);
}
else
{
break;
}
if(bytesWritten == totalBytes)
{
break;
}
}
localFile.close();
QByteArray md5 = ch.result();
QString strRes="";
strRes.append(md5.toHex());
return strRes;
}