mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-12-13 04:12:03 +08:00
加入应用列表的翻页功能
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "page/spkpagebase.h"
|
||||
|
||||
SpkPageBase::SpkPageBase(QWidget *parent) : QScrollArea(parent)
|
||||
SpkPageBase::SpkPageBase(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -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 ====================
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QScrollArea>
|
||||
#include <QtWidgets>
|
||||
#include <spkresource.h>
|
||||
|
||||
class SpkPageBase : public QScrollArea
|
||||
class SpkPageBase : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user