homescreens/folio: Add applications drawer search bar

Add a search bar to the applications drawer, to allow for quickly filtering apps.
This commit is contained in:
Devin Lin 2024-07-01 16:04:32 +00:00
parent 49e7102f7b
commit c2791f3975
8 changed files with 85 additions and 12 deletions

View file

@ -96,10 +96,17 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
} }
FolioDelegate *delegate = m_delegates.at(index.row());
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
case DelegateRole: 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: default:
return QVariant(); return QVariant();
} }
@ -113,3 +120,11 @@ int ApplicationListModel::rowCount(const QModelIndex &parent) const
return m_delegates.count(); return m_delegates.count();
} }
ApplicationListSearchModel::ApplicationListSearchModel(HomeScreen *parent, ApplicationListModel *model)
: QSortFilterProxyModel(parent)
{
setFilterCaseSensitivity(Qt::CaseInsensitive);
setSourceModel(model);
setFilterRole(ApplicationListModel::NameRole);
}

View file

@ -26,6 +26,7 @@ class ApplicationListModel : public QAbstractListModel
public: public:
enum Roles { enum Roles {
DelegateRole = Qt::UserRole + 1, DelegateRole = Qt::UserRole + 1,
NameRole,
}; };
ApplicationListModel(HomeScreen *parent = nullptr); ApplicationListModel(HomeScreen *parent = nullptr);
@ -47,3 +48,11 @@ protected:
HomeScreen *m_homeScreen{nullptr}; HomeScreen *m_homeScreen{nullptr};
QList<FolioDelegate *> m_delegates; QList<FolioDelegate *> m_delegates;
}; };
class ApplicationListSearchModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
ApplicationListSearchModel(HomeScreen *parent = nullptr, ApplicationListModel *model = nullptr);
};

View file

@ -17,6 +17,7 @@ HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVari
, m_homeScreenState{new HomeScreenState{this}} , m_homeScreenState{new HomeScreenState{this}}
, m_widgetsManager{new WidgetsManager{this}} , m_widgetsManager{new WidgetsManager{this}}
, m_applicationListModel{new ApplicationListModel{this}} , m_applicationListModel{new ApplicationListModel{this}}
, m_applicationListSearchModel{new ApplicationListSearchModel{this, m_applicationListModel}}
, m_favouritesModel{new FavouritesModel{this}} , m_favouritesModel{new FavouritesModel{this}}
, m_pageListModel{new PageListModel{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"; const char *uri = "org.kde.private.mobile.homescreen.folio";
qmlRegisterUncreatableType<HomeScreen>(uri, 1, 0, "HomeScreen", ""); qmlRegisterUncreatableType<HomeScreen>(uri, 1, 0, "HomeScreen", "");
qmlRegisterUncreatableType<ApplicationListModel>(uri, 1, 0, "ApplicationListModel", ""); qmlRegisterUncreatableType<ApplicationListModel>(uri, 1, 0, "ApplicationListModel", "");
qmlRegisterUncreatableType<ApplicationListSearchModel>(uri, 1, 0, "ApplicationListSearchModel", "");
qmlRegisterUncreatableType<FavouritesModel>(uri, 1, 0, "FavouritesModel", ""); qmlRegisterUncreatableType<FavouritesModel>(uri, 1, 0, "FavouritesModel", "");
qmlRegisterUncreatableType<PageListModel>(uri, 1, 0, "PageListModel", ""); qmlRegisterUncreatableType<PageListModel>(uri, 1, 0, "PageListModel", "");
qmlRegisterUncreatableType<FolioSettings>(uri, 1, 0, "FolioSettings", ""); qmlRegisterUncreatableType<FolioSettings>(uri, 1, 0, "FolioSettings", "");
@ -86,6 +88,11 @@ ApplicationListModel *HomeScreen::applicationListModel()
return m_applicationListModel; return m_applicationListModel;
} }
ApplicationListSearchModel *HomeScreen::applicationListSearchModel()
{
return m_applicationListSearchModel;
}
FavouritesModel *HomeScreen::favouritesModel() FavouritesModel *HomeScreen::favouritesModel()
{ {
return m_favouritesModel; return m_favouritesModel;

View file

@ -27,6 +27,7 @@ class WidgetsManager;
class HomeScreenState; class HomeScreenState;
class FavouritesModel; class FavouritesModel;
class ApplicationListModel; class ApplicationListModel;
class ApplicationListSearchModel;
class HomeScreen : public Plasma::Containment class HomeScreen : public Plasma::Containment
{ {
@ -35,6 +36,7 @@ class HomeScreen : public Plasma::Containment
Q_PROPERTY(HomeScreenState *HomeScreenState READ homeScreenState CONSTANT) Q_PROPERTY(HomeScreenState *HomeScreenState READ homeScreenState CONSTANT)
Q_PROPERTY(WidgetsManager *WidgetsManager READ widgetsManager CONSTANT) Q_PROPERTY(WidgetsManager *WidgetsManager READ widgetsManager CONSTANT)
Q_PROPERTY(ApplicationListModel *ApplicationListModel READ applicationListModel CONSTANT) Q_PROPERTY(ApplicationListModel *ApplicationListModel READ applicationListModel CONSTANT)
Q_PROPERTY(ApplicationListSearchModel *ApplicationListSearchModel READ applicationListSearchModel CONSTANT)
Q_PROPERTY(FavouritesModel *FavouritesModel READ favouritesModel CONSTANT) Q_PROPERTY(FavouritesModel *FavouritesModel READ favouritesModel CONSTANT)
Q_PROPERTY(PageListModel *PageListModel READ pageListModel CONSTANT) Q_PROPERTY(PageListModel *PageListModel READ pageListModel CONSTANT)
@ -48,6 +50,7 @@ public:
HomeScreenState *homeScreenState(); HomeScreenState *homeScreenState();
WidgetsManager *widgetsManager(); WidgetsManager *widgetsManager();
ApplicationListModel *applicationListModel(); ApplicationListModel *applicationListModel();
ApplicationListSearchModel *applicationListSearchModel();
FavouritesModel *favouritesModel(); FavouritesModel *favouritesModel();
PageListModel *pageListModel(); PageListModel *pageListModel();
@ -63,6 +66,7 @@ private:
HomeScreenState *m_homeScreenState{nullptr}; HomeScreenState *m_homeScreenState{nullptr};
WidgetsManager *m_widgetsManager{nullptr}; WidgetsManager *m_widgetsManager{nullptr};
ApplicationListModel *m_applicationListModel{nullptr}; ApplicationListModel *m_applicationListModel{nullptr};
ApplicationListSearchModel *m_applicationListSearchModel{nullptr};
FavouritesModel *m_favouritesModel{nullptr}; FavouritesModel *m_favouritesModel{nullptr};
PageListModel *m_pageListModel{nullptr}; PageListModel *m_pageListModel{nullptr};
}; };

View file

@ -44,6 +44,7 @@ Item {
// drawer header // drawer header
MobileShell.BaseItem { MobileShell.BaseItem {
id: drawerHeader id: drawerHeader
z: 1
height: root.headerHeight height: root.headerHeight
anchors.top: parent.top anchors.top: parent.top
@ -72,5 +73,3 @@ Item {
} }
} }
} }

View file

@ -78,7 +78,7 @@ MobileShell.GridView {
id: velocityCalculator id: velocityCalculator
} }
model: folio.ApplicationListModel model: folio.ApplicationListSearchModel
delegate: AppDelegate { delegate: AppDelegate {
id: appDelegate id: appDelegate

View file

@ -8,25 +8,64 @@ import QtQuick.Layouts
import org.kde.kirigami as Kirigami import org.kde.kirigami as Kirigami
import org.kde.plasma.components 3.0 as PlasmaComponents import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
import './delegate'
Item { Item {
id: root id: root
property Folio.HomeScreen folio
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false Kirigami.Theme.inherit: false
function clearSearchText(): void {
searchField.text = '';
}
RowLayout { RowLayout {
anchors.topMargin: Kirigami.Units.smallSpacing anchors.topMargin: Kirigami.Units.largeSpacing
anchors.leftMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing anchors.leftMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
anchors.rightMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing anchors.rightMargin: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
anchors.fill: parent anchors.fill: parent
spacing: Kirigami.Units.smallSpacing
QQC2.Label { Kirigami.SearchField {
color: "white" id: searchField
text: i18n("Applications") 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.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 = '';
}
}
}
}
} }
} }
} }

View file

@ -413,8 +413,8 @@ Item {
// it doesn't mess with app drag and drop from the app drawer // it doesn't mess with app drag and drop from the app drawer
y: (opacity > 0) ? animationY : parent.height y: (opacity > 0) ? animationY : parent.height
headerHeight: Math.round(Kirigami.Units.gridUnit * 5) headerHeight: Math.round(Kirigami.Units.gridUnit * 4)
headerItem: AppDrawerHeader {} headerItem: AppDrawerHeader { folio: root.folio }
// account for panels // account for panels
topPadding: root.topMargin topPadding: root.topMargin