From f5649a121fd5908ce9eaa6fa58e79b0599f50913 Mon Sep 17 00:00:00 2001 From: RigoLigoRLC Date: Mon, 6 Sep 2021 20:19:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=BA=94=E7=94=A8=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E7=9A=84=E7=BF=BB=E9=A1=B5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gui/page/spkpageapplist.cpp | 86 +++++++++++++++++++++++++++++++++++-- gui/page/spkpagebase.cpp | 2 +- gui/spkmainwindow.cpp | 29 ++++++++++--- gui/spkstretchlayout.cpp | 26 ++++++----- inc/page/spkpageapplist.h | 23 +++++++++- inc/page/spkpagebase.h | 4 +- inc/spkmainwindow.h | 6 +-- 7 files changed, 148 insertions(+), 28 deletions(-) diff --git a/gui/page/spkpageapplist.cpp b/gui/page/spkpageapplist.cpp index fa7c7f3..65d9073 100644 --- a/gui/page/spkpageapplist.cpp +++ b/gui/page/spkpageapplist.cpp @@ -1,14 +1,50 @@ -#include -#include "inc/page/spkpageapplist.h" +#include "page/spkpageapplist.h" #include "spkutils.h" +#include "spkuimsg.h" namespace SpkUi { SpkPageAppList::SpkPageAppList(QWidget *parent) : SpkPageBase(parent) { - mItemLay = new SpkStretchLayout(this); - mItemLay->setContentsMargins(6, 6, 6, 6); + mAppsWidget = new QWidget; + mAppsArea = new QScrollArea(this); + mMainLay = new QVBoxLayout(this); + mItemLay = new SpkStretchLayout(mAppsWidget); + + mPageSwitchWidget = new QWidget; + mPageSwitchLay = new QHBoxLayout(mPageSwitchWidget); + mBtnPgUp = new QPushButton; + mBtnPgDown = new QPushButton; + mBtnGotoPage = new QPushButton; + mPageInput = new QLineEdit; + mPageValidator = new QIntValidator(mPageInput); + mPageIndicator = new QLabel; + + mPageValidator->setRange(1, 99); + mPageInput->setFixedWidth(50); + mPageInput->setValidator(mPageValidator); + mBtnGotoPage->setText(tr("Goto")); + mBtnPgUp->setText(tr("Previous")); + mBtnPgDown->setText(tr("Next")); + + mPageSwitchLay->addWidget(mPageIndicator); + mPageSwitchLay->addStretch(); + mPageSwitchLay->addWidget(mPageInput); + mPageSwitchLay->addWidget(mBtnGotoPage); + mPageSwitchLay->addWidget(mBtnPgUp); + mPageSwitchLay->addWidget(mBtnPgDown); + + mAppsArea->setWidget(mAppsWidget); + mAppsArea->setWidgetResizable(true); + + mMainLay->addWidget(mAppsArea); + mMainLay->addWidget(mPageSwitchWidget); + setLayout(mMainLay); + + connect(mBtnPgUp, &QPushButton::clicked, this, &SpkPageAppList::PageUp); + connect(mBtnPgDown, &QPushButton::clicked, this, &SpkPageAppList::PageDown); + connect(mBtnGotoPage, &QPushButton::clicked, this, &SpkPageAppList::GotoPage); } void SpkPageAppList::AddApplicationEntry(QString name, QString pkgName, QString description, @@ -78,6 +114,48 @@ namespace SpkUi } } + void SpkPageAppList::SetPageStatus(int total, int current, int itemCount) + { + mCurrentPage = current; + mPageIndicator->setText(tr("Page %1 / %2, %3 apps in total") + .arg(current).arg(total).arg(itemCount)); + mBtnPgUp->setDisabled(current == 1); + mBtnPgDown->setDisabled(total == current || total == 1); + mBtnGotoPage->setDisabled(total == 1); + mPageValidator->setTop(total); + } + + void SpkPageAppList::DisablePageSwitchers() + { + mBtnPgDown->setDisabled(true); + mBtnPgUp->setDisabled(true); + mBtnGotoPage->setDisabled(true); + } + + void SpkPageAppList::PageUp() + { + DisablePageSwitchers(); + emit SwitchListPage(mCategoryId, mCurrentPage - 1); + } + + void SpkPageAppList::PageDown() + { + DisablePageSwitchers(); + emit SwitchListPage(mCategoryId, mCurrentPage + 1); + } + + void SpkPageAppList::GotoPage() + { + if(mPageInput->text().isEmpty()) + return SpkUiMessage::SendStoreNotification(tr("Please enter page number to go to!")); + int page = mPageInput->text().toInt(); + if(page > mPageValidator->top()) + return SpkUiMessage::SendStoreNotification(tr("Page %1 is not a valid page number!") + .arg(page)); + DisablePageSwitchers(); + emit SwitchListPage(mCategoryId, page); + } + void SpkPageAppList::Activated() { RES->Acquire(this, false); diff --git a/gui/page/spkpagebase.cpp b/gui/page/spkpagebase.cpp index 215620d..507890c 100644 --- a/gui/page/spkpagebase.cpp +++ b/gui/page/spkpagebase.cpp @@ -1,7 +1,7 @@ #include "page/spkpagebase.h" -SpkPageBase::SpkPageBase(QWidget *parent) : QScrollArea(parent) +SpkPageBase::SpkPageBase(QWidget *parent) : QWidget(parent) { } diff --git a/gui/spkmainwindow.cpp b/gui/spkmainwindow.cpp index 8bb4e63..d710381 100644 --- a/gui/spkmainwindow.cpp +++ b/gui/spkmainwindow.cpp @@ -89,7 +89,7 @@ void SpkMainWindow::CategoryDataReceived() PopulateCategories(retval.toArray()); } -void SpkMainWindow::EnterCategoryList(int aCategoryId) +void SpkMainWindow::EnterCategoryList(int aCategoryId, int aPage) { // Asynchronously call category API using namespace SpkUtils; @@ -97,12 +97,14 @@ void SpkMainWindow::EnterCategoryList(int aCategoryId) QJsonObject reqData; QJsonDocument reqDoc; reqData.insert("type_id", QJsonValue(aCategoryId)); + reqData.insert("page", QJsonValue(aPage)); reqDoc.setObject(reqData); mCategoryAppListGetReply = STORE->SendApiRequest("application/get_application_list", reqDoc); DeleteReplyLater(mCategoryAppListGetReply); connect(mCategoryAppListGetReply, &QNetworkReply::finished, this, &SpkMainWindow::CategoryListDataReceived); setCursor(Qt::BusyCursor); + ui->PageAppList->SetCurrentCategory(aCategoryId); // AppList needs to remember current category } void SpkMainWindow::CategoryListDataReceived() @@ -122,12 +124,27 @@ void SpkMainWindow::PopulateAppList(QJsonObject appData) { auto w = ui->PageAppList; w->ClearAll(); + static auto err = + [](){ + sErr("Received invalid application list data!"); + SpkUiMessage::SendStoreNotification(tr("An invalid response was received. Please try again!")); + return; + }; + int pgCurrent, pgTotal, totalApps; + + if(appData.contains("currentPage") && appData.value("currentPage").isDouble()) + pgCurrent = appData.value("currentPage").toInt(); + else return err(); + if(appData.contains("totalPages") && appData.value("totalPages").isDouble()) + pgTotal = appData.value("totalPages").toInt(); + else return err(); + if(appData.contains("count") && appData.value("count").isDouble()) + totalApps = appData.value("count").toInt(); + else return err(); + w->SetPageStatus(pgTotal, pgCurrent, totalApps); if(!appData.contains("data") || !appData.value("data").isArray()) - { - sErrPop(tr("Received invalid application list data!")); - return; - } + return err(); auto apps = appData.value("data").toArray(); @@ -165,6 +182,8 @@ void SpkMainWindow::Initialize() { connect(ui->SidebarMgr, &SpkUi::SpkSidebarSelector::SwitchToCategory, this, &SpkMainWindow::EnterCategoryList); + connect(ui->PageAppList, &SpkUi::SpkPageAppList::SwitchListPage, + this, &SpkMainWindow::EnterCategoryList); } // ==================== Main Widget Initialization ==================== diff --git a/gui/spkstretchlayout.cpp b/gui/spkstretchlayout.cpp index 347d3ef..fff292d 100644 --- a/gui/spkstretchlayout.cpp +++ b/gui/spkstretchlayout.cpp @@ -19,21 +19,22 @@ void SpkStretchLayout::addItem(QLayoutItem *item) QSize SpkStretchLayout::sizeHint() const { - int n = mItems.count(); - auto minSize = mItems.isEmpty() ? QSize { 0, 0 } : mItems.first()->minimumSize(); - QSize s { 200, 50 }; // s: Hint - if(n) - s = s.expandedTo(QSize { minSize.width(), minSize.height() * n }); - return s + n * QSize(spacing(), spacing()); + if(mItems.isEmpty()) + return { 300, 300 }; + auto w = geometry().width(); + auto it = mItems.first(); + int countPerLine = w / (it->minimumSize().width() + spacing()); + int lines = ceil((double)mItems.size() / countPerLine); + auto h = static_cast(it->minimumSize().height() * lines + spacing() * lines); + return { w, h }; } QSize SpkStretchLayout::minimumSize() const { - int n = mItems.count(); - auto minSize = mItems.isEmpty() ? QSize { 0, 0 } : mItems.first()->minimumSize(); - QSize s(minSize.width(), minSize.height() * n); - return s + n * QSize(spacing(), spacing()); - + // It works this way, but I honestly have no idea WHY IT WORKS + auto r = sizeHint(); + r.setWidth(300); + return r; } int SpkStretchLayout::count() const @@ -65,6 +66,9 @@ void SpkStretchLayout::setGeometry(const QRect &rect) // Figure out how many at most can we squeeze into one line int countPerLine = w / (itm->minimumSize().width() + spacing()); + if(countPerLine < 1) + countPerLine = 1; + if(countPerLine >= mItems.size()) // All items fit in one line size = itm->minimumSize(); // Won't fit in one line. diff --git a/inc/page/spkpageapplist.h b/inc/page/spkpageapplist.h index 543e503..2133a85 100644 --- a/inc/page/spkpageapplist.h +++ b/inc/page/spkpageapplist.h @@ -1,8 +1,7 @@ #pragma once -#include -#include +#include #include "spkresource.h" #include "spkappitem.h" #include "page/spkpagebase.h" @@ -19,20 +18,40 @@ namespace SpkUi void AddApplicationEntry(QString name, QString pkgName, QString description, QString iconUrl, int appId); void ClearAll(); + void SetPageStatus(int total, int current, int itemCount); + void SetCurrentCategory(int categoryId) { mCategoryId = categoryId; } private: + void DisablePageSwitchers(); public: private: + QVBoxLayout *mMainLay; + QHBoxLayout *mPageSwitchLay; + QPushButton *mBtnPgUp, *mBtnPgDown, *mBtnGotoPage; + QLineEdit *mPageInput; + QScrollArea *mAppsArea; + QLabel *mPageIndicator; + QWidget *mAppsWidget, *mPageSwitchWidget; SpkStretchLayout *mItemLay; QList mAppItemList; + QIntValidator *mPageValidator; + + int mCategoryId, mCurrentPage; + signals: void ApplicationClicked(QString name, QString pkgName); + void SwitchListPage(int categoryId, int page); public slots: void ResourceAcquisitionFinished(int id, ResourceResult result); void Activated(); + + private slots: + void PageUp(); + void PageDown(); + void GotoPage(); }; } diff --git a/inc/page/spkpagebase.h b/inc/page/spkpagebase.h index 7477a8c..90d4d33 100644 --- a/inc/page/spkpagebase.h +++ b/inc/page/spkpagebase.h @@ -1,10 +1,10 @@ #pragma once -#include +#include #include -class SpkPageBase : public QScrollArea +class SpkPageBase : public QWidget { Q_OBJECT public: diff --git a/inc/spkmainwindow.h b/inc/spkmainwindow.h index 872a73f..540bfe6 100644 --- a/inc/spkmainwindow.h +++ b/inc/spkmainwindow.h @@ -99,7 +99,7 @@ namespace SpkUi } mLastSelectedItem = item; if(item->data(column, RoleItemIsCategory).toBool()) - emit SwitchToCategory(item->data(column, RoleItemCategoryPageId).toInt()); + emit SwitchToCategory(item->data(column, RoleItemCategoryPageId).toInt(), 0); else emit SwitchToPage(item->data(column, RoleItemCategoryPageId).toInt()); } @@ -117,7 +117,7 @@ namespace SpkUi } signals: - void SwitchToCategory(int aCategoryId); + void SwitchToCategory(int aCategoryId, int aPage); void SwitchToPage(int aPageId); }; @@ -179,7 +179,7 @@ class SpkMainWindow : public SpkWindow void CategoryDataReceived(); - void EnterCategoryList(int id); + void EnterCategoryList(int aCategoryId, int aPage); void CategoryListDataReceived(); private: