culturered_client/ProjectorDisplay/MainWindow.cpp
2024-09-07 11:34:44 +08:00

502 lines
17 KiB
C++

#include "MainWindow.h"
#include <QMessageBox>
#include <QWidget>
#include <QScreen>
#include <QApplication>
#include <QDebug>
#include <QHostAddress>
#include <QKeyEvent>
#include <QSettings>
#include "FileHelper.h"
#include "ScreenWidget.h"
#include "DisplayMovieWidget.h"
#include "DisplayMovieGLWidget.h"
#include "TcpClient.h"
#include "TokenRequest.h"
#include "MediaPlayer.h"
MainWindow* mainWindow = nullptr;
MainWindow& MainWindow::Get() {
return *mainWindow;
}
MainWindow::MainWindow(const QStringList& fontFamily, QWidget *parent) :
QMainWindow(parent),
m_fontFamily(fontFamily)
{
mainWindow = this;
setWindowFlags(Qt::FramelessWindowHint);
const QString configPath = QApplication::applicationDirPath() + "/ProjectDisplay/config.ini";
QSettings setting(configPath, QSettings::IniFormat);
int value = setting.value("screen/mainScreenX", 0).toInt();
m_mainScreen.setX(value);
value = setting.value("screen/mainScreenY", 0).toInt();
m_mainScreen.setY(value);
value = setting.value("screen/mainScreenWidth", 1920).toInt();
m_mainScreen.setWidth(value);
value = setting.value("screen/mainScreenHeight", 1080).toInt();
m_mainScreen.setHeight(value);
qDebug() << "mainScreen:" << m_mainScreen;
value = setting.value("screen/projectX", 0).toInt();
m_projectScreen.setX(value);
value = setting.value("screen/projectY", 0).toInt();
m_projectScreen.setY(value);
value = setting.value("screen/projectWidth", 1920).toInt();
m_projectScreen.setWidth(value);
value = setting.value("screen/projectHeight", 1080).toInt();
m_projectScreen.setHeight(value);
qDebug() << "projectScreen:" << m_projectScreen;
value = setting.value("screen/textX", 3040).toInt();
m_textRect.setX(value);
value = setting.value("screen/textY", 800).toInt();
m_textRect.setY(value);
value = setting.value("screen/textWidth", 600).toInt();
m_textRect.setWidth(value);
value = setting.value("screen/textHeight", 500).toInt();
m_textRect.setHeight(value);
qDebug() << "textRect:" << m_textRect;
value = setting.value("screen/imageWidth", 1960).toInt();
m_imageSize.setWidth(value);
value = setting.value("screen/imageHeight", 1100).toInt();
m_imageSize.setHeight(value);
qDebug() << "imageSize:" << m_imageSize;
m_delayRestore = setting.value("screen/delay", "20").toInt();
m_delayCricle = setting.value("screen/cricle", "40").toInt();
QRect movieRect;
movieRect.setX(setting.value("movie/x", 0).toInt());
movieRect.setY(setting.value("movie/y", 0).toInt());
movieRect.setWidth(setting.value("movie/width", 640).toInt());
movieRect.setHeight(setting.value("movie/height", 480).toInt());
qDebug() << "movieRect:" << movieRect;
m_moviePath = setting.value("movie/path").toString();
qDebug() << "moviePath:" << m_moviePath;
m_wavName = setting.value("movie/wav", "").toString();
bool success = FileHelper::GetItemFromJsonConfig(&m_config);
if (!success) {
QMessageBox::warning(this, tr("error"), tr("read config failed"));
exit(-1);
}
QString ip = setting.value("network/ip", "127.0.0.1").toString();;
qDebug() << "ip:" << ip;
int port = setting.value("network/port", 0).toInt();
qDebug() << "port:" << port;
int localPort = setting.value("network/localPort", 0).toInt();
qDebug() << "localPort:" << localPort;
/*int boardcastPort = 8527;
success = m_udpSocket.bind(QHostAddress::AnyIPv4, boardcastPort, QUdpSocket::ShareAddress);
if (!success) {
qDebug() << "bind port failed "<< boardcastPort;
QMessageBox::warning(this, tr("error"), tr("bind port failed"));
exit(1);
}*/
//m_tcpClient = new TcpClient(this);
//connect(m_tcpClient, &TcpClient::MessageReceivered, this, &MainWindow::OnMessage);
//QString serverHost = QString("%1:%2").arg(ip).arg(port);
//m_tcpClient->ConnectToServer(serverHost);
if (!zmqServer_.Start(port)) {
qDebug() << "QMainServer::Start listen failed" << port;
return;
}
connect(&zmqServer_, &ZMQServer::MessageReady, this, &MainWindow::OnMessage);
m_udpSocket.bind(QHostAddress::AnyIPv4, localPort);
connect(&m_udpSocket, &QUdpSocket::readyRead, this, [=]() {
QByteArray buffer;
buffer.resize(m_udpSocket.pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
m_udpSocket.readDatagram(buffer.data(), buffer.size(),
&sender, &senderPort);
QString message(buffer);
if (message == "play_movie") {
PlayMovie();
}
}
);
QList<QScreen*> screens = QGuiApplication::screens();
if (screens.size() >= 2) {
QScreen* primaryScreen = screens[0];
QRect rect1 = screens[0]->geometry();
QRect rect2 = screens[1]->geometry();
//QRect rect(0, 0, rect1.width() + rect2.width(), rect1.height() + rect2.height());
QRect rect(0, 0, rect1.width() + 1, rect1.height() + 1);
setGeometry(rect);
qDebug() << "main rect:" << rect;
m_glWidget = new DisplayMovieGLWidget;
m_cmdReceivers.append(m_glWidget);
//DisplayMovieWidget* glWidget = new DisplayMovieWidget;
//m_widgets.append(widget1);
setCentralWidget(m_glWidget);
//const QString path2 = (items.begin() + 1).value();
ScreenWidget* widget = new ScreenWidget();
connect(m_glWidget, &DisplayMovieGLWidget::AlphaChanged, widget, &ScreenWidget::OnAlphaChanged);
m_cmdReceivers.append(widget);
m_projectWidget = widget;
m_projectWidget->setGeometry(screens[screens.count() - 1]->geometry());
m_projectWidget->show();
// m_projectWidget->setWindowFlags(Qt::FramelessWindowHint);
//setCentralWidget(m_projectWidget);
qDebug() << "main rect:" << m_projectWidget->geometry();
}
else {
QScreen* screen = screens.at(0);
m_glWidget = new DisplayMovieGLWidget;
m_cmdReceivers.append(m_glWidget);
// glWidget->InitImages();
setCentralWidget(m_glWidget);
const QRect& rect = screen->geometry();
qDebug() << "geometry rect:" << " " << rect;
m_glWidget->setGeometry(rect);
ScreenWidget* widget = new ScreenWidget();
connect(m_glWidget, &DisplayMovieGLWidget::AlphaChanged, widget, &ScreenWidget::OnAlphaChanged);
m_cmdReceivers.append(widget);
m_projectWidget = widget;
// const QRect& rect = screen->geometry();
// qDebug() << "geometry rect:" << " " << rect;
m_projectWidget->setGeometry(rect);
m_projectWidget->show();
// m_projectWidget->setWindowFlags(Qt::FramelessWindowHint);
QScreen* primaryScreen = screens[0];
setGeometry(primaryScreen->geometry());
}
CreateMovieWidget(movieRect);
qApp->installEventFilter(this);
m_soundEngine = irrklang::createIrrKlangDevice();
m_tokenRequest = new TokenRequest(this);
connect(&m_updateTimer, &QTimer::timeout, [this]() {
m_glWidget->OnTimeout();
reinterpret_cast<ScreenWidget*>(m_projectWidget)->OnTimeout();
});
m_updateTimer.start(16);
connect(qApp, &QApplication::screenAdded, this, &MainWindow::ScreenChange);
connect(qApp, &QApplication::screenRemoved, this, &MainWindow::ScreenChange);
connect(qApp, &QApplication::primaryScreenChanged, this, &MainWindow::ScreenChange);
}
MainWindow::~MainWindow() {
qApp->removeEventFilter(this);
if (nullptr != m_projectWidget) {
delete m_projectWidget;
}
//if (nullptr != m_tcpClient) {
// m_tcpClient->Disconnect();
//}
if (nullptr != m_soundEngine) {
m_soundEngine->drop();
m_soundEngine = nullptr;
}
mainWindow = nullptr;
}
void MainWindow::OnMessage(const QString& cmd) {
if (m_playing) {
qDebug() << __FUNCTION__ << "playing movie";
return;
}
for (auto receiver : m_cmdReceivers) {
receiver->OnMessage(cmd);
}
}
void MainWindow::closeEvent(class QCloseEvent* event) {
if (nullptr != m_projectWidget) {
m_projectWidget->close();
}
zmqServer_.Stop();
}
void MainWindow::keyPressEvent(QKeyEvent* event) {
/* DisplayMovieGLWidget* glWidget = (DisplayMovieGLWidget*)centralWidget();
glWidget->ReInit();*/
if (event->key() == Qt::Key_1) {
OnMessage("6|20|0");
} else if (event->key() == Qt::Key_2) {
OnMessage("6|29|0");
} else if (event->key() == Qt::Key_3) {
OnMessage("6|44|0");
} else if (event->key() == Qt::Key_4) {
OnMessage("6|44|1");
}
}
bool MainWindow::eventFilter(QObject* obj, QEvent* event) {
static const char* messageBoxQss = R"(
QMessageBox{
background - color: #F2F2F2;
}
QMessageBox QLabel#qt_msgbox_label{ /* textLabel */
color: #298DFF;
background - color: transparent;
min - width: 240px;
min - height: 40px;
}
QMessageBox QLabel#qt_msgboxex_icon_label{ /* iconLabel */
width: 40px;
height: 40px;
}
QMessageBox QPushButton{
border: 1px solid #298DFF;
border - radius: 3px;
background - color: #F2F2F2;
color: #298DFF;
font - family: "Microsoft YaHei";
font - size: 10pt;
min - width: 70px;
min - height: 25px;
}
QMessageBox QPushButton : hover{
background - color: #298DFF;
color: #F2F2F2;
}
QMessageBox QPushButton : pressed{
background - color: #257FE6;
}
QMessageBox QDialogButtonBox#qt_msgbox_buttonbox{ /* buttonBox */
button - layout: 0; /* 设置QPushButton布局好像没啥作用 */
})";
if (QEvent::KeyRelease == event->type()) {
QKeyEvent* keyEvent = reinterpret_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Escape) {
QMessageBox::StandardButton reply;
QMessageBox messaBox(this);
messaBox.setStyleSheet(QString(messageBoxQss));
messaBox.setButtonText(QMessageBox::Yes, "确定");
messaBox.setButtonText(QMessageBox::No, "取消");
reply = messaBox.question(this, "询问", "确定关闭系统?", QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
qDebug() << "Yes was clicked";
QApplication::quit();
return true;
} else {
qDebug() << "Yes was *not* clicked";
}
}
}
return false;
}
void MainWindow::CreateMovieWidget(const QRect& movieRect) {
m_mediaPlayer = new MediaPlayer(this);
connect(m_mediaPlayer, &MediaPlayer::SignalFrame, m_glWidget, &DisplayMovieGLWidget::OnMoveFrame);
connect(m_mediaPlayer, &MediaPlayer::Stopped, [=]() { m_playing = false; });
/* m_mediaPlayer->setGeometry(movieRect);
m_mediaPlayer->setAttribute(Qt::WA_TranslucentBackground);
m_mediaPlayer->setWindowFlags(Qt::CustomizeWindowHint| Qt::Tool | Qt::FramelessWindowHint | windowFlags());
m_mediaPlayer->hide();
connect(m_mediaPlayer, &MediaPlayer::Stopped, [=]() { m_mediaPlayer->hide(); m_playing = false; });*/
//connect(m_mediaPlayer, &MediaPlayer::mediaStatusChanged, [=](QMediaPlayer::MediaStatus status) {
// if (QMediaPlayer::MediaStatus::EndOfMedia == status || QMediaPlayer::MediaStatus::InvalidMedia == status ||
// QMediaPlayer::MediaStatus::NoMedia == status) {
// qDebug() << __FUNCTION__ << " status: " << status;
// // return;
// m_mediaPlayer->hide();
// m_playing = false;
// }
// }
//);
}
void MainWindow::PlayMovie() {
if (nullptr == m_mediaPlayer) {
qDebug() << __FUNCTION__ << "m_mediaPlayer is nullptr";
return;
}
//m_mediaPlayer->show();
m_mediaPlayer->Stop();
const QString path = QApplication::applicationDirPath() + "/ProjectDisplay/" + m_moviePath;
m_mediaPlayer->Play(path);
m_playing = true;
}
void MainWindow::ScreenChange(QScreen* screen) {
const QList<QScreen*> screens = QApplication::screens();
qDebug() << __FUNCTION__ << "screen:" << screens.count();
if (screens.size() >= 2) {
QScreen* primaryScreen = screens[0];
QRect rect1 = screens[0]->geometry();
QRect rect2 = screens[1]->geometry();
//QRect rect(0, 0, rect1.width() + rect2.width(), rect1.height() + rect2.height());
QRect rect(0, 0, rect1.width() + 1, rect1.height() + 1);
setGeometry(rect);
if (nullptr != m_projectWidget) {
m_projectWidget->setGeometry(screens[screens.count() - 1]->geometry());
m_projectWidget->show();
qDebug() << "m_projectWidget rect:" << rect2;
}
qDebug() << "main rect:" << rect1;
}
}
QString MainWindow::GetTownName(int32_t town) const {
if (!m_config.datas.contains(town)) {
qWarning() << "MainWindow::GetTownName failed town:" << town;
return "";
}
return m_config.datas[town].name;
}
QString MainWindow::GetPlaceName(int32_t town, int32_t place) const {
if (!m_config.datas.contains(town)) {
qWarning() << "MainWindow::GetPlaceName failed town:" << town;
return "";
}
const MedianItem& mediaItem = m_config.datas[town];
if (!mediaItem.datas.contains(place)) {
qWarning() << "MainWindow::GetPlaceName failed place:" << place;
return "";
}
const MediaInfo& mediaInfo = mediaItem.datas[place];
return mediaInfo.button;
}
QString MainWindow::GetTitleName(int32_t town, int32_t place) const {
if (!m_config.datas.contains(town)) {
qWarning() << "MainWindow::GetPlaceName failed town:" << town;
return "";
}
const MedianItem& mediaItem = m_config.datas[town];
if (!mediaItem.datas.contains(place)) {
qWarning() << "MainWindow::GetPlaceName failed place:" << place;
return "";
}
const MediaInfo& mediaInfo = mediaItem.datas[place];
return mediaInfo.name;
}
QString MainWindow::GetImageName(int32_t town, int32_t place, int32_t image) const {
if (!m_config.datas.contains(town)) {
qWarning() << "MainWindow::GetImageName failed town:" << town;
return "";
}
const MedianItem& mediaItem = m_config.datas[town];
if (!mediaItem.datas.contains(place)) {
qWarning() << "MainWindow::GetImageName failed place:" << place;
return "";
}
const MediaInfo& mediaInfo = mediaItem.datas[place];
if (image < 0 || image >= mediaInfo.images.size()) {
qWarning() << "MainWindow::GetImageName failed image:" << image << " image count:" << mediaInfo.images.size();
return "";
}
return mediaInfo.images[image];
}
Scope MainWindow::GetScope(int32_t town, int32_t place) const {
if (!m_config.datas.contains(town)) {
qWarning() << "MainWindow::GetPlaceName failed town:" << town;
return Scope();
}
const MedianItem& mediaItem = m_config.datas[town];
if (!mediaItem.datas.contains(place)) {
qWarning() << "MainWindow::GetPlaceName failed place:" << place;
return Scope();
}
const MediaInfo& mediaInfo = mediaItem.datas[place];
return mediaInfo.scope;
}
void MainWindow::SetScope(int32_t town, int32_t place, const Scope& scope) {
if (!m_config.datas.contains(town)) {
qWarning() << "MainWindow::SetScope failed town:" << town;
return;
}
MedianItem& mediaItem = m_config.datas[town];
if (!mediaItem.datas.contains(place)) {
qWarning() << "MainWindow::SetScope failed place:" << place;
return ;
}
MediaInfo& mediaInfo = mediaItem.datas[place];
mediaInfo.scope = scope;
}
void MainWindow::Adjust() {
setGeometry(m_mainScreen);
m_projectWidget->setGeometry(m_projectScreen);
/* bool isConnected = m_tcpClient->IsConnected();
m_glWidget->SetNetConnectStatus(isConnected);*/
}
void MainWindow::SaveConfig() {
const QString kConfigName = "/ProjectDisplay/config_new.json";
const QString configPath = QApplication::applicationDirPath() + kConfigName;
if (!FileHelper::SaveItemToJsonConfig(&m_config, configPath)) {
QMessageBox::warning(this, "error", "save config error!", QMessageBox::Ok);
}
}
void MainWindow::PlayWav() {
const QString wavPath = QApplication::applicationDirPath() + "/ProjectDisplay/wav/" + m_wavName;
m_soundEngine->play2D(wavPath.toStdString().c_str());
}
void MainWindow::SetNetStatus(int connected) {
if (nullptr != m_glWidget) {
m_glWidget->SetNetConnectStatus(connected);
}
}