2023-04-18 14:14:46 +08:00
|
|
|
#include "playwin.h"
|
|
|
|
#include "digiclock.h"
|
|
|
|
#include "eleanaclock.h"
|
|
|
|
#include "eleborder.h"
|
|
|
|
#include "elegif.h"
|
|
|
|
#include "eleimg.h"
|
|
|
|
#include "elemultipng.h"
|
|
|
|
#include "elescroll.h"
|
|
|
|
#include "eletimer.h"
|
|
|
|
#include "elevideo.h"
|
|
|
|
#include "posdlg.h"
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QJsonArray>
|
|
|
|
#include <QJsonObject>
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QMouseEvent>
|
|
|
|
#include <QMovie>
|
|
|
|
#include <QThread>
|
|
|
|
#include <QWebEngineView>
|
|
|
|
#include <QGuiApplication>
|
|
|
|
|
2023-05-08 09:59:15 +08:00
|
|
|
PlayWin* PlayWin::self = 0;
|
2023-04-18 14:14:46 +08:00
|
|
|
QPoint gPlayPos{0, 0};
|
|
|
|
|
|
|
|
Page::Page(QWidget *parent) : QWidget{parent} {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
PlayWin *PlayWin::newIns(int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) {
|
|
|
|
if(! gPlayPos.isNull() && QGuiApplication::screenAt(QPoint(gPlayPos.x()+width/2, gPlayPos.y()+height/2))==0) gPlayPos = QPoint();
|
|
|
|
return new PlayWin(gPlayPos.x(), gPlayPos.y(), width, height, dir, aprog, parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) : QWidget(parent) {
|
|
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
setAttribute(Qt::WA_QuitOnClose, false);
|
|
|
|
setWindowFlag(Qt::FramelessWindowHint);
|
|
|
|
setWindowFlag(Qt::WindowStaysOnTopHint);
|
|
|
|
setGeometry(x, y, width, height);
|
|
|
|
QPalette plt = palette();
|
|
|
|
plt.setColor(QPalette::Window, QColor(0,0,0));
|
|
|
|
setPalette(plt);
|
|
|
|
connect(this, &PlayWin::sigSetVisible, this, &PlayWin::sltSetVisible);
|
|
|
|
|
|
|
|
const auto pageMaps = aprog["task"]["items"].toArray();
|
|
|
|
int pageCnt = pageMaps.size();
|
|
|
|
EleBase ele; Page *page;
|
|
|
|
for(int p=0; p<pageCnt; p++) {
|
|
|
|
auto _program = pageMaps[p]["_program"].toObject();
|
|
|
|
auto layers = _program["layers"].toArray();
|
|
|
|
if(layers.isEmpty()) continue;
|
|
|
|
auto splitWidths = _program["splitWidths"].toArray();
|
|
|
|
page = new Page(this);
|
|
|
|
page->setGeometry(0, 0, width, height);
|
|
|
|
page->setVisible(false);
|
|
|
|
for(int ll=layers.size()-1; ll>=0; ll--) {
|
2023-04-19 14:42:06 +08:00
|
|
|
auto layer = layers[ll].toObject();
|
2023-04-18 14:14:46 +08:00
|
|
|
auto repeat = layer["repeat"].toBool();
|
2023-04-19 14:42:06 +08:00
|
|
|
auto srcMaps = layer["sources"].toArray();
|
2023-04-18 14:14:46 +08:00
|
|
|
QJsonValue border = layer["border"];
|
2023-04-19 14:42:06 +08:00
|
|
|
EleBorder *bdEle = 0;
|
2023-04-18 14:14:46 +08:00
|
|
|
int bdWidth = 0, bdStart = 0xffff, bdEnd = 0;
|
|
|
|
if(! border.isNull()) {
|
|
|
|
bdEle = new EleBorder(dir+"/"+border["img"].toString(), border["eff"].toString(), border["speed"].toInt(), page);
|
|
|
|
bdWidth = bdEle->img.height();
|
|
|
|
}
|
2023-04-19 14:42:06 +08:00
|
|
|
foreach(QJsonValue srcMap, srcMaps) {
|
2023-04-18 14:14:46 +08:00
|
|
|
ele.type = srcMap["_type"].toString();
|
|
|
|
if(ele.type.isEmpty()) continue;
|
|
|
|
auto timeSpan = srcMap["timeSpan"].toInt()*1000;
|
|
|
|
if(timeSpan==0) continue;
|
|
|
|
ele.x = srcMap["left"].toInt()+bdWidth;
|
|
|
|
ele.y = srcMap["top"].toInt()+bdWidth;
|
|
|
|
ele.w = srcMap["width"].toInt()-bdWidth-bdWidth;
|
|
|
|
ele.h = srcMap["height"].toInt()-bdWidth-bdWidth;
|
|
|
|
bool notAudio = ele.type!="Audio";
|
|
|
|
if((ele.w<=0 || ele.h<=0) && notAudio) continue;
|
|
|
|
ele.repeat = repeat;
|
|
|
|
ele.startTime = srcMap["playTime"].toInt()*1000;
|
|
|
|
if(bdStart > ele.startTime) bdStart = ele.startTime;
|
|
|
|
ele.endTime = ele.startTime + timeSpan;
|
|
|
|
if(bdEnd < ele.endTime) bdEnd = ele.endTime;
|
|
|
|
if(page->timeSpan < ele.endTime && notAudio) page->timeSpan = ele.endTime;
|
|
|
|
ele.id = srcMap["id"].toString();
|
|
|
|
ele.wgt = 0;
|
|
|
|
if(ele.type=="Image") {
|
|
|
|
if(srcMap["mime"].toString().endsWith("gif")) ele.wgt = new EleGif(dir+"/"+ele.id, page);
|
|
|
|
else ele.wgt = new EleImg(dir+"/"+ele.id, page);
|
|
|
|
} else if(ele.type.startsWith("Environ")) {
|
|
|
|
QJsonValue arrayPics = srcMap["arrayPics"];
|
|
|
|
for(int i=arrayPics.toArray().size()-1; i>=0; i--) if(arrayPics[i]["name"].toString() == "previewTmp") {
|
|
|
|
if(srcMap["bSingleScroll"].toBool()) ele.wgt = new EleScroll(page, dir+"/" + arrayPics[i]["id"].toString(), 'l', srcMap["iScrollSpeed"].toDouble());
|
|
|
|
else ele.wgt = new EleScroll(page, dir+"/"+arrayPics[i]["id"].toString());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if(ele.type=="MultiPng") {
|
|
|
|
QJsonArray imgs = srcMap["arrayPics"].toArray();
|
|
|
|
if(imgs.isEmpty()) continue;
|
|
|
|
if(imgs.size()==1 && imgs.at(0)["picDuration"].toInt()==0) ele.wgt = new EleScroll(page, dir+"/", imgs[0].toObject());
|
|
|
|
else ele.wgt = new EleMultiPng(dir+"/", imgs, page);
|
|
|
|
} else if(ele.type=="SplitText") {
|
|
|
|
QJsonArray imgs = srcMap["arrayPics"].toArray();
|
|
|
|
if(imgs.isEmpty()) continue;
|
|
|
|
ele.wgt = new QWidget(page);
|
|
|
|
ele.wgt->setGeometry(0, 0, width, height);
|
|
|
|
auto height = _program["height"].toInt();
|
|
|
|
if(imgs.size()==1 && imgs.at(0)["picDuration"].toInt()==0) {
|
|
|
|
auto wgt = new EleScroll(ele.wgt, dir+"/", imgs[0].toObject());
|
|
|
|
wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
|
|
|
|
for(int i=1; i<splitWidths.size(); i++) {
|
|
|
|
ele.x -= splitWidths[i-1].toInt();
|
|
|
|
ele.y += height;
|
|
|
|
auto split = new EleSplitScroll(ele.wgt, wgt);
|
|
|
|
split->setGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h);
|
|
|
|
wgt->splits.append(split);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
auto wgt = new EleMultiPng(dir+"/", imgs, ele.wgt);
|
|
|
|
wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
|
|
|
|
for(int i=1; i<splitWidths.size(); i++) {
|
|
|
|
ele.x -= splitWidths[i-1].toInt();
|
|
|
|
ele.y += height;
|
|
|
|
auto split = new EleSplitPng(wgt, ele.wgt);
|
|
|
|
split->setGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h);
|
|
|
|
wgt->splits.append(split);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ele.w = 0;
|
|
|
|
} else if(ele.type=="DigitalClockNew") ele.wgt = new DigiClock(dir+"/", srcMap.toObject(), page);
|
|
|
|
else if(ele.type=="AnalogClock") ele.wgt = new EleAnaClock(ele.w, ele.h, dir+"/"+ele.id, srcMap.toObject(), page);
|
|
|
|
else if(ele.type=="Video" || ele.type=="Audio") {
|
|
|
|
auto video = new EleVideo(dir+"/"+ele.id, page);
|
|
|
|
auto vol = srcMap["vol"].toInt(100);
|
|
|
|
if(vol<100) video->player->setVol(vol/100.0);
|
|
|
|
ele.wgt = video;
|
|
|
|
} else if(ele.type=="WebURL") {
|
|
|
|
auto web = new QWebEngineView(page);
|
|
|
|
web->load(QUrl(srcMap["url"].toString()));
|
|
|
|
ele.wgt = web;
|
|
|
|
}
|
|
|
|
else if(ele.type=="Timer") ele.wgt = new EleTimer(srcMap.toObject(), page);
|
|
|
|
else continue;
|
|
|
|
if(ele.wgt==0) continue;
|
|
|
|
if(ele.startTime>0) ele.wgt->setVisible(false);
|
|
|
|
if(ele.w) ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
|
|
|
|
page->eles.append(ele);
|
|
|
|
}
|
|
|
|
if(bdEle && ! srcMaps.isEmpty()) {
|
|
|
|
QJsonArray geometry = border["geometry"].toArray();
|
|
|
|
ele.x = geometry[0].toInt();
|
|
|
|
ele.y = geometry[1].toInt();
|
|
|
|
ele.w = geometry[2].toInt();
|
|
|
|
ele.h = geometry[3].toInt();
|
|
|
|
ele.startTime = bdStart;
|
|
|
|
ele.endTime = bdEnd;
|
|
|
|
ele.wgt = bdEle;
|
|
|
|
if(ele.startTime>0) ele.wgt->setVisible(false);
|
|
|
|
ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
|
|
|
|
page->eles.append(ele);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(page->timeSpan==0) continue;
|
|
|
|
for(int i=0; i<page->eles.size(); i++) if(page->eles[i].repeat) page->eles[i].endTime = page->timeSpan;
|
|
|
|
pages.append(page);
|
|
|
|
}
|
|
|
|
setVisible(true);
|
|
|
|
if(! pages.isEmpty()) {
|
|
|
|
Page* page0 = pages[0];
|
|
|
|
EleBase* eleptr;
|
|
|
|
for(int ee=0; ee<page0->eles.size(); ee++) if((eleptr = &page0->eles[ee])->startTime > 0 || eleptr->endTime < page0->timeSpan) {
|
|
|
|
if(eleptr->startTime > 0) timerMap.insert(startTimer(eleptr->startTime), TimerValue(eleptr->wgt, true));
|
|
|
|
timerMap.insert(startTimer(eleptr->endTime), TimerValue(eleptr->wgt, false));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
menu = new QMenu(this);
|
|
|
|
auto act = menu->addAction(tr("Move to Top Left"));
|
|
|
|
connect(act, &QAction::triggered, this, [this] {
|
|
|
|
move(0,0);
|
|
|
|
});
|
|
|
|
act = menu->addAction(tr("Set Position"));
|
|
|
|
connect(act, &QAction::triggered, this, [this] {
|
|
|
|
PosDlg dlg(this);
|
|
|
|
dlg.exec();
|
|
|
|
});
|
|
|
|
act = menu->addAction(tr("Close"));
|
|
|
|
connect(act, &QAction::triggered, this, [this] {
|
|
|
|
if(self==this) self = nullptr;
|
|
|
|
close();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
void PlayWin::sltNext() {
|
|
|
|
if(isVisible()) {
|
|
|
|
pages[cur]->setVisible(false);
|
|
|
|
if(cur+2 > pages.size()) cur = 0;
|
|
|
|
else cur++;
|
|
|
|
Page* page = pages[cur];
|
|
|
|
if(timer) timer->inter = page->timeSpan;
|
|
|
|
EleBase* ele;
|
|
|
|
for(int ee=0; ee<page->eles.size(); ee++) if((ele = &page->eles[ee])->startTime > 0 || ele->endTime < page->timeSpan) {
|
|
|
|
if(ele->startTime > 0) timerMap.insert(startTimer(ele->startTime), TimerValue(ele->wgt, true));
|
|
|
|
else ele->wgt->setVisible(true);
|
|
|
|
timerMap.insert(startTimer(ele->endTime), TimerValue(ele->wgt, false));
|
|
|
|
}
|
|
|
|
page->setVisible(true);
|
|
|
|
} else if(timer) {
|
|
|
|
timer->stop();
|
|
|
|
timer = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void PlayWin::timerEvent(QTimerEvent *e){
|
|
|
|
int id = e->timerId();
|
|
|
|
killTimer(id);
|
|
|
|
TimerValue value = timerMap[id];
|
|
|
|
if(value.ele) {
|
|
|
|
timerMap.remove(id);
|
|
|
|
value.ele->setVisible(value.visible);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void PlayWin::paintEvent(QPaintEvent *e){
|
|
|
|
if(timer==0 && isVisible() && ! pages.isEmpty()) {
|
|
|
|
if(cur!=0) {
|
|
|
|
pages[cur]->setVisible(false);
|
|
|
|
cur = 0;
|
|
|
|
}
|
|
|
|
pages[cur]->setVisible(true);
|
|
|
|
timer = new SyncTimer(pages[cur]->timeSpan);
|
|
|
|
connect(timer, &SyncTimer::timeout, this, &PlayWin::sltNext, Qt::BlockingQueuedConnection);
|
|
|
|
timer->start();
|
|
|
|
}
|
|
|
|
QWidget::paintEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayWin::mousePressEvent(QMouseEvent *e) {
|
|
|
|
if(e->button() == Qt::LeftButton) {
|
|
|
|
mPressRel = pos() - e->globalPos();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void PlayWin::mouseReleaseEvent(QMouseEvent *e) {
|
|
|
|
if(e->button() == Qt::LeftButton) mPressRel.setX(INT_MAX);
|
|
|
|
}
|
|
|
|
void PlayWin::mouseMoveEvent(QMouseEvent *e) {
|
|
|
|
if(e->buttons() & Qt::LeftButton) {
|
|
|
|
if(mPressRel.x()==INT_MAX) return;
|
|
|
|
move(mPressRel + e->globalPos());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void PlayWin::leaveEvent(QEvent *) {
|
|
|
|
mPressRel.setX(INT_MAX);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayWin::contextMenuEvent(QContextMenuEvent *event){
|
|
|
|
menu->exec(event->globalPos());
|
|
|
|
}
|
|
|
|
void PlayWin::closeEvent(QCloseEvent *) {
|
|
|
|
if(self==this) self = nullptr;
|
|
|
|
gPlayPos = pos();
|
|
|
|
}
|