710 lines
26 KiB
C++
710 lines
26 KiB
C++
|
#include "ebase.h"
|
||
|
#include "gqt.h"
|
||
|
#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;
|
||
|
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<qreal>{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; i<borderImgs.size(); i++) if(borderImgs[i].name==bdName) {bdImgIdx = i; break;}
|
||
|
bdEff = json["borderEff"].toString();
|
||
|
bdSpeed = json["borderSpeed"].toInt(2);
|
||
|
} else {
|
||
|
bdName = geometry["border"].toString();
|
||
|
if(! bdName.isEmpty()) {
|
||
|
for(int i=0; i<borderImgs.size(); i++) if(borderImgs[i].name==bdName) {bdImgIdx = i; break;}
|
||
|
bdEff = geometry["border_eff"].toString();
|
||
|
bdSpeed = geometry["border_speed"].toInt(2);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
void EBase::addBaseAttr(QJsonObject &obj) const {
|
||
|
auto ele = mMultiWin!=nullptr ? mMultiWin : this;
|
||
|
int bdWidth = ele->bdImgIdx > -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<EBase*>(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; i<borderImgs.size(); i++) borderFd->addItem(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);
|
||
|
}
|
||
|
}
|