From c2791f39758194d4aa73a6fe6956aff8bb966da7 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Mon, 1 Jul 2024 16:04:32 +0000 Subject: [PATCH] homescreens/folio: Add applications drawer search bar Add a search bar to the applications drawer, to allow for quickly filtering apps. --- .../folio/applicationlistmodel.cpp | 17 ++++++- .../homescreens/folio/applicationlistmodel.h | 9 ++++ containments/homescreens/folio/homescreen.cpp | 7 +++ containments/homescreens/folio/homescreen.h | 4 ++ .../folio/package/contents/ui/AppDrawer.qml | 3 +- .../package/contents/ui/AppDrawerGrid.qml | 2 +- .../package/contents/ui/AppDrawerHeader.qml | 51 ++++++++++++++++--- .../folio/package/contents/ui/HomeScreen.qml | 4 +- 8 files changed, 85 insertions(+), 12 deletions(-) diff --git a/containments/homescreens/folio/applicationlistmodel.cpp b/containments/homescreens/folio/applicationlistmodel.cpp index 8cdb17d9..4a517876 100644 --- a/containments/homescreens/folio/applicationlistmodel.cpp +++ b/containments/homescreens/folio/applicationlistmodel.cpp @@ -96,10 +96,17 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const return QVariant(); } + FolioDelegate *delegate = m_delegates.at(index.row()); + switch (role) { case Qt::DisplayRole: case DelegateRole: - return QVariant::fromValue(m_delegates.at(index.row())); + return QVariant::fromValue(delegate); + case NameRole: + if (!delegate->application()) { + return QVariant(); + } + return m_delegates.at(index.row())->application()->name(); default: return QVariant(); } @@ -113,3 +120,11 @@ int ApplicationListModel::rowCount(const QModelIndex &parent) const return m_delegates.count(); } + +ApplicationListSearchModel::ApplicationListSearchModel(HomeScreen *parent, ApplicationListModel *model) + : QSortFilterProxyModel(parent) +{ + setFilterCaseSensitivity(Qt::CaseInsensitive); + setSourceModel(model); + setFilterRole(ApplicationListModel::NameRole); +} diff --git a/containments/homescreens/folio/applicationlistmodel.h b/containments/homescreens/folio/applicationlistmodel.h index 286efa73..4838cfb8 100644 --- a/containments/homescreens/folio/applicationlistmodel.h +++ b/containments/homescreens/folio/applicationlistmodel.h @@ -26,6 +26,7 @@ class ApplicationListModel : public QAbstractListModel public: enum Roles { DelegateRole = Qt::UserRole + 1, + NameRole, }; ApplicationListModel(HomeScreen *parent = nullptr); @@ -47,3 +48,11 @@ protected: HomeScreen *m_homeScreen{nullptr}; QList m_delegates; }; + +class ApplicationListSearchModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + ApplicationListSearchModel(HomeScreen *parent = nullptr, ApplicationListModel *model = nullptr); +}; diff --git a/containments/homescreens/folio/homescreen.cpp b/containments/homescreens/folio/homescreen.cpp index 257f0f44..f076b25b 100644 --- a/containments/homescreens/folio/homescreen.cpp +++ b/containments/homescreens/folio/homescreen.cpp @@ -17,6 +17,7 @@ HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVari , m_homeScreenState{new HomeScreenState{this}} , m_widgetsManager{new WidgetsManager{this}} , m_applicationListModel{new ApplicationListModel{this}} + , m_applicationListSearchModel{new ApplicationListSearchModel{this, m_applicationListModel}} , m_favouritesModel{new FavouritesModel{this}} , m_pageListModel{new PageListModel{this}} { @@ -26,6 +27,7 @@ HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVari const char *uri = "org.kde.private.mobile.homescreen.folio"; qmlRegisterUncreatableType(uri, 1, 0, "HomeScreen", ""); qmlRegisterUncreatableType(uri, 1, 0, "ApplicationListModel", ""); + qmlRegisterUncreatableType(uri, 1, 0, "ApplicationListSearchModel", ""); qmlRegisterUncreatableType(uri, 1, 0, "FavouritesModel", ""); qmlRegisterUncreatableType(uri, 1, 0, "PageListModel", ""); qmlRegisterUncreatableType(uri, 1, 0, "FolioSettings", ""); @@ -86,6 +88,11 @@ ApplicationListModel *HomeScreen::applicationListModel() return m_applicationListModel; } +ApplicationListSearchModel *HomeScreen::applicationListSearchModel() +{ + return m_applicationListSearchModel; +} + FavouritesModel *HomeScreen::favouritesModel() { return m_favouritesModel; diff --git a/containments/homescreens/folio/homescreen.h b/containments/homescreens/folio/homescreen.h index b911ee30..25265094 100644 --- a/containments/homescreens/folio/homescreen.h +++ b/containments/homescreens/folio/homescreen.h @@ -27,6 +27,7 @@ class WidgetsManager; class HomeScreenState; class FavouritesModel; class ApplicationListModel; +class ApplicationListSearchModel; class HomeScreen : public Plasma::Containment { @@ -35,6 +36,7 @@ class HomeScreen : public Plasma::Containment Q_PROPERTY(HomeScreenState *HomeScreenState READ homeScreenState CONSTANT) Q_PROPERTY(WidgetsManager *WidgetsManager READ widgetsManager CONSTANT) Q_PROPERTY(ApplicationListModel *ApplicationListModel READ applicationListModel CONSTANT) + Q_PROPERTY(ApplicationListSearchModel *ApplicationListSearchModel READ applicationListSearchModel CONSTANT) Q_PROPERTY(FavouritesModel *FavouritesModel READ favouritesModel CONSTANT) Q_PROPERTY(PageListModel *PageListModel READ pageListModel CONSTANT) @@ -48,6 +50,7 @@ public: HomeScreenState *homeScreenState(); WidgetsManager *widgetsManager(); ApplicationListModel *applicationListModel(); + ApplicationListSearchModel *applicationListSearchModel(); FavouritesModel *favouritesModel(); PageListModel *pageListModel(); @@ -63,6 +66,7 @@ private: HomeScreenState *m_homeScreenState{nullptr}; WidgetsManager *m_widgetsManager{nullptr}; ApplicationListModel *m_applicationListModel{nullptr}; + ApplicationListSearchModel *m_applicationListSearchModel{nullptr}; FavouritesModel *m_favouritesModel{nullptr}; PageListModel *m_pageListModel{nullptr}; }; diff --git a/containments/homescreens/folio/package/contents/ui/AppDrawer.qml b/containments/homescreens/folio/package/contents/ui/AppDrawer.qml index 60424c63..10167a61 100644 --- a/containments/homescreens/folio/package/contents/ui/AppDrawer.qml +++ b/containments/homescreens/folio/package/contents/ui/AppDrawer.qml @@ -44,6 +44,7 @@ Item { // drawer header MobileShell.BaseItem { id: drawerHeader + z: 1 height: root.headerHeight anchors.top: parent.top @@ -72,5 +73,3 @@ Item { } } } - - diff --git a/containments/homescreens/folio/package/contents/ui/AppDrawerGrid.qml b/containments/homescreens/folio/package/contents/ui/AppDrawerGrid.qml index d060e857..dff54dec 100644 --- a/containments/homescreens/folio/package/contents/ui/AppDrawerGrid.qml +++ b/containments/homescreens/folio/package/contents/ui/AppDrawerGrid.qml @@ -78,7 +78,7 @@ MobileShell.GridView { id: velocityCalculator } - model: folio.ApplicationListModel + model: folio.ApplicationListSearchModel delegate: AppDelegate { id: appDelegate diff --git a/containments/homescreens/folio/package/contents/ui/AppDrawerHeader.qml b/containments/homescreens/folio/package/contents/ui/AppDrawerHeader.qml index 280ad0ac..abf9f707 100644 --- a/containments/homescreens/folio/package/contents/ui/AppDrawerHeader.qml +++ b/containments/homescreens/folio/package/contents/ui/AppDrawerHeader.qml @@ -8,25 +8,64 @@ import QtQuick.Layouts import org.kde.kirigami as Kirigami import org.kde.plasma.components 3.0 as PlasmaComponents +import org.kde.private.mobile.homescreen.folio 1.0 as Folio +import './delegate' Item { id: root + property Folio.HomeScreen folio Kirigami.Theme.colorSet: Kirigami.Theme.Complementary Kirigami.Theme.inherit: false + function clearSearchText(): void { + searchField.text = ''; + } + RowLayout { - anchors.topMargin: Kirigami.Units.smallSpacing + anchors.topMargin: Kirigami.Units.largeSpacing anchors.leftMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing anchors.rightMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing anchors.fill: parent - spacing: Kirigami.Units.smallSpacing - QQC2.Label { - color: "white" - text: i18n("Applications") + Kirigami.SearchField { + id: searchField + onTextChanged: folio.ApplicationListSearchModel.setFilterFixedString(text) + Layout.maximumWidth: Kirigami.Units.gridUnit * 30 + Layout.alignment: Qt.AlignHCenter + + background: Rectangle { + radius: Kirigami.Units.cornerRadius + color: Qt.rgba(255, 255, 255, (searchField.hovered || searchField.focus) ? 0.2 : 0.1) + + Behavior on color { ColorAnimation {} } + } + + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Kirigami.Theme.Complementary + + topPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing + bottomPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing + Layout.fillWidth: true + + horizontalAlignment: QQC2.TextField.AlignHCenter + placeholderText: i18nc("@info:placeholder", "Search applications…") + placeholderTextColor: Qt.rgba(255, 255, 255, 0.8) + color: 'white' + font.weight: Font.Bold - font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.5 + + Connections { + target: folio.HomeScreenState + function onViewStateChanged(): void { + if (folio.HomeScreenState.viewState !== Folio.HomeScreenState.AppDrawerView) { + // Reset search field if the app drawer is not shown + if (searchField.text !== '') { + searchField.text = ''; + } + } + } + } } } } diff --git a/containments/homescreens/folio/package/contents/ui/HomeScreen.qml b/containments/homescreens/folio/package/contents/ui/HomeScreen.qml index 6d437975..ef50f945 100644 --- a/containments/homescreens/folio/package/contents/ui/HomeScreen.qml +++ b/containments/homescreens/folio/package/contents/ui/HomeScreen.qml @@ -413,8 +413,8 @@ Item { // it doesn't mess with app drag and drop from the app drawer y: (opacity > 0) ? animationY : parent.height - headerHeight: Math.round(Kirigami.Units.gridUnit * 5) - headerItem: AppDrawerHeader {} + headerHeight: Math.round(Kirigami.Units.gridUnit * 4) + headerItem: AppDrawerHeader { folio: root.folio } // account for panels topPadding: root.topMargin