#include "ebase.h" #include "gqt.h" #include "tools.h" #include #include #include #include #include #include #include #include #include struct BorderImg { QString name; QPixmap img; }; QVector borderImgs; int borderImgMaxWidth = 0; int borderImgMaxHeight = 0; struct Initer{ Initer() { QDirIterator it(":res/borders/", QDirIterator::Subdirectories); while(it.hasNext()) { BorderImg bdImg; bdImg.name = it.next(); bdImg.img = QPixmap(bdImg.name); int idx = bdImg.name.lastIndexOf('/'); if(idx>-1) bdImg.name = bdImg.name.mid(idx+1); borderImgs.append(bdImg); if(bdImg.img.width() > borderImgMaxWidth) borderImgMaxWidth = bdImg.img.width(); if(bdImg.img.height() > borderImgMaxHeight) borderImgMaxHeight = bdImg.img.height(); } } }; EBase::EBase(EBase *multiWin) : mMultiWin(multiWin) { static struct Initer aaa; if(mMultiWin == nullptr) { setFlag(ItemIsMovable); setFlag(ItemIsSelectable); } mSidePen.setCapStyle(Qt::FlatCap); mSidePen.setDashPattern(QVector{1,3}); } void EBase::setBaseAttr(const QJsonObject &json) { mStartTime = json["startTime"].toInt(); auto geometry = json["geometry"].toObject(); setPos(geometry["x"].toInt(), geometry["y"].toInt()); setSize(geometry["w"].toInt(), geometry["h"].toInt()); setZValue(geometry["order"].toInt()); QString bdName = json["border"].toString(); if(! bdName.isEmpty()) { for(int i=0; ibdImgIdx > -1 ? borderImgs[ele->bdImgIdx].img.height() : 0; obj.insert("startTime", mStartTime); obj.insert("innerX", ele->x()+bdWidth); obj.insert("innerY", ele->y()+bdWidth); obj.insert("innerW", ele->mWidth-bdWidth-bdWidth); obj.insert("innerH", ele->mHeight-bdWidth-bdWidth); QJsonObject geometry; geometry["order"] = zValue(); geometry["x"] = (int)ele->x(); geometry["y"] = (int)ele->y(); geometry["w"] = (int)ele->mWidth; geometry["h"] = (int)ele->mHeight; if(bdImgIdx>-1) { obj["border"] = borderImgs[bdImgIdx].name; obj["borderSize"] = QJsonArray{borderImgs[bdImgIdx].img.width(), borderImgs[bdImgIdx].img.height()}; obj["borderEff"] = bdEff.isEmpty() ? QJsonValue() : bdEff; obj["borderSpeed"] = bdSpeed; // geometry["border"] = borderImgs[bdImgIdx].name; // geometry["border_eff"] = bdEff.isEmpty() ? QJsonValue() : bdEff; // geometry["border_speed"] = bdSpeed; } obj.insert("geometry", geometry); } QRectF EBase::innerRect() const { auto ele = mMultiWin!=nullptr ? mMultiWin : this; int bdWidth = ele->bdImgIdx > -1 ? borderImgs[ele->bdImgIdx].img.height() : 0; return QRectF(bdWidth, bdWidth, ele->mWidth-bdWidth-bdWidth, ele->mHeight-bdWidth-bdWidth); } void EBase::fitProgSize() { if(gProgWidth < mWidth || gProgHeight < mHeight) { auto rate = qMin(gProgWidth / mWidth, gProgHeight / mHeight); prepareGeometryChange(); mWidth *= rate; mHeight *= rate; emit sizeChanged(); } int lmt = gProgWidth - mWidth; if(x() > lmt) setX(lmt); lmt = gProgHeight - mHeight; if(y() > lmt) setY(lmt); } QRectF EBase::boundingRect() const { qreal xy = -m_handleLen / 2; return QRectF(xy, xy, mWidth + m_handleLen, mHeight + m_handleLen); } //绘制选中和未选中的区域边框 void EBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if(mMultiWin!=nullptr) return; painter->save(); //绘制边框 if(bdImgIdx > -1) { if(bdTimerId==0 && !bdEff.isEmpty()) { if(bdEff.startsWith("ro")) bdTimerId = startTimer(bdSpeed==1 ? 66 : (bdSpeed==2 ? 33 : 16), Qt::PreciseTimer); else bdTimerId = startTimer(bdSpeed==1 ? 500 : (bdSpeed==2 ? 250 : 66)); } if(!bdEff.startsWith("bl") || bdOff==0) { int bdWidth = borderImgs[bdImgIdx].img.height(); int halfBdWidth = (bdWidth+1)/2; QBrush brush(borderImgs[bdImgIdx].img); QTransform transTop = QTransform::fromTranslate(halfBdWidth+bdOff, 0); QTransform transRight = QTransform::fromTranslate(mWidth - bdWidth, halfBdWidth*3-mWidth+bdOff); transRight.rotate(90); QTransform transBottom = QTransform::fromTranslate(halfBdWidth*3-mHeight-bdOff, mHeight - bdWidth); transBottom.rotate(180); QTransform transLeft = QTransform::fromTranslate(0, halfBdWidth-bdOff); transLeft.rotate(270); brush.setTransform(transTop); QPainterPath path(QPointF(0, 0)); path.lineTo(mWidth, 0); path.lineTo(mWidth - bdWidth, bdWidth); path.lineTo(bdWidth, bdWidth); path.closeSubpath(); painter->fillPath(path, brush); brush.setTransform(transRight); path = QPainterPath(QPointF(mWidth, 0)); path.lineTo(mWidth, mHeight); path.lineTo(mWidth - bdWidth, mHeight - bdWidth); path.lineTo(mWidth - bdWidth, bdWidth); path.closeSubpath(); painter->fillPath(path, brush); brush.setTransform(transBottom); path = QPainterPath(QPointF(mWidth, mHeight)); path.lineTo(0, mHeight); path.lineTo(bdWidth, mHeight - bdWidth); path.lineTo(mWidth - bdWidth, mHeight - bdWidth); path.closeSubpath(); painter->fillPath(path, brush); brush.setTransform(transLeft); path = QPainterPath(QPointF(0, mHeight)); path.lineTo(0, 0); path.lineTo(bdWidth, bdWidth); path.lineTo(bdWidth, mHeight - bdWidth); path.closeSubpath(); painter->fillPath(path, brush); } } if(isSelected()) { mSidePen.setColor(Qt::green); painter->setPen(mSidePen); painter->drawRect(0, 0, mWidth, mHeight); m_rLT = QRectF(-m_handleLen/2, -m_handleLen/2, m_handleLen, m_handleLen);//左上角 m_rT = QRectF(mWidth/2 - m_handleLen/2, -m_handleLen/2, m_handleLen, m_handleLen);//上中 m_rRT = QRectF(mWidth - m_handleLen/2, - m_handleLen/2, m_handleLen, m_handleLen);//右上角 m_rL = QRectF(-m_handleLen/2, mHeight/2 - m_handleLen/2, m_handleLen, m_handleLen); m_rR = QRectF(mWidth - m_handleLen/2, mHeight/2 - m_handleLen/2, m_handleLen, m_handleLen); m_rLB = QRectF(-m_handleLen/2, mHeight - m_handleLen/2, m_handleLen, m_handleLen); m_rB = QRectF(mWidth/2 - m_handleLen/2, mHeight - m_handleLen/2, m_handleLen, m_handleLen); m_rRB = QRectF(mWidth - m_handleLen/2, mHeight - m_handleLen/2, m_handleLen, m_handleLen); static QPen handlePen = QPen(Qt::green); painter->setPen(handlePen); 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, mWidth, mHeight); } //磁条吸附时两化吸附的边 static QPen snapPen(Qt::green); painter->setPen(snapPen); if(mLRSnap==1) painter->drawLine(0, 0, 0, mHeight); else if(mLRSnap==2) painter->drawLine(mWidth, 0, mWidth, mHeight); if(mTBSnap==1) painter->drawLine(0, 0, mWidth, 0); else if(mTBSnap==2) painter->drawLine(0, mHeight, mWidth, mHeight); painter->restore(); } void EBase::mousePressEvent(QGraphicsSceneMouseEvent *e) { QGraphicsObject::mousePressEvent(e); if(e->button() != Qt::LeftButton) return; setFrmSec(e->pos()); auto mousePos = e->scenePos(); 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(mWidth - mousePos.x(), mHeight - mousePos.y()); else if(mFrmSec==Qt::RightSection ) mPressRel = QPointF(mWidth - mousePos.x(), mHeight ); else if(mFrmSec==Qt::BottomSection ) mPressRel = QPointF(mWidth , mHeight - mousePos.y()); else if(mFrmSec==Qt::TopRightSection ) mPressRel = QPointF(elePos.x()+mWidth - mousePos.x(), elePos.y() - mousePos.y()); else if(mFrmSec==Qt::BottomLeftSection ) mPressRel = QPointF(elePos.x() - mousePos.x(), elePos.y()+mHeight - mousePos.y()); else if(mFrmSec==Qt::NoSection) mPressRel.setX(FLT_MAX); if(mPressRel.x()!=FLT_MAX) { mOtherEles.clear(); auto scene = this->scene(); if(0 == scene) return; auto items = scene->items(); foreach(auto item, items) { if(item==this) continue; auto ele = static_cast(item); if(ele->mMultiWin) continue; mOtherEles.append(ele); } } } void EBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { QGraphicsObject::mouseReleaseEvent(event); if(Qt::LeftButton == event->button()) { mPressRel.setX(FLT_MAX); clearSnap(); foreach(auto ele, mOtherEles) ele->clearSnap(); } } #define SnapSpace 6 void EBase::mouseMoveEvent(QGraphicsSceneMouseEvent *e){ if(! (e->buttons() & Qt::LeftButton)) return; if(! isSelected()) return; if(mFrmSec==Qt::NoSection || mPressRel.x()>=FLT_MAX) return; auto mousePos = e->scenePos(); 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.0, dstHor, gProgWidth - mWidth); dstVer = qBound(0.0, dstVer, gProgHeight - mHeight); if(dstHor==0) mLRSnap = 1; else if(dstHor==gProgWidth - mWidth) mLRSnap = 2; if(dstVer==0) mTBSnap = 1; else if(dstVer==gProgHeight - mHeight) mTBSnap = 2; if(mLRSnap==0) foreach(EBase *ele, mOtherEles) {//左右 if(fabs(dstHor - ele->x()) < SnapSpace && ele->x() <= gProgWidth - mWidth) { dstHor = ele->x(); mLRSnap = 1; ele->mLRSnap = 1; ele->update(); break; } auto eleRight = ele->x() + ele->mWidth; if(fabs(dstHor - eleRight) < SnapSpace && eleRight <= gProgWidth - mWidth) { dstHor = eleRight; mLRSnap = 1; ele->mLRSnap = 2; ele->update(); break; } auto right = dstHor + mWidth; if(fabs(right - ele->x()) < SnapSpace && ele->x() - mWidth >= 0) { dstHor = ele->x() - mWidth; mLRSnap = 2; ele->mLRSnap = 1; ele->update(); break; } if(fabs(right - eleRight) < SnapSpace && eleRight - mWidth >= 0) { dstHor = eleRight - mWidth; mLRSnap = 2; ele->mLRSnap = 2; ele->update(); break; } } if(mTBSnap==0) foreach(EBase *ele, mOtherEles) {//上下 if(fabs(dstVer-ele->y()) < SnapSpace && ele->y() <= gProgHeight - mHeight) { dstVer = ele->y(); mTBSnap = 1; ele->mTBSnap = 1; ele->update(); break; } auto eleBtm = ele->y() + ele->mHeight; if(fabs(dstVer - eleBtm) < SnapSpace && eleBtm <= gProgHeight - mHeight) { dstVer = eleBtm; mTBSnap = 1; ele->mTBSnap = 2; ele->update(); break; } auto btm = dstVer + mHeight; if(fabs(btm - ele->y()) < SnapSpace && ele->y() - mHeight >= 0) { dstVer = ele->y() - mHeight; mTBSnap = 2; ele->mTBSnap = 1; ele->update(); break; } if(fabs(btm - eleBtm) < SnapSpace && eleBtm - mHeight >= 0) { dstVer = eleBtm - mHeight; mTBSnap = 2; ele->mTBSnap = 2; ele->update(); break; } } setPos(dstHor, dstVer); } else if(mFrmSec==Qt::BottomRightSection) { if(dstHor < m_handleLen) dstHor = m_handleLen; if(dstVer < m_handleLen) dstVer = m_handleLen; if(mType!=Audio && gProgWidth>0 && gProgHeight>0) { dstHor = qMin(dstHor, gProgWidth - x()); dstVer = qMin(dstVer, gProgHeight - y()); } setSize(dstHor, dstVer); } else if(mFrmSec==Qt::RightSection) { if(dstHor < m_handleLen) dstHor = m_handleLen; if(mType!=Audio && gProgWidth>0 && gProgHeight>0) dstHor = qMin(dstHor, gProgWidth - x()); auto right = x() + dstHor; if(right < gProgWidth-8) foreach(EBase *ele, mOtherEles) {//左右 if(fabs(right - ele->x()) < SnapSpace) { dstHor = ele->x() - x(); mLRSnap = 2; ele->mLRSnap = 1; ele->update(); break; } auto eleRight = ele->x() + ele->mWidth; if(fabs(right - eleRight) < SnapSpace) { dstHor = eleRight - x(); mLRSnap = 2; ele->mLRSnap = 2; ele->update(); break; } } setSize(dstHor, mPressRel.y()); } else if(mFrmSec==Qt::BottomSection) { if(dstVer < m_handleLen) dstVer = m_handleLen; if(mType!=Audio && gProgWidth>0 && gProgHeight>0) dstVer = qMin(dstVer, gProgHeight - y()); auto btm = y() + dstVer; if(btm < gProgHeight-8) foreach(EBase *ele, mOtherEles) {//上下 auto eleBtm = ele->y() + ele->mHeight; if(fabs(btm - ele->y()) < SnapSpace) { dstVer = ele->y() - y(); mTBSnap = 2; ele->mTBSnap = 1; ele->update(); break; } if(fabs(btm - eleBtm) < SnapSpace) { dstVer = eleBtm - y(); mTBSnap = 2; ele->mTBSnap = 2; ele->update(); break; } } setSize(mPressRel.rx(), dstVer); } else { QRectF geo(x(), y(), mWidth, mHeight); if(mFrmSec==Qt::LeftSection) { dstHor = qMin(dstHor, geo.right() - m_handleLen); if(mType!=Audio && dstHor < 0) dstHor = 0; if(dstHor > 8) foreach(EBase *ele, mOtherEles) {//左右 if(fabs(dstHor - ele->x()) < SnapSpace) { dstHor = ele->x(); mLRSnap = 1; ele->mLRSnap = 1; ele->update(); break; } auto eleRight = ele->x() + ele->mWidth; if(fabs(dstHor - eleRight) < SnapSpace) { dstHor = eleRight; mLRSnap = 1; ele->mLRSnap = 2; ele->update(); break; } } geo.setLeft(dstHor); setX(dstHor); } else if(mFrmSec==Qt::TopSection) { dstVer = qMin(dstVer, geo.bottom() - m_handleLen); if(mType!=Audio && dstVer < 0) dstVer = 0; if(dstVer > 8) foreach(EBase *ele, mOtherEles) {//上下 if(fabs(dstVer - ele->y()) < SnapSpace) { dstVer = ele->y(); mTBSnap = 1; ele->mTBSnap = 1; ele->update(); break; } auto eleBtm = ele->y() + ele->mHeight; if(fabs(dstVer - eleBtm) < SnapSpace) { dstVer = eleBtm; mTBSnap = 1; ele->mTBSnap = 2; ele->update(); break; } } geo.setTop(dstVer); setY(dstVer); } else if(mFrmSec==Qt::TopLeftSection) { dstHor = qMin(dstHor, geo.right() - m_handleLen); dstVer = qMin(dstVer, geo.bottom() - m_handleLen); if(mType!=Audio) { if(dstHor < 0) dstHor = 0; if(dstVer < 0) dstVer = 0; } geo.setLeft(dstHor); geo.setTop(dstVer); setPos(dstHor, dstVer); } else if(mFrmSec==Qt::TopRightSection) { dstHor = qMax(dstHor, geo.x() + m_handleLen); dstVer = qMin(dstVer, geo.bottom() - m_handleLen); if(mType!=Audio) { if(dstHor > gProgWidth) dstHor = gProgWidth; if(dstVer < 0) dstVer = 0; } geo.setRight(dstHor); geo.setTop(dstVer); setY(dstVer); } else if(mFrmSec==Qt::BottomLeftSection) { dstHor = qMin(dstHor, geo.right() - m_handleLen); dstVer = qMax(dstVer, geo.y() + m_handleLen); if(mType!=Audio) { if(dstHor < 0) dstHor = 0; if(dstVer > gProgHeight) dstVer = gProgHeight; } geo.setLeft(dstHor); geo.setBottom(dstVer); setX(dstHor); } setSize(geo.width(), geo.height()); } } void EBase::hoverMoveEvent(QGraphicsSceneHoverEvent *e) { setFrmSec(e->pos()); } void EBase::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); mPressRel.setX(FLT_MAX); } void EBase::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()<=mWidth && pos.y()>=0 && pos.y()<=mHeight) setFrmSecIfNeed(Qt::TitleBarArea, Qt::SizeAllCursor); else setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); } void EBase::setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor) { if(mFrmSec==frmSec) return; mFrmSec = frmSec; if(cursor==Qt::ArrowCursor) unsetCursor(); else setCursor(cursor); } QVariant EBase::itemChange(GraphicsItemChange change, const QVariant &value) { if(change==QGraphicsItem::ItemVisibleChange) { if(value.toBool()) goto end; if(bdTimerId>0) { killTimer(bdTimerId); bdTimerId = 0; } } else if(change==QGraphicsItem::ItemSelectedChange) { bool isSel = value.toBool(); setAcceptHoverEvents(isSel); if(! isSel) unsetCursor(); } end: return QGraphicsObject::itemChange(change, value); } void EBase::timerEvent(QTimerEvent *event) { if(event->timerId()!=bdTimerId) QGraphicsObject::timerEvent(event); else { if(bdEff.isEmpty()){ killTimer(bdTimerId); bdTimerId = 0; return; } if(bdEff.startsWith("ro")) { if(bdImgIdx < 0) return; if(bdOff >= borderImgs[bdImgIdx].img.width() - 1) bdOff = 0; else bdOff++; } else bdOff = bdOff==0 ? 1 : 0; update(); } } void EBase::clearSnap() { if(mLRSnap==0 && mTBSnap==0) return; mLRSnap = mTBSnap = 0; update(); } void EBase::addBaseAttrWgt(QVBoxLayout *vBox) { if(mMultiWin!=nullptr) return; auto hBox = new QHBoxLayout(); hBox->addWidget(new QLabel(tr("Area"))); auto line = new QFrame(); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line,1); vBox->addLayout(hBox); auto spacing = vBox->spacing(); if(spacing < 0) spacing = 0; vBox->addSpacing(-spacing-2); hBox = new QHBoxLayout(); hBox->addStretch(); hBox->addWidget(new QLabel(tr("X")+": ")); auto fdX = new QSpinBox(); fdX->setRange(0, 9999); fdX->setValue(x()); connect(fdX, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdX](int value) { int max = gProgWidth - mWidth; if(value > max) { value = max; fdX->blockSignals(true); fdX->setValue(value); fdX->blockSignals(false); } setX(value); }); hBox->addWidget(fdX); hBox->addSpacing(10); hBox->addWidget(new QLabel(tr("Y")+": ")); auto fdY = new QSpinBox(); fdY->setRange(0, 9999); fdY->setValue(y()); connect(fdY, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdY](int value) { int max = gProgHeight - mHeight; if(value > max) { value = max; fdY->blockSignals(true); fdY->setValue(value); fdY->blockSignals(false); } setY(value); }); hBox->addWidget(fdY); hBox->addStretch(); vBox->addLayout(hBox); hBox = new QHBoxLayout(); hBox->addStretch(); hBox->addWidget(new QLabel(tr("W")+": ")); auto fdW = new QSpinBox(); fdW->setRange(6, 9999); fdW->setValue(mWidth); connect(fdW, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdW](int value) { int max = gProgWidth - x(); if(value > max) { value = max; fdW->blockSignals(true); fdW->setValue(value); fdW->blockSignals(false); } setSize(value, mHeight); }); hBox->addWidget(fdW); hBox->addSpacing(10); hBox->addWidget(new QLabel(tr("H")+": ")); auto fdH = new QSpinBox(); fdH->setRange(6, 9999); fdH->setValue(mHeight); connect(fdH, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdH](int value) { int max = gProgHeight - y(); if(value > max) { value = max; fdH->blockSignals(true); fdH->setValue(value); fdH->blockSignals(false); } setSize(mWidth, value); }); hBox->addWidget(fdH); hBox->addStretch(); vBox->addLayout(hBox); vBox->addSpacing(-spacing); connect(this, &EBase::xChanged, fdX, [this, fdX] { fdX->blockSignals(true); fdX->setValue(x()); fdX->blockSignals(false); }); connect(this, &EBase::yChanged, fdY, [this, fdY] { fdY->blockSignals(true); fdY->setValue(y()); fdY->blockSignals(false); }); connect(this, &EBase::sizeChanged, fdW, [this, fdW, fdH] { fdW->blockSignals(true); fdW->setValue(mWidth); fdW->blockSignals(false); fdH->blockSignals(true); fdH->setValue(mHeight); fdH->blockSignals(false); }); hBox = new QHBoxLayout(); hBox->addWidget(new QLabel(tr("Border"))); line = new QFrame(); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); vBox->addLayout(hBox); vBox->addSpacing(-spacing-2); hBox = new QHBoxLayout(); hBox->setSpacing(0); hBox->addStretch(); auto borderFd = new QComboBox(); borderFd->addItem(tr("None")); for(int i=0; iaddItem(QIcon(borderImgs[i].img), QString::number(borderImgs[i].img.height()), borderImgs[i].name); borderFd->setIconSize(QSize(borderImgMaxWidth, borderImgMaxHeight)); connect(borderFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int idx){ bdImgIdx = idx-1; if(bdImgIdx==-1 && bdTimerId>0) { killTimer(bdTimerId); bdTimerId = 0; } bdOff = 0; update(); emit sizeChanged(); }); hBox->addWidget(borderFd); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Effect")+":")); auto borderEffFd = new QComboBox(); borderEffFd->addItem(tr("Rotate"), "rotate"); borderEffFd->addItem(tr("Blink"), "blink"); borderEffFd->addItem(tr("None"), ""); connect(borderEffFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderEffFd] { bdEff = borderEffFd->currentData().toString(); if(bdTimerId>0) { killTimer(bdTimerId); bdTimerId = 0; } bdOff = 0; update(); }); hBox->addWidget(borderEffFd); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Speed")+":")); auto borderSpeedFd = new QComboBox(); borderSpeedFd->addItem(tr("Slow"), 1); borderSpeedFd->addItem(tr("Moderate"), 2); borderSpeedFd->addItem(tr("Fast"), 3); borderSpeedFd->setCurrentIndex(1); connect(borderSpeedFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderSpeedFd] { bdSpeed = borderSpeedFd->currentData().toInt(); if(bdTimerId>0) { killTimer(bdTimerId); bdTimerId = 0; } update(); }); hBox->addWidget(borderSpeedFd); hBox->addStretch(); vBox->addLayout(hBox); if(bdImgIdx>-1) { borderFd->setCurrentIndex(bdImgIdx+1); select(borderEffFd, bdEff); select(borderSpeedFd, bdSpeed); } }