qt/LedOK/program/ebase.cpp

925 lines
35 KiB
C++
Raw Normal View History

2022-08-25 18:37:24 +08:00
#include "ebase.h"
2023-04-18 14:14:46 +08:00
#include "gutil/qgui.h"
2022-08-25 18:37:24 +08:00
#include "tools.h"
#include <QDirIterator>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QJsonArray>
#include <QJsonObject>
#include <QLabel>
#include <QPainter>
#include <QSpinBox>
#include <QtMath>
struct BorderImg {
QString name;
QPixmap img;
};
QVector<BorderImg> borderImgs;
int borderImgMaxWidth = 0;
int borderImgMaxHeight = 0;
2023-08-01 11:42:41 +08:00
struct Initer {
2022-08-25 18:37:24 +08:00
Initer() {
2023-08-01 11:42:41 +08:00
auto names = QDir("borders").entryList(QDir::Files);
2024-06-19 18:54:32 +08:00
for(auto &name : names) {
2022-08-25 18:37:24 +08:00
BorderImg bdImg;
2023-08-01 11:42:41 +08:00
bdImg.name = name;
bdImg.img = QPixmap("borders/"+bdImg.name);
2022-08-25 18:37:24 +08:00
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;
2024-02-21 18:08:50 +08:00
if(mMultiWin == 0) {
2022-08-25 18:37:24 +08:00
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
}
mSidePen.setCapStyle(Qt::FlatCap);
mSidePen.setDashPattern(QVector<qreal>{1,3});
}
2023-10-23 14:58:29 +08:00
void EBase::setBaseAttr(const JObj &json) {
2022-08-25 18:37:24 +08:00
mStartTime = json["startTime"].toInt();
2024-02-21 18:08:50 +08:00
mDuration = json["duration"].toInt();
if(mDuration==0) {
mDuration = json["play"]["playDuration"].toInt();
if(mDuration==0) mDuration = json["play"]["duration"].toInt(10);
}
mEntryEffect = json["entryEffect"].toStr();
mExitEffect = json["exitEffect"].toStr();
mEntryDur = json["entryDur"].toInt();
mExitDur = json["exitDur"].toInt();
2024-06-19 18:54:32 +08:00
_rotate = json["rotate"].toInt();
_blinkFreq = json["blinkFreq"].toDouble(1.0);
_hasBlink = json["hasBlink"].toBool();
2023-10-23 14:58:29 +08:00
auto geometry = json["geometry"];
2022-08-25 18:37:24 +08:00
setPos(geometry["x"].toInt(), geometry["y"].toInt());
setSize(geometry["w"].toInt(), geometry["h"].toInt());
setZValue(geometry["order"].toInt());
2023-10-23 14:58:29 +08:00
auto bdName = json["border"].toString();
2022-08-25 18:37:24 +08:00
if(! bdName.isEmpty()) {
for(int i=0; i<borderImgs.size(); i++) if(borderImgs[i].name==bdName) {bdImgIdx = i; break;}
bdEff = json["borderEff"].toString();
bdSpeed = json["borderSpeed"].toInt(2);
}
}
2023-10-23 14:58:29 +08:00
void EBase::addBaseAttr(JObj &obj) const {
auto ele = mMultiWin ? mMultiWin : this;
2022-08-25 18:37:24 +08:00
int bdWidth = ele->bdImgIdx > -1 ? borderImgs[ele->bdImgIdx].img.height() : 0;
2023-10-23 14:58:29 +08:00
JObj geometry;
2022-08-25 18:37:24 +08:00
geometry["order"] = zValue();
geometry["x"] = (int)ele->x();
geometry["y"] = (int)ele->y();
geometry["w"] = (int)ele->mWidth;
geometry["h"] = (int)ele->mHeight;
2024-02-21 18:08:50 +08:00
obj.insert("geometry", geometry);
obj.insert("innerX", ((int)ele->x())+bdWidth);
obj.insert("innerY", ((int)ele->y())+bdWidth);
obj.insert("innerW", ((int)ele->mWidth)-bdWidth-bdWidth);
obj.insert("innerH", ((int)ele->mHeight)-bdWidth-bdWidth);
obj.insert("startTime", mStartTime);
obj.insert("duration", mDuration);
obj.insert("entryEffect", mEntryEffect);
obj.insert("exitEffect", mExitEffect);
obj.insert("entryDur", mEntryDur);
obj.insert("exitDur", mExitDur);
2024-06-19 18:54:32 +08:00
obj["rotate"] = _rotate;
obj["blinkFreq"] = _blinkFreq;
obj["hasBlink"] = _hasBlink;
2022-08-25 18:37:24 +08:00
if(bdImgIdx>-1) {
obj["border"] = borderImgs[bdImgIdx].name;
2023-10-23 14:58:29 +08:00
obj["borderSize"] = JArray{borderImgs[bdImgIdx].img.width(), borderImgs[bdImgIdx].img.height()};
obj["borderEff"] = bdEff.isEmpty() ? JValue() : bdEff;
2022-08-25 18:37:24 +08:00
obj["borderSpeed"] = bdSpeed;
}
}
QRectF EBase::innerRect() const {
2023-04-18 14:14:46 +08:00
auto ele = mMultiWin ? mMultiWin : this;
2022-08-25 18:37:24 +08:00
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() {
2022-10-27 15:07:45 +08:00
if(gProgItem->mWidth < mWidth || gProgItem->mHeight < mHeight) {
auto rate = qMin(gProgItem->mWidth / mWidth, gProgItem->mHeight / mHeight);
2022-08-25 18:37:24 +08:00
prepareGeometryChange();
mWidth *= rate;
mHeight *= rate;
emit sizeChanged();
}
2022-10-27 15:07:45 +08:00
int lmt = gProgItem->mWidth - mWidth;
2022-08-25 18:37:24 +08:00
if(x() > lmt) setX(lmt);
2022-10-27 15:07:45 +08:00
lmt = gProgItem->mHeight - mHeight;
2022-08-25 18:37:24 +08:00
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();
2024-06-19 18:54:32 +08:00
for(auto item : items) {
2022-08-25 18:37:24 +08:00
if(item==this) continue;
2024-06-19 18:54:32 +08:00
auto ele = (EBase*) item;
2022-08-25 18:37:24 +08:00
if(ele->mMultiWin) continue;
2024-06-19 18:54:32 +08:00
mOtherEles.emplace_back(ele);
2022-08-25 18:37:24 +08:00
}
}
}
void EBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
QGraphicsObject::mouseReleaseEvent(event);
if(Qt::LeftButton == event->button()) {
mPressRel.setX(FLT_MAX);
clearSnap();
2024-06-19 18:54:32 +08:00
for(auto ele : mOtherEles) ele->clearSnap();
2022-08-25 18:37:24 +08:00
}
}
#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;
2024-06-19 18:54:32 +08:00
for(auto ele : mOtherEles) ele->clearSnap();
2022-08-25 18:37:24 +08:00
if(mFrmSec==Qt::TitleBarArea) {
2024-06-19 18:54:32 +08:00
if(type()!=Web) {
dstHor = qBound(0.0, dstHor, gProgItem->mWidth - mWidth);
dstVer = qBound(0.0, dstVer, gProgItem->mHeight - mHeight);
}
if(fabs(dstHor) < SnapSpace) {
dstHor = 0;
mLRSnap = 1;
} else if(fabs(dstHor - (gProgItem->mWidth - mWidth)) < SnapSpace) {
dstHor = gProgItem->mWidth - mWidth;
mLRSnap = 2;
}if(fabs(dstVer) < SnapSpace) {
dstVer = 0;
mTBSnap = 1;
} else if(fabs(dstVer - (gProgItem->mHeight - mHeight)) < SnapSpace) {
dstVer = gProgItem->mHeight - mHeight;
mTBSnap = 2;
}
if(mLRSnap==0) for(EBase *ele : mOtherEles) {//左右
2022-10-27 15:07:45 +08:00
if(fabs(dstHor - ele->x()) < SnapSpace && ele->x() <= gProgItem->mWidth - mWidth) {
2022-08-25 18:37:24 +08:00
dstHor = ele->x();
mLRSnap = 1;
ele->mLRSnap = 1;
ele->update();
break;
}
auto eleRight = ele->x() + ele->mWidth;
2022-10-27 15:07:45 +08:00
if(fabs(dstHor - eleRight) < SnapSpace && eleRight <= gProgItem->mWidth - mWidth) {
2022-08-25 18:37:24 +08:00
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;
}
}
2024-06-19 18:54:32 +08:00
if(mTBSnap==0) for(EBase *ele : mOtherEles) {//上下
2022-10-27 15:07:45 +08:00
if(fabs(dstVer-ele->y()) < SnapSpace && ele->y() <= gProgItem->mHeight - mHeight) {
2022-08-25 18:37:24 +08:00
dstVer = ele->y();
mTBSnap = 1;
ele->mTBSnap = 1;
ele->update();
break;
}
auto eleBtm = ele->y() + ele->mHeight;
2022-10-27 15:07:45 +08:00
if(fabs(dstVer - eleBtm) < SnapSpace && eleBtm <= gProgItem->mHeight - mHeight) {
2022-08-25 18:37:24 +08:00
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;
2024-06-19 18:54:32 +08:00
if(mType!=Web && gProgItem->mWidth>0 && gProgItem->mHeight>0) {
2022-10-27 15:07:45 +08:00
dstHor = qMin(dstHor, gProgItem->mWidth - x());
dstVer = qMin(dstVer, gProgItem->mHeight - y());
2022-08-25 18:37:24 +08:00
}
setSize(dstHor, dstVer);
} else if(mFrmSec==Qt::RightSection) {
if(dstHor < m_handleLen) dstHor = m_handleLen;
2024-06-19 18:54:32 +08:00
if(mType!=Web && gProgItem->mWidth>0 && gProgItem->mHeight>0) dstHor = qMin(dstHor, gProgItem->mWidth - x());
2022-08-25 18:37:24 +08:00
auto right = x() + dstHor;
2024-06-19 18:54:32 +08:00
if(right < gProgItem->mWidth-8) for(EBase *ele : mOtherEles) {//左右
2022-08-25 18:37:24 +08:00
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;
2024-06-19 18:54:32 +08:00
if(mType!=Web && gProgItem->mWidth>0 && gProgItem->mHeight>0) dstVer = qMin(dstVer, gProgItem->mHeight - y());
2022-08-25 18:37:24 +08:00
auto btm = y() + dstVer;
2024-06-19 18:54:32 +08:00
if(btm < gProgItem->mHeight-8) for(EBase *ele : mOtherEles) {//上下
2022-08-25 18:37:24 +08:00
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);
2024-06-19 18:54:32 +08:00
if(mType!=Web && dstHor < 0) dstHor = 0;
if(dstHor > 8) for(EBase *ele : mOtherEles) {//左右
2022-08-25 18:37:24 +08:00
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);
2024-06-19 18:54:32 +08:00
if(mType!=Web && dstVer < 0) dstVer = 0;
if(dstVer > 8) for(EBase *ele : mOtherEles) {//上下
2022-08-25 18:37:24 +08:00
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);
2024-06-19 18:54:32 +08:00
if(mType!=Web) {
2022-08-25 18:37:24 +08:00
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);
2024-06-19 18:54:32 +08:00
if(mType!=Web) {
2022-10-27 15:07:45 +08:00
if(dstHor > gProgItem->mWidth) dstHor = gProgItem->mWidth;
2022-08-25 18:37:24 +08:00
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);
2024-06-19 18:54:32 +08:00
if(mType!=Web) {
2022-08-25 18:37:24 +08:00
if(dstHor < 0) dstHor = 0;
2022-10-27 15:07:45 +08:00
if(dstVer > gProgItem->mHeight) dstVer = gProgItem->mHeight;
2022-08-25 18:37:24 +08:00
}
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();
}
2023-04-18 14:14:46 +08:00
void EBase::addBaseAttrWgt(QBoxLayout *vBox) {
2022-08-25 18:37:24 +08:00
auto spacing = vBox->spacing();
if(spacing < 0) spacing = 0;
2024-02-21 18:08:50 +08:00
if(mMultiWin==0) {
auto hBox = new HBox(vBox);
hBox->addLabel(tr("Area"));
auto line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addSpacing(-spacing-2);
hBox = new HBox(vBox);
hBox->addStretch();
hBox->addLabel(tr("X")+": ");
auto fdX = new QSpinBox;
2024-06-19 18:54:32 +08:00
fdX->setRange(-99999, 999999);
2024-02-21 18:08:50 +08:00
fdX->setValue(x());
connect(fdX, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdX](int value) {
2024-06-19 18:54:32 +08:00
if(type()!=Web) {
int max = gProgItem->mWidth - mWidth;
if(value < 0 || value > max) {
value = max;
fdX->blockSignals(true);
fdX->setValue(value);
fdX->blockSignals(false);
}
2024-02-21 18:08:50 +08:00
}
setX(value);
});
hBox->addWidget(fdX);
hBox->addSpacing(10);
hBox->addLabel(tr("Y")+": ");
auto fdY = new QSpinBox;
2024-06-19 18:54:32 +08:00
fdY->setRange(-99999, 999999);
2024-02-21 18:08:50 +08:00
fdY->setValue(y());
connect(fdY, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdY](int value) {
2024-06-19 18:54:32 +08:00
if(type()!=Web) {
int max = gProgItem->mHeight - mHeight;
if(value < 0 || value > max) {
value = max;
fdY->blockSignals(true);
fdY->setValue(value);
fdY->blockSignals(false);
}
2024-02-21 18:08:50 +08:00
}
setY(value);
});
hBox->addWidget(fdY);
hBox->addStretch();
hBox = new HBox(vBox);
hBox->addStretch();
hBox->addLabel(tr("W")+": ");
auto fdW = new QSpinBox;
fdW->setRange(6, 999999);
fdW->setValue(mWidth);
connect(fdW, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdW](int value) {
2024-06-19 18:54:32 +08:00
if(type()!=Web) {
int max = gProgItem->mWidth - x();
if(value > max) {
value = max;
fdW->blockSignals(true);
fdW->setValue(value);
fdW->blockSignals(false);
}
2024-02-21 18:08:50 +08:00
}
setSize(value, mHeight);
});
hBox->addWidget(fdW);
hBox->addSpacing(10);
hBox->addLabel(tr("H")+": ");
auto fdH = new QSpinBox;
fdH->setRange(6, 999999);
fdH->setValue(mHeight);
connect(fdH, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdH](int value) {
2024-06-19 18:54:32 +08:00
if(type()!=Web) {
int max = gProgItem->mHeight - y();
if(value > max) {
value = max;
fdH->blockSignals(true);
fdH->setValue(value);
fdH->blockSignals(false);
}
2024-02-21 18:08:50 +08:00
}
setSize(mWidth, value);
});
hBox->addWidget(fdH);
hBox->addStretch();
connect(this, &EBase::xChanged, fdX, [this, fdX] {
2022-08-25 18:37:24 +08:00
fdX->blockSignals(true);
2024-02-21 18:08:50 +08:00
fdX->setValue(x());
2022-08-25 18:37:24 +08:00
fdX->blockSignals(false);
2024-02-21 18:08:50 +08:00
});
connect(this, &EBase::yChanged, fdY, [this, fdY] {
2022-08-25 18:37:24 +08:00
fdY->blockSignals(true);
2024-02-21 18:08:50 +08:00
fdY->setValue(y());
2022-08-25 18:37:24 +08:00
fdY->blockSignals(false);
2024-02-21 18:08:50 +08:00
});
connect(this, &EBase::sizeChanged, fdW, [this, fdW, fdH] {
2022-08-25 18:37:24 +08:00
fdW->blockSignals(true);
2024-02-21 18:08:50 +08:00
fdW->setValue(mWidth);
2022-08-25 18:37:24 +08:00
fdW->blockSignals(false);
fdH->blockSignals(true);
2024-02-21 18:08:50 +08:00
fdH->setValue(mHeight);
2022-08-25 18:37:24 +08:00
fdH->blockSignals(false);
2024-02-21 18:08:50 +08:00
});
2022-08-25 18:37:24 +08:00
2024-06-19 18:54:32 +08:00
hBox = new HBox(vBox);
hBox->addStretch();
hBox->addLabel(tr("Rotate")+": ");
auto fdRotate = new QSpinBox;
fdRotate->setRange(0, 359);
fdRotate->setValue(_rotate);
fdRotate->setToolTip("Need Player 2.1.4");
connect(fdRotate, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
_rotate = value;
});
hBox->addWidget(fdRotate);
hBox->addSpacing(-spacing+2);
hBox->addLabel("°");
hBox->addStretch();
vBox->addSpacing(-spacing);
2022-08-25 18:37:24 +08:00
2024-02-21 18:08:50 +08:00
hBox = new HBox(vBox);
hBox->addLabel(tr("Border"));
line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addSpacing(-spacing-2);
hBox = new HBox(vBox);
hBox->setSpacing(2);
hBox->addStretch();
auto borderFd = new QComboBox;
borderFd->addItem(tr("None"));
for(int i=0; i<borderImgs.size(); i++) borderFd->addItem(QIcon(borderImgs[i].img), QString::number(borderImgs[i].img.height()), borderImgs[i].name);
borderFd->setIconSize(QSize(borderImgMaxWidth, borderImgMaxHeight));
if(bdImgIdx>-1) borderFd->setCurrentIndex(bdImgIdx+1);
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->addStretch();
hBox->addLabel(tr("Effect"));
auto borderEffFd = new QComboBox;
borderEffFd->addItem(tr("Rotate"), "rotate");
borderEffFd->addItem(tr("Blink"), "blink");
borderEffFd->addItem(tr("None"), "");
if(bdImgIdx>-1) SetCurData(borderEffFd, bdEff);
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->addStretch();
hBox->addLabel(tr("Speed"));
auto borderSpeedFd = new QComboBox;
borderSpeedFd->addItem(tr("Slow"), 1);
borderSpeedFd->addItem(tr("Moderate"), 2);
borderSpeedFd->addItem(tr("Fast"), 3);
if(bdImgIdx>-1) SetCurData(borderSpeedFd, bdSpeed);
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();
}
if(mType!=Window) {
auto hBox = new HBox(vBox);
hBox->addLabel(tr("Play Time"));
auto line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addSpacing(-spacing-2);
hBox = new HBox(vBox);
hBox->setSpacing(4);
hBox->addStretch();
if(mMultiWin==0) {
hBox->addLabel(tr("Start"));
auto fdStart = new QSpinBox;
fdStart->setRange(0, 9999);
fdStart->setValue(mStartTime);
hBox->addWidget(fdStart);
hBox->addLabel(tr("s"));
hBox->addStretch();
2022-08-25 18:37:24 +08:00
}
2024-02-21 18:08:50 +08:00
hBox->addLabel(tr("Duration"));
fdDuration = new QSpinBox;
fdDuration->setRange(1, 9999);
fdDuration->setValue(mDuration);
hBox->addWidget(fdDuration);
hBox->addLabel(tr("s"));
hBox->addStretch();
hBox = new HBox(vBox);
hBox->addLabel(tr("Effect"));
line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addSpacing(-spacing-2);
auto grid = new Grid(vBox);
grid->setSpacing(4);
int ccc = 0;
grid->setColumnStretch(ccc++, 1);
grid->addLabel(tr("Entry"), 0, ccc++, Qt::AlignRight|Qt::AlignVCenter);
auto fdEntryEff = new QComboBox;
fdEntryEff->addItem(tr("None"), "");
fdEntryEff->addItem(tr("Random"), "Random");
fdEntryEff->addItem(tr("Expand horizontal"), "EXPAND_HOR");
fdEntryEff->addItem(tr("Expand vertical"), "EXPAND_VER");
fdEntryEff->addItem(tr("Expand to left"), "EXPAND_LEFT");
fdEntryEff->addItem(tr("Expand to top"), "EXPAND_TOP");
fdEntryEff->addItem(tr("Expand to right"), "EXPAND_RIGHT");
fdEntryEff->addItem(tr("Expand to bottom"), "EXPAND_BOTTOM");
fdEntryEff->addItem(tr("Zoom in"), "ZOOM");
fdEntryEff->addItem(tr("Zoom in from left-top"), "ZOOM_TL");
fdEntryEff->addItem(tr("Zoom in from right-top"), "ZOOM_TR");
fdEntryEff->addItem(tr("Zoom in from right-bottom"), "ZOOM_BR");
fdEntryEff->addItem(tr("Zoom in from left-bottom"), "ZOOM_BL");
fdEntryEff->addItem(tr("Rotate zoom"), "ROTATE");
fdEntryEff->addItem(tr("Rotate zoom reverse"), "ROTATE_R");
fdEntryEff->addItem(tr("Fade in"), "FADE");
fdEntryEff->addItem(tr("Move to left"), "MOVE_LEFT");
fdEntryEff->addItem(tr("Move to top"), "MOVE_TOP");
fdEntryEff->addItem(tr("Move to right"), "MOVE_RIGHT");
fdEntryEff->addItem(tr("Move to bottom"), "MOVE_BOTTOM");
SetCurData(fdEntryEff, mEntryEffect);
connect(fdEntryEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
mEntryEffect = fdEntryEff->currentData().toString();
});
grid->addWidget(fdEntryEff, 0, ccc++);
grid->setColumnStretch(ccc++, 1);
grid->addLabel(tr("Dur"), 0, ccc++, Qt::AlignRight|Qt::AlignVCenter);
auto fdEntryDur = new QSpinBox;
fdEntryDur->setRange(1, 99);
fdEntryDur->setValue(mEntryDur);
connect(fdEntryDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
mEntryDur = value;
if(mDuration < value) {
mDuration = value;
fdDuration->setValue(value);
}
});
grid->addWidget(fdEntryDur, 0, ccc++);
grid->addLabel(tr("s"), 0, ccc++);
grid->setColumnStretch(ccc, 1);
ccc = 1;
grid->addLabel(tr("Exit"), 1, ccc++, Qt::AlignRight|Qt::AlignVCenter);
auto fdExitEff = new QComboBox;
fdExitEff->addItem(tr("None"), "");
fdExitEff->addItem(tr("Random"), "Random");
fdExitEff->addItem(tr("Expand horizontal"), "EXPAND_HOR");
fdExitEff->addItem(tr("Expand vertical"), "EXPAND_VER");
fdExitEff->addItem(tr("Expand to left"), "EXPAND_LEFT");
fdExitEff->addItem(tr("Expand to top"), "EXPAND_TOP");
fdExitEff->addItem(tr("Expand to right"), "EXPAND_RIGHT");
fdExitEff->addItem(tr("Expand to bottom"), "EXPAND_BOTTOM");
fdExitEff->addItem(tr("Zoom out"), "ZOOM");
fdExitEff->addItem(tr("Zoom out to left-top"), "ZOOM_TL");
fdExitEff->addItem(tr("Zoom out to right-top"), "ZOOM_TR");
fdExitEff->addItem(tr("Zoom out to right-bottom"), "ZOOM_BR");
fdExitEff->addItem(tr("Zoom out to left-bottom"), "ZOOM_BL");
fdExitEff->addItem(tr("Rotate zoom"), "ROTATE");
fdExitEff->addItem(tr("Rotate zoom reverse"), "ROTATE_R");
fdExitEff->addItem(tr("Fade out"), "FADE");
fdExitEff->addItem(tr("Move to left"), "MOVE_LEFT");
fdExitEff->addItem(tr("Move to top"), "MOVE_TOP");
fdExitEff->addItem(tr("Move to right"), "MOVE_RIGHT");
fdExitEff->addItem(tr("Move to bottom"), "MOVE_BOTTOM");
SetCurData(fdExitEff, mExitEffect);
connect(fdExitEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
mExitEffect = fdExitEff->currentData().toString();
});
grid->addWidget(fdExitEff, 1, ccc++);
ccc++;
grid->addLabel(tr("Dur"), 1, ccc++, Qt::AlignRight|Qt::AlignVCenter);
auto fdExitDur = new QSpinBox;
fdExitDur->setRange(1, 99);
fdExitDur->setValue(mExitDur);
connect(fdExitDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
mExitDur = value;
if(mDuration < value) {
mDuration = value;
fdDuration->setValue(value);
}
});
grid->addWidget(fdExitDur, 1, ccc++);
grid->addLabel(tr("s"), 1, ccc++);
connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
mDuration = value;
if(mEntryDur > value) {
mEntryDur = value;
fdEntryDur->setValue(value);
}
if(mExitDur > value) {
mExitDur = value;
fdExitDur->setValue(value);
}
});
2024-06-19 18:54:32 +08:00
ccc = 2;
auto fdBlink = new QCheckBox(tr("Blink"));
fdBlink->setChecked(_hasBlink);
fdBlink->setToolTip("Need Player 2.1.4");
connect(fdBlink, &QCheckBox::stateChanged, this, [=](int state) {
_hasBlink = state==Qt::Checked;
});
grid->addWidget(fdBlink, 2, ccc++);
ccc++;
grid->addLabel(tr("Freq"), 2, ccc++, Qt::AlignRight|Qt::AlignVCenter);
auto fdBlinkFreq = new QDoubleSpinBox;
fdBlinkFreq->setDecimals(1);
fdBlinkFreq->setSingleStep(0.1);
fdBlinkFreq->setValue(_blinkFreq);
connect(fdBlinkFreq, (void(QDoubleSpinBox::*)(double))&QDoubleSpinBox::valueChanged, this, [=](double value) {
_blinkFreq = value;
});
grid->addWidget(fdBlinkFreq, 2, ccc++);
grid->addLabel("Hz", 2, ccc++);
2024-02-21 18:08:50 +08:00
}
2022-08-25 18:37:24 +08:00
}