加入应用列表的翻页功能

This commit is contained in:
RigoLigoRLC
2021-09-06 20:19:52 +08:00
parent 4ede620e71
commit f5649a121f
7 changed files with 148 additions and 28 deletions

View File

@@ -1,14 +1,50 @@
#include <page/spkpageapplist.h>
#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);

View File

@@ -1,7 +1,7 @@
#include "page/spkpagebase.h"
SpkPageBase::SpkPageBase(QWidget *parent) : QScrollArea(parent)
SpkPageBase::SpkPageBase(QWidget *parent) : QWidget(parent)
{
}

View File

@@ -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 ====================

View File

@@ -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<int>(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.

View File

@@ -1,8 +1,7 @@
#pragma once
#include <QScrollArea>
#include <QList>
#include <QtWidgets>
#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<SpkAppItem *> 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();
};
}

View File

@@ -1,10 +1,10 @@
#pragma once
#include <QScrollArea>
#include <QtWidgets>
#include <spkresource.h>
class SpkPageBase : public QScrollArea
class SpkPageBase : public QWidget
{
Q_OBJECT
public:

View File

@@ -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: