mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-09-23 11:32:21 +08:00
加入应用列表的搜索功能
This commit is contained in:
parent
f5649a121f
commit
f96aa8150a
@ -70,6 +70,7 @@ set(SOURCE_FILES
|
|||||||
inc/spkappitem.h gui/spkappitem.cpp
|
inc/spkappitem.h gui/spkappitem.cpp
|
||||||
inc/spkpopup.h gui/spkpopup.cpp
|
inc/spkpopup.h gui/spkpopup.cpp
|
||||||
inc/spkstretchlayout.h gui/spkstretchlayout.cpp
|
inc/spkstretchlayout.h gui/spkstretchlayout.cpp
|
||||||
|
inc/spkfocuslineedit.h
|
||||||
|
|
||||||
inc/page/spkpagebase.h gui/page/spkpagebase.cpp
|
inc/page/spkpagebase.h gui/page/spkpagebase.cpp
|
||||||
inc/page/spkpageuitest.h gui/page/spkpageuitest.cpp
|
inc/page/spkpageuitest.h gui/page/spkpageuitest.cpp
|
||||||
|
@ -114,9 +114,10 @@ namespace SpkUi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpkPageAppList::SetPageStatus(int total, int current, int itemCount)
|
void SpkPageAppList::SetPageStatus(int total, int current, int itemCount, QString &keyword)
|
||||||
{
|
{
|
||||||
mCurrentPage = current;
|
mCurrentPage = current;
|
||||||
|
mKeyword = keyword;
|
||||||
mPageIndicator->setText(tr("Page %1 / %2, %3 apps in total")
|
mPageIndicator->setText(tr("Page %1 / %2, %3 apps in total")
|
||||||
.arg(current).arg(total).arg(itemCount));
|
.arg(current).arg(total).arg(itemCount));
|
||||||
mBtnPgUp->setDisabled(current == 1);
|
mBtnPgUp->setDisabled(current == 1);
|
||||||
@ -135,13 +136,19 @@ namespace SpkUi
|
|||||||
void SpkPageAppList::PageUp()
|
void SpkPageAppList::PageUp()
|
||||||
{
|
{
|
||||||
DisablePageSwitchers();
|
DisablePageSwitchers();
|
||||||
emit SwitchListPage(mCategoryId, mCurrentPage - 1);
|
if(mKeyword.isEmpty())
|
||||||
|
emit SwitchListPage(mCategoryId, mCurrentPage - 1);
|
||||||
|
else
|
||||||
|
emit SwitchSearchPage(mKeyword, mCurrentPage - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpkPageAppList::PageDown()
|
void SpkPageAppList::PageDown()
|
||||||
{
|
{
|
||||||
DisablePageSwitchers();
|
DisablePageSwitchers();
|
||||||
emit SwitchListPage(mCategoryId, mCurrentPage + 1);
|
if(mKeyword.isEmpty())
|
||||||
|
emit SwitchListPage(mCategoryId, mCurrentPage + 1);
|
||||||
|
else
|
||||||
|
emit SwitchSearchPage(mKeyword, mCurrentPage + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpkPageAppList::GotoPage()
|
void SpkPageAppList::GotoPage()
|
||||||
@ -153,7 +160,10 @@ namespace SpkUi
|
|||||||
return SpkUiMessage::SendStoreNotification(tr("Page %1 is not a valid page number!")
|
return SpkUiMessage::SendStoreNotification(tr("Page %1 is not a valid page number!")
|
||||||
.arg(page));
|
.arg(page));
|
||||||
DisablePageSwitchers();
|
DisablePageSwitchers();
|
||||||
emit SwitchListPage(mCategoryId, page);
|
if(mKeyword.isEmpty())
|
||||||
|
emit SwitchListPage(mCategoryId, page);
|
||||||
|
else
|
||||||
|
emit SwitchSearchPage(mKeyword, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpkPageAppList::Activated()
|
void SpkPageAppList::Activated()
|
||||||
|
@ -116,11 +116,41 @@ void SpkMainWindow::CategoryListDataReceived()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SwitchToPage(SpkUi::PgAppList);
|
SwitchToPage(SpkUi::PgAppList);
|
||||||
PopulateAppList(retval.toObject());
|
PopulateAppList(retval.toObject(), "");
|
||||||
setCursor(Qt::ArrowCursor);
|
setCursor(Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpkMainWindow::PopulateAppList(QJsonObject appData)
|
void SpkMainWindow::SearchKeyword(QString aKeyword, int aPage)
|
||||||
|
{
|
||||||
|
using namespace SpkUtils;
|
||||||
|
VerifySingleRequest(mCategoryAppListGetReply);
|
||||||
|
QJsonObject reqData;
|
||||||
|
QJsonDocument reqDoc;
|
||||||
|
reqData.insert("application_name", QJsonValue(aKeyword));
|
||||||
|
reqData.insert("page", QJsonValue(aPage));
|
||||||
|
reqDoc.setObject(reqData);
|
||||||
|
mCategoryAppListGetReply = STORE->SendApiRequest("application/get_application_list", reqDoc);
|
||||||
|
mCategoryAppListGetReply->setProperty("keyword", aKeyword);
|
||||||
|
DeleteReplyLater(mCategoryAppListGetReply);
|
||||||
|
connect(mCategoryAppListGetReply, &QNetworkReply::finished,
|
||||||
|
this, &SpkMainWindow::SearchDataReceived);
|
||||||
|
setCursor(Qt::BusyCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpkMainWindow::SearchDataReceived()
|
||||||
|
{
|
||||||
|
QJsonValue retval;
|
||||||
|
if(!SpkUtils::VerifyReplyJson(mCategoryAppListGetReply, retval) || !retval.isObject())
|
||||||
|
{
|
||||||
|
sErrPop(tr("Failed to search keyword! Type of retval: %1.").arg(retval.type()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SwitchToPage(SpkUi::PgAppList);
|
||||||
|
PopulateAppList(retval.toObject(), mCategoryAppListGetReply->property("keyword").toString());
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpkMainWindow::PopulateAppList(QJsonObject appData, QString &&keyword)
|
||||||
{
|
{
|
||||||
auto w = ui->PageAppList;
|
auto w = ui->PageAppList;
|
||||||
w->ClearAll();
|
w->ClearAll();
|
||||||
@ -141,7 +171,7 @@ void SpkMainWindow::PopulateAppList(QJsonObject appData)
|
|||||||
if(appData.contains("count") && appData.value("count").isDouble())
|
if(appData.contains("count") && appData.value("count").isDouble())
|
||||||
totalApps = appData.value("count").toInt();
|
totalApps = appData.value("count").toInt();
|
||||||
else return err();
|
else return err();
|
||||||
w->SetPageStatus(pgTotal, pgCurrent, totalApps);
|
w->SetPageStatus(pgTotal, pgCurrent, totalApps, keyword);
|
||||||
|
|
||||||
if(!appData.contains("data") || !appData.value("data").isArray())
|
if(!appData.contains("data") || !appData.value("data").isArray())
|
||||||
return err();
|
return err();
|
||||||
@ -184,6 +214,10 @@ void SpkMainWindow::Initialize()
|
|||||||
this, &SpkMainWindow::EnterCategoryList);
|
this, &SpkMainWindow::EnterCategoryList);
|
||||||
connect(ui->PageAppList, &SpkUi::SpkPageAppList::SwitchListPage,
|
connect(ui->PageAppList, &SpkUi::SpkPageAppList::SwitchListPage,
|
||||||
this, &SpkMainWindow::EnterCategoryList);
|
this, &SpkMainWindow::EnterCategoryList);
|
||||||
|
connect(ui->PageAppList, &SpkUi::SpkPageAppList::SwitchSearchPage,
|
||||||
|
this, &SpkMainWindow::SearchKeyword);
|
||||||
|
connect(ui->SearchEdit, &QLineEdit::returnPressed,
|
||||||
|
[=](){ emit SearchKeyword(ui->SearchEdit->text(), 1); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Main Widget Initialization ====================
|
// ==================== Main Widget Initialization ====================
|
||||||
@ -282,6 +316,45 @@ SpkUi::SpkMainWidget::SpkMainWidget(QWidget *parent) : QFrame(parent)
|
|||||||
HorizontalDivide->addWidget(SideBarRestrictor);
|
HorizontalDivide->addWidget(SideBarRestrictor);
|
||||||
HorizontalDivide->addLayout(VLayMain);
|
HorizontalDivide->addLayout(VLayMain);
|
||||||
|
|
||||||
|
//============ Search Bar ============
|
||||||
|
|
||||||
|
SearchEdit = new SpkFocusLineEdit(this);
|
||||||
|
SearchEdit->setPlaceholderText(tr("Press Enter to search"));
|
||||||
|
SearchEdit->setFixedWidth(30);
|
||||||
|
SearchEdit->setFixedHeight(30);
|
||||||
|
SearchBarAnim = new QTimeLine(300, this);
|
||||||
|
SearchBarAnim->setDuration(300);
|
||||||
|
SearchBarAnim->setEasingCurve(QEasingCurve::OutExpo);
|
||||||
|
SearchBarAnim->setUpdateInterval(20);
|
||||||
|
ActClearSearchBar = SearchEdit->addAction(QIcon(":/icons/clear-input.svg"),
|
||||||
|
QLineEdit::TrailingPosition);
|
||||||
|
ActClearSearchBar->setVisible(false); // Invisible by default
|
||||||
|
ActSearchIcon = SearchEdit->addAction(QIcon(":/icons/search-mini.svg"), QLineEdit::LeadingPosition);
|
||||||
|
connect(SearchEdit, &SpkFocusLineEdit::focusGained,
|
||||||
|
[=](){
|
||||||
|
ActClearSearchBar->setVisible(true);
|
||||||
|
SearchBarAnim->setDirection(QTimeLine::Forward);
|
||||||
|
SearchBarAnim->start();
|
||||||
|
});
|
||||||
|
connect(SearchEdit, &SpkFocusLineEdit::focusLost,
|
||||||
|
[=](){
|
||||||
|
ActClearSearchBar->setVisible(false);
|
||||||
|
SearchBarAnim->setDirection(QTimeLine::Backward);
|
||||||
|
SearchBarAnim->start();
|
||||||
|
});
|
||||||
|
connect(SearchBarAnim, &QTimeLine::valueChanged,
|
||||||
|
[=](qreal v){
|
||||||
|
SearchEdit->setFixedWidth(static_cast<int>(250 * v) + 30);
|
||||||
|
});
|
||||||
|
connect(ActClearSearchBar, &QAction::triggered, [=](){ SearchEdit->clear(); });
|
||||||
|
|
||||||
|
auto space = TitleBar->GetUserSpace();
|
||||||
|
space->addWidget(SearchEdit);
|
||||||
|
space->addStretch();
|
||||||
|
|
||||||
|
|
||||||
|
//============ Pages =============
|
||||||
|
|
||||||
// Red-Black tree based map will be able to sort things
|
// Red-Black tree based map will be able to sort things
|
||||||
QMap<SpkStackedPages, QWidget*> sorter;
|
QMap<SpkStackedPages, QWidget*> sorter;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace SpkUi
|
|||||||
void AddApplicationEntry(QString name, QString pkgName, QString description, QString iconUrl,
|
void AddApplicationEntry(QString name, QString pkgName, QString description, QString iconUrl,
|
||||||
int appId);
|
int appId);
|
||||||
void ClearAll();
|
void ClearAll();
|
||||||
void SetPageStatus(int total, int current, int itemCount);
|
void SetPageStatus(int total, int current, int itemCount, QString &keyword);
|
||||||
void SetCurrentCategory(int categoryId) { mCategoryId = categoryId; }
|
void SetCurrentCategory(int categoryId) { mCategoryId = categoryId; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -40,10 +40,12 @@ namespace SpkUi
|
|||||||
QIntValidator *mPageValidator;
|
QIntValidator *mPageValidator;
|
||||||
|
|
||||||
int mCategoryId, mCurrentPage;
|
int mCategoryId, mCurrentPage;
|
||||||
|
QString mKeyword;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ApplicationClicked(QString name, QString pkgName);
|
void ApplicationClicked(QString name, QString pkgName);
|
||||||
void SwitchListPage(int categoryId, int page);
|
void SwitchListPage(int categoryId, int page);
|
||||||
|
void SwitchSearchPage(QString keyword, int page);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void ResourceAcquisitionFinished(int id, ResourceResult result);
|
void ResourceAcquisitionFinished(int id, ResourceResult result);
|
||||||
|
19
inc/spkfocuslineedit.h
Normal file
19
inc/spkfocuslineedit.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtWidgets/QLineEdit>
|
||||||
|
|
||||||
|
class SpkFocusLineEdit final : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SpkFocusLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void focusInEvent(QFocusEvent *e) override { emit focusGained(); }
|
||||||
|
void focusOutEvent(QFocusEvent *e) override { emit focusLost(); }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void focusGained();
|
||||||
|
void focusLost();
|
||||||
|
};
|
@ -12,8 +12,10 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include "spksidebartree.h" // In place of #include <QTreeWidget>
|
#include "spksidebartree.h" // In place of #include <QTreeWidget>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include "inc/page/spkpageuitest.h"
|
#include <QTimeLine>
|
||||||
#include "inc/page/spkpageapplist.h"
|
#include "spkfocuslineedit.h"
|
||||||
|
#include "page/spkpageuitest.h"
|
||||||
|
#include "page/spkpageapplist.h"
|
||||||
|
|
||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
|
|
||||||
@ -146,6 +148,11 @@ namespace SpkUi
|
|||||||
|
|
||||||
QTreeWidgetItem *CategoryParentItem;
|
QTreeWidgetItem *CategoryParentItem;
|
||||||
|
|
||||||
|
// Title bar search bar
|
||||||
|
SpkFocusLineEdit *SearchEdit;
|
||||||
|
QAction *ActClearSearchBar, *ActSearchIcon;
|
||||||
|
QTimeLine *SearchBarAnim;
|
||||||
|
|
||||||
//Pages
|
//Pages
|
||||||
SpkPageUiTest *PageQssTest;
|
SpkPageUiTest *PageQssTest;
|
||||||
SpkPageAppList *PageAppList;
|
SpkPageAppList *PageAppList;
|
||||||
@ -178,10 +185,13 @@ class SpkMainWindow : public SpkWindow
|
|||||||
void SwitchToPage(SpkUi::SpkStackedPages page);
|
void SwitchToPage(SpkUi::SpkStackedPages page);
|
||||||
|
|
||||||
void CategoryDataReceived();
|
void CategoryDataReceived();
|
||||||
|
// Enter a category (and switch pages)
|
||||||
void EnterCategoryList(int aCategoryId, int aPage);
|
void EnterCategoryList(int aCategoryId, int aPage);
|
||||||
void CategoryListDataReceived();
|
void CategoryListDataReceived();
|
||||||
|
// Search a keyword (and switch pages)
|
||||||
|
void SearchKeyword(QString aKeyword, int aPage);
|
||||||
|
void SearchDataReceived();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PopulateAppList(QJsonObject appData);
|
void PopulateAppList(QJsonObject appData, QString &&keyword);
|
||||||
};
|
};
|
||||||
|
@ -9,5 +9,7 @@
|
|||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>icons/spark-store.svg</file>
|
<file>icons/spark-store.svg</file>
|
||||||
<file>icons/settings-dark.svg</file>
|
<file>icons/settings-dark.svg</file>
|
||||||
|
<file>icons/clear-input.svg</file>
|
||||||
|
<file>icons/search-mini.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user