#include "playwin.h" #include "eledigiclock.h" #include "eleanaclock.h" #include "eleborder.h" #include "elegif.h" #include "elemultipng.h" #include "elescroll.h" #include "eletimer.h" #include "elevideo.h" #include "posdlg.h" #include #include #include #include #include #include #include PlayWin* PlayWin::self = 0; QPoint gPlayPos{0, 0}; Page::Page(QWidget *parent) : QWidget{parent} { } PlayWin *PlayWin::newIns(int width, int height, QString dir, const JValue &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 JValue &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); auto pageMaps = aprog["task"]["items"]; EleBase ele; Page *page; for(auto &pageMap : pageMaps) { auto _program = pageMap["_program"]; auto layers = _program["layers"]; if(layers.empty()) continue; auto splitWidths = _program["splitWidths"]; page = new Page(this); page->setGeometry(0, 0, width, height); page->setVisible(false); for(int ll=(int)layers.size()-1; ll>=0; ll--) { auto layer = layers[ll].toObj(); auto repeat = layer["repeat"].toBool(); auto sources = layer["sources"]; auto border = layer["border"]; EleBorder *bdEle = 0; 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(); } for(auto &source : sources) { ele.type = source["_type"].toString(); if(ele.type.isEmpty()) continue; auto timeSpan = source["timeSpan"].toInt()*1000; if(timeSpan==0) continue; ele.x = source["left"].toInt()+bdWidth; ele.y = source["top"].toInt()+bdWidth; ele.w = source["width"].toInt()-bdWidth-bdWidth; ele.h = source["height"].toInt()-bdWidth-bdWidth; bool notAudio = ele.type!="Audio"; if((ele.w<=0 || ele.h<=0) && notAudio) continue; ele.repeat = repeat; ele.startTime = source["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 = source["id"].toString(); ele.wgt = 0; if(ele.type=="Image") { if(source["mime"].toString().endsWith("gif")) ele.wgt = new EleGif(dir+"/"+ele.id, page); else { auto lb = new QLabel(page); lb->setPixmap(QPixmap(dir+"/"+ele.id)); lb->setScaledContents(true); ele.wgt = lb; } } else if(ele.type.startsWith("Environ")) { auto arrayPics = source["arrayPics"]; for(int i=(int)arrayPics.size()-1; i>=0; i--) if(arrayPics[i]["name"].toString() == "previewTmp") { if(source["bSingleScroll"].toBool()) ele.wgt = new EleScroll(page, dir+"/" + arrayPics[i]["id"].toString(), 'l', source["iScrollSpeed"].toDouble()); else ele.wgt = new EleScroll(page, dir+"/"+arrayPics[i]["id"].toString()); break; } } else if(ele.type=="MultiPng") { auto imgs = source["arrayPics"]; if(imgs.empty()) continue; if(imgs.size()==1 && imgs[0]["picDuration"].toInt()==0) ele.wgt = new EleScroll(page, dir+"/", imgs[0]); else ele.wgt = new EleMultiPng(dir+"/", imgs, page); } else if(ele.type=="SplitText") { auto imgs = source["arrayPics"]; if(imgs.empty()) continue; ele.wgt = new QWidget(page); ele.wgt->setGeometry(0, 0, width, height); auto height = _program["height"].toInt(); if(imgs.size()==1 && imgs[0]["picDuration"].toInt()==0) { auto wgt = new EleScroll(ele.wgt, dir+"/", imgs[0]); wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); for(int i=1; i<(int)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.emplace_back(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<(int)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 EleDigiClock(dir+"/", source, page); else if(ele.type=="AnalogClock") ele.wgt = new EleAnaClock(ele.w, ele.h, dir+"/"+ele.id, source, page); else if(ele.type=="Video" || ele.type=="Audio") { auto video = new EleVideo(dir+"/"+ele.id, page); auto vol = source["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(source["url"].toString())); ele.wgt = web; } else if(ele.type=="Timer") ele.wgt = new EleTimer(source, 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.emplace_back(ele); } if(bdEle && ! sources.empty()) { auto geometry = border["geometry"]; 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.emplace_back(ele); } } if(page->timeSpan==0) continue; for(int i=0; ieles.size(); i++) if(page->eles[i].repeat) page->eles[i].endTime = page->timeSpan; pages.emplace_back(page); } setVisible(true); if(! pages.empty()) for(auto& ele : pages[0]->eles) if(ele.startTime > 0 || ele.endTime < pages[0]->timeSpan) { if(ele.startTime > 0) timerMap.insert(startTimer(ele.startTime), TimerValue(ele.wgt, true)); timerMap.insert(startTimer(ele.endTime), TimerValue(ele.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++; auto page = pages[cur]; if(timer) timer->inter = page->timeSpan; for(auto &ele : page->eles) if(ele.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.empty()) { 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 = 0; gPlayPos = pos(); }