From ee21693f2c3b8db0ef6913b091838813bc171f71 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 17 Apr 2022 21:17:58 -0400 Subject: [PATCH] Improve news banner Now it properly "slideshows" just like the real client, instead of being a static image like it was before. The banners are now clickable, but there's still a bug causing the controls to be reloaded twice on startup - delaying the first animation. --- CMakeLists.txt | 4 +- include/bannerwidget.h | 17 ++++ include/launcherwindow.h | 11 ++- src/bannerwidget.cpp | 17 ++++ src/launcherwindow.cpp | 176 +++++++++++++++++++++++++-------------- 5 files changed, 160 insertions(+), 65 deletions(-) create mode 100644 include/bannerwidget.h create mode 100644 src/bannerwidget.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 89a6c86..9b614e2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,9 @@ set(SRC src/gameinstaller.cpp src/encryptedarg.cpp src/aboutwindow.cpp - include/aboutwindow.h) + include/aboutwindow.h + src/bannerwidget.cpp + include/bannerwidget.h) include(FetchContent) diff --git a/include/bannerwidget.h b/include/bannerwidget.h new file mode 100644 index 0000000..c9f4044 --- /dev/null +++ b/include/bannerwidget.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +class BannerWidget : public QLabel { +public: + BannerWidget(); + + void setUrl(QUrl url); + +protected: + void mousePressEvent(QMouseEvent *event) override; + + private: + QUrl url; +}; \ No newline at end of file diff --git a/include/launcherwindow.h b/include/launcherwindow.h index 1c4c120..6853db2 100644 --- a/include/launcherwindow.h +++ b/include/launcherwindow.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "launchercore.h" #include "headline.h" @@ -25,6 +26,8 @@ public slots: void reloadControls(); private: + void reloadNews(); + LauncherCore& core; Headline headline; @@ -34,8 +37,14 @@ private: QGridLayout* layout; QFormLayout* loginLayout; - QLabel* bannerImageView; + QScrollArea* bannerScrollArea; + QWidget* bannerParentWidget; + QHBoxLayout* bannerLayout; QTreeWidget* newsListView; + QTimer* bannerTimer = nullptr; + int currentBanner = 0; + + std::vector bannerWidgets; QAction* launchOfficial; QAction* launchSysInfo; diff --git a/src/bannerwidget.cpp b/src/bannerwidget.cpp new file mode 100644 index 0000000..58f847a --- /dev/null +++ b/src/bannerwidget.cpp @@ -0,0 +1,17 @@ +#include "bannerwidget.h" + +#include +#include + +BannerWidget::BannerWidget() : QLabel() { + setCursor(Qt::CursorShape::PointingHandCursor); +} + +void BannerWidget::mousePressEvent(QMouseEvent* event) { + qDebug() << "Clicked!"; + QDesktopServices::openUrl(url); +} + +void BannerWidget::setUrl(QUrl url) { + this->url = url; +} diff --git a/src/launcherwindow.cpp b/src/launcherwindow.cpp index 5883f37..8c676d4 100644 --- a/src/launcherwindow.cpp +++ b/src/launcherwindow.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "settingswindow.h" #include "squareboot.h" @@ -19,6 +21,7 @@ #include "config.h" #include "aboutwindow.h" #include "gameinstaller.h" +#include "bannerwidget.h" #include "encryptedarg.h" LauncherWindow::LauncherWindow(LauncherCore& core, QWidget* parent) : QMainWindow(parent), core(core) { @@ -181,13 +184,24 @@ LauncherWindow::LauncherWindow(LauncherCore& core, QWidget* parent) : QMainWindo layout = new QGridLayout(); - bannerImageView = new QLabel(); + bannerScrollArea = new QScrollArea(); + bannerLayout = new QHBoxLayout(); + bannerLayout->setContentsMargins(0, 0, 0, 0); + bannerLayout->setSpacing(0); + bannerLayout->setSizeConstraint(QLayout::SizeConstraint::SetMinAndMaxSize); + bannerParentWidget = new QWidget(); + bannerParentWidget->setFixedHeight(250); + bannerScrollArea->setFixedWidth(640); + bannerScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + bannerScrollArea->verticalScrollBar()->setEnabled(false); + bannerScrollArea->horizontalScrollBar()->setEnabled(false); + + bannerScrollArea->setWidget(bannerParentWidget); + bannerParentWidget->setLayout(bannerLayout); newsListView = new QTreeWidget(); newsListView->setColumnCount(2); newsListView->setHeaderLabels({"Title", "Date"}); - //newsListView->header()->setStretchLastSection(true); - //newsListView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); connect(newsListView, &QTreeWidget::itemClicked, [](QTreeWidgetItem* item, int column) { auto url = item->data(0, Qt::UserRole).toUrl(); qInfo() << "clicked" << url; @@ -282,6 +296,11 @@ LauncherWindow::LauncherWindow(LauncherCore& core, QWidget* parent) : QMainWindo QCoreApplication::quit(); }); + getHeadline(core,[&](Headline headline) { + this->headline = headline; + reloadNews(); + }); + reloadControls(); } @@ -375,8 +394,8 @@ void LauncherWindow::reloadControls() { wineCfg->setEnabled(currentProfile().isWineInstalled()); #endif - layout->removeWidget(bannerImageView); - bannerImageView->hide(); + layout->removeWidget(bannerScrollArea); + bannerScrollArea->hide(); layout->removeWidget(newsListView); newsListView->hide(); @@ -405,11 +424,23 @@ void LauncherWindow::reloadControls() { registerButton->show(); } + reloadNews(); + + currentlyReloadingControls = false; +} + +void LauncherWindow::reloadNews() { if(core.appSettings.showBanners || core.appSettings.showNewsList) { + for(auto widget : bannerWidgets) { + bannerLayout->removeWidget(widget); + } + + bannerWidgets.clear(); + int totalRow = 0; if(core.appSettings.showBanners) { - bannerImageView->show(); - layout->addWidget(bannerImageView, totalRow++, 0); + bannerScrollArea->show(); + layout->addWidget(bannerScrollArea, totalRow++, 0); } if(core.appSettings.showNewsList) { @@ -419,77 +450,96 @@ void LauncherWindow::reloadControls() { newsListView->clear(); - getHeadline(core, [&](Headline headline) { - this->headline = headline; - - if (!headline.banner.empty()) { - if(core.appSettings.showBanners) { - auto request = - QNetworkRequest(headline.banner[0].bannerImage); + if (!headline.banner.empty()) { + if(core.appSettings.showBanners) { + for(auto banner : headline.banner) { + auto request = QNetworkRequest(banner.bannerImage); core.buildRequest(currentProfile(), request); auto reply = core.mgr->get(request); connect(reply, &QNetworkReply::finished, [=] { + auto bannerImageView = new BannerWidget(); + bannerImageView->setUrl(banner.link); + QPixmap pixmap; pixmap.loadFromData(reply->readAll()); bannerImageView->setPixmap(pixmap); + + bannerLayout->addWidget(bannerImageView); + bannerWidgets.push_back(bannerImageView); }); } - if(core.appSettings.showNewsList) { - QTreeWidgetItem* newsItem = new QTreeWidgetItem( - (QTreeWidgetItem*)nullptr, QStringList("News")); - for (auto news : headline.news) { - QTreeWidgetItem* item = new QTreeWidgetItem(); - item->setText(0, news.title); - item->setText(1, QLocale().toString( - news.date, QLocale::ShortFormat)); - item->setData(0, Qt::UserRole, news.url); + if(bannerTimer == nullptr) { + bannerTimer = new QTimer(); + connect(bannerTimer, &QTimer::timeout, this, [=] { + if (currentBanner >= headline.banner.size()) + currentBanner = 0; - newsItem->addChild(item); - } + bannerScrollArea->ensureVisible( + 640 * (currentBanner + 1), 0, 0, 0); - QTreeWidgetItem* pinnedItem = new QTreeWidgetItem( - (QTreeWidgetItem*)nullptr, QStringList("Pinned")); - for (auto pinned : headline.pinned) { - QTreeWidgetItem* item = new QTreeWidgetItem(); - item->setText(0, pinned.title); - item->setText(1, - QLocale().toString(pinned.date, - QLocale::ShortFormat)); - item->setData(0, Qt::UserRole, pinned.url); - - pinnedItem->addChild(item); - } - - QTreeWidgetItem* topicsItem = new QTreeWidgetItem( - (QTreeWidgetItem*)nullptr, QStringList("Topics")); - for (auto news : headline.topics) { - QTreeWidgetItem* item = new QTreeWidgetItem(); - item->setText(0, news.title); - item->setText(1, QLocale().toString( - news.date, QLocale::ShortFormat)); - item->setData(0, Qt::UserRole, news.url); - - qInfo() << news.url; - - topicsItem->addChild(item); - } - - newsListView->insertTopLevelItems( - 0, QList( - {newsItem, pinnedItem, topicsItem})); - - for (int i = 0; i < 3; i++) { - newsListView->expandItem(newsListView->topLevelItem(i)); - newsListView->resizeColumnToContents(i); - } + currentBanner++; + }); + bannerTimer->start(5000); + } + } else { + if(bannerTimer != nullptr) { + bannerTimer->stop(); + bannerTimer->deleteLater(); + bannerTimer = nullptr; } } - }); - } - currentlyReloadingControls = false; + if(core.appSettings.showNewsList) { + QTreeWidgetItem* newsItem = new QTreeWidgetItem( + (QTreeWidgetItem*)nullptr, QStringList("News")); + for (auto news : headline.news) { + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0, news.title); + item->setText(1, QLocale().toString( + news.date, QLocale::ShortFormat)); + item->setData(0, Qt::UserRole, news.url); + + newsItem->addChild(item); + } + + QTreeWidgetItem* pinnedItem = new QTreeWidgetItem( + (QTreeWidgetItem*)nullptr, QStringList("Pinned")); + for (auto pinned : headline.pinned) { + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0, pinned.title); + item->setText(1, + QLocale().toString(pinned.date, + QLocale::ShortFormat)); + item->setData(0, Qt::UserRole, pinned.url); + + pinnedItem->addChild(item); + } + + QTreeWidgetItem* topicsItem = new QTreeWidgetItem( + (QTreeWidgetItem*)nullptr, QStringList("Topics")); + for (auto news : headline.topics) { + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0, news.title); + item->setText(1, QLocale().toString( + news.date, QLocale::ShortFormat)); + item->setData(0, Qt::UserRole, news.url); + + topicsItem->addChild(item); + } + + newsListView->insertTopLevelItems( + 0, QList( + {newsItem, pinnedItem, topicsItem})); + + for (int i = 0; i < 3; i++) { + newsListView->expandItem(newsListView->topLevelItem(i)); + newsListView->resizeColumnToContents(i); + } + } + } + } } void LauncherWindow::openPath(const QString path) {