mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-08-01 17:24:48 +00:00
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:
parent
49e7102f7b
commit
c2791f3975
8 changed files with 85 additions and 12 deletions
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ MobileShell.GridView {
|
||||||
id: velocityCalculator
|
id: velocityCalculator
|
||||||
}
|
}
|
||||||
|
|
||||||
model: folio.ApplicationListModel
|
model: folio.ApplicationListSearchModel
|
||||||
|
|
||||||
delegate: AppDelegate {
|
delegate: AppDelegate {
|
||||||
id: appDelegate
|
id: appDelegate
|
||||||
|
|
|
||||||
|
|
@ -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 = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue